我注意到我的openGL纹理渲染存在一个大问题:
假定透明像素被呈现为实心白色。根据StackOverflow上讨论的类似问题的大多数解决方案,我需要设置glBlend/正确的函数,但是我已经设置了必要的gl状态,并且可以确定纹理加载正确(就我所知)。我的纹理加载函数如下:
我还检查了我的片段着色器,看看透明度是否正常工作。随着时间的推移改变alpha确实会增加透明度,因此alpha并没有被完全忽略。由于某种原因,1、1、1、0被视为实心。 此外,使用 glClearColor 将背景颜色设置为黑色似乎可以防止 alpha 增加透明度。
我不知道如何解释其中的一些行为,但感觉有点奇怪。无论颜色如何,alpha 值为 0 应该是相同的,不是吗?
(请注意,我在彼此之上渲染了几个形状,但我已经尝试了仅渲染一个以进行测试。)
我能做的最好的就是发布更多的设置代码(省略了一些细节):
// 顶点数组和缓冲区设置
假定透明像素被呈现为实心白色。根据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;
}
我使用Adobe Photoshop导出“网页用”24位+透明度.png文件-- 72像素/英寸,6400 x 720。我不确定如何设置颜色模式(8、16、32),但这可能与问题有关。我也使用默认的sRGB颜色配置文件,但曾经考虑过删除颜色配置文件。这没有起到任何作用。
无论如何,从Photoshop导出的png文件在透明像素上显示为纯白色。
如果我在Gimp中创建图像,则具有正确的透明度。导入Adobe.psd或.png似乎不起作用,在任何情况下,我更喜欢使用Photoshop进行编辑。
是否有人遇到过这个问题?我想Photoshop必须添加一些奇怪的元数据,或者我没有使用正确的颜色模式--或两者兼而有之。 (我担心这超出了Stack Overflow的范围,但我的问题涉及图像编辑和编程。不管怎样,请告诉我这是否是正确的地方。)
编辑:
在Photoshop和Gimp中,我都创建了一个测试案例--顺时针8个像素(红色、绿色、透明、蓝色)。
在 Photoshop 中,透明方块读作 1、1、1、0,并显示为白色。在Gimp中,透明方块为 0、0、0、0。我还检查了我的片段着色器,看看透明度是否正常工作。随着时间的推移改变alpha确实会增加透明度,因此alpha并没有被完全忽略。由于某种原因,1、1、1、0被视为实心。 此外,使用 glClearColor 将背景颜色设置为黑色似乎可以防止 alpha 增加透明度。
我不知道如何解释其中的一些行为,但感觉有点奇怪。无论颜色如何,alpha 值为 0 应该是相同的,不是吗?
(请注意,我在彼此之上渲染了几个形状,但我已经尝试了仅渲染一个以进行测试。)
我能做的最好的就是发布更多的设置代码(省略了一些细节):
// 顶点数组和缓冲区设置
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);
}