VC运用OPENGL加载BMP纹理图的实现方法汇总
OpenGL是专业的图形程序接口,功能非常强大,调用方便的底层图形库。本文汇总了运用OPENGL加载BMP纹理图的几个实现方法。
方法一:
首先获取位图句柄:
HBITMAPhBmp=(HBITMAP)::LoadImage(AfxGetResourceHandle(),MAKEINTRESOURCE(IDB_BITMAP1),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);
然后根据位图句柄得到位图信息:
BITMAPBM; ::GetObject(hBmp,sizeof(BM),&BM);
最后根据位图信息中的RGB值建立纹理:
gluBuild2DMipmaps(GL_TEXTURE_2D,3,BM.bmWidth,BM.bmHeight,GL_BGR_EXT,GL_UNSIGNED_BYTE,BM.bmBits);
方法二:
首先用OpenGL辅助库获得位图信息:
AUX_RGBImageRec*TextureImage[1];
TextureImage[0]=auxDIBImageLoad("1.bmp");
然后建立纹理
gluBuild2DMipmaps(GL_TEXTURE_2D,3,TextureImage[0]->sizeX,TextureImage[0]->sizeY,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[0]->data);
方法三:
从底层做,需要了解bmp文件的结构,首先读取bmp文件结构,包括文件头、信息头和数据,数据用于后面定义纹理
longImageWidth=256;
longImageHeight=256;
GLubyteImage[256][256][3];
voidReadHeader(FILE*fp,BITMAPFH*p_bitmapheader,BITMAPIH*p_bitmapinfo)
{
fseek(fp,0,SEEK_SET);
fread(&p_bitmapheader->bfType,sizeof(unsignedshort),1,fp);
fseek(fp,2,SEEK_SET);
fread(&p_bitmapheader->bfSize,sizeof(unsignedlong),1,fp);
fseek(fp,6,SEEK_SET);
fread(&p_bitmapheader->bfReserved1,sizeof(unsignedshort),1,fp);
fseek(fp,8,SEEK_SET);
fread(&p_bitmapheader->bfReserved2,sizeof(unsignedshort),1,fp);
fseek(fp,10,SEEK_SET);
fread(&p_bitmapheader->bfOffBits,sizeof(unsignedlong),1,fp);
fseek(fp,14,SEEK_SET);
fread(&p_bitmapinfo->biSize,sizeof(unsignedlong),1,fp);
fseek(fp,18,SEEK_SET);
fread(&p_bitmapinfo->biWidth,sizeof(unsignedlong),1,fp);
fseek(fp,22,SEEK_SET);
fread(&p_bitmapinfo->biHeight,sizeof(unsignedlong),1,fp);
fseek(fp,26,SEEK_SET);
fread(&p_bitmapinfo->biPlanes,sizeof(unsignedshort),1,fp);
fseek(fp,28,SEEK_SET);
fread(&p_bitmapinfo->biBitCount,sizeof(unsignedshort),1,fp);
fseek(fp,30,SEEK_SET);
fread(&p_bitmapinfo->biCompression,sizeof(unsignedlong),1,fp);
fseek(fp,34,SEEK_SET);
fread(&p_bitmapinfo->biSizeImage,sizeof(unsignedlong),1,fp);
fseek(fp,38,SEEK_SET);
fread(&p_bitmapinfo->biXPelsPerMeter,sizeof(unsignedlong),1,fp);
fseek(fp,42,SEEK_SET);
fread(&p_bitmapinfo->biYPelsPerMeter,sizeof(unsignedlong),1,fp);
fseek(fp,46,SEEK_SET);
fread(&p_bitmapinfo->biClrUsed,sizeof(unsignedlong),1,fp);
fseek(fp,50,SEEK_SET);
fread(&p_bitmapinfo->biClrImportant,sizeof(unsignedlong),1,fp);
}
voidReadBitmapFile()
{
BITMAPFHbitmapheader;
BITMAPIHbitmapinfo;
FILE*fp;
fp=fopen("6.bmp","r");
if(!fp)
{
puts("Readfilefailed.");
return;
}
ReadHeader(fp,&bitmapheader,&bitmapinfo);
if(bitmapinfo.biBitCount!=24)
{
puts("UNSUPPORT");
return;
}
ImageWidth=bitmapinfo.biWidth;
ImageHeight=bitmapinfo.biHeight;
inti=bitmapheader.bfOffBits;
while(i<bitmapheader.bfSize)
{
for(intj=0;j<ImageWidth;j++)
for(intk=0;k<ImageHeight;k++)
{
fseek(fp,i,SEEK_SET);
fread(Image[j][k]+2,1,1,fp);
fseek(fp,i+1,SEEK_SET);
fread(Image[j][k]+1,1,1,fp);
fseek(fp,i+2,SEEK_SET);
fread(Image[j][k],1,1,fp);
i=i+3;
}
}
fclose(fp);
}
glTexImage2D(GL_TEXTURE_2D,0,3,ImageWidth,ImageHeight,0,GL_RGB,GL_UNSIGNED_BYTE,&Image[0][0][0]);
#include<gl\glext.h>
这是因为后面的GL_BGR_EXT是定义在这个头文件里的,因为BMP格式是按Blue,Green,Red顺序储存图像数据的,这与OpenGL中正好相反。GL_BGR_EXT就是完成两者之间的转换的。
下面就是不用AUX库来加载BMP图片作为纹理的函数:
boolLoadTexture(LPTSTRszFileName,GLuint&texid)//CreatesTextureFromABitmapFile
{
HBITMAPhBMP;//HandleOfTheBitmap
BITMAPBMP;//BitmapStructure
glGenTextures(1,&texid);//CreateTheTexture
hBMP=(HBITMAP)LoadImage(GetModuleHandle(NULL),szFileName,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE);
if(!hBMP)//DoesTheBitmapExist?
returnFALSE;//IfNotReturnFalse
GetObject(hBMP,sizeof(BMP),&BMP);//GetTheObject
//hBMP:HandleToGraphicsObject
//sizeof(BMP):SizeOfBufferForObjectInformation
//&BMP:BufferForObjectInformation
glPixelStorei(GL_UNPACK_ALIGNMENT,4);//PixelStorageMode(WordAlignment/4Bytes)
//TypicalTextureGenerationUsingDataFromTheBitmap
glBindTexture(GL_TEXTURE_2D,texid);//BindToTheTextureID
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);//LinearMinFilter
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);//LinearMagFilter
glTexImage2D(GL_TEXTURE_2D,0,3,BMP.bmWidth,BMP.bmHeight,0,GL_BGR_EXT,GL_UNSIGNED_BYTE,BMP.bmBits);
DeleteObject(hBMP);//DeleteTheObject
returnTRUE;//LoadingWasSuccessful
}