gpt4 book ai didi

VAO 中的 C++ GLSL 多个 IBO

转载 作者:行者123 更新时间:2023-11-28 06:45:15 25 4
gpt4 key购买 nike

我正在开发一个小项目,我正在使用 VBO、IBO 和 VAO,我有一个顶点数组及其各自的数组索引,我对 Material 做同样的事情(因为相同的顶点可以有不同的另一边的 Material ),但是 VAO 中的这个链接同样不显示任何内容。每个 VAO 都必须是 IBO?

附件是我的代码,分别向gpu和render发送数据!

非常感谢您的帮助,问候 :)

void Upload(){
GLuint ibo[2], vbo[3];

glGenBuffers(3, vbo);
glGenBuffers(2, ibo);
glGenVertexArrays(1, vao);

glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); //Vertices
glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(vec3), vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]); //Normales
glBufferData(GL_ARRAY_BUFFER, vertex_normal.size()*sizeof(vec3), vertex_normal.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[0]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, v_indices.size()*sizeof(GLuint), v_indices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

glBindBuffer(GL_ARRAY_BUFFER, vbo[2]); //Material
glBufferData(GL_ARRAY_BUFFER, materials.size()*sizeof(Material), materials.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indices.size()*sizeof(GLuint), m_indices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

glBindVertexArray(vao[0]);
//Vertices:
glEnableVertexAttribArray(attrib_vertex);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glVertexAttribPointer(attrib_vertex, 3, GL_FLOAT, GL_FALSE, 0, 0);
//Normales:
glEnableVertexAttribArray(attrib_normal);
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glVertexAttribPointer(attrib_normal, 3, GL_FLOAT, GL_FALSE, 0, 0);
//IBO:
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[0]);

//Materiales:
for(int i=0; i<5; ++i)
glEnableVertexAttribArray(attrib_material+i);
glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
glVertexAttribPointer(attrib_material, 4, GL_FLOAT, GL_FALSE, sizeof(Material), NULL);
glVertexAttribPointer(attrib_material+1, 4, GL_FLOAT, GL_FALSE, sizeof(Material), (void*)offsetof(Material, diffuse));
glVertexAttribPointer(attrib_material+2, 4, GL_FLOAT, GL_FALSE, sizeof(Material), (void*)offsetof(Material, specular));
glVertexAttribPointer(attrib_material+3, 4, GL_FLOAT, GL_FALSE, sizeof(Material), (void*)offsetof(Material, emission));
glVertexAttribPointer(attrib_material+4, 1, GL_FLOAT, GL_FALSE, sizeof(Material), (void*)offsetof(Material, shininess));

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[1]);

//Desactivando todo:
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(attrib_vertex);
glDisableVertexAttribArray(attrib_normal);
for(int i=0; i<5; ++i)
glDisableVertexAttribArray(attrib_material+i);
}
void Draw(){
glBindVertexArray(vao[0]);
glDrawElements(GL_TRIANGLES, v_indices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}

最佳答案

每个 VAO 存储当前 GL_ELEMENT_ARRAY_BUFFER_BINDING 的值。

当您调用 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[0])glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[1]) 时设置该存储值。

您的代码的问题是您对 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,...) 的第二次调用覆盖了第一次调用存储的值。发生这种情况是因为每个 VAO 只能为 GL_ELEMENT_ARRAY_BUFFER_BINDING 存储一个值。也就是说,每个 VAO 只允许 1 个 IBO。

我提出的一些解决方案:

  • 您可以以不同方式存储 Material 数据,使其与网格中的索引匹配。这可能意味着您需要复制 Material 数据。
  • 您可以将 Material 数据存储在统一缓冲区中,然后将 Material 数据的索引作为每个顶点的顶点属性存储在统一缓冲区中。
  • 您的 Material 似乎定义了光照信息。也许您可以将渲染分成多个 channel 。 (即环境 channel 、漫反射 channel 、镜面反射 channel ……)像延迟照明这样的渲染方法将使这不是问题。
  • 您可以将顶点索引和 Material 合并到一个大 IBO 中。 (可能与我提到的其他方法结合使用。)
  • 如果您的数据符合该模式,您或许可以使用 glVertexAttribDivisor

无论哪种方式,核心问题是每个 VAO 只能有 1 个 IBO。您必须发挥创造力才能找到适合您使用的解决方案。祝你好运!

关于VAO 中的 C++ GLSL 多个 IBO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25135574/

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