OpenGL 中的纹理透明度

发布于 2024-12-19 10:21:18 字数 2336 浏览 2 评论 0原文

我正在我的环境中制作一个排除所有白色像素的纹理。我读入 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();

屏幕截图: 树不是实心

在此输入图像描述

I am making a texture in my environment that excludes all white pixels. I read in a ppm file and the fourth value is always set to 0 if it is a white pixel. Everything seems to be in order, I have set up my view correctly and so forth. The texture image is visible with my current code, however the image as a whole is not fully opaque. It is highly see through. Is this a problem with how I am setting up my GL_Blend? Why is the entire texture not opaque as it should be only excluding the white pixels?

first three values are read in as rgb values and fourth value is not in file, it is selected depending on the total value of the three previous numbers from rgb. This texture is not loaded every time I render it is in a display list so only done once.

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

Screen shots:
Tree is not solid

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

楠木可依 2024-12-26 10:21:18

如果将视点移动到离树非常近的位置,树会变得不透明吗?或者如果您禁用 mipmap 也会这样吗?

编辑

通过将眼睛移近树,使用 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,这将有效禁用 mipmap。通过将 GL_TEXTURE_MAX_LEVEL 和 GL_TEXTURE_BASE_LEVEL 设置为相同的值,您将能够看到该特定 mipmap 级别的内容。

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

If you move the viewpoint really close to the tree, does it become opaque? Or does it if you disable mipmapping?

edit

By moving the eye closer to a tree, the level 0 mipmap (your original image) is used. To select a mipmap, OpenGL computes which level provides the best match between the size of its texels and the size of a pixel.

To disable mipmapping generation, you must use glTexImage2D to upload your texture instead of gluBuild2DMipmaps.

To disable usage of mipmaps, change the following line

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);

to

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

You could also do as Jim Buck suggests and use

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);

to force the highest mipmap level used to 0. The lowest being by default 0, this effectively disables mipmapping. By setting GL_TEXTURE_MAX_LEVEL and GL_TEXTURE_BASE_LEVEL to the same value, you will be able to see the content of that specific mipmap level.

All this is to confirm if it's a problem with the mipmaps.

骄傲 2024-12-26 10:21:18

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

glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );

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

In addition to what @bernie pointed out about GluByte arrays and including glBegin/end, the problem was in..

glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );

GL_MODULATE needed to be replaced with GL_REPLACE. This fixed the issue. Thanks for your guys' help.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文