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 }