Graphics BindBuffer和BufferData背靠背调用

Graphics BindBuffer和BufferData背靠背调用,graphics,opengl-es,webgl,Graphics,Opengl Es,Webgl,在OpenGL ES(或者在我的例子中是WebGL)中,我不知道如何将顶点和颜色缓冲区背靠背绑定,然后调用DrawArray。例如,这里有一些示例代码供您理解: vertexBuffer = glCreateBuffer(); glBindBuffer(GL_ARRAY_BUFFER, vertextBuffer); glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW); colorBuffer = glCreateBuffer();

在OpenGL ES(或者在我的例子中是WebGL)中,我不知道如何将顶点和颜色缓冲区背靠背绑定,然后调用DrawArray。例如,这里有一些示例代码供您理解:

vertexBuffer = glCreateBuffer();
glBindBuffer(GL_ARRAY_BUFFER, vertextBuffer);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);

colorBuffer = glCreateBuffer();
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glBufferData(GL_ARRAY_BUFFER, colors, GL_STATIC_DRAW);

glDrawArrays(GL_TRIANGLES, 0, numberOfVertices);
如果我先将GL_ARRAY_BUFFER绑定到顶点、bufferData,然后再绑定一些颜色,那么幕后会发生什么?在我看来,顶点信息似乎应该被忽略,因为我将颜色信息绑定到GL_数组缓冲区,就在它之后。

glDrawArrays()
根本不关心绑定的是什么。它确实关心顶点属性指针


在这里真正重要的东西并没有显示在您粘贴的代码中:属性指针设置。调用
glVertexAttribPointer()
时,对当前绑定的
GL\u数组\u缓冲区的引用将成为attrib指针的一部分。不同的属性可以来自不同的VBO,也可以使用一个VBO作为属性的源,这完全取决于您。

gl。VertexAttributePointer
实际设置哪些属性使用哪些缓冲区

你可以把它想象成

gl = { 
   arrayBuffer: someBuffer, 
   vertexArray: {
     elementArrayBuffer: someOtherBuffer,
     attributes: [], 
   },
};
调用
gl.bindBuffer
时,您只需在gl状态下设置两个全局变量之一

gl.bindBuffer = function(bindPoint, buffer) {
   switch (bindPoint) {
      case: this.ARRAY_BUFFER:
         this.arrayBuffer = buffer;
         break;
      case: this.ELEMENT_ARRAY_BUFFER:
         this.vertexArray.elementArrayBuffer = buffer;
         break;
   }
};
调用
gl.VertexAttributePointer
时,它会将
arrayBuffer
的当前值复制到指定的属性

gl.vertexAttribPointer = function(index, size, type, normalized, stride, offset) {
    var attribute = this.vertexArray.attributes[index];
    attribute.size = size;
    attribute.type = type;
    attribute.normalized = normalized;
    attribute.stride = stride;
    attribute.offset = offset;
    attribute.buffer = this.arrayBuffer;  // copies the current buffer reference.
};
除了只有一个全局变量外,纹理的工作方式类似

gl = { 
    activeTextureUnit: 0,
    textureUnits: [], 
};
gl.activeTexture
设置您正在使用的纹理单元

gl.activeTexture = function(unit) {
   this.activeTextureUnit = unit - this.TEXTURE_0;  // make it zero based.
};
每个纹理单元都有一个
texture\u 2D
和一个
texture\u CUBEMAP
so
gl。bindTexture(b,t)
是有效的

gl.bindTexture = function(bindPoint, texture) {
   var textureUnit = this.textureUnits[this.activeTextureUnit];
   switch (bindPoint) {
       case this.TEXTURE_2D:
           textureUnit.texture2D = texture;
           break;
       case this.TEXTURE_CUBEMAP:
           textureUnit.textureCubeMap = texture;
           break;
   }
};

这是一个

事实上,如果这是您的全部代码,那么它不起作用,因为您没有设置任何顶点数组指针。是的,opengl i缺少的一点是顶点属性的赋值,这是@derhass解释的。很抱歉这个坏例子(现在我知道我误解了什么)。啊,好吧,我想我现在明白了。它类似于GL_ARRAY_BUFFER,只是一个全局变量,用于实现glvertexttribpointer。如果我执行我在示例中所做的操作,但不调用glVertexAttribPointer,那么它将不起作用,因为GL_ARRAY_缓冲区将在通过glVertexAttribPointer.Well分配给着色器属性之前被覆盖。
GL\u ARRAY\u BUFFER
绑定是GL状态的一部分,实际上是全局绑定(wrt.GL上下文)。是的,在设置顶点属性指针时,此状态是相关的。它还与其他一些事情相关,尤其是当使用
GL\u ARRAY\u BUFFER
目标时,任何带有缓冲区的GL函数操作。这是我根据前面的答案在脑海中看到的,但非常感谢您将其写出来@gman那么这是否意味着如果海报想要设置颜色和顶点属性(我认为他想要这样做),他必须调用
gl.vertexAttribPointer
,并在调用
gl.bindBuffer
之间调用
gl.enableVertexAttribArray
?简单的答案是肯定的。我认为这是一个极好的答案。