我对实例绘图和每个实例数据比较熟悉:过去我已成功实现了这一点。
现在我正在重构一些旧代码,并且我介绍了如何将每个实例数据提供给着色器的错误。 相关位如下:
我有一个vbo存储我的对象的世界变换。我使用AMD的CodeXL来调试这个:缓冲区正确填充数据,并在绘制框架时绑定。
glBindBuffer(GL_ARRAY_BUFFER,batch.mTransformBuffer); glBufferData(GL_ARRAY_BUFFER,sizeof(glm :: mat4)* OBJ_NUM,& xforms,GL_DYNAMIC_DRAW);
着色器明确指定输入位置:
#version 450
layout(location = 0) in vec3 vertexPos;
layout(location = 1) in vec4 vertexCol;
//...
layout(location = 6)uniform mat4 ViewProj;
layout(location = 10)uniform mat4 Model;
ViewProj
矩阵对于所有实例都相同,并使用以下方式正确设置:
glUniformMatrix4fv(6, 1, GL_FALSE, &viewProjMat[0][0]);
Model
是每个实例世界矩阵,它是错误的:包含全零。
在绑定缓冲区之后和绘制每个帧之前,我试图设置属性指针和除数,使得每个绘制的实例都将接收不同的变换:
for (size_t i = 0; i < 4; ++i)
{
glEnableVertexAttribArray(10 + i);
glVertexAttribPointer(10 + i, 4, GL_FLOAT, GL_FALSE,
sizeof(GLfloat) * 16,
(const GLvoid*) (sizeof(GLfloat) * 4 * i));
glVertexAttribDivisor(10 + i, 1);
}
现在,我看了一会儿代码,我真的无法弄清楚我错过了什么。 CodeXL清楚地表明模型(位置10)未正确填充。没有生成OpenGL错误。
我的问题是:有没有人知道在每种情况下每个实例数据的设置可能会无声地失败?或者有关如何进一步调试此问题的任何建议?
答案 0 :(得分:2)
layout(location = 6)uniform mat4 ViewProj; layout(location = 10)uniform mat4 Model;
这些是制服,而不是输入值。他们不受属性的影响;他们通过glUniform*
电话接听。如果您希望Model
成为输入值,请使用in
而不是uniform
对其进行限定。
同样重要的是,输入和制服不会获得相同的位置。我的意思是统一的位置与输入位置有不同的空间。输入可以具有与统一相同的位置索引,并且它们不会引用相同的内容。输入位置仅涉及属性索引;统一的位置指的是统一的位置。
最后,统一位置不像输入位置那样工作。对于属性,每个vec4
- 等效使用单独的属性索引。对于统一的位置,每个基本类型(任何不是结构或数组的东西)都使用单个统一位置。因此,如果ViewProj
是一个统一的位置,那么它只占用一个位置。但如果Model
是输入,那么它会占用4个属性索引。