gpt4 book ai didi

c++ - OpenGL 优化网格绘图(VAO?没有索引?)

转载 作者:行者123 更新时间:2023-11-30 02:40:11 25 4
gpt4 key购买 nike

好的,超时后我继续研究 OpenGL3.2+,现在我对如何优化这样的东西感到困惑:

// Verts
glBindBuffer(GL_ARRAY_BUFFER, VertBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * size, verts, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(VERTEX_COORD_ATTRIB);
glVertexAttribPointer(VERTEX_COORD_ATTRIB,3,GL_FLOAT, GL_FALSE, sizeof(float) * floatsPerVertex, 0);

// Textures
glBindBuffer(GL_ARRAY_BUFFER, TexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * texsize, tex, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(TEXTURE_COORD_ATTRIB);
glVertexAttribPointer(TEXTURE_COORD_ATTRIB, 2, GL_FLOAT, GL_FALSE, sizeof(float) * TexCoords2D, 0);

//add light color info
glBindBuffer(GL_ARRAY_BUFFER, ColorBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * colorsize, lightcolor, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(COLOR_ATTRIB);
glVertexAttribPointer(COLOR_ATTRIB, 4, GL_FLOAT, GL_FALSE, sizeof(float) * ColorInfo, 0);

// Draw
glDrawArrays(GL_TRIANGLES, 0, size);

// Clean up
glDisableVertexAttribArray(VERTEX_COORD_ATTRIB);
glDisableVertexAttribArray(TEXTURE_COORD_ATTRIB);
glDisableVertexAttribArray(COLOR_ATTRIB);

让我们假设这是为几个网格完成的,目前每个网格总是像这样被推送、绑定(bind)、缓冲和绘制。不用说,这肯定不是有效的方法。

现在,在阅读(许多)教程时,我总是看到的一件事是建议使用 VAO 来改进它,现在我难以理解的是 - 每个单独的教程似乎都在这种关系中引用了索引绘图。虽然这种方法在使用像 2 个四边形这样极其简单的示例时似乎非常好,但我现在想知道应该如何为真正的复杂网格创建索引?或者只是假设这是可用的(由于 .obj 文件或其他原因)。此外,我对 VAO 是否总是需要索引或者是否可以在没有索引的情况下使用感到困惑?如果是这样,没有它甚至有意义吗,因为我读到优化利用了对索引的了解?你看这里还有很多困惑,我意识到这可能又是一个愚蠢的问题:)

不过,我最终想要实现的是,不是像这样推送每个网格,而是将每个网格在显卡内存中缓冲一次,然后从缓冲区中重新绘制。我还不知道 VAO 是否是正确的方法,但我阅读的每个教程似乎都将 VAO 作为下一步。

最佳答案

首先,您应该将使用 glBufferData() 的 GRAM 写入与使用 glDrawArrays() 的绘图调用分开。这会显着降低您的性能,因为您基本上是在每次绘图调用时将数据从 RAM 复制到 GRAM。

为此,您可以使用 VAO:

//设置缓冲区

glBindVertexArray(VertexArrayIndex);

glBindBuffer(GL_ARRAY_BUFFER, VertBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * size, verts, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(VERTEX_COORD_ATTRIB);
glVertexAttribPointer(VERTEX_COORD_ATTRIB,3,GL_FLOAT, GL_FALSE, sizeof(float) * floatsPerVertex, 0);

// Textures
glBindBuffer(GL_ARRAY_BUFFER, TexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * texsize, tex, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(TEXTURE_COORD_ATTRIB);
glVertexAttribPointer(TEXTURE_COORD_ATTRIB, 2, GL_FLOAT, GL_FALSE, sizeof(float) * TexCoords2D, 0);

//add light color info
glBindBuffer(GL_ARRAY_BUFFER, ColorBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * colorsize, lightcolor, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(COLOR_ATTRIB);
glVertexAttribPointer(COLOR_ATTRIB, 4, GL_FLOAT, GL_FALSE, sizeof(float) * ColorInfo, 0);

glBindVertexArray(0);

//你的绘图调用

glBindVertexArray(VertexArrayIndex);
glDrawArrays(GL_TRIANGLES, 0, size);
glBindVertexArray(0);

如果您想绘制非常大的网格(它们的大小比您显卡上可用的 GRAM 大),您应该对将数据分成小块感兴趣。将所有这些数据放在一个大数组中可能会导致一些讨厌的内存分配和渲染问题(相信我 - 我遇到过这种情况;))。

关于c++ - OpenGL 优化网格绘图(VAO?没有索引?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29150246/

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