Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Texture binding with VBO does not work correctly

the purpose of my program is to display 2 quads with 2 different textures. The problem is that the oldest texture loaded is set on the two quads (only texQuadB). I tried to replace the two call of buf[3] by texQuadA and texQuadB but it doesn't work. I cannot find the right way to bind a texture with a specific VBO.

#define OFFSET_BUFFER(bytes) ((GLfloat *)NULL + bytes)

GLfloat verticesQuadA[12] =
{
    -1.0f, 0.0f, 1.0f,
    -1.0f, 1.0f, 1.0f,
    0.0f, 1.0f, 1.0f,
    0.0f, 0.0f, 1.0f,
};

GLfloat verticesQuadB[12] =
{
    0.0f, 0.0f, 1.0f,
    0.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f, 0.0f, 1.0f,
};

GLfloat colors[12] =
{
    1.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f,
    0.0f, 0.0f, 1.0f,
    1.0f, 0.0f, 1.0f,
};

GLfloat texture[8] =
{
    0.0f, 0.0f,
    1.0f, 0.0f,
    1.0f, 1.0f,
    0.0f, 1.0f
};

int main(int argc, char *argv[])
{
    SDL_Init(SDL_INIT_VIDEO);
    SDL_WM_SetCaption("Texture Mapping",NULL);
    SDL_SetVideoMode(500, 500, 32, SDL_OPENGL);

    bool continuer = true;
    SDL_Event event;
    GLuint  buf[4];
    GLuint texQuadA, texQuadB;

    glClearDepth(1.0f);
    glClearColor(0.1f, 0.1f, 0.1f, 0.1f);
    glEnable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(70.0f, (float)500.0f / (float)500.0f, 1.0f, 3000.0f);
    glewInit();

    texQuadA = loadTexture("caisse.jpg");
    texQuadB = loadTexture("metal.jpg");

    //glBindTexture(GL_TEXTURE_2D, texQuadA);
    //glBindTexture(GL_TEXTURE_2D, texQuadB);

    glGenBuffers(4, buf);

    glBindBuffer(GL_ARRAY_BUFFER, buf[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(verticesQuadA), verticesQuadA, GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, buf[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(verticesQuadB), verticesQuadB, GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, buf[2]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, buf[3]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(texture), texture, GL_STATIC_DRAW);

    while (continuer)
    {
        SDL_WaitEvent(&event);
        switch(event.type)
        {
            case SDL_QUIT:
                continuer = false;
        }

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glEnable(GL_TEXTURE_2D);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        gluLookAt(0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);

        //Draw Quad A ---------------------------------------

        glBindBuffer(GL_ARRAY_BUFFER, buf[0]);
        glVertexPointer(3, GL_FLOAT, 0, OFFSET_BUFFER(0));

        glBindBuffer(GL_ARRAY_BUFFER, buf[2]);
        glColorPointer(3, GL_FLOAT, 0, OFFSET_BUFFER(0));

        glBindBuffer(GL_ARRAY_BUFFER, buf[3]);
        glTexCoordPointer(2, GL_FLOAT, 0, OFFSET_BUFFER(0));

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_COLOR_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        glDrawArrays(GL_QUADS, 0, 4);

        glDisableClientState(GL_TEXTURE_COORD_ARRAY);   
        glDisableClientState(GL_COLOR_ARRAY);
        glDisableClientState(GL_VERTEX_ARRAY);

        //Draw Quad B ---------------------------------------

        glBindBuffer(GL_ARRAY_BUFFER, buf[1]);
        glVertexPointer(3, GL_FLOAT, 0, OFFSET_BUFFER(0));

        glBindBuffer(GL_ARRAY_BUFFER, buf[2]);
        glColorPointer(3, GL_FLOAT, 0, OFFSET_BUFFER(0));

        glBindBuffer(GL_ARRAY_BUFFER, buf[3]);
        glTexCoordPointer(2, GL_FLOAT, 0, OFFSET_BUFFER(0));

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_COLOR_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        glDrawArrays(GL_QUADS, 0, 4);

        glDisableClientState(GL_TEXTURE_COORD_ARRAY);   
        glDisableClientState(GL_COLOR_ARRAY);
        glDisableClientState(GL_VERTEX_ARRAY);

        //----------------------------------------------------

        glFlush();
        SDL_GL_SwapBuffers();
    }
    glDeleteBuffers(3, buf);
    glDisable(GL_TEXTURE_2D);
    SDL_Quit();

    return 0;
}
like image 587
user1364743 Avatar asked Apr 30 '12 14:04

user1364743


2 Answers

OpenGL is a state machine. Binding a texture is setting part of that state. When textures are enabled, OpenGL will use the current texture state (the last texture you bound) when it goes to draw the geometry. Before you draw Quad A, bind texQuadA. Before you draw Quad B, bind texQuadB:

glBindTexture(GL_TEXTURE_2D, texQuadA);
// Draw Quad A

glBindTexture(GL_TEXTURE_2D, texQuadB);
// Draw Quad B

VBOs are unrelated in this case.

like image 166
luke Avatar answered Sep 28 '22 07:09

luke


VBOs have no interaction with texture objects. Binding a VBO does not associate it to a texture.

To select which texture you want to use for drawing you call glBindTexture before doing the drawing commands using it.

like image 45
datenwolf Avatar answered Sep 28 '22 06:09

datenwolf