C++ 如何将多个纹理应用于立方体的VBO?

C++ 如何将多个纹理应用于立方体的VBO?,c++,opengl,textures,vbo,C++,Opengl,Textures,Vbo,我是VBO的新手,读了一些关于创建和使用VBO的文章。我正在开发一个应用程序,我想创建一打旋转立方体。我连接到一个服务器,该服务器将文本消息推送到我的应用程序。当我收到6条文本消息时,我使用Pango和Cairo呈现这些消息。然后,我想从这6条渲染的消息中创建纹理,并将其应用于新的立方体 虽然我通常只使用2D纹理并将其应用于GL_四边形,但我不确定如何将6个纹理应用于使用VBOs创建的立方体 我发现了一个关于如何使用VBO创建多维数据集的示例。它们的创建方式如下: VBO // v6---

我是VBO的新手,读了一些关于创建和使用VBO的文章。我正在开发一个应用程序,我想创建一打旋转立方体。我连接到一个服务器,该服务器将文本消息推送到我的应用程序。当我收到6条文本消息时,我使用Pango和Cairo呈现这些消息。然后,我想从这6条渲染的消息中创建纹理,并将其应用于新的立方体

虽然我通常只使用2D纹理并将其应用于GL_四边形,但我不确定如何将6个纹理应用于使用VBOs创建的立方体

我发现了一个关于如何使用VBO创建多维数据集的示例。它们的创建方式如下:

VBO

//    v6----- v5
//   /|      /|
//  v1------v0|
//  | |     | |
//  | |v7---|-|v4
//  |/      |/
//  v2------v3

GLfloat vertices[] = {1,1,1,  -1,1,1,  -1,-1,1,  1,-1,1,        // v0-v1-v2-v3
                          1,1,1,  1,-1,1,  1,-1,-1,  1,1,-1,        // v0-v3-v4-v5
                          1,1,1,  1,1,-1,  -1,1,-1,  -1,1,1,        // v0-v5-v6-v1
                          -1,1,1,  -1,1,-1,  -1,-1,-1,  -1,-1,1,    // v1-v6-v7-v2
                          -1,-1,-1,  1,-1,-1,  1,-1,1,  -1,-1,1,    // v7-v4-v3-v2
                          1,-1,-1,  -1,-1,-1,  -1,1,-1,  1,1,-1};   // v4-v7-v6-v5

    // normal array
    GLfloat normals[] = {0,0,1,  0,0,1,  0,0,1,  0,0,1,             // v0-v1-v2-v3
                         1,0,0,  1,0,0,  1,0,0, 1,0,0,              // v0-v3-v4-v5
                         0,1,0,  0,1,0,  0,1,0, 0,1,0,              // v0-v5-v6-v1
                         -1,0,0,  -1,0,0, -1,0,0,  -1,0,0,          // v1-v6-v7-v2
                         0,-1,0,  0,-1,0,  0,-1,0,  0,-1,0,         // v7-v4-v3-v2
                         0,0,-1,  0,0,-1,  0,0,-1,  0,0,-1};        // v4-v7-v6-v5

    // color array
    GLfloat colors[] = {1,1,1,  1,1,0,  1,0,0,  1,0,1,              // v0-v1-v2-v3
                        1,1,1,  1,0,1,  0,0,1,  0,1,1,              // v0-v3-v4-v5
                        1,1,1,  0,1,1,  0,1,0,  1,1,0,              // v0-v5-v6-v1
                        1,1,0,  0,1,0,  0,0,0,  1,0,0,              // v1-v6-v7-v2
                        0,0,0,  0,0,1,  1,0,1,  1,0,0,              // v7-v4-v3-v2
                        0,0,1,  0,0,0,  0,1,0,  0,1,1};             // v4-v7-v6-v5

    glGenBuffersARB(1, &vbo_id);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_id);
    glBufferDataARB(
        GL_ARRAY_BUFFER_ARB
        ,sizeof(vertices)+sizeof(normals)+sizeof(colors)
        ,0
        ,GL_STATIC_DRAW_ARB
    );


    glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(vertices), vertices);
    glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertices), sizeof(normals),normals);
    glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertices)+sizeof(normals), sizeof(colors), colors);  // copy colours after normals
    s_vertices = sizeof(vertices);
    s_colors = sizeof(colors);
    s_normals = sizeof(colors);

    cube = new Cube(vbo_id, ofxVec3f(0.0, 0.0, 0.0),0.1, s_vertices, s_colors, s_normals);
