简体   繁体   English

glVertexArrayVertexBuffer() / glVertexArrayAttribFormat() 在不同缓冲区布局中的问题

[英]Trouble with glVertexArrayVertexBuffer() / glVertexArrayAttribFormat() in different buffer layouts

I'm trying to bring my OpenGL code up to speed with Direct State access and have been closely following the code from Guide to Modern OpenGL Functions .我正在尝试通过直接 State 访问使我的 OpenGL 代码加速,并且一直密切关注现代 OpenGL 函数指南中的代码。 I have a little test project with some vertices and colors in the form of:我有一个带有一些顶点和 colors 形式的小测试项目:

std::vector<float> vertices;
for (float y = -1.0f; y < 1.1f; y += 1.0f) {
    for (float x = -1.0f; x < 1.1f; x += 1.0f) {
        vertices.emplace_back(x);
        vertices.emplace_back(y);
        vertices.emplace_back(0.5f);
        vertices.emplace_back(0.5f);
        vertices.emplace_back(0.5f);
    }
}

A visual representation of those vertices and their indices:这些顶点及其索引的可视化表示:

在此处输入图像描述

My main draw code is something like this:我的主要绘制代码是这样的:

unsigned int vbo = 0;
glCreateBuffers(1, &vbo);
glNamedBufferStorage(vbo, sizeof(float) * vertices.size(), vertices.data(), GL_DYNAMIC_STORAGE_BIT);

// Indices
unsigned int indices[]{ 0,1,3,5,8,7 };
unsigned int ibo = 0;
glCreateBuffers(1, &ibo);
glNamedBufferStorage(ibo, sizeof(unsigned int) * 6, indices, GL_DYNAMIC_STORAGE_BIT);

int bindingindex_a = 1;
int bindingindex_b = 2;
int pos_location = 3;
int color_location = 4;

unsigned int vao = 0;
glCreateVertexArrays(1, &vao);
glVertexArrayVertexBuffer(vao, bindingindex_a, vbo, 0, 5 * sizeof(float));
glVertexArrayVertexBuffer(vao, bindingindex_b, vbo, 0, 5 * sizeof(float));
glVertexArrayElementBuffer(vao, ibo);

glEnableVertexArrayAttrib(vao, pos_location);
glEnableVertexArrayAttrib(vao, color_location);

glVertexArrayAttribFormat(vao, pos_location, 2, GL_FLOAT, GL_FALSE, 0);
glVertexArrayAttribFormat(vao, color_location, 3, GL_FLOAT, GL_FALSE, 2*sizeof(float));

glVertexArrayAttribBinding(vao, pos_location, bindingindex_a);
glVertexArrayAttribBinding(vao, color_location, bindingindex_b);

So I'm drawing two gray triangles with the indices 0,1,3 and 5,8,7.所以我正在绘制两个灰色三角形,索引为 0,1,3 和 5,8,7。 Attribute locations in my shader are specified as in the cpp code:我的着色器中的属性位置在 cpp 代码中指定:

layout (location = 3) in vec2 pos;
layout (location = 4) in vec3 col;

And this works::这有效::

在此处输入图像描述

Even when I increase the difficulty and add a single float value in front, I can adjust the offset in the glVertexArrayVertexBuffer() function by 4 bytes.即使我增加难度并在前面添加单个浮点值,我也可以将glVertexArrayVertexBuffer() function 中的偏移量调整 4 个字节。

The problem is when I want to go from buffer layout A to B:问题是当我想从缓冲区布局 A 到 B 的 go 时:

在此处输入图像描述

I adjust my data filling loop to first write the positions, then the colors:我调整我的数据填充循环以首先写入位置,然后是 colors:

for (float y = -1.0f; y < 1.1f; y += 1.0f) {
    for (float x = -1.0f; x < 1.1f; x += 1.0f) {
        vertices.emplace_back(x);
        vertices.emplace_back(y);
    }
}
for (float y = -1.0f; y < 1.1f; y += 1.0f) {
    for (float x = -1.0f; x < 1.1f; x += 1.0f) {
        vertices.emplace_back(0.5f);
        vertices.emplace_back(0.5f);
        vertices.emplace_back(0.5f);
    }
}

and adjust the calls to glVertexArrayVertexBuffer() and glVertexArrayAttribFormat() :并调整对glVertexArrayVertexBuffer()glVertexArrayAttribFormat()的调用:

