我知道如何创建顶点着色器和片段着色器,并创建顶点数组并将它们放入缓冲区,但如何将两者链接起来呢?
也就是说,当我运行程序时,它如何知道当前活动缓冲区上的顶点数组应该被"喂"到顶点着色器中?
这是否只需要使用glVertexAttribPointer来完成?
也就是说,当我运行程序时,它如何知道当前活动缓冲区上的顶点数组应该被"喂"到顶点着色器中?
这是否只需要使用glVertexAttribPointer来完成?
GL_ARRAY_BUFFER
在绘制调用期间“不被使用”,它仅仅是告诉glVertexAttribPointer
函数应该绑定哪个缓冲区到VAO上。一旦建立了这种连接,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
函数调用将“活动”缓冲区绑定到VAO。如果您使用直接状态访问API(DSA)设置VAO,则甚至不需要激活任何缓冲区。
glVertexAttribPointer
来告诉GPU如何处理缓冲区中的数据? - gambit20088glVertexAttribPointer
的第一个参数中,我写了一个着色器变量的引用,是吗?这就是程序知道将顶点发送到着色器的方式吗? - gambit20088layout(location = n)
指定它。 - Yakov GalkaglVertexAttribPointer
等的缓冲区... 然后绑定另一个VAO,并使用其他数据和不同的指针创建不同的缓冲区,然后我可以在VAO之间切换,随后的绘制调用将使用当前绑定的VAO? - gambit20088