加载位图树纹理的两种方法,这两种方法都有局限性,如果大家还知道其他方法,可以分享一下~~
方法一:
//
//函数名称: LoadTreeBmpFile
//函数介绍:
// 加载树纹理函数
//输入参数:
// LPCWSTR filename 文件名
// GLuint& TreeTexture 存放纹理对象的变量
//输出参数:
// 无
//返回值:
// 无
//备注: 此函数是专门用来加载树纹理的函数,此函数对加载进来的图片进行去掉背景的操作,仅留下树的
// 颜色数据
///
glGenTextures(1,&TreeTexture);
glBindTexture(GL_TEXTURE_2D,TreeTexture);
AUX_RGBImageRec* myimage ;
unsigned char *image ;
myimage = auxDIBImageLoad(filename);
int width , height ;
width = myimage->sizeX ;
height = myimage->sizeY ;
FILE *fp;
fp=_wfopen(filename,L"rb");
if(!fp)
return;
fseek(fp,54,SEEK_SET); //读取24位真彩色位图
image=(unsigned char*)malloc(width*height*3) ;
int rc;
rc = fread(image ,sizeof(unsigned char) ,width*height*3 ,fp) ;
fclose(fp);
BYTE texture[256][256][4]; //注意:每个像素占用4个字节,不是原来的3个
for(int i = 0 ; i < width ; i ++)
{
for(int j = 0 ;j < height ; j ++)
{
//把颜色值写入
texture[i][j][0] = (GLubyte)*(image+i*width*3+j*3);
texture[i][j][1] = (GLubyte)*(image+i*width*3+j*3+1);
texture[i][j][2] = (GLubyte)*(image+i*width*3+j*3+2);
//设置alpha值,假设黑色为透明色
if(texture[i][j][0] == 0.0 && texture[i][j][1 ]== 0.0 && texture[i][j][2] == 0.0)
texture[i][j][3] = 0.0 ;//透明,设为0
else
texture[i][j][3] = 1.0 ;//不透明,设为1.0
}
}
//映射纹理
glPixelStorei(GL_UNPACK_ALIGNMENT,1) ;
glTexImage2D(GL_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,texture);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
free(myimage->data);
free(myimage) ;
free(image) ;
----------------------------------------------------------------------------------------------------------------------------------------------------
方法二:
1.下面为主函数
glGenTextures(1, &texture); //获取1个未使用的贴图名称
glBindTexture(GL_TEXTURE_2D, texture); //选择要绑定的贴图(纹理)
BITMAPINFOHEADER bitHeader; //定义位图结构
unsigned char *buffer; //定义位图指针
buffer=LoadBitmapFileWithAlpha(filename,&bitHeader); //调入位图
gluBuild2DMipmaps ( GL_TEXTURE_2D, // 创建一个 2D贴图(纹理)
4, // 使用3种颜色(RGB)+ 颜色深度
bitHeader.biWidth, // 图像宽
bitHeader.biHeight,// 图像高
GL_RGBA, // 红绿蓝顺序
GL_UNSIGNED_BYTE, // 图像的数据类型是字节
buffer // 指定贴图(纹理)数据
); // 创建贴图(纹理)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR); //缩小采用三线性滤波
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//放大采用线性滤波
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
free(buffer); // 释放位图数据
2.下面为被主函数调用的两个函数(放到了bitmap.h文件中)
#include <stdlib.h>
#include <windows.h>
#include <stdio.h>
#define BITMAP_ID 0x4D42 // the universal bitmap ID
/*****************************************************************************
LoadBitmapFile()
Returns a pointer to the bitmap image of the bitmap specified by filename.
Also returns the bitmap header information. No support for 8-bit bitmaps.
*****************************************************************************/
unsigned char *LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
{
FILE *filePtr; // the file pointer
BITMAPFILEHEADER bitmapFileHeader; // bitmap file header
unsigned char *bitmapImage; // bitmap image data
unsigned int imageIdx = 0; // image index counter
unsigned char tempRGB; // swap variable
// open filename in "read binary" mode
filePtr = fopen(filename, "rb");
if (filePtr == NULL)
return NULL;
// read the bitmap file header
fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, filePtr);
// verify that this is a bitmap by checking for the universal bitmap id
if (bitmapFileHeader.bfType != BITMAP_ID)
{
fclose(filePtr);
return NULL;
}
// read the bitmap information header
fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, filePtr);
// move file pointer to beginning of bitmap data
fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);
// allocate enough memory for the bitmap image data
bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);
// verify memory allocation
if (!bitmapImage)
{
free(bitmapImage);
fclose(filePtr);
return NULL;
}
// read in the bitmap image data
fread(bitmapImage, 1, bitmapInfoHeader->biSizeImage, filePtr);
// make sure bitmap image data was read
if (bitmapImage == NULL)
{
fclose(filePtr);
return NULL;
}
// swap the R and B values to get RGB since the bitmap color format is in BGR
for (imageIdx = 0; imageIdx < bitmapInfoHeader->biSizeImage; imageIdx+=3)
{
tempRGB = bitmapImage[imageIdx];
bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
bitmapImage[imageIdx + 2] = tempRGB;
}
// close the file and return the bitmap image data
fclose(filePtr);
return bitmapImage;
} // end LoadBitmapFile()
/*****************************************************************************
LoadBitmapFileWithAlpha
Loads a bitmap file normally, and then adds an alpha component to use for
blending
*****************************************************************************/
unsigned char *LoadBitmapFileWithAlpha(char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
{
unsigned char *bitmapImage = LoadBitmapFile(filename, bitmapInfoHeader);
unsigned char *bitmapWithAlpha = (unsigned char *)malloc(bitmapInfoHeader->biSizeImage * 4 / 3);
if (bitmapImage == NULL || bitmapWithAlpha == NULL)
return NULL;
// loop through the bitmap data
for (unsigned int src = 0, dst = 0; src < bitmapInfoHeader->biSizeImage; src +=3, dst +=4)
{
// if the pixel is black, set the alpha to 0. Otherwise, set it to 255.
if (bitmapImage[src] == 0 && bitmapImage[src+1] == 0 && bitmapImage[src+2] == 0)
bitmapWithAlpha[dst+3] = 0;
else
bitmapWithAlpha[dst+3] = 0xFF;
// copy pixel data over
bitmapWithAlpha[dst] = bitmapImage[src];
bitmapWithAlpha[dst+1] = bitmapImage[src+1];
bitmapWithAlpha[dst+2] = bitmapImage[src+2];
}
free(bitmapImage);
return bitmapWithAlpha;
} // end LoadBitmapFileWithAlpha()