glVertexArrayVertexBuffer(vao, bindingindex_a, vbo, 0, 2 * sizeof(float));
glVertexArrayVertexBuffer(vao, bindingindex_b, vbo, 18*sizeof(float), 3 * sizeof(float));

glVertexArrayAttribFormat(vao, pos_location, 2, GL_FLOAT, GL_FALSE, 0);
glVertexArrayAttribFormat(vao, color_location, 3, GL_FLOAT, GL_FALSE, 0);

So now my global color offset is at 18 floats (9 positions times two components) and my relativeoffset (that's how khronos.org calls it) is at 0 for both.所以现在我的全局颜色偏移量是 18 个浮点数(9 个位置乘以两个分量),而我的relativeoffset偏移量(这就是khronos.org的称呼)两者都是 0。 This displays grey things, but not the way they did before.这会显示灰色的东西,但不会像以前那样。 My mental model of how these things work is obviously wrong - where?我对这些东西如何工作的心理 model 显然是错误的——在哪里?

The offset parameter of glVertexArrayVertexBuffer is the offset of the first element of the buffer in bytes, form the begin of the buffer and stride is distance between consecutive attributes within the buffer. glVertexArrayVertexBufferoffset参数是缓冲区的第一个元素的偏移量,以字节为单位,形成缓冲区的开头, stride是缓冲区内连续属性之间的距离。


The vertex specification for case A is wrong:案例 A 的顶点规范是错误的:

 glVertexArrayVertexBuffer(vao, bindingindex_a, vbo, 0, 5 * sizeof(float)); glVertexArrayVertexBuffer(vao, bindingindex_b, vbo, 0, 5 * sizeof(float));

Each vertex attribute tuple consists of 5 components (x, y, r, g, b).每个顶点属性元组由 5 个组件(x、y、r、g、b)组成。

(x1, y1, r1, g1, b1,   x2, y2, r2, g2, b2,   x3, y3, r3, g3, b3, ...)

Hence the offset for the color attribute is 2*sizeof(float) :因此颜色属性的偏移量是2*sizeof(float)

glVertexArrayVertexBuffer(vao, bindingindex_a, vbo, 0, 5 * sizeof(float));
glVertexArrayVertexBuffer(vao, bindingindex_b, vbo, 2 * sizeof(float), 5 * sizeof(float));

The byte offset of x1 is 0 . x1的字节偏移量为0
The byte offset of r1 is 2 * sizeof(float) . r1的字节偏移量是2 * sizeof(float)
The distance in bytes from x1 to x2 is 5 * sizeof(float) .x1x2的字节距离为5 * sizeof(float)
The distance in bytes form r1 to r2 is 5 * sizeof(float) .r1r2的字节距离为5 * sizeof(float)


The offset for case B is correct:案例 B 的偏移量是正确的:

 glVertexArrayVertexBuffer(vao, bindingindex_a, vbo, 0, 2 * sizeof(float)); glVertexArrayVertexBuffer(vao, bindingindex_b, vbo, 18*sizeof(float), 3 * sizeof(float));

In case B there are 9 vertex coordinates, followed by 3 color attributes.在情况 B 中,有 9 个顶点坐标,后跟 3 个颜色属性。 A vertex tuple has w components and a color tuple has 3 components:一个顶点元组有 w 个分量,一个颜色元组有 3 个分量:

(x1, y1, x2, y2, ... x9, y9,  r1, g1, b1, r2, g2, b2, ..., r9, g9, b9)

Hence the offset of the start of the color attribute is 9*sizeof(float) (3 * (x, y)):因此颜色属性开始的偏移量是9*sizeof(float) (3 * (x, y)):

glVertexArrayVertexBuffer(vao, bindingindex_a, vbo, 0, 2 * sizeof(float));
glVertexArrayVertexBuffer(vao, bindingindex_b, vbo, 18 * sizeof(float), 3 * sizeof(float));

The byte offset of x1 is 0 . x1的字节偏移量为0
The byte offset of r1 is 18 * sizeof(float) . r1的字节偏移量是18 * sizeof(float)
The distance in bytes form x1 to x2 is 2 * sizeof(float) .x1x2的字节距离为2 * sizeof(float)
The distance in bytes from r1 to r2 is 3 * sizeof(float) .r1r2的字节距离为3 * sizeof(float)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM