概述
如何让一个2D图形看起来有3D的效果呢?把我们之前学习的坐标变换应用到顶点着色器即可,概括来说需要我们定义三个矩阵
- 模型矩阵:负责将局部空间坐标转化为世界坐标空间;
- 观察矩阵:让物体在我们的观察范围内;
-
投影矩阵
我们要绘制的第一个3D图形看起来像下面这样:
变换矩阵的实现
- 模型矩阵
在这个例子中,我们的笑脸箱子看来像放在地上一样。怎么做呢?我们将顶点数据围绕X轴进行旋转,创建模型矩阵如下:
glm::mat4 model(1.0f);
model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0f, 0.0f, 0.0f));
- 观察矩阵
接下来移动场景让物体变得可见,将整个场景向后移动,创建观察矩阵如下:
glm::mat4 view(1.0f);
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
- 投影矩阵
在此例中我们使用投影矩阵,创建矩阵如下:
glm::mat4 projection(1.0f);
projection = glm::perspective(glm::radians(45.0f),
float(LEARN_OPEN_GL::SCR_WIDTH/LEARN_OPEN_GL::SCR_HEIGHT),
0.1f,
100.0f);
着色器的实现
在此例中我们使用在使用两个纹理渲染时的顶点着色器和片段着色器,将它们拷贝一份重命名为5_1_3d.vs, 5_1_3d.fs,片段着色器不用修改,进行顶点着色器的修改:
- 定义三个uniform矩阵;
- 修改顶点位置的计算方式;
实现如下:
#version 330 core
layout (location=0) in vec3 aPos;
layout (location=1) in vec3 aColor;
layout (location=2) in vec2 aTexCoord;
out vec3 ourColor;
out vec2 TexCoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection*view*model*vec4(aPos, 1.0f);
ourColor = aColor;
TexCoord = aTexCoord;
}
渲染类的实现
渲染类定义为draw3D_0,以以两个纹理渲染类drawRectanleWithTwoTex为基础,在_bindData方法中进行矩形的定义和像顶点着色器传入矩阵的操作,定义矩阵使用上面的方法,传入着色器的操作如下:
//传入顶点着色器
m_pShader->use();
GLuint locModel = glGetUniformLocation(m_pShader->ID, "model");
glUniformMatrix4fv(locModel, 1, GL_FALSE, glm::value_ptr(model));
GLuint locView = glGetUniformLocation(m_pShader->ID, "view");
glUniformMatrix4fv(locView, 1, GL_FALSE, glm::value_ptr(view));
GLuint locProjection = glGetUniformLocation(m_pShader->ID, "projection");
glUniformMatrix4fv(locProjection, 1, GL_FALSE, glm::value_ptr(projection));