【问题标题】:Texture Transparency in OpenGLOpenGL中的纹理透明度
【发布时间】:2011-12-02 22:21:40
【问题描述】:

我正在我的环境中制作一个不包括所有白色像素的纹理。我读入一个 ppm 文件,如果它是一个白色像素,第四个值总是设置为 0。一切似乎都井井有条,我已经正确设置了我的视图等等。使用我当前的代码可以看到纹理图像,但是整个图像并不是完全不透明的。它是高度透明的。这是我如何设置 GL_Blend 的问题吗?为什么整个纹理不透明,因为它应该只排除白色像素?

前三个值作为 rgb 值读入,第四个值不在文件中,它是根据 rgb 中前三个数字的总值选择的。每次我在显示列表中渲染它时都不会加载此纹理,因此只完成一次。

glPushMatrix();

    FILE *inFile3;
    char dump3[3];
    int max3, k3 = 0;

    inFile3 = fopen("tree.ppm", "r");
    int x3;
    int y3;

    fscanf(inFile3, "%s", dump3);
    fscanf(inFile3, "%d %d", &x3, &y3);


    fscanf(inFile3, "%d", &max3);
    int arraySize3 = y3*(4*x3);
    int pixel3, rgb = 0;
    GLubyte data3[arraySize3];

    for (int i = 0; i < x3; i++) {
        for (int j = 0; j < y3; j++) {
            fscanf(inFile3, "%d", &pixel3);
            data3[k3++] = pixel3;
            rgb += pixel3;

            fscanf(inFile3, "%d", &pixel3);
            data3[k3++] = pixel3;
            rgb += pixel3;

            fscanf(inFile3, "%d", &pixel3);
            data3[k3++] = pixel3;
            rgb += pixel3;

            data3[k3++] = ((rgb) > 760) ? 0 : 255;
            rgb = 0;
        }
    }


    fclose(inFile3);

    glGenTextures(1,&texture3);
    glBindTexture(GL_TEXTURE_2D,texture3);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST_MIPMAP_NEAREST);


    gluBuild2DMipmaps(GL_TEXTURE_2D,4,x3,y3,GL_RGBA,GL_UNSIGNED_BYTE,data3);


    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glEnable( GL_TEXTURE_2D );
    glBindTexture( GL_TEXTURE_2D, texture3 );
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );

    glRotatef(180, 0, 0, 0);
    glTranslatef(0, -19, 0);

    glBegin(GL_QUADS);

    glTexCoord2d(0,0); glVertex3f(30,0,10);
    glTexCoord2d(0,1); glVertex3f(30,20,10);
    glTexCoord2d(1,1); glVertex3f(30,20,-10);
    glTexCoord2d(1,0); glVertex3f(30,0,-10);

    glEnd();

    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);
    glPopMatrix();

屏幕截图:

【问题讨论】:

  • 你能张贴你的纹理和最终结果的截图吗?
  • 没问题。我添加了截图。如果很难辨认,树在中间哈哈。
  • 为了确定,在指定顶点之前,请致电glColor4f(1, 1, 1, 1);

标签: opengl transparency textures glut


【解决方案1】:

如果您将视点真正靠近树,它会变得不透明吗?或者如果你禁用 mipmapping 会这样做吗?

编辑

通过将眼睛移近一棵树,将使用 0 级 mipmap(您的原始图像)。为了选择 mipmap,OpenGL 会计算哪个级别提供了其纹理像素大小和像素大小之间的最佳匹配。

要禁用 mipmapping 生成,您必须使用 glTexImage2D 而不是 gluBuild2DMipmaps 来上传纹理。

要禁用 mipmap,请更改以下行

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);

到

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

你也可以按照 Jim Buck 的建议去做并使用

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);

强制使用的最高 mipmap 级别为 0。默认情况下最低为 0,这有效地禁用了 mipmapping。通过将 GL_TEXTURE_MAX_LEVEL 和 GL_TEXTURE_BASE_LEVEL 设置为相同的值,您将能够看到该特定 mipmap 级别的内容。

所有这些都是为了确认它是否是 mipmap 的问题。

【讨论】:

  • 您的意思是将眼睛移近图像吗?如果是这样,它没有任何影响。为什么禁用 mipmapping 会做任何事情?我尝试使用 glTexImage2D 代替它只是做了一个空白正方形(透明)
  • 尝试将 mipmap 的 max_level 设置为零并且不要生成 mipmap。这只是为了确认它不是一个糟糕的 mipmap。
  • 很抱歉,我有点不知所措。
  • glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); - 这实际上不会使用 mipmap。
  • 嘿,我没有意识到@bernie 添加了那些特别的东西。 :)
【解决方案2】:

除了@bernie 指出的关于 GluByte 数组和包括 glBegin/end 的内容之外,问题出在..

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

GL_MODULATE 需要替换为 GL_REPLACE。这解决了这个问题。感谢你们的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-03
    • 2015-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多