Graphics BindBuffer和BufferData背靠背调用
在OpenGL ES(或者在我的例子中是WebGL)中,我不知道如何将顶点和颜色缓冲区背靠背绑定,然后调用DrawArray。例如,这里有一些示例代码供您理解: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();
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
sogl。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
?简单的答案是肯定的。我认为这是一个极好的答案。