這個代碼寫得有些阿格里拉,但也不失為一種方法
#ifndef _BMPLOAD_H_
#define _BMPLOAD_H_
#include <iostream>
#include <stdio.h>
using namespace std;
/*-------------
類型定義
--------------*/
// 紋理圖像結構
typedef struct {
int imgWidth; // 紋理寬度
int imgHeight; // 紋理高度
unsigned int rgbType; // 每個象素對應的字節數,3:24位圖,4:帶alpha通道的24位圖
unsigned char *data; // 紋理數據
} TEXTUREIMAGE;
// BMP文件頭
typedef struct {
unsigned short bfType; // 文件類型
unsigned long bfSize; // 文件大小
unsigned short bfReserved1; // 保留位
unsigned short bfReserved2; // 保留位
unsigned long bfOffBits; // 數據偏移位置
} BMPFILEHEADER;
// BMP信息頭
typedef struct {
unsigned long biSize; // 此結構大小
long biWidth; // 圖像寬度
long biHeight; // 圖像高度
unsigned short biPlanes; // 調色板數量
unsigned short biBitCount; // 每個象素對應的位數,24:24位圖,32:帶alpha通道的24位圖
unsigned long biCompression; // 壓縮
unsigned long biSizeImage; // 圖像大小
long biXPelsPerMeter; // 橫向分辨率
long biYPelsPerMeter; // 縱向分辨率
unsigned long biClrUsed; // 顏色使用數
unsigned long biClrImportant; // 重要顏色數
} BMPINFOHEADER;
// 讀取BMP文件創建紋理
GLboolean LoadBmp(char *filename, TEXTUREIMAGE *textureImg) {
int i, j;
FILE *file;
BMPFILEHEADER bmpFile;
BMPINFOHEADER bmpInfo;
int pixel_size;
// 初始化紋理數據
textureImg->imgWidth = 0;
textureImg->imgHeight = 0;
textureImg->rgbType = 0;
if (textureImg->data != NULL) {
delete []textureImg->data;
}
// 打開文件
file = fopen(filename, "rb");
if (file == NULL) {
cout << "Open File Error" <<endl;
return false;
}
// 獲取文件頭
rewind(file);
fread(&bmpFile, sizeof(BMPFILEHEADER)-2, 1, file);
//因為C語言對結構按四位對齊,所以不能直接用sizeof(BMPFILEHEADER)
fread(&bmpInfo, sizeof(BMPINFOHEADER), 1, file);
// 驗證文件類型
if (bmpFile.bfType != 0x4D42) {
cout << "File Type Error" <<endl;
fclose(file);
return false;
}
// 獲取圖像色彩數
pixel_size = bmpInfo.biBitCount >> 3;
// 讀取文件數據
textureImg->data = new unsigned char[bmpInfo.biWidth * bmpInfo.biHeight * pixel_size];
if (textureImg->data == NULL) {
fclose(file);
return false;
}
rewind(file);
fseek(file, 54L, 0);
for (i = 0; i < bmpInfo.biHeight; i++) {
for (j = 0; j < bmpInfo.biWidth; j++) {
// 紅色分量
fread(textureImg->data + (i * bmpInfo.biWidth + j) * pixel_size + 2,
sizeof(unsigned char), 1, file);
// 綠色分量
fread(textureImg->data + (i * bmpInfo.biWidth + j) * pixel_size + 1,
sizeof(unsigned char), 1, file);
// 藍色分量
fread(textureImg->data + (i * bmpInfo.biWidth + j) * pixel_size + 0,
sizeof(unsigned char), 1, file);
// Alpha分量
if (pixel_size == 4) {
fread(textureImg->data + (i * bmpInfo.biWidth + j) * pixel_size + 3,
sizeof(unsigned char), 1, file);
}
}
}
// 記錄圖像相關參數
textureImg->imgWidth = bmpInfo.biWidth;
textureImg->imgHeight = bmpInfo.biHeight;
textureImg->rgbType = pixel_size;
fclose(file);
return false;
}
#endif