提问者:小点点

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


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

现在我正在重构一些旧代码,并介绍了一个关于每个实例数据如何提供给着色器的bug。

>

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

    GL_ARRAY_BUFFER; glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4)*OBJ_NUM,

    着色器显式指定输入位置:

    #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]);
    

    模型是每个实例的世界矩阵,这是错误的:包含所有零。

    绑定缓冲区后,在绘制每个帧之前,我尝试设置属性指针和除数,以便每个绘制的实例都会收到不同的转换:

    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个答案

    匿名用户

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

    这些是制服,而不是输入值。他们不受属性的影响;他们被glUniform*调用喂养。如果您希望Model作为输入值,那么在中使用来限定它,而不是uniform

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

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