opengl 教程(10) index draw
原帖地址:http://ogldev.atspace.co.uk/www/tutorial10/tutorial10.html
OpenGL提供了几个draw函数: 之前用的 glDrawArrays() 称作ordered draws(顺序的draw调用),如果指定draw体元为线,则顶点缓冲中按排列顺序,每2个顶点解释为线,如果体元为三角形,每三个顶点解释为三角形,在这里并没有共享的概念,比如要渲染一个四边形,就要画2个三角形,需要6个顶点。通过indexed draws,我们能实现顶点的共享,就是除了顶点缓冲外,我们会再定义一个索引缓冲,索引缓冲的值是顶点在定点缓冲中的索引值。
下面是ordered draw的例子,此时将产生v0-v1-v2, v3-v4-v5,v6-v7-v8的三角形:
下面是indexed draw的例子,此时将产生v4-v0-v1,v5-v2-v1,v6-v1-v7的三角形:
主要代码:
GLuint IBO;
增加一个缓冲对象用来存放索引。
Vertices[0] = Vector3f(-1.0f, -1.0f, 0.0f);
Vertices[1] = Vector3f(0.0f, -1.0f, 1.0f);
Vertices[2] = Vector3f(1.0f, -1.0f, 0.0f);
Vertices[3] = Vector3f(0.0f, 1.0f, 0.0f);
为了使用顶点共享,我们将渲染一个旋转的金字塔,共四个三角形,需要四个顶点。
我们沿着y轴向下俯视,我们能够得到下面俯视图:
unsigned int Indices[] = { 0, 3, 1,
1, 3, 2,
2, 3, 0,
0, 2, 1 };
索引缓冲中有12个索引,定义了四个三角形,它的值都是顶点缓冲中对应顶点的索引值。注意:我们渲染的金字塔并不是对称的。
glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
上面的三行代码,用来创建索引缓冲对象,指定类型名,并绑定到索引缓冲,注意它和顶点缓冲的区别:用GL_ELEMENT_ARRAY_BUFFER替代了GL_ELEMENT_ARRAY_BUFFER。
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_INT, 0);
最后用glDrawElements代替glDrawArrays,该函数的第一个参数是体元类型,第二个参数是索引的数量,第三个参数是索引的类型GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT等等,GPU会根据这个类型来读取索引值,如果我们的索引顶点不多,可以用范围较小的类型,这样可以提高效率,否则的话就用范围较大的类型。最后一个变量是在索引缓冲中的偏移,在我们程序中,我们是从起始位置开始,所以是0。
程序执行后界面如下,四面体将绕y轴旋转:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程