views:

83

answers:

1

Dear reader,

I'm new to VBO's and read some articles on creating and using VBO's. I am working on a application where I want to create a dozen of rotating cubes. I'm connected to a server which pushes text messages to my application. When I receive 6 text messages, I render these messages using Pango and Cairo. Then I want to create textures from these 6 rendered messages and apply those to a new Cube.

Though I normally just use a 2D texture and apply these to a GL_QUAD, I'm not sure how I can apply 6 textures to a cube which is created using VBOs?

I've found an example on how to create a cube using VBO. Those are created like:

The 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);

The Cube class which uses the VBO

#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();

}
+2  A: 

Though I normally just use a 2D texture and apply these to a GL_QUAD, I'm not sure how I can apply 6 textures to a cube which is created using VBOs?

The simplest, most straightforward approach is to stitch them together into a single large texture, and adjust your texture coordinates to match.

Alternatively, since the cube is so simple, a display list instead of VBO might suffice.

greyfade
Dear greyfade, thanks for answering so quickly! Can you maybe online how I can would stitch the textures into one large texture? (I know how to create one big rgba array from the data btw). What I don't know is how to specify the texture coordinates using vbos.
pollux
You specify the texture coordinates exactly the same way you specify normals and colors. They're just 2D vectors instead of 3D like the others. Just create a texture large enough to hold the six images at least three on a side, and blit them to their own little spots. It's a collage of images, if that helps.
greyfade
Thus lets say I create a large texture with 3 images per row (so 2 rows). Then I specify the coordinates like (for the upperleft texture), `(0,0.5)`;`(1/3,0.5)`;`(1/3,1)`;`(0,1)` ?
pollux
Something like that.
greyfade