#include "Cube.h"
Cube::Cube(
    GLuint nVBO
    ,ofxVec3f oPosition
    ,float fSize
    ,int nVertices
    ,int nNormals
    ,int nColors
)
:vbo_id(nVBO)
,position(oPosition)
,size(fSize)
,s_vertices(nVertices)
,s_normals(nNormals)
,s_colors(nColors)  
{
r = 0;
}

void Cube::update() {
}


void Cube::draw() {
    glPushMatrix();

        glTranslatef(position.x,position.y,position.z);
        glRotatef((r++),0,1,0);
        glScalef(size, size, size);

        // bind VBOs with IDs and set the buffer offsets of the bound VBOs
        // When buffer object is bound with its ID, all pointers in gl*Pointer()
        // are treated as offset instead of real pointer.
        glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_id);

        // enable vertex arrays
        glEnableClientState(GL_NORMAL_ARRAY);
        glEnableClientState(GL_COLOR_ARRAY);
        glEnableClientState(GL_VERTEX_ARRAY);


        // before draw, specify vertex and index arrays with their offsets
        glNormalPointer(GL_FLOAT, 0, (void*)s_vertices);
        glColorPointer(3, GL_FLOAT, 0, (void*)(s_vertices+s_normals));
        glVertexPointer(3, GL_FLOAT, 0, 0);

        glDrawArrays(GL_QUADS, 0, 24);

        glDisableClientState(GL_VERTEX_ARRAY);  // disable vertex arrays
        glDisableClientState(GL_COLOR_ARRAY);
        glDisableClientState(GL_NORMAL_ARRAY);

        // it is good idea to release VBOs with ID 0 after use.
        // Once bound with 0, all pointers in gl*Pointer() behave as real
        // pointer, so, normal vertex array operations are re-activated
        glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
        glPopMatrix();

}
使用VBO的多维数据集类

//    v6----- v5
//   /|      /|
//  v1------v0|
//  | |     | |
//  | |v7---|-|v4
//  |/      |/
//  v2------v3

GLfloat vertices[] = {1,1,1,  -1,1,1,  -1,-1,1,  1,-1,1,        // v0-v1-v2-v3
                          1,1,1,  1,-1,1,  1,-1,-1,  1,1,-1,        // v0-v3-v4-v5
                          1,1,1,  1,1,-1,  -1,1,-1,  -1,1,1,        // v0-v5-v6-v1
                          -1,1,1,  -1,1,-1,  -1,-1,-1,  -1,-1,1,    // v1-v6-v7-v2
                          -1,-1,-1,  1,-1,-1,  1,-1,1,  -1,-1,1,    // v7-v4-v3-v2
                          1,-1,-1,  -1,-1,-1,  -1,1,-1,  1,1,-1};   // v4-v7-v6-v5

    // normal array
    GLfloat normals[] = {0,0,1,  0,0,1,  0,0,1,  0,0,1,             // v0-v1-v2-v3
                         1,0,0,  1,0,0,  1,0,0, 1,0,0,              // v0-v3-v4-v5
                         0,1,0,  0,1,0,  0,1,0, 0,1,0,              // v0-v5-v6-v1
                         -1,0,0,  -1,0,0, -1,0,0,  -1,0,0,          // v1-v6-v7-v2
                         0,-1,0,  0,-1,0,  0,-1,0,  0,-1,0,         // v7-v4-v3-v2
                         0,0,-1,  0,0,-1,  0,0,-1,  0,0,-1};        // v4-v7-v6-v5

    // color array
    GLfloat colors[] = {1,1,1,  1,1,0,  1,0,0,  1,0,1,              // v0-v1-v2-v3
                        1,1,1,  1,0,1,  0,0,1,  0,1,1,              // v0-v3-v4-v5
                        1,1,1,  0,1,1,  0,1,0,  1,1,0,              // v0-v5-v6-v1
                        1,1,0,  0,1,0,  0,0,0,  1,0,0,              // v1-v6-v7-v2
                        0,0,0,  0,0,1,  1,0,1,  1,0,0,              // v7-v4-v3-v2
                        0,0,1,  0,0,0,  0,1,0,  0,1,1};             // v4-v7-v6-v5

    glGenBuffersARB(1, &vbo_id);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_id);
    glBufferDataARB(
        GL_ARRAY_BUFFER_ARB
        ,sizeof(vertices)+sizeof(normals)+sizeof(colors)
        ,0
        ,GL_STATIC_DRAW_ARB
    );


    glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(vertices), vertices);
    glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertices), sizeof(normals),normals);
    glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertices)+sizeof(normals), sizeof(colors), colors);  // copy colours after normals
    s_vertices = sizeof(vertices);
    s_colors = sizeof(colors);
    s_normals = sizeof(colors);

    cube = new Cube(vbo_id, ofxVec3f(0.0, 0.0, 0.0),0.1, s_vertices, s_colors, s_normals);
