OpenGL / OpenGLES VBO是否只保持相同大小的顶点?
我问,因为我发现glDrawElements的参数只有索引缓冲区的偏移值(它的最后一个参数),这意味着: 1.如果已经部分填充缓冲区,我必须手动抵消我的索引,然后再将其提交给IBO。无论如何,手动偏移索引很容易,所以这里不是问题。 2.用作顶点缓冲区的VBO必须保持相同大小的顶点,否则索引无意义。
此行为与DirectX Vertex Buffer不同,在directx中,有一个SetStreamSource,可用于偏移Verterx Buffer,以及DrawIndexedPrimitive,您的VB可以保存任意大小的顶点。
也许OpenGLES 1.1版本的SetStreamSource不可用?也许OpenGLES 2.0会支持它吗?
我的目标平台是iPhone OpenGLES 1.1,所以如果GL版本的SetStreamSource不可用我将放弃使用VBO,因为: 1.它带来了更多的麻烦(我将不得不分配许多持有不同大小顶点的VBO) 2.无论如何都没有性能改进(OpenGLES 1.1中没有硬件支持)
感谢阅读并感谢您分享您在OpenGLES 1.1中使用VBO的正确方法的经验。谢谢。
答案 0 :(得分:1)
OpenGL缓冲区对象(VBO是其中一种使用模式)可以包含任意信息。但是绘制函数(如glDrawElements
)对相同格式的顶点信息的连续数组起作用(显然,每个顶点占据相同的大小)。如果这是你要问的尺寸 - 那么我看不出它是如何改变的。
如果要使用特定偏移量的VBO(例如,包含不同格式的顶点) - 那么最后一个参数为glVertexAttribPointer
。绑定VBO时,最后一个参数是用于顶点属性的数据段的字节偏移量。
答案 1 :(得分:1)
当你说你有不同大小的顶点时,我不确定我完全明白你的意思。但是OpenGL可以处理D3D可以使用的任何顶点格式。
OpenGL没有的是顶点“流”的概念。那是因为它不需要它们;将每个单独的属性(位置,法线,颜色等)视为单独的流。但它们都可以来自同一个缓冲区,它们可以互相交织在一起。
缓冲对象的工作方式非常简单。缓冲区对象只是一个由OpenGL控制的大小的内存块。你可以在里面输入你想要的任何字节。
要告诉OpenGL如何从中获取顶点数据,必须定义多个数组,每个数组都与一个属性相关联。其功能是glVertexPointer,glNormalPointer等;它们都是gl * Pointer的形式。你似乎已经掌握了很多。
您可能不理解的是,这些函数定义的顶点格式不会与缓冲区对象永久关联。例如,您可以使用具有字节颜色的3D位置,所有这些都来自同一个缓冲区对象:
glBindBuffer(GL_ARRAY_BUFFER, bufferObject);
glEnableClientState(GL_VERTEX_ARRAY); //Our vertices contain positions.
glVertexPointer(3, GL_FLOAT, 16, (void*)0); //The last parameter is the byte offset from the beginning of the buffer to where the data starts.
glEnableClientState(GL_COLOR_ARRAY); //Our vertices contain colors.
glColorPointer(4, GL_UNSIGNED_BYTE, 16, (void*)12); //Offset must add in the 3 floats from the vertex.
//Draw stuff.
然后,您可以重新定义此指针,然后根据需要更改格式。这一次,我们使用2D定位,定义为短裤,根本没有颜色:
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_SHORT, 4, (void*)1024);
glDisableClientState(GL_COLOR_ARRAY); //Our vertices contain no colors.
//Draw stuff.
这些调用之间的缓冲区绑定没有改变。这个新数组从缓冲区的开头开始1024个字节。因此,您可以将多个对象的数据放在同一个缓冲区中。
现在,OpenGL ES 1.1没有提供D3D的功能。调用DrawIndexedPrimitives时,可以提供在从数组中提取顶点之前添加到每个索引的偏移量。桌面OpenGL 3.2及更高版本提供了此功能(通过扩展程序提供较低版本),但不提供ES 1.1。