opengl 使用bmp位图纹理(8-bit 24bit)

opengl 使用bmp位图纹理(8-bit 24bit)


   前两天,在使用位图当纹理时候,遇到了问题.就是关于8-bit位图不能派上用场时候,于是就萌生了想法,希望能将它完善下整理出来.于是查了一些关于bitmap的文件结构.关于位图结构等,我就不在此详细叙述了.因为网上已经相当的多 而且很多人也实现了很多读取的方法.可参考此篇博文:位图综述

     其实呢.我原先并不知道原来已经有了很强大的一个开源工具..FreeImage ..是个已经支持目前所有格式的图像文件..所以我的基本算是白写了.关于1 4 16 32 的完全可参考其源代码 完善下我以下这个类:

     现在仅将我写了一个下午的源代码献上:详细情况不在综述,全部在类里表明了注释:

BmpLoader.h
//======================================================================
/**//**
*  @file      BmpLoader.h
*
*  文件描述:  载入位图类 
*  适用平台: Windows98/2000/NT/XP
*  
*  作者:     acmiyou
*  电子邮件:  [email protected]
*    
*/
                                                                            
//======================================================================
#include <windows.h>
#include 
<stdio.h>
#ifndef _BMPLOADER_H_
#define _BMPLOADER_H_

#define BITMAP_ID 0x4D42    /**< 位图文件的标志 */

#define BLUE 0
#define GREEN 1
#define RED 2

#define swapcolor(a,b){ \
        (a) 
^= (b);     \
        (b) 
^= (a);     \
        (a) 
^= (b);     \
}

class BmpLoader
{
public:
    BmpLoader();
    
~BmpLoader();

    
void Free();                                             /**//** 释放内存*/

    BITMAPINFOHEADER
* bitInfo;                               /**//** 记录位图的头信息*/
    BYTE
* image;                                             /**//** 图像数据*/

    
bool loadBitmap(const char* filename);                   /**//** 载入位图文件*/
    

private:

    
void computePaletteSize();                               /**//** 计算位图中颜色表项数*/
    
int getImageLine(int width,int bitCount);                /**//** 计算每行的字节数,结果为4的倍数*/

    BYTE
* getScanLine(BYTE* data ,int pitch,int scanline);   /**//** 获得像素数据每行的起始地址*/
    
bool covertTo24bits(BYTE* data);                         /**//** 强制转换所有类型至24-bit*/
    
void covertLine8bTo24b(BYTE* dst,BYTE* src);             /**//** 转换8-bit行为24-bit行 */

    RGBQUAD
* p_ColorTable;                                   /**//** 颜色表*/
}
;

#endif



 

BmpLoader.cpp
//======================================================================
/**//**
*  @file      BmpLoader.cpp
*
*  文件描述:  载入位图类 
*  适用平台: Windows98/2000/NT/XP
*  
*  作者:     acmiyou
*  电子邮件:  [email protected]
*    
*/
                                                                            
//======================================================================

#include 
"BmpLoader.h"

BmpLoader::BmpLoader()
{
    bitInfo
= 0;
    image 
= 0;
    p_ColorTable 
= 0;
}


BmpLoader::
~BmpLoader()
{
    Free();
}

/**//**
** 释放占用内存
*/

void BmpLoader::Free()
{
    
if(image!=NULL)
    
{
        delete[] image;
        image 
= 0;
    }

    
if(bitInfo!=NULL)
    
{
        delete[] bitInfo;
        bitInfo 
= 0;
    }

    
if(p_ColorTable !=NULL)
    
{
        delete[] p_ColorTable;
        p_ColorTable 
= 0;
    }

}

/**//*
** 载入位图文件
** @param:
** filename 文件名
*/

