gpt4 book ai didi

c++ - 在不同的缓冲区布局中使用glVertexArrayVertexBuffer()/glVertexArrayAttribFormat()造成麻烦

转载 作者:行者123 更新时间:2023-12-02 10:02:22 35 4
gpt4 key购买 nike

我正在尝试通过直接状态访问来加快我的OpenGL代码的速度,并且一直在密切关注Guide to Modern OpenGL Functions中的代码。我有一个带有一些顶点和颜色的小测试项目,形式为:

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);
}
}

这些顶点及其索引的视觉表示:

enter image description here

我的主要绘画代码是这样的:
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);

因此,我绘制了两个灰色的三角形,索引分别为0、1、3和5、8、7。着色器中的属性位置如cpp代码中所指定:
layout (location = 3) in vec2 pos;
layout (location = 4) in vec3 col;

这有效!:

enter image description here

即使增加难度并在前面添加单个浮点值,我也可以将 glVertexArrayVertexBuffer()函数中的偏移量调整4个字节。

问题是当我想从缓冲区布局A转到B:

enter image description here

我调整数据填充循环以首先写入位置,然后输入颜色:
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);
}
}

并调整对 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);

因此,现在我的全局颜色偏移为18个浮点数(9个位置乘以两个分量),而我的 relativeoffset(即 khronos.org称呼它)的均为0。这会显示灰色的东西,但不会显示以前的样子。我对这些事情如何运作的思维模式显然是错误的-在哪里?

最佳答案

glVertexArrayVertexBuffer 的offset参数是缓冲区的第一个元素的偏移量(以字节为单位),从缓冲区的开头开始,而stride是缓冲区内连续属性之间的距离。

情况A的顶点规范错误:

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


每个顶点属性元组包含5个成分(x,y,r,g,b)。

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

因此,color属性的偏移量为 2*sizeof(float):

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

x1的字节偏移为 0
r1的字节偏移为 2 * sizeof(float)
从x1到x2的字节距离为 5 * sizeof(float)
从r1到r2的字节距离为 5 * sizeof(float)

情况B的偏移量是正确的:

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


在情况B中,有9个顶点坐标,后跟3个颜色属性。一个顶点元组具有w个分量,一个颜色元组具有3个分量:

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

因此,color属性起始位置的偏移量为 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));

x1的字节偏移为 0
r1的字节偏移为 18 * sizeof(float)
从x1到x2的字节距离是 2 * sizeof(float)
从r1到r2的字节距离为 3 * sizeof(float)

关于c++ - 在不同的缓冲区布局中使用glVertexArrayVertexBuffer()/glVertexArrayAttribFormat()造成麻烦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62005944/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com