位图操作与OpenGL纹理结合

//Texture Mapping Functions
void CCY457OpenGLView::LoadGLTextures()
{
    //Create Texture Names
    glGenTextures(3, m_Texture);
    LoadTexture("Apple.bmp",0);
    LoadTexture("Fauve.bmp",1);
    LoadTexture("Flower.bmp",2);
}

void CCY457OpenGLView::LoadTexture (CString fileName, int texName)
{
    //Load Texture
    AUX_RGBImageRec* m_texture;
    m_texture = auxDIBImageLoad((const char*)fileName);
    if(!m_texture)
    {
       MessageBox("Picture could not be loaded");

       exit(1);
    }

    glBindTexture(GL_TEXTURE_2D, m_Texture[texName]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_texWrap);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_texWrap);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_texFilter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_texFilter);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, m_texMode);
    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, m_texture->sizeX,m_texture->sizeY, GL_RGB, GL_UNSIGNED_BYTE, m_texture->data);
}

 

---------------------------------------------------------------------------------------------------------------

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

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

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

//======================================================================
/**
* @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


 

//======================================================================
/**
* @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纹理结合)