c++ - 在 opengl c++ 中加载 32 位 .bmp 纹理时出现问题

标签 c++ opengl textures alpha bmp

我在我的 opengl 游戏中加载 32 位 .bmp 图像时遇到了一些问题。到目前为止,我可以完美地加载和显示 24 位。我现在想加载一张位图,其纹理的一部分是透明的或不可见的。

这个函数在 24 位上没有问题。但是带有 alpha channel 的 32 位 .bmp 似乎会扭曲颜色并导致在意想不到的地方透明。

Texture LoadTexture( const char * filename, int width, int height, bool alpha) 
    {
        GLuint texture;
        GLuint* data;
        FILE* file;

        fopen_s(&file, filename, "rb");  
        if(!file)
        {
            std::cout << filename <<": Load Texture Fail!\n";
            exit(0);
        }

        data = new GLuint[width * height];

        fread( data, width * height * sizeof(GLuint), 1, file ); 
        fclose(file);

        glGenTextures( 1, &texture );
        glBindTexture( GL_TEXTURE_2D, texture);
        glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

        if(alpha) //for .bmp 32 bit
        {
            glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
            glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
        }
        else //for .bmp 24 bit
        {
            glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 
            glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
        }

        std::cout<<"Texture: "<<filename<< " loaded"<<std::endl;
        delete data;

        return Texture(texture); 
    }

在 Game Texture 中,绘制在一个平面上 enter image description here

这可能看起来正常,但 0xff00ff 颜色应该是透明的。如果我在 photoshop 中反转 alpha channel ,结果是相同的,内部球体始终是透明的。

我还启用了:

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

透明度没有问题,问题似乎出在用 alpha channel 加载位图。我加载的所有位图似乎都向右偏移了一点。只是想知道这是否有原因?

最佳答案

我将假设您的文件“解析”实际上是正确的来回答这个问题。文件数据只是.BMP 的图像部分,没有任何标题信息。

glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);

glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 
glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);

令我感到奇怪的是,您的 3 分量数据是 BGR 顺序,而您的 4 分量数据是 RGBA 顺序。特别是如果此数据来自 .BMP 文件(尽管它们不允许 alpha channel )。您确定您的数据没有以不同的顺序排列吗?例如,也许 ABGR 顺序?

此外,停止使用数字表示图像格式。你应该使用 real, sized internal format对于您的纹理,而不是“3”或“4”。

关于c++ - 在 opengl c++ 中加载 32 位 .bmp 纹理时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18325714/

相关文章:

c++ - 一次通过 OpenGL 绘制立方体贴图

java - Mac OSX El Capitan 上的 OpenGL 3.3 和 LWJGL

android - 使用 canvas.drawBitmap() 填充屏幕

c++ - 可以在不取消引用的情况下增加指针仍然是段错误或具有其他(未)定义的肮脏吗?

c++ - 如何只创建一个文件而不打开它

c++ - 结构的内存大小

c++ - 从保存在字符串 vector C++ 中的文本文件中检查单词序列

OpenGL 混合 GL_SRC_COLOR/GL_DST_COLOR

opengl-es - 使用 Three.js 在 WebGL 中的环形几何体上进行非径向纹理映射

opengl - 为什么我的纹理在使用 Sampler2D 将其渲染到表面上后进行插值