【发布时间】:2014-07-30 21:01:02
【问题描述】:
我是现代 OpenGL VBO/VAO 的新手,我为一件事而苦恼:我已经基于 this tutorial 编写了一个 RectangleAsset,但我不确定如何将有关纹理 UV 的信息移动到 RactangleAssetInstance(我的矩形可以有不同的纹理)。
我必须为其创建新的 VAO,还是可以通过其他方式传递 UV?或者为 UV 添加第二个 VBO?最重要的是:解决这个问题的最佳实践是什么?
struct RectangleAsset {
GLuint VBO;
GLuint VAO;
};
struct RectangleAssetInstance { //this is actually more complex class in my code
RectangleAsset rect; //but tried to extract the most imporatant code
glm::mat4 transform;
Texture * texture;
void UpdateTransform(int,int,int,int);
private:
int x,y,width,height;
};
以及加载 RectangleAsset 的函数:
void GUIRenderer::init()
{
image = new Program ("vs.glsl", "fs.glsl");
glGenVertexArrays(1, &rect.VAO);
glBindVertexArray(rect.VAO);
glGenBuffers(1, &rect.VBO);
glBindBuffer(GL_ARRAY_BUFFER, rect.VAO);
GLfloat vertexData[] = {
// X Y Z U V
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
};
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
glEnableVertexAttribArray(image->attrib("vert"));
glVertexAttribPointer(image->attrib("vert"), 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), NULL);
glEnableVertexAttribArray(image->attrib("vertTexCoord"));
glVertexAttribPointer(image->attrib("vertTexCoord"), 2, GL_FLOAT, GL_TRUE, 5*sizeof(GLfloat), (const GLvoid*)(3 * sizeof(GLfloat)));
glBindVertexArray(0);
}
注意:我计划只在一个地方使用 RectangleAssetInstances,在一个 std::vector 中进行 GUI 渲染(非静态 gui)。将所有矩形合并到一个 VBO 和 VAO 中可能是个好主意(并在添加/删除 UIElement 时重新创建它)?
欢迎任何学习 OpenGL 最佳实践的建议。
【问题讨论】:
-
我认为每个属性都需要 1 个 VBO。虽然,您可以在同一个 VAO 中拥有所有数据(顶点和纹理坐标),并使用
glVertexAttribPointer的stride参数来指定属性之间的跳转。我通常为每个属性设置 1 个 VBO 和 1 个 VAO。不过,我不知道最佳做法是什么。 -
如果我理解正确的话,RectangleAssetInstance 应该同时具有 UV VBO 和 UV VAO(在构造函数中生成),对吧?那么合并呢,是不是有很多短缓冲区效率低下?
-
你可以这样做。不过,如果您愿意,您可以为
vertices和texture coordinates使用相同的 VAO。这是如何工作的?我们可以在glVertexAttribPointer上的每个属性的数据之间设置stride(jump)。对于顶点我会调用glVertexAttribPointer(start pos=0, size=3, stride=2)和UVglVertexAttribPointer(start pos=2, size=2, stride=3。类似的东西。 -
我认为,这就是资产教程中的内容。好吧...我想如果 UV 和 Vert 缓冲区都在 RectangleAssetInstance 中,那么保留 RectangleAsset 是没有意义的。
标签: c++ opengl vbo opengl-3 vao