bool BmpLoader::loadBitmap(const char *filename)
{
           /** 如果已经存在数据 则释放内存*/
         Free();                /** 释放内存*/

    FILE
* fp= fopen(filename,"rb");

    
if(fp==NULL) return false;   /**//** 打开文件失败*/

    BITMAPFILEHEADER header;

    fread(
&header,sizeof(BITMAPFILEHEADER),1,fp); /**//** 读入bitmap文件头*/

    
if(header.bfType !=BITMAP_ID)  /**//** 若不是 位图类型 直接返回*/
    
{
        Free();
        fclose(fp);
        
return false;
    }


    bitInfo
=(BITMAPINFOHEADER*)new BYTE[sizeof(BITMAPINFOHEADER)];
    fread(bitInfo,
sizeof(BITMAPINFOHEADER),1,fp); /**//** 位图信息头*/

    
if(bitInfo->biSize !=40)
    
{
        Free();
        
return false/**//** 不是RGB格式 而是压缩的 该类不支持 返回读取失败 */
    }


    computePaletteSize();  
/**//** 计算颜色表值*/

    
if(bitInfo->biClrUsed !=0)
    
{
        p_ColorTable
=(RGBQUAD*)new BYTE[sizeof(RGBQUAD)*bitInfo->biClrUsed];
        fread(p_ColorTable,
sizeof(RGBQUAD) * bitInfo->biClrUsed,1,fp);
    }


    
/**//** 位图像素数据大小 */
    bitInfo
->biSizeImage=getImageLine(bitInfo->biWidth,bitInfo->biBitCount) * bitInfo->biHeight;
    BYTE
* imagedata = new BYTE[bitInfo->biSizeImage];

    fseek(fp,header.bfOffBits,SEEK_SET);

    
/**//** 读取像素信息*/
    fread(imagedata,bitInfo
->biSizeImage,1,fp);
    fclose(fp);

    
/**//** 强制转换成24-bit*/
    
if(!covertTo24bits(imagedata)) /**//** 不支持 1 4 16 32位格式 则返回*/
    
{
        Free();
        
return false;
    }

    delete[] imagedata;

    
/**//** 转换bgr --> rgb*/
    
for(int inx= 0;inx < bitInfo->biSizeImage;inx+=3)
        swapcolor(image[inx],image[inx
+2]);
    
    
return true;
}


/**//*
** 计算位图中颜色表项数
** @param: 无
*/

void BmpLoader::computePaletteSize()
{
    
/**//** 仅 1 4 8 存在颜色表*/
    
if(bitInfo->biClrUsed==0)
    
{
        
switch(bitInfo->biBitCount)
        
{
        
case 1:
            bitInfo
->biClrUsed=2;break;
        
case 4:
            bitInfo
->biClrUsed=16;break;
        
case 8:
            bitInfo
->biClrUsed=256;break;
        
case 16:
        
case 24:
        
case 32:
            bitInfo
->biClrUsed=0;break;
        
default:
            
break;
        }

    }

}


/**//*
** 计算每行的字节数
** @param:
** width 宽度
** bitCount 每个像素的位数
** @return: 行字节数
*/

int BmpLoader::getImageLine(int width,int bitCount)
{
    
return ((width * bitCount) + 7/ 8 + 3 & ~3;
}



/**//** 获得像素数据每行的起始地址
** @param:
** data  像素数据
** pitch 像素行字节数
** scanline 第几行
** @return: 行起始地址
*/

BYTE
* BmpLoader::getScanLine(BYTE* data ,int pitch, int scanline)
{
    
return data + pitch * scanline;
}


/**//*
** 强制转换所有类型至24-bit
** @param:
** data 像素数据
*/

bool BmpLoader::covertTo24bits(BYTE *data)
{
    
if(bitInfo==NULL || data == NULL) return false;

    
int lineImage = getImageLine(bitInfo->biWidth,24);
    
int lineData  = getImageLine(bitInfo->biWidth,bitInfo->biBitCount);

    bitInfo
->biSizeImage =lineImage * bitInfo->biHeight ;

    image 
= new BYTE[bitInfo->biSizeImage];
    memset(image,
0,bitInfo->biSizeImage);
    
switch(bitInfo->biBitCount)
    
{
    
case 1:return false;
    
case 4:return false;
    
case 8:
        
for(int row = 0; row < bitInfo->biHeight; row++)
            covertLine8bTo24b(getScanLine(image,lineImage,row),getScanLine(data,lineData,row));
        
break;
    
case 16:
        
return false;
    
case 24:
        memcpy(image,data,bitInfo
->biSizeImage);
        
break;
    
case 32:
        
return false;
    }

    
return true;
}

/**//*
** 转换8-bit行为24-bit行
** @param:
** dst 目标地址
** src 源地址
*/

void BmpLoader::covertLine8bTo24b(BYTE *dst,BYTE *src)
{
    
for(int col = 0; col < bitInfo->biWidth ; col++)
    
{
        
/**//** 将索引值转换成颜色表中的颜色*/
        dst[BLUE] 
= p_ColorTable[src[col]].rgbBlue;
        dst[GREEN]  
=p_ColorTable[src[col]].rgbGreen;
        dst[RED] 
=p_ColorTable[src[col]].rgbRed;
        dst
+=3;
    }

}

 

你可能感兴趣的:(opengl 使用bmp位图纹理(8-bit 24bit))