【问题标题】:Problems Loading 32 bit .bmp texture in opengl c++在 opengl c++ 中加载 32 位 .bmp 纹理的问题
【发布时间】:2013-08-21 22:52:29
【问题描述】:

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

此功能在 24 位下没有问题。但是带有 alpha 通道的 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); 
    }

在游戏纹理中,绘制在平面上

这可能看起来像它的工作,但 0xff00ff 颜色应该是透明的。如果我在 Photoshop 中反转 alpha 通道,结果是相同的,内部球体始终是透明的。

我也启用了:

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

透明度没有问题,问题似乎在于使用 Alpha 通道加载位图。我加载的所有位图似乎都偏右了。只是想知道这是否有原因?

【问题讨论】:

  • 它是一个真正的 BMP 文件吗?您似乎没有在像素数据之前的开头处理标题等。
  • 没有图片格式是.bmp。这是你的要求吗?
  • 它是保存到磁盘并命名为 something.bmp 的原始像素数组,还是实际的 bmp 格式文件,例如从 Photoshop、Gimp 中将图像另存为 bmp 格式文件, 等等。?如果是第二个,那么在读取实际像素之前,您需要解析一个标题以了解在哪里寻找。 en.wikipedia.org/wiki/BMP_file_format
  • 前段时间我遇到过这样的问题。首先,我编写了一个函数,它可以手动写出一个完整的 .bmp 文件,另一个函数可以将它重新加载并使用它。然后,每当我使用来自 GIMP 或 PS 的文件尝试使用相同的加载器时,我的颜色会被反转,除非我使用不同的字节顺序枚举或混合位。保存一个纯色文件并在原始视图文本编辑器中检查字节本身以调试您的问题,也就是说,如果我理解您的问题是正确的。

标签: c++ opengl textures alpha bmp


【解决方案1】:

我将假设您的文件“解析”实际上是正确的来回答这个问题。文件数据只是 .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 通道)。你确定你的数据没有不同的顺序吗?例如,也许ABGR 订购?

另外,停止在图像格式中使用数字。你应该为你的纹理使用real, sized internal format,而不是“3”或“4”。

【讨论】:

    【解决方案2】:

    所以我使用的代码 100% 为我使用由 visual c 2012 编译的代码

    glBindTexture(GL_TEXTURE_2D, texture_id);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); //Thia is very important!!!!
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,  imag_ptr,  ptr->image->height, 0,GL_RGBA, GL_UNSIGNED_BYTE, imag_ptr); 
    

    比在渲染中我使用

    glPushMatrix();
    glTranslatef(0,0,0);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, 1);
    glEnable(GL_BLEND);
    glColor4ub(255,255,255,255);  //This is veryveryvery importent !!!!!!!!!!! (try to play and you see)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glBegin(GL_QUADS);
    glTexCoord3d(1,  1,  0);
    glVertex2f(8,8);
    glTexCoord3d(0,  1,  0);
    glVertex2f(-8,8);
    glTexCoord3d(0,  0,  0);
    glVertex2f(-8,-8);
    glTexCoord3d(1,  0,  0);
    glVertex2f(8,-8);
    glEnd();
    glEnd();
    glDisable(GL_TEXTURE_2D);
    glPopMatrix();
    

    我使用例如 android png 图标和另一个我尝试发布另一张图片,但我对此没有任何看法,所以如果你想要我将它发送给你

    所以所有这些都是 png 格式 但是在 bmp 格式和 tga 中,您必须将颜色从 ARGB 交换为 RGBA,否则它不起作用

    for( x=0;x<bmp_in_fheader.width;x++)
        {
            t=pixel[i];
            t1=pixel[i+1];
            t2=pixel[i+2];
            t3=pixel[i+3];
    
            pixel_temp[j]=t2;
            pixel_temp[j+1]=t1;
            pixel_temp[j+2]=t;
            pixel_temp[j+3]=t3;
    
            i+=4;
            j+=4;
        }
    

    ==下一个== 要在 Photoshop 中创建它们,您必须删除背景并在新图层上绘制而不是添加 Alpha 图层 在频道记住!非常重要的是,在 alpha 中,所有黑色都代表透明度 并且您的图像必须仅在白色下

    【讨论】:

      猜你喜欢
      • 2010-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-04
      相关资源
      最近更新 更多