简体   繁体   English

openGL透明像素意外白色

[英]openGL Transparent pixels unexpectedly White

I noticed a big problem in my openGL texture rendering: 我注意到我的openGL纹理渲染存在一个大问题:

Assumedly transparent pixels are rendered as solid white. 假设透明像素呈现为纯白色。 According to most solutions to similar issues discussed on StackOverflow, I need to set glBlend / the proper functions, but I have already set the necessary gl state and am positive that textures are loaded correctly as far as I can tell. 根据关于StackOverflow讨论的类似问题的大多数解决方案,我需要设置glBlend /适当的功能,但是我已经设置了必要的gl状态,并且我确信可以正确地加载纹理。 My texture load function is below: 我的纹理加载功能如下:

GLboolean GL_texture_load(Texture* texture_id, const char* const path, const GLboolean alpha, const GLint param_edge_x, const GLint param_edge_y)
{
    // load image
    SDL_Surface* img = nullptr; 
    if (!(img = IMG_Load(path))) {
        fprintf(stderr, "SDL_image could not be loaded %s, SDL_image Error: %s\n", 
               path, IMG_GetError());
        return GL_FALSE;
    }


    glBindTexture(GL_TEXTURE_2D, *texture_id);
    // image assignment
    GLuint format = (alpha) ? GL_RGBA : GL_RGB;
    glTexImage2D(GL_TEXTURE_2D, 0, format, img->w, img->h, 0, format, GL_UNSIGNED_BYTE, img->pixels);

    // wrapping behavior
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, param_edge_x);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, param_edge_y);
    // texture filtering
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glBindTexture(GL_TEXTURE_2D, 0);
    // free the surface
    SDL_FreeSurface(img);

    return GL_TRUE;
}

I use Adobe Photoshop to export "for the web" 24-bit + transparency .png files -- 72 pixels/inch, 6400 x 720. I am not sure how to set the color mode (8, 16, 32), but this might have something to do with the issue. 我使用Adobe Photoshop导出“用于网络”的24位+透明度.png文件-72像素/英寸,6400 x720。我不确定如何设置颜色模式(8、16、32),但这可能与该问题有关。 I also use the default sRGB color profile, but I thought to remove the color profile at one point. 我也使用默认的sRGB颜色配置文件,但我想一次性删除该颜色配置文件。 This didn't do anything. 这什么也没做。 No matter what, a png exported from Photoshop displays as solid white over transparent pixels. 无论如何,从Photoshop导出的png在透明像素上均显示为纯白色。

If I create an image in eg Gimp, I have correct transparency. 如果在例如Gimp中创建图像,则我具有正确的透明度。 Importing the Adobe .psd or .png does not seem to work, and in any case I prefer to use Photoshop for editing purposes. 导入Adobe .psd或.png似乎无效,无论如何我都喜欢使用Photoshop进行编辑。

Has anyone experienced this issue? 有人遇到过这个问题吗? I imagine that Photoshop must add some strange metadata or I am not using the correct color modes--or both. 我认为Photoshop必须添加一些奇怪的元数据,或者我没有使用正确的颜色模式-或同时使用这两种颜色。 (I am concerned that this goes beyond the scope of Stack Overflow, but my issue intersects image editing and programming. Regardless, please let me know if this is not the right place.) (我担心这超出了堆栈溢出的范围,但是我的问题与图像编辑和编程相交。无论如何,请让我知道这是否不合适。)

EDIT: 编辑:

In both Photoshop and Gimp I created a test case-- 8 pixels (red, green, transparent, blue) clockwise. 在Photoshop和Gimp中,我都创建了一个测试用例-顺时针旋转8像素(红色,绿色,透明,蓝色)。

小方块

In Photoshop, the transparent square is read as 1, 1, 1, 0 and displays as white. 在Photoshop中,透明正方形被读取为1、1、1、0,并显示为白色。 In Gimp, the transparent square is 0, 0, 0, 0. 在Gimp中,透明正方形为0、0、0、0。

I also checked my fragment shader to see whether transparency works at all. 我还检查了片段着色器,以查看透明度是否完全起作用。 Varying the alpha over time does increase transparency, so the alpha isn't outright ignored. 随着时间的推移更改Alpha确实会增加透明度,因此Alpha不会被完全忽略。 For some reason 1, 1, 1, 0 counts as solid. 由于某种原因,1、1、1、0视为实体。 In addition, setting the background color to black with glClearColor seems to prevent the alpha from increasing transparency. 此外,使用glClearColor将背景色设置为黑色似乎可以防止Alpha透明度增加。

I don't know how to explain some of these behaviors, but something seems off. 我不知道如何解释其中一些行为,但似乎有些不对劲。 0 alpha should be the same regardless of color, shouldn't it? 0 alpha无论颜色如何都应该相同,不是吗?

(Note that I render a few shapes on top of each other, but I've tried just rendering one for testing purposes.) (请注意,我在彼此之上渲染了一些形状,但我尝试仅渲染一个形状以进行测试。)

The best I can do is post more of my setup code (with bits omitted): 我能做的最好的就是发布更多的设置代码(省略一些位):

// vertex array and buffers setup //顶点数组和缓冲区设置

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
// I think that the blend function may be wrong (GL_ONE that is).
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

glDepthRange(0, 1);
glDepthFunc(GL_LEQUAL);

Texture tex0;
// same function as above, but generates one texture id for me
if (GL_texture_gen_and_load_1(&tex0, "./textures/sq2.png", GL_TRUE,  GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE) == GL_FALSE) {
    return EXIT_FAILURE;
}

glUseProgram(shader_2d);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex0);
glUniform1i(glGetUniformLocation(shader_2d, "tex0"), 0);

bool active = true;
while (active) {
       glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

       // uniforms, game logic, etc.

       glDrawElements(GL_TRIANGLES, tri_data.i_count, GL_UNSIGNED_INT,   (void*)0);
}

I don't know how to explain some of these behaviors, but something seems off. 我不知道如何解释其中一些行为,但似乎有些不对劲。 0 alpha should be the same regardless of color, shouldn't it? 0 alpha无论颜色如何都应该相同,不是吗?

If you want to get an identical result for an alpha channel of 0.0, independent on the red, green and blue channels, the you have to change the blend function. 如果要获得与Alpha通道0.0相同的结果,而与红色,绿色和蓝色通道无关,则必须更改混合功能。 See glBlendFunc . 参见glBlendFunc

Use: 采用:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

This cause tha the the red, green and blue channel are multiplied by the alpha channel. 这导致红色,绿色和蓝色通道乘以alpha通道。 If the alpha channel is 0.0, the resulting RGB color is (0, 0, 0). 如果Alpha通道为0.0,则结果RGB颜色为(0,0,0)。 If the alpha channel is 1.0, the RGB color channels keep unchanged. 如果Alpha通道为1.0,则RGB颜色通道保持不变。


See further Alpha Compositing, OpenGL Blending and Premultiplied Alpha 进一步了解Alpha合成,OpenGL混合和预乘Alpha

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM