在这个您好世界的示例https://github.com/jvm-graphics-labs/hello-triangle/blob/master/src/main/java/gl4/HelloTriangleSimple.java中,我试图替换元素缓冲区的内容,并通过使用glBufferSubData
进行了一些小的更改,但我对此感到好奇-在我的显示方法中,我必须先致电glBufferSubData
,然后再致电glBindVertexArray
:
gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferName.get(Buffer.ELEMENT));
elementBuffer.rewind();
elementBuffer.put(elementData).rewind();
gl.glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, elementBuffer.capacity() * Short.BYTES, elementBuffer);
gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
gl.glBindVertexArray(vertexArrayName.get(0));
如果在glBindVertexArray
之后执行此操作,则只会显示黑色窗口。奇怪的是,GL_ARRAY_BUFFER
可以在glBindVertexArray
之后进行更新。此观察结果背后的顶点缓冲区和元素缓冲区有什么区别?
答案 0 :(得分:3)
GL_ELEMENT_ARRAY_BUFFER
对象存储在顶点数组对象状态向量中。
如果绑定Vertex Array Object 可以通过以下方式将元素缓冲区附加到其上:
gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferName.get(Buffer.ELEMENT));
但如果您这样做
gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
然后将元素缓冲区对象的名称替换为0,并断开对元素的引用。这将导致gl.drawElements
对于此VAO不再起作用,因为它没有引用任何索引列表。
另外,总是有一个顶点数组对象。顶点数组对象0是默认的顶点数组对象,仅当您使用兼容性配置文件上下文(而非核心)时才有效。
这意味着
gl.glBindVertexArray(0);
gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferName.get(Buffer.ELEMENT));
会将元素缓冲区与默认的顶点数组对象(0)关联。这在兼容性配置文件上下文中完全有效。
请参见OpenGL 4.6 API Compatibility Profile Specification; 10.3.1 Vertex Array Objects; page 393:
顶点数组对象的名称空间是无符号整数,为零 GL保留以表示默认顶点数组对象。 命令
void GenVertexArrays( sizei n, uint *arrays );
返回数组中的n个先前未使用的顶点数组对象名称。
...
通过将
GenVertexArray
返回的名称与命令绑定在一起来创建顶点数组对象void BindVertexArray( uint array );
array
是顶点数组对象名称。所得的顶点数组对象是一个新的状态向量,包括所有状态,并且初始值与表23.3和23.4中列出的相同。
BindVertexArray
也可以用于绑定现有的顶点数组对象。如果绑定成功,则不会更改绑定的顶点数组对象的状态,并且任何先前的绑定都会中断。表23.4,顶点数组对象状态
ELEMENT_ARRAY_BUFFER_BINDING
,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
,VERTEX_ATTRIB_BINDING
,VERTEX_ATTRIB_RELATIVE_OFFSET
,VERTEX_BINDING_OFFSET
,VERTEX_BINDING_STRIDE
,VERTEX_BINDING_DIVISOR
,{ {1}}。