发布顶点数组对象有哪些指导原则,例如:绑定到null?
有趣的是,似乎我可以拥有类似的着色器,我只需要在一些分组之后发布......或者是在每个分组着色器之后执行此操作的最佳做法?
我想在每次抽奖之后还有另一种可能性,即使他们是由着色器进行批处理,但我认为没必要......
答案 0 :(得分:1)
目前还不清楚你在问什么。 "何时发布纹理"。当你完成使用它?我认为你的意思是"解开"不是"发布"。 "释放"在大多数编程中意味着从内存中删除或至少允许从内存中删除。
假设你的意思是什么时候取消绑定顶点数组对象(VAO),事实是你永远不必解开VAO。
正如其他所解释的那样,VAO包含所有属性状态和ELEMENT_ARRAY_BUFFER
绑定所以
currentVAO = {
elementArrayBuffer: someIndexBuffer,
attributes: [
{ enabled: true, size: 3, type: gl.FLOAT, stride: 0, offset: 0, buffer: someBuffer, },
{ enabled: true, size: 3, type: gl.FLOAT, stride: 0, offset: 0, buffer: someBuffer, },
{ enabled: true, size: 3, type: gl.FLOAT, stride: 0, offset: 0, buffer: someBuffer, },
{ enabled: false, size: 3, type: gl.FLOAT, stride: 0, offset: 0, buffer: null, },
{ enabled: false, size: 3, type: gl.FLOAT, stride: 0, offset: 0, buffer: null, },
{ enabled: false, size: 3, type: gl.FLOAT, stride: 0, offset: 0, buffer: null, },
...
... up to MAX_VERTEX_ATTRIBS ...
]
};
只要您记住当前VAO中的gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, someBuffer)
影响状态,而不是像gl.bindBuffer(gl.ARRAY_BUFFER)
那样的全局状态。
我认为这是最令人困惑的部分。大多数WebGL方法更清楚地说明受影响的gl.bufferXXX
影响缓冲区,gl.texXXX
影响纹理。 gl.renderbufferXXX
渲染缓冲区,gl.framebufferXX
帧缓冲区,gl.vertexXXX
影响顶点属性(VAO)。但是gl.bindBuffer
至少在这种情况下不同,它在绑定到ARRAY_BUFFER
时会影响全局状态,但在绑定到ELEMENT_ARRAY_BUFFER
时会影响VAO状态。
我的建议是在初始化期间按照这个顺序执行这些步骤
for each object
1. create VAO
2. create vertex buffers and fill with data
3. setup all attributes
4. create index buffers (ELEMENT_ARRAY_BUFFER) and fill with data
在渲染时间
for each object
1. use program (if program is different)
2. bind VAO for object (if different)
3. set uniforms and bind textures
4. draw
要记住的重要事项是,如果您曾致电gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ...)
影响当前的VAO。
为什么我要绑定null
VAO?主要是因为我经常忘记上面的段落,因为在VAO ELEMENT_ARRAY_BUFFER
之前是全球状态。所以,当我忘记了这一点并且我随机绑定了一些ELEMENT_ARRAY_BUFFER
以便我可以在其中添加一些索引时,我刚刚更改了当前VAO中的ELEMENT_ARRAY_BUFFER
绑定。可能不是我想做的事情。通过绑定null
,比如在初始化所有对象之后和渲染循环之后,我不太可能导致该错误。
另请注意,如果我确实要更新某些几何体的索引,这意味着我想调用gl.bufferData
或gl.bufferSubData
我可以肯定我会影响2中的正确缓冲区之一方法。一种方法是将缓冲区绑定到ELEMENT_ARRAY_BUFFER
,然后调用gl.bufferData
。另一种是通过绑定适当的VAO。
如果那没有意义,那么假设我有3个VAO
// pseudo code
forEach([sphere, cube, torus])
create vao
create buffers and fill with data
create indices (ELEMENT_ARRAY_BUFFER)
fill out attributes
现在我有3个形状可以说我想改变球体中的指数。我可以做两种方式
一,我可以直接绑定球体的ELEMENT_ARRAY_BUFFER
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereElementArrayBuffer)
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER...); // update the indices
这有一个问题,如果其他一些VAO被绑定我只是改变它的ELEMENT_ARRAY_BUFFER绑定
二,我可以绑定球体的VAO,因为它已经得到了ELEMENT_ARRAY_BUFFER绑定
gl.bindVertexArray(sphereVAO);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, ...); // update the indices
这似乎更安全的IMO。
重申一下,ELEMENT_ARRAY_BUFFER绑定是VAO状态的一部分。