如何在OpenGL中使纹理透明?

时间:2009-04-15 14:01:17

标签: c++ opengl textures opacity

我试图在谷歌上研究这个问题,但似乎没有任何连贯的简单答案。这是因为它不简单,还是因为我没有使用正确的关键字?

尽管如此,这是我迄今取得的进步。

  1. 创建了8个顶点以形成2个正方形。
  2. 创建一个具有200位alpha值的纹理(因此,大约80%透明)。
  3. 为每个正方形指定相同的纹理,正确显示。
  4. 注意到当我使用255 alpha的纹理时,它看起来更亮。
  5. init类似于以下内容:

    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
    glEnable(GL_DEPTH_TEST);
    
    glEnable(GL_CULL_FACE);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glGenTextures(1, textureIds);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    
    int i, j;
    GLubyte pixel;
    for (i = 0; i < TEXTURE_HEIGHT; i++)
    {
        for (j = 0; j < TEXTURE_WIDTH; j++)
        {
            pixel = ((((i & 0x8) == 0) ^ ((j & 0x8) == 0)) * 255);
            texture[i][j][0] = pixel;
            texture[i][j][1] = pixel;
            texture[i][j][2] = pixel;
            texture[i][j][3] = 200;
        }
    }
    
    glBindTexture(GL_TEXTURE_2D, textureIds[0]);
    
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    
    glTexImage2D(
        GL_TEXTURE_2D, 0, GL_RGBA,
        TEXTURE_WIDTH, TEXTURE_HEIGHT,
        0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
    

    这有点类似于本书第417页的 OpenGL编程指南中的代码段,并创建了一个检查模式。

    然后,显示功能包含......

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
    
    // Use model view so that rotation value is literal, not added.
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    
    // ... translation, etc ...
    
    glBindTexture(GL_TEXTURE_2D, textureIds[0]);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, +1.0, 0.0); // top left
    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 0.0); // bottom left
    glTexCoord2f(1.0, 1.0); glVertex3f(+1.0, -1.0, 0.0); // bottom right
    glTexCoord2f(1.0, 0.0); glVertex3f(+1.0, +1.0, 0.0); // top right
    glEnd();
    
        // not neccecary to repeat, just good practice
    glBindTexture(GL_TEXTURE_2D, textureIds[0]);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0); glVertex3f(-0.5, +1.0, -1.0); // top left
    glTexCoord2f(0.0, 1.0); glVertex3f(-0.5, -1.0, -1.0); // bottom left
    glTexCoord2f(1.0, 1.0); glVertex3f(+1.5, -1.0, -1.0); // bottom right
    glTexCoord2f(1.0, 0.0); glVertex3f(+1.5, +1.0, -1.0); // top right
    glEnd();
    
    glFlush();
    glDisable(GL_TEXTURE_2D);
    
    glPopMatrix();
    
    SwapBuffers();
    

    因此,这会在背景中呈现第二个方格;我可以看到这个,但看起来它们与背景混合(我假设这是因为它们比200位alpha更暗而不是255位)而不是背后的纹理......

    Transparent textures not working

    如您所见,没有透明度......我该如何解决这个问题?

1 个答案:

答案 0 :(得分:9)

所以这里的另一个答案却被删除了 - 通常,为了使alpha混合正常工作,你需要在摄像机的坐标系中从远到近排序对象。
这就是您的多边形与背景混合的原因。您可以通过禁用深度测试来确认这确实是问题。如果没有深度测试,则会显示所有片段,您将能够看到Alpha混合。

this page.

中的更多内容