使用 VBO 的纹理绑定无法正常工作

Posted

技术标签:

【中文标题】使用 VBO 的纹理绑定无法正常工作【英文标题】:Texture binding with VBO does not work correctly 【发布时间】:2012-04-30 14:54:02 【问题描述】:

我的程序的目的是显示 2 个具有 2 个不同纹理的四边形。问题是加载的最旧纹理设置在两个四边形(仅 texQuadB)上。我试图用 texQuadA 和 texQuadB 替换 buf[3] 的两个调用,但它不起作用。我找不到将纹理与特定 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;

【问题讨论】:

【参考方案1】:

OpenGL 是一个状态机。绑定纹理是设置该状态的一部分。启用纹理后,OpenGL 将在绘制几何图形时使用当前纹理状态(您绑定的最后一个纹理)。在绘制 Quad A 之前,绑定 texQuadA。在绘制 Quad B 之前,绑定 texQuadB:

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

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

在这种情况下,VBO 是不相关的。

【讨论】:

是的,当然这是一个愚蠢的帖子,哈哈。非常感谢您的快速答复。再见。【参考方案2】:

VBO 与纹理对象没有交互。绑定 VBO 不会将其与纹理相关联。

要选择要用于绘制的纹理,请在使用它执行绘制命令之前调用 glBindTexture。

【讨论】:

以上是关于使用 VBO 的纹理绑定无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

一个 VBO 可以绑定多个 VAO 吗?

无法将纹理绑定到 GL_QUADS

在OpenGL中将纹理映射到VBO的问题

在多个 GLKViewController 之间共享 VBO?

Android OpenGL ES2 一个 VBO 的许多纹理

VBO/FBO/DisplayLists 如何在 Haskell 的 OpenGL 绑定中工作?