计算机图形学作业( 三):使用openGL画一个立方体,并实现平移、旋转和放缩变换
- 题目
- 引入GLM库
- 画立方体
- 模型、观察和投影
- 修改着色器
- 立方体的顶点
- 深度测试
- 立方体变换
- 平移
- 旋转
- 放缩
- 渲染管线的理解
- 代码
题目
引入GLM库
利用 openGL 进行 3D 绘图需要用到大量的数学矩阵运算,而 OpenGL 没有自带任何的矩阵和向量知识,需要我们自己定义数学类和函数,这相对比较麻烦。所以我们需要引入 GLM 库,GLM 能快速帮助我们实现各种数学矩阵运算。
前往 GLM官方github仓库,选择0.9.8.5版本,下载该版本的 glm-0.9.8.5.zip 或 glm-0.9.8.5.zip 压缩包,解压之后,在项目里引用以下文件即可:
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
画立方体
模型、观察和投影
利用 openGL 进行 3D 绘图时,首先要定义一个模型矩阵 model,这个矩阵包含了对 3D 物体的位移、缩放与旋转操作。这个模型矩阵创建如下:
glm::mat4 model;
model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0f, 0.0f, 0.0f));
然后,我们需要创建一个观察矩阵,因为我们创建的 3D 物体默认在世界坐标的原点(0, 0, 0),而摄像机的位置也是(0, 0, 0),所以,为了能看清楚3D物体的全貌,我们必须向前移动整个场景,这就是观察矩阵的作用。
在 openGL 中,世界坐标系的坐标表示为(x, y, z),分别对应下图位置:
注意,将摄像机向后移动,和将整个场景向前移动是一样的。这里我们将场景向 z 轴的负方向移动,以便于摄像机能观察到物体。
glm::mat4 view;
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
最后我们需要做的是定义一个投影矩阵。我们希望在场景中使用透视投影,所以像这样声明一个投影矩阵:
glm::mat4 projection;
projection = glm::perspective(glm::radians(45.0f), screenWidth / screenHeight, 0.1f, 100.0f);
修改着色器
我们创建了模型、观察和投影矩阵,应该把它们传入着色器,着色器的修改如下:
const char* vertexShaderSource = "#version 330 core\n""layout (location = 0) in vec3 aPos;\n""layout (location = 1) in vec3 aColor;\n""out vec3 ourColor;\n""uniform mat4 model;\n""uniform mat4 view;\n""uniform mat4 projection;\n""void main()\n""{\n""gl_Position = projection * view * model * vec4(aPos, 1.0);\n""ourColor = aColor;\n""}\0";
然后再程序中获取 uniform 变量,并赋值
//获取着色器程序uniform
unsigned int modelLoc = glGetUniformLocation(shaderProgram, "model");
unsigned int viewLoc = glGetUniformLocation(shaderProgram, "view");
unsigned int projectionLoc = glGetUniformLocation(shaderProgram, "projection");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, &view[0][0]);
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, &projection[0][0]);
立方体的顶点
要想渲染一个立方体,我们一共需要36个顶点(6个面 x 每个面有2个三角形组成 x 每个三角形有3个顶点),顶点如下:
float vertices[] = {-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,0.5f, -0.5f, -0.5f