物联网
您现在所在的位置:首页>企业动态>物联网

OpenGL 3D

编辑:学到牛牛IT培训    发布日期: 2023-10-13 09:04:30  


1.从2D到3D:

到目前为止,我们一直都在使用一个2D平面,而且甚至是在3D空间里!所以,让我们大胆地拓展我们的2D平面为一个3D立方体。要想渲染一个立方体,我们一共需要36个顶点(6个面 x 每个面有2个三角形组成 x 每个三角形有3个顶点)

我们将原来的顶点数据:

1.png

修改为:

2.png


然后我们使用glDrawArrays来绘制立方体,但这一次总共有36个顶点。

如果操作无误,效果应该是:

3.png

这确实是一个立方体,但是立方体某些本应该被遮挡的面被绘制在了这个立方体其他面之上。这是因为OpenGL在绘制时是以一个三角形一个三角形地来绘制你的立方体,所以即便之前那里有东西他也会覆盖之前的像素。

为了解决这个问题,我们就不得不了解一个叫做Z缓冲的缓冲。


2.Z缓冲

OpenGL存储它的所有深度信息于一个Z缓冲(Z-buffer)中,也被称为深度缓冲(Depth Buffer)。GLFW会自动为你生成这样一个缓冲(就像它也有一个颜色缓冲来存储输出图像的颜色)。深度值存储在每个片段里面(作为片段的z值),当片段想要输出它的颜色时,OpenGL会将它的深度值和z缓冲进行比较,如果当前的片段在其它片段之后,它将会被丢弃,否则将会覆盖。这个过程称为深度测试(Depth Testing),它是由OpenGL自动完成的。

我们可以使用glEnable函数来开启深度测试:

glEnable(GL_DEPTH_TEST);

因为我们使用了深度测试,我们也想要在每次渲染迭代之前清除深度缓冲(否则前一帧的深度信息仍然保存在缓冲中)。就像清除颜色缓冲一样,我们可以通过在glClear函数中指定DEPTH_BUFFER_BIT位来清除深度缓冲:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

现在就达到了我们想要的效果:

4.png

3.绘制更多的立方体

如果我们想在屏幕上显示10个立方体。每个立方体看起来都是一样的,区别在于它们在世界的位置及旋转角度不同。立方体的图形布局已经定义好了,所以当渲染更多物体的时候我们不需要改变我们的缓冲数组和属性数组,我们唯一需要做的只是改变每个对象的模型矩阵来将立方体变换到世界坐标系中。

首先,让我们为每个立方体定义一个位移向量来指定它在世界空间的位置。我们将在一个glm::vec3数组中定义10个立方体位置:

5.png

接着,我们只需要调用十次glDrawArrays,只是我们在渲染之前每次传入一个不同的模型矩阵到顶点着色器中就可以了。需要注意的是我们可以对每个箱子加一点旋转。

glBindVertexArray(VAO); 

for(unsigned int i = 0; i < 10; i++) { 

glm::mat4 model; 

model = glm::translate(model, cubePositions[i]); 

float angle = 20.0f * i; 

model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f)); 

ourShader.setMat4("model", model); 

glDrawArrays(GL_TRIANGLES, 0, 36); 

}


最终,我们就可以得到以下的效果:

6.png

免费试学
课程好不好,不如实地听一听

封闭学习

2

1

联系我们

电话:028-61775817

邮箱:1572396657@qq.com

地址:成都市金牛区西城国际A座8楼

  • 物联网_物联网专题新闻_物联网IOT资讯-学到牛牛
    物联网_物联网专题新闻_物联网IOT资讯-学到牛牛

    扫一扫,免费咨询

  • 物联网_物联网专题新闻_物联网IOT资讯-学到牛牛
    物联网_物联网专题新闻_物联网IOT资讯-学到牛牛

    微信公众号

  • 物联网_物联网专题新闻_物联网IOT资讯-学到牛牛
物联网_物联网专题新闻_物联网IOT资讯-学到牛牛

学一流技术,找高薪工作

物联网_物联网专题新闻_物联网IOT资讯-学到牛牛

7-24小时服务热线:

028-61775817

版权声明 网站地图

蜀ICP备2021001672号

课程问题轻松问