Webgl 何时释放顶点阵列对象?

Webgl 何时释放顶点阵列对象?,webgl,Webgl,释放顶点数组对象的准则是什么,例如绑定到null 有趣的是,我似乎可以有类似的着色器,我只需要在一些分组后发布。。。还是在每个分组着色器之后执行此操作的最佳实践 我想在每次绘制调用之后都有另一种可能,即使它们是由着色器批处理的,但我认为这不是必要的…不清楚您在问什么。“何时释放纹理”。当你用完它的时候?我想你的意思是“解开”而不是“释放”。在大多数编程中,“释放”意味着从内存中删除或至少允许从内存中删除 假设您的意思是何时解除绑定顶点数组对象(VAO),事实上您永远不必解除绑定VAO 如其他地方

释放顶点数组对象的准则是什么,例如绑定到null

有趣的是,我似乎可以有类似的着色器,我只需要在一些分组后发布。。。还是在每个分组着色器之后执行此操作的最佳实践


我想在每次绘制调用之后都有另一种可能,即使它们是由着色器批处理的,但我认为这不是必要的…

不清楚您在问什么。“何时释放纹理”。当你用完它的时候?我想你的意思是“解开”而不是“释放”。在大多数编程中,“释放”意味着从内存中删除或至少允许从内存中删除

假设您的意思是何时解除绑定顶点数组对象(VAO),事实上您永远不必解除绑定VAO

如其他地方所述,VAO包含所有属性状态和
元素\u数组\u缓冲区
绑定so

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 ...
  ]
};
只要您记得
gl.bindBuffer(gl.ELEMENT\u ARRAY\u BUFFER,someBuffer)
影响当前VAO中的状态,而不是像
gl.bindBuffer(gl.ARRAY\u BUFFER)
那样的全局状态

我认为这是最令人困惑的部分。大多数WebGL方法都可以更清楚地了解受影响的内容
gl.bufferXXX
影响缓冲区,
gl.texXXX
影响纹理
gl.renderbufferXXX
renderbuffers,
gl.framebufferXX
framebuffers,
gl.vertexXXX
影响顶点属性(VAO)。等但是
gl.bindBuffer
是不同的,至少在这种情况下,当绑定到
ARRAY\u BUFFER
时,它会影响全局状态,但当绑定到
ELEMENT\u ARRAY\u 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\u ARRAY\u BUFFER,…)
会影响当前VAO

为什么要绑定
null
VAO?主要是因为我经常忘记上面的段落,因为VAOs
元素\u数组\u缓冲区之前是全局状态。因此,当我忘记了这一点,我随机绑定了一些
元素数组缓冲区
,这样我就可以在其中放置一些索引,我刚刚更改了当前VAO中的
元素数组缓冲区
绑定。可能不是我想做的事。通过绑定
null
,比方说在初始化所有对象和渲染循环之后,我就不太可能导致该错误

还请注意,如果我确实想更新某些几何体的索引,这意味着我想调用
gl.bufferData
gl.bufferSubData
,我可以确定我正在以两种方式之一影响正确的缓冲区。一种方法是将该缓冲区绑定到
元素\u数组\u缓冲区
,然后调用
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个形状,假设我想改变球体中的索引。我可以用两种方法

首先,我可以直接绑定球体的元素数组缓冲区

 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereElementArrayBuffer)
 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER...);  // update the indices
问题是,如果绑定了其他VAO,我只是更改了它的元素\数组\缓冲区绑定

第二,我可以绑定球体的VAO,因为它已经绑定了元素数组缓冲区

 gl.bindVertexArray(sphereVAO);
 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, ...);  // update the indices
这看起来更安全


重申一下,元素\u数组\u缓冲区绑定是VAO状态的一部分。

不清楚您在问什么。“何时释放纹理”。当你用完它的时候?我想你的意思是“解开”而不是“释放”。在大多数编程中,“释放”意味着从内存中删除或至少允许从内存中删除

假设您的意思是何时解除绑定顶点数组对象(VAO),事实上您永远不必解除绑定VAO

如其他地方所述,VAO包含所有属性状态和
元素\u数组\u缓冲区
绑定so

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 ...
  ]
};
只要您记得
gl.bindBuffer(gl.ELEMENT\u ARRAY\u BUFFER,someBuffer)
影响当前VAO中的状态,而不是像
gl.bindBuffer(gl.ARRAY\u BUFFER)
那样的全局状态

我认为这是最令人困惑的部分。大多数WebGL方法都可以更清楚地了解受影响的内容
gl.bufferXXX
影响缓冲区,
gl.texXXX
影响纹理
gl.renderbufferXXX
renderbuffers,
gl.framebufferXX
framebuffers,
gl.vertexXXX
影响顶点属性(VAO)。等但是
gl.bindBuffer
是不同的,至少在这种情况下,当绑定到
ARRAY\u BUFFER
时,它会影响全局状态,但当绑定到
ELEMENT\u ARRAY\u 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\u ARRAY\u BUFFER,…)
会影响当前VAO

为什么要绑定
null
VAO?主要是因为我经常忘记上面的段落,因为VAOs
元素\u数组\u缓冲区之前是全局状态。因此,当我忘记了这一点,我随机绑定了一些
元素数组缓冲区
,这样我就可以在其中放置一些索引,我刚刚更改了当前VAO中的
元素数组缓冲区
绑定。可能不是我想做的事。通过绑定
null
,比方说在初始化所有对象和渲染循环之后,我就不太可能导致该错误

还请注意,如果我确实想更新某些几何体的索引,这意味着我想调用
gl.bufferData
gl.bufferSubData
,我可以确定我正在以两种方式之一影响正确的缓冲区。一种方法是将该缓冲区绑定到
元素\u数组\u缓冲区
,然后调用
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个形状,假设我想改变球体中的索引。我可以用两种方法