OpenGL统一缓冲区对象(数组)跳过其他Vec2

时间:2014-11-11 22:19:03

标签: c++ debugging opengl

enter image description here

问题

这些白线之间不应有间隙。这些线由正方形组成(最终我不会生成另一个巨大的正方形;这是用于调试)。出于某种原因,当我通过我的统一缓冲区对象(下面的示例)发送数据时,我得到了空白。它几乎就像是在跳过其他y值。每个位置实际上有两个正方形,而不是一个在(y),一个在(y + 1)。

代码段

生成数据指针数组

blockData = new glm::vec2[24*24];
for (int x = 0; x < 24; x++) {
    for (int y = 0; y < 24; y++) {
        int i = x * 24 + y;
        blockData[i] = glm::vec2(x, y);
    }
}

在渲染类

glBindBuffer(GL_UNIFORM_BUFFER, ubo);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::vec2) * blocksActive, blockData);
glBindBufferRange(GL_UNIFORM_BUFFER, uniBlockData, ubo, 0, sizeof(glm::vec2) * blocksActive);
glBindBuffer(GL_UNIFORM_BUFFER, 0);

glBindVertexArray(vao);
glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)0, blocksActive);
glBindVertexArray(0);

顶点着色器(GLSL)

layout (std140) uniform blockData {
    vec2 blockDataPosition[5184];
};

测试

  • 当我将blockData[i] = glm::vec2(x, y);更改为blockData[i] = glm::vec2(y, x);(切换y和x)时,间隙会移至x轴。
  • 我尝试在for循环中切换x和y,但它不会影响它。此问题以某种方式与y变量相关联。
  • 如果我在int i = x * 24 + y;
  • 中切换x和y,会有什么影响
  • 将vec2设置为(x,x)会产生正确放置的对角线。
  • 将vec2设置为(y,y)会导致奇怪的对角线(下方)
  • 在切换到UBO之前,我只是在着色器中使用了一个制服,它工作正常。这就是为什么我认为它与我通过UBO发送数据有关。 enter image description here

1 个答案:

答案 0 :(得分:2)

那么正在发生的事情很可能是对齐问题。使用std140,您必须对齐4个浮点数。但是,如果没有看到所有代码,我就无法完全确定您是如何缓冲数据的。但是,我可以建议使用glGetActiveUniformsiv查询块偏移量,然后根据它对齐对象。所以一个典型的例子就是:

    char* bufferNames[] = [generate the values with a for loop, this should be pretty easy with string and sprintf e.g "blockData.blockDataPosition[0]" to "block.Data.blockDataPosition[5184]"];

    GLuint uniformBlockIndex = glGetUniformBlockIndex(yourprogram, "block name");

    GLuint uniformIndices[number of names in bufferNames];

    glGetUniformIndices(yourprogram, the number of names in bufferNames, bufferNames, indices);

    GLint uniformOffsets[the number of names in bufferNames];

    glGetActiveUniformsiv(yourprogram, 1, &uniformIndices, GL_UNIFORM_OFFSET, uniformOffsets);

抵消将告诉您需要知道的一切。它们是每个名称的偏移量(以字节为单位)。您可以使用for循环来填充每个偏移量,或者只是将其打印出来以查看所有内容是如何对齐的。这不应该在循环中完成,而是一次用于初始化等。 如果您有任何问题或需要更具体的示例,请告诉我。