OpenGL索引绘制

OpenGL 提供了多个绘制函数。一般使用的 glDrawArrays()函数属于“顺序绘制”的类别。这意味着顶点缓冲区以指定的偏移量进行扫描,它将每 X( 1 个顶点时表示点,两个顶点表示线,等等)个顶点作为一个图元。这种方法使用起来很方便,但是它的缺点是如果有多个图元共享通一个顶点,那么这个被共享的顶点就会在顶点缓冲区中存在多次。即,在顺序绘制中不存在共享的概念。要实现顶点的共享,我们需要使用与“索引绘制”相关的函数,实际上在 OpenGL 中除了顶点缓冲区之外还有索引缓冲区,索引缓冲区中存放的是指向顶点缓冲区内顶点的索引。

        扫描索引缓冲区和扫描顶点缓冲区相似:都是以每 X 个索引作为一个图元,为了实现共享,你仅需要重复使用共享顶点的索引即可。顶点共享对于内存效率来说是非常重要的,因为场景中的大多数对象都是由相互紧挨着的三角形封闭网格来表现,所以大多数顶点都是被多个三角形共享的。

如果我们用上面的数据绘制三角形,GPU将依据后面的数据序列进行绘制:V0/1/2,V3/4/5,V6/7/8 等。

在此情况下,GPU 将依据后面的数据序列进行绘制:V4/0/1,V5/2/1,V6/1/7等。

使用 OpenGL 中的索引绘制要求生成并填充一个索引缓冲区,而且它必须在调用绘制命令之前使用不同于绑定顶点缓存区的API将其绑定。

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);

unsigned intIndices[] = { 0, 3, 1,

                          1, 3, 2,

                          2, 3, 0,

                         0, 1, 2 };

在这个索引缓冲区中我们使用索引数组来填充。索引值与顶点缓冲区中顶点的位置相对应。由索引数组和上面的示意图你能看出,最后一个三角形是角锥底座而其它三三角形组成了角锥的三个面。角锥不是对称的,但对我们来说很容易生成。

glGenBuffers(1, &IBO);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);

glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices),

Indices, GL_STATIC_DRAW);

我们创建一个索引缓存并使用索引数组填充索引缓冲区。你可以看到,创建顶点缓冲区和索引缓冲区唯一的区别是,顶点缓存使用 GL_ARRAY_BUFFER 作为缓冲区类型,而索引缓存使用 GL_ELEMENT_ARRAY_BUFFER 作为缓冲区类型。

在绘制之前,除了绑定顶点缓存之外,我们还必须绑定索引缓存。我们再一次使用 GL_ELEMENT_ARRAY_BUFFER 作为缓冲类型。

glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_INT, 0);

在绘制的时候我们调用 glDrawElements 函数而不是 glDrawArrays 函数。第一个参数是要绘制的图元的类型(与 glDrawArrays 相同)。第二个参数是图元生成所要用到的索引缓冲区中索引的数量。第三个参数是每个索引的类型,GPU 必须被告知每个索引的大小,否则它就不知道如何解析缓冲区。这里我们也有其他参数可供选择,如 GL_UNSIGNED_BYTE,GL_UNSIGNED_SHORT 和 GL_UNSIGNED_INT。如果索引的范围较小,那么你也许会想用占用内存空间较小的数据类型以节约空间;如果索引范围较大,你也许会想用占用内存空间较大的数据类型以满足数据的索引。最后一个参数告诉 GPU 要进行绘制的第一个索引的位置相对于索引缓冲区起始位置的偏移量的字节数。当相同的索引缓冲区包含多个对象的索引时,这是很有用的。通过指定偏移量和偏移数,你能告诉 GPU 要渲染哪个对象。本例中我们要从索引缓冲区的起始地址进行绘制,所以我们将其指定为 0。请注意,最后一个参数的类型是 GLvoid* 的,因此如果您指定 0 以外的其他值,你需要将它转换为这种类型。

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenGL是一种图形绘制库,用于创建各种图形效果和动画。在绘制mesh(网格)时,我们可以使用OpenGL绘制函数和几何变换来实现。以下是使用OpenGL绘制mesh的一般步骤: 1. 初始化OpenGL环境:包括创建窗口、设置视口、初始化OpenGL相关设置等。 2. 加载mesh数据:读取网格模型的顶点、法线、纹理坐标等信息。通常可以使用支持多种文件格式的库来加载mesh数据,例如Open Asset Import Library(Assimp)。 3. 创建并绑定顶点缓冲对象(Vertex Buffer Object,VBO):将mesh的顶点数据(包括坐标、法线、纹理坐标等)存储到VBO中。 4. 创建并绑定索引缓冲对象(Index Buffer Object,IBO):将mesh的索引数据(指示顶点绘制顺序的索引值)存储到IBO中。 5. 创建着色器程序:编写顶点着色器和片段着色器,用于处理顶点和片段的着色逻辑。 6. 设置顶点属性指针:告诉OpenGL如何解析VBO中的数据,以便正确渲染mesh。 7. 启用深度测试:根据需要设置深度测试,以保证mesh的正确渲染顺序。 8. 绑定纹理(如果有):如果mesh需要贴图渲染,可以先加载纹理数据,并将其绑定到对应的纹理单元上。 9. 渲染mesh:使用顶点和索引缓冲对象绘制mesh。可以使用glDrawElements函数指定绘制方式(如三角形、线段等)和数量。 10. 释放资源:当绘制完成后,需要释放申请的缓冲对象、着色器程序、纹理等资源。 使用上述步骤,我们可以利用OpenGL绘制mesh,实现各种复杂的图形效果和动画。绘制mesh时,可以根据需求对材质、光照、纹理等进行调整,以获得想要的视觉效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值