具有不同纹理UV的矩形实例

时间:2014-07-30 21:01:03

标签: c++ opengl vbo opengl-3 vao

我是现代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 个答案:

答案 0 :(得分:2)

VAO存储输入数据的格式和输入数据的来源位置。这实际上是两个独立的概念。如果要更改UV的来源,必须再次调用glVertexAttribPointer。此调用看起来像glVertexAttribPointer(uvLoc, GL_FLOAT, false, sizeof(float) * 5, (const GLvoid*)(sizeof(float) * 3))注意,这不会改变您的位置信息来自的VBO。

现在你提到你想要这样做,因为你的矩形实例可能有不同的纹理。您无需更改UV以实现此目的。在一般位置,UV和法线都是网格的一部分,您只需要它们的一个副本。要更改纹理,只需调用glActiveTexture(GL_TEXTURE0 + i),然后调用glBindTexture(GL_TEXTURE_2D, tex),然后在着色器中设置采样器均匀,以使用带有glUniform1i(samplerLoc, i)的正确图像单元

还有ARB_vertex_attrib_binding扩展,它成为OpenGL 4.3的核心。这允许您将属性布局与数据位置分开。 OpenGL wiki上的文章提供了有关如何执行此操作的信息,但同样最好使用相同的UV为给定网格创建所有纹理。

关于将所有内容合并到一个VAO和VBO中的问题:如果您只想要矩形而不是这样,那么您可以使用具有非均匀缩放分量的仿射变换获得任何类型的矩形。因此,您只需要一个VAO和一个VBO,并且不需要合并任何东西。

相关问题