#include "Cube.h"
Cube::Cube(
    GLuint nVBO
    ,ofxVec3f oPosition
    ,float fSize
    ,int nVertices
    ,int nNormals
    ,int nColors
)
:vbo_id(nVBO)
,position(oPosition)
,size(fSize)
,s_vertices(nVertices)
,s_normals(nNormals)
,s_colors(nColors)  
{
r = 0;
}

void Cube::update() {
}


void Cube::draw() {
    glPushMatrix();

        glTranslatef(position.x,position.y,position.z);
        glRotatef((r++),0,1,0);
        glScalef(size, size, size);

        // bind VBOs with IDs and set the buffer offsets of the bound VBOs
        // When buffer object is bound with its ID, all pointers in gl*Pointer()
        // are treated as offset instead of real pointer.
        glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_id);

        // enable vertex arrays
        glEnableClientState(GL_NORMAL_ARRAY);
        glEnableClientState(GL_COLOR_ARRAY);
        glEnableClientState(GL_VERTEX_ARRAY);


        // before draw, specify vertex and index arrays with their offsets
        glNormalPointer(GL_FLOAT, 0, (void*)s_vertices);
        glColorPointer(3, GL_FLOAT, 0, (void*)(s_vertices+s_normals));
        glVertexPointer(3, GL_FLOAT, 0, 0);

        glDrawArrays(GL_QUADS, 0, 24);

        glDisableClientState(GL_VERTEX_ARRAY);  // disable vertex arrays
        glDisableClientState(GL_COLOR_ARRAY);
        glDisableClientState(GL_NORMAL_ARRAY);

        // it is good idea to release VBOs with ID 0 after use.
        // Once bound with 0, all pointers in gl*Pointer() behave as real
        // pointer, so, normal vertex array operations are re-activated
        glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
        glPopMatrix();

}
虽然我通常只使用2D纹理并将其应用于GL_四边形,但我不确定如何将6个纹理应用于使用VBOs创建的立方体

最简单、最直接的方法是将它们缝合到一个大纹理中,并调整纹理坐标以匹配


或者,由于多维数据集非常简单,用显示列表代替VBO就足够了。

亲爱的greyfade,感谢您这么快地回答!你能在线告诉我如何将纹理缝合成一个大纹理吗?(顺便说一句,我知道如何从数据创建一个大rgba阵列)。我不知道的是如何使用vbos指定纹理坐标。指定纹理坐标的方式与指定法线和颜色的方式完全相同。它们只是2D矢量,而不像其他矢量那样是3D矢量。只需创建一个足够大的纹理,使六幅图像的一侧至少有三幅,然后将它们拼接到各自的小斑点上。如果有帮助的话,这是一个图像拼贴。因此,假设我创建了一个大纹理,每行有3个图像(所以2行)。然后指定坐标,如(对于左上纹理),
(0,0.5)
<代码>(1/3,0.5)<代码>(1/3,1)<代码>(0,1)?