gpt4 book ai didi

c++ - openGL 透明像素意外变白

转载 作者:行者123 更新时间:2023-11-30 03:23:35 29 4
gpt4 key购买 nike

我注意到我的 openGL 纹理渲染中存在一个大问题:

假设透明像素呈现为纯白色。根据 StackOverflow 上讨论的类似问题的大多数解决方案,我需要设置 glBlend/适当的功能,但我已经设置了必要的 gl 状态,并且据我所知,纹理已正确加载。我的纹理加载函数如下:

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;
}

我使用 Adob​​e Photoshop 导出“用于网络”的 24 位 + 透明度 .png 文件——72 像素/英寸,6400 x 720。我不确定如何设置颜色模式(8、16、32) ,但这可能与问题有关。我也使用默认的 sRGB 颜色配置文件,但我想一次性删除颜色配置文件。这没有做任何事情。无论如何,从 Photoshop 导出的 png 在透明像素上显示为纯白色。

如果我在例如Gimp,我有正确的透明度。导入 Adob​​e .psd 或 .png 似乎不起作用,无论如何我更喜欢使用 Photoshop 进行编辑。

有人遇到过这个问题吗?我想 Photoshop 必须添加一些奇怪的元数据,或者我没有使用正确的颜色模式——或两者兼而有之。(我担心这超出了 Stack Overflow 的范围,但我的问题涉及图像编辑和编程。无论如何,如果这不是正确的地方,请告诉我。)

编辑:

在 Photoshop 和 Gimp 中,我都创建了一个测试用例——顺时针 8 像素(红色、绿色、透明、蓝色)。

tiny square

在 Photoshop 中,透明正方形被读取为 1, 1, 1, 0 并显示为白色。在 Gimp 中,透明方 block 是 0, 0, 0, 0。

我还检查了片段着色器以查看透明度是否有效。随着时间的推移改变 alpha 确实会增加透明度,因此不会完全忽略 alpha。出于某种原因,1、1、1、0 算作实数。此外,使用 glClearColor 将背景颜色设置为黑色似乎可以防止 alpha 增加透明度。

我不知道如何解释其中的一些行为,但似乎有些不对劲。无论颜色如何,0 alpha 都应该相同,不是吗?

(请注意,我在彼此之上渲染了几个形状,但出于测试目的,我尝试只渲染一个。)

我能做的最好的就是发布更多我的设置代码(省略一些位):

//顶点数组和缓冲区设置

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.0 的 alpha channel 获得相同的结果,独立于红色、绿色和蓝色 channel ,则必须更改混合函数。参见 glBlendFunc .

使用:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

这导致红色、绿色和蓝色 channel 乘以 alpha channel 。如果 alpha channel 为 0.0,则生成的 RGB 颜色为 (0, 0, 0)。如果 alpha channel 为 1.0,则 RGB 颜色 channel 保持不变。


进一步查看 Alpha Compositing, OpenGL Blending and Premultiplied Alpha

关于c++ - openGL 透明像素意外变白,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50260764/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com