我知道如何创建顶点和碎片着色器,以及如何创建顶点数组并将它们放在缓冲区中,但我如何将两者联系起来呢?意思是-当我运行我的程序时,它怎么知道当前活动缓冲区中的顶点数组应该被“馈送”到顶点着色器?这是通过使用glVertexAttribPointer简单地完成的吗?
glVertexAttribPointer
hzbexzde1#
它怎么知道当前活动缓冲区中的顶点数组应该被“馈送”到顶点着色器“当前活动缓冲区”,即GL_ARRAY_BUFFER,在绘制调用期间不使用。其唯一目的是告知glVertexAttribPointer函数将哪个缓冲区绑定到 VAO 。一旦建立此连接,即可解除绑定GL_ARRAY_BUFFER。......但我如何将两者联系起来呢?顶点数组和顶点着色器之间的链接是当前活动的顶点数组对象( VAO )。管道将从绑定到VAO的缓冲区中获取着色器所需的顶点属性。将 VAO 状态总结为以下伪C定义可能会有所帮助:
GL_ARRAY_BUFFER
struct VertexArrayObject { // VertexArrayElementBuffer uint element_buffer; struct Binding { // VertexArrayVertexBuffers uint buffer; intptr offset; sizei stride; // VertexArrayBindingDivisor uint divisor; } bindings[]; struct Attrib { // VertexArrayAttribBinding uint binding; // This is an index into bindings[] // EnableVertexArrayAttrib bool enabled; // VertexArrayAttrib*Format int size; enum type; boolean normalized; boolean integer; boolean long; uint relativeoffset; } attribs[]; };
注解中提到了相应的OpenGL 4.5 DSA函数,可用于设置相应的状态。当您使用glVertexAttribPointer时,它实际上在当前绑定的 VAO 上执行以下操作:
vao.attribs[index].binding = index; vao.attribs[index].size = size; vao.attribs[index].type = type; vao.attribs[index].normalized = normalized; vao.attribs[index].relativeoffset = 0; vao.bindings[index].buffer = current ARRAY_BUFFER; vao.bindings[index].offset = pointer; vao.bindings[index].stride = stride; // if stride == 0 computes based on size and type
请注意,glVertexAttribPointer调用将“active”缓冲区绑定到 VAO ,如果使用直接状态访问API(DSA)设置VAO,则甚至不需要“activate”任何缓冲区。
1条答案
按热度按时间hzbexzde1#
它怎么知道当前活动缓冲区中的顶点数组应该被“馈送”到顶点着色器
“当前活动缓冲区”,即
GL_ARRAY_BUFFER
,在绘制调用期间不使用。其唯一目的是告知glVertexAttribPointer
函数将哪个缓冲区绑定到 VAO 。一旦建立此连接,即可解除绑定GL_ARRAY_BUFFER
。......但我如何将两者联系起来呢?
顶点数组和顶点着色器之间的链接是当前活动的顶点数组对象( VAO )。管道将从绑定到VAO的缓冲区中获取着色器所需的顶点属性。
将 VAO 状态总结为以下伪C定义可能会有所帮助:
注解中提到了相应的OpenGL 4.5 DSA函数,可用于设置相应的状态。
当您使用
glVertexAttribPointer
时,它实际上在当前绑定的 VAO 上执行以下操作:请注意,
glVertexAttribPointer
调用将“active”缓冲区绑定到 VAO ,如果使用直接状态访问API(DSA)设置VAO,则甚至不需要“activate”任何缓冲区。