【原创】OPENGL加载BMP纹理图的方式
方法一:
首先获取位图句柄
HBITMAP hBmp = (HBITMAP) ::LoadImage (AfxGetResourceHandle(),MAKEINTRESOURCE(IDB_BITMAP1), IMAGE_BITMAP, 0, 0,LR_CREATEDIBSECTION);
然后根据位图句柄得到位图信息
BITMAP BM;
::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文件结构,包括文件头、信息头和数据,数据用于后面定义纹理
1
long
ImageWidth
=
256
;
2 long ImageHeight = 256 ;
3 GLubyte Image[ 256 ][ 256 ][ 3 ];
4 void ReadHeader(FILE * fp , BITMAPFH * p_bitmapheader , BITMAPIH * p_bitmapinfo)
5 {
6 fseek(fp, 0 , SEEK_SET) ;
7 fread( & p_bitmapheader -> bfType, sizeof (unsigned short ), 1 , fp );
8 fseek(fp, 2 , SEEK_SET) ;
9 fread( & p_bitmapheader -> bfSize, sizeof (unsigned long ), 1 , fp );
10 fseek(fp, 6 , SEEK_SET) ;
11 fread( & p_bitmapheader -> bfReserved1, sizeof (unsigned short ), 1 , fp );
12 fseek(fp, 8 , SEEK_SET) ;
13 fread( & p_bitmapheader -> bfReserved2, sizeof (unsigned short ), 1 , fp );
14 fseek(fp, 10 , SEEK_SET) ;
15 fread( & p_bitmapheader -> bfOffBits, sizeof (unsigned long ), 1 , fp );
16 fseek(fp, 14 , SEEK_SET) ;
17 fread( & p_bitmapinfo -> biSize, sizeof (unsigned long ), 1 , fp );
18 fseek(fp, 18 , SEEK_SET) ;
19 fread( & p_bitmapinfo -> biWidth, sizeof (unsigned long ), 1 , fp );
20
21 fseek(fp, 22 , SEEK_SET) ;
22 fread( & p_bitmapinfo -> biHeight, sizeof (unsigned long ), 1 , fp );
23
24 fseek(fp, 26 , SEEK_SET) ;
25 fread( & p_bitmapinfo -> biPlanes, sizeof (unsigned short ), 1 , fp );
26
27 fseek(fp, 28 , SEEK_SET) ;
28 fread( & p_bitmapinfo -> biBitCount, sizeof (unsigned short ), 1 , fp );
29
30 fseek(fp, 30 , SEEK_SET) ;
31 fread( & p_bitmapinfo -> biCompression, sizeof (unsigned long ), 1 , fp );
32
33 fseek(fp, 34 , SEEK_SET) ;
34 fread( & p_bitmapinfo -> biSizeImage, sizeof (unsigned long ), 1 , fp );
35
36 fseek(fp, 38 , SEEK_SET) ;
37 fread( & p_bitmapinfo -> biXPelsPerMeter, sizeof (unsigned long ), 1 , fp );
38
39 fseek(fp, 42 , SEEK_SET) ;
40 fread( & p_bitmapinfo -> biYPelsPerMeter, sizeof (unsigned long ), 1 , fp );
41
42 fseek(fp, 46 , SEEK_SET) ;
43 fread( & p_bitmapinfo -> biClrUsed, sizeof (unsigned long ), 1 , fp );
44 fseek(fp, 50 , SEEK_SET) ;
45 fread( & p_bitmapinfo -> biClrImportant, sizeof (unsigned long ), 1 , fp );
46
47 }
48 void ReadBitmapFile()
49 {
50 BITMAPFH bitmapheader ;
51 BITMAPIH bitmapinfo ;
52 FILE * fp;
53
54 fp = fopen( " 6.bmp " , " r " ) ;
55 if ( ! fp)
56 {
57 puts( " Read file failed. " ) ;
58 return ;
59 }
60
61 ReadHeader(fp, & bitmapheader , & bitmapinfo) ;
62
63 if (bitmapinfo.biBitCount != 24 )
64 {
65 puts( " UNSUPPORT " ) ;
66 return ;
67 }
68 ImageWidth = bitmapinfo.biWidth;
69 ImageHeight = bitmapinfo.biHeight;
70
71 int i = bitmapheader.bfOffBits;
72 while (i < bitmapheader.bfSize)
73 {
74 for ( int j = 0 ;j < ImageWidth;j ++ )
75 for ( int k = 0 ;k < ImageHeight;k ++ )
76 {
77 fseek(fp, i, SEEK_SET) ;
78 fread(Image[j][k] + 2 , 1 , 1 , fp) ;
79 fseek(fp, i + 1 , SEEK_SET) ;
80 fread(Image[j][k] + 1 , 1 , 1 , fp) ;
81 fseek(fp, i + 2 , SEEK_SET) ;
82 fread(Image[j][k], 1 , 1 , fp) ;
83
84 i = i + 3 ;
85 }
86 }
87
88 fclose(fp) ;
89 }
90 glTexImage2D(GL_TEXTURE_2D, 0 , 3 ,ImageWidth,ImageHeight, 0 ,GL_RGB,GL_UNSIGNED_BYTE, & Image[ 0 ][ 0 ][ 0 ]);
2 long ImageHeight = 256 ;
3 GLubyte Image[ 256 ][ 256 ][ 3 ];
4 void ReadHeader(FILE * fp , BITMAPFH * p_bitmapheader , BITMAPIH * p_bitmapinfo)
5 {
6 fseek(fp, 0 , SEEK_SET) ;
7 fread( & p_bitmapheader -> bfType, sizeof (unsigned short ), 1 , fp );
8 fseek(fp, 2 , SEEK_SET) ;
9 fread( & p_bitmapheader -> bfSize, sizeof (unsigned long ), 1 , fp );
10 fseek(fp, 6 , SEEK_SET) ;
11 fread( & p_bitmapheader -> bfReserved1, sizeof (unsigned short ), 1 , fp );
12 fseek(fp, 8 , SEEK_SET) ;
13 fread( & p_bitmapheader -> bfReserved2, sizeof (unsigned short ), 1 , fp );
14 fseek(fp, 10 , SEEK_SET) ;
15 fread( & p_bitmapheader -> bfOffBits, sizeof (unsigned long ), 1 , fp );
16 fseek(fp, 14 , SEEK_SET) ;
17 fread( & p_bitmapinfo -> biSize, sizeof (unsigned long ), 1 , fp );
18 fseek(fp, 18 , SEEK_SET) ;
19 fread( & p_bitmapinfo -> biWidth, sizeof (unsigned long ), 1 , fp );
20
21 fseek(fp, 22 , SEEK_SET) ;
22 fread( & p_bitmapinfo -> biHeight, sizeof (unsigned long ), 1 , fp );
23
24 fseek(fp, 26 , SEEK_SET) ;
25 fread( & p_bitmapinfo -> biPlanes, sizeof (unsigned short ), 1 , fp );
26
27 fseek(fp, 28 , SEEK_SET) ;
28 fread( & p_bitmapinfo -> biBitCount, sizeof (unsigned short ), 1 , fp );
29
30 fseek(fp, 30 , SEEK_SET) ;
31 fread( & p_bitmapinfo -> biCompression, sizeof (unsigned long ), 1 , fp );
32
33 fseek(fp, 34 , SEEK_SET) ;
34 fread( & p_bitmapinfo -> biSizeImage, sizeof (unsigned long ), 1 , fp );
35
36 fseek(fp, 38 , SEEK_SET) ;
37 fread( & p_bitmapinfo -> biXPelsPerMeter, sizeof (unsigned long ), 1 , fp );
38
39 fseek(fp, 42 , SEEK_SET) ;
40 fread( & p_bitmapinfo -> biYPelsPerMeter, sizeof (unsigned long ), 1 , fp );
41
42 fseek(fp, 46 , SEEK_SET) ;
43 fread( & p_bitmapinfo -> biClrUsed, sizeof (unsigned long ), 1 , fp );
44 fseek(fp, 50 , SEEK_SET) ;
45 fread( & p_bitmapinfo -> biClrImportant, sizeof (unsigned long ), 1 , fp );
46
47 }
48 void ReadBitmapFile()
49 {
50 BITMAPFH bitmapheader ;
51 BITMAPIH bitmapinfo ;
52 FILE * fp;
53
54 fp = fopen( " 6.bmp " , " r " ) ;
55 if ( ! fp)
56 {
57 puts( " Read file failed. " ) ;
58 return ;
59 }
60
61 ReadHeader(fp, & bitmapheader , & bitmapinfo) ;
62
63 if (bitmapinfo.biBitCount != 24 )
64 {
65 puts( " UNSUPPORT " ) ;
66 return ;
67 }
68 ImageWidth = bitmapinfo.biWidth;
69 ImageHeight = bitmapinfo.biHeight;
70
71 int i = bitmapheader.bfOffBits;
72 while (i < bitmapheader.bfSize)
73 {
74 for ( int j = 0 ;j < ImageWidth;j ++ )
75 for ( int k = 0 ;k < ImageHeight;k ++ )
76 {
77 fseek(fp, i, SEEK_SET) ;
78 fread(Image[j][k] + 2 , 1 , 1 , fp) ;
79 fseek(fp, i + 1 , SEEK_SET) ;
80 fread(Image[j][k] + 1 , 1 , 1 , fp) ;
81 fseek(fp, i + 2 , SEEK_SET) ;
82 fread(Image[j][k], 1 , 1 , fp) ;
83
84 i = i + 3 ;
85 }
86 }
87
88 fclose(fp) ;
89 }
90 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图片作为纹理的函数:
1
bool
LoadTexture(LPTSTR szFileName, GLuint
&
texid)
//
Creates Texture From A Bitmap File
2 {
3 HBITMAP hBMP; // Handle Of The Bitmap
4 BITMAP BMP; // Bitmap Structure
5
6 glGenTextures( 1 , & texid); // Create The Texture
7 hBMP = (HBITMAP)LoadImage(GetModuleHandle(NULL), szFileName, IMAGE_BITMAP, 0 , 0 , LR_CREATEDIBSECTION | LR_LOADFROMFILE );
8
9 if ( ! hBMP) // Does The Bitmap Exist?
10 return FALSE; // If Not Return False
11
12 GetObject(hBMP, sizeof (BMP), & BMP); // Get The Object
13 // hBMP: Handle To Graphics Object
14 // sizeof(BMP): Size Of Buffer For Object Information
15 // &BMP: Buffer For Object Information
16
17 glPixelStorei(GL_UNPACK_ALIGNMENT, 4 ); // Pixel Storage Mode (Word Alignment / 4 Bytes)
18
19 // Typical Texture Generation Using Data From The Bitmap
20 glBindTexture(GL_TEXTURE_2D, texid); // Bind To The Texture ID
21 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Min Filter
22 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Mag Filter
23 glTexImage2D(GL_TEXTURE_2D, 0 , 3 , BMP.bmWidth, BMP.bmHeight, 0 , GL_BGR_EXT, GL_UNSIGNED_BYTE, BMP.bmBits);
24
25 DeleteObject(hBMP); // Delete The Object
26
27 return TRUE; // Loading Was Successful
28 }
2 {
3 HBITMAP hBMP; // Handle Of The Bitmap
4 BITMAP BMP; // Bitmap Structure
5
6 glGenTextures( 1 , & texid); // Create The Texture
7 hBMP = (HBITMAP)LoadImage(GetModuleHandle(NULL), szFileName, IMAGE_BITMAP, 0 , 0 , LR_CREATEDIBSECTION | LR_LOADFROMFILE );
8
9 if ( ! hBMP) // Does The Bitmap Exist?
10 return FALSE; // If Not Return False
11
12 GetObject(hBMP, sizeof (BMP), & BMP); // Get The Object
13 // hBMP: Handle To Graphics Object
14 // sizeof(BMP): Size Of Buffer For Object Information
15 // &BMP: Buffer For Object Information
16
17 glPixelStorei(GL_UNPACK_ALIGNMENT, 4 ); // Pixel Storage Mode (Word Alignment / 4 Bytes)
18
19 // Typical Texture Generation Using Data From The Bitmap
20 glBindTexture(GL_TEXTURE_2D, texid); // Bind To The Texture ID
21 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Min Filter
22 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Mag Filter
23 glTexImage2D(GL_TEXTURE_2D, 0 , 3 , BMP.bmWidth, BMP.bmHeight, 0 , GL_BGR_EXT, GL_UNSIGNED_BYTE, BMP.bmBits);
24
25 DeleteObject(hBMP); // Delete The Object
26
27 return TRUE; // Loading Was Successful
28 }