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

时间:2016-07-04 22:36:20

标签: c++ opengl shader geometry-instancing

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

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

  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;
    
  4. 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错误。

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

1 个答案:

答案 0 :(得分:2)

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

这些是制服,而不是输入值。他们不受属性的影响;他们通过glUniform*电话接听。如果您希望Model成为输入值,请使用in而不是uniform对其进行限定。

同样重要的是,输入和制服不会获得相同的位置。我的意思是统一的位置与输入位置有不同的空间。输入可以具有与统一相同的位置索引,并且它们不会引用相同的内容。输入位置仅涉及属性索引;统一的位置指的是统一的位置。

最后,统一位置不像输入位置那样工作。对于属性,每个vec4 - 等效使用单独的属性索引。对于统一的位置,每个基本类型(任何不是结构或数组的东西)都使用单个统一位置。因此,如果ViewProj是一个统一的位置,那么它只占用一个位置。但如果Model是输入,那么它会占用4个属性索引。