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

标签 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

最佳答案

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

    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 循环来填充每个偏移量,或者只是将其打印出来以查看所有内容是如何对齐的。这不应该在循环中完成,而是一次用于初始化等。 如果您有任何问题或需要更具体的示例,请告诉我。

关于c++ - OpenGL 统一缓冲对象(数组)跳过其他 Vec2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26875669/

相关文章:

c++ - 为什么我们需要在编译期间包含 C 或 CPP 声明文件而不是像 iostream 这样的默认库?

C++:在没有事件异常的情况下终止调用(GCC)

c++ - 必须使用 'class' 标记来引用此范围内的类型 '____'

ios - iOS设备上的Phonegap调试需要拔出/插入才能工作

c++ - OpenGL - 使用两个 GL 程序改变顶点的位置

opengl - 如何找出我的 OpenGL 可以在其颜色缓冲区上表示多少种颜色?

c++ - 我无法向 C++ 字符串添加新行

php - NetBeans + XDebug 断点不起作用

c - GluProject 未在 C 中显示准确的坐标

android - 将应用程序移植到安卓