OpenGL 实例化:如何调试丢失的每个实例数据

OpenGL instancing : how to debug missing per instance data

我对实例化绘图和每个实例数据比较熟悉:我过去成功地实现了这一点。

现在我正在重构一些旧代码,并且我引入了一个关于如何将每个实例数据提供给着色器的错误。 相关位如下:

  1. 我有一个使用 glMultiDrawElementsIndirect 实现的工作渲染循环:如果我忽略每个实例数据,一切都会按预期绘制。
  2. 我有一个 vbo 存储我的对象的世界变换。我使用 AMD 的 CodeXL 进行调试:缓冲区已正确填充数据,并在绘制帧时绑定。

    glBindBuffer(GL_ARRAY_BUFFER,batch.mTransformBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4) * OBJ_NUM, &xforms, GL_DYNAMIC_DRAW);

  3. 着色器明确指定输入位置:

    #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 错误。

我的问题是:有人知道在什么情况下每个实例数据的设置可能会无提示地失败吗?或者关于如何进一步调试此问题的任何建议?

layout(location = 6)uniform mat4 ViewProj;
layout(location = 10)uniform mat4 Model;

这些是制服,不是输入值。他们不受属性的影响;他们被 glUniform* 个电话喂饱了。如果您希望 Model 作为输入值,则使用 in 限定它,而不是 uniform.

同样重要的是,输入和制服的位置不同。我的意思是统一位置与输入位置有不同的 space。输入可以具有与制服相同的位置索引,并且它们不会指代同一事物。输入位置仅指属性索引; uniform locations指的是统一的位置。

最后,统一位置与输入位置不同。对于属性,每个 vec4 等价物使用一个单独的属性索引。有了统一的位置,每个基本类型(任何不是结构或数组的类型)都使用一个统一的位置。所以如果ViewProj是一个统一的位置,那么它只占1个位置。但是如果Model是一个输入,那么它就占用了4个属性索引。