上述纹理创建比较容易,但是这种方法很难创造出漂亮、复杂的纹理。通常我们使用的纹理都来自于图形文件。下面我们使用最常见的BMP文件来创建一个纹理,同样贴在立方体的六个面上。
glInit需要做一下改动,将
g_Texture[0] = HappyTexture();
改为
g_Texture[0] = CreateTexture("baby.bmp"),表示使用baby.bmp文件创建一个纹理。
纹理创建函数CreateTexture()带有一个表示纹理图形文件名的参数。本程序使用了一个纹理,所以定义的纹理为UINT g_Texture[1]。如果还需要使用更多的纹理,只需要在定义中增加数组的数目,同时在glInit()中多次调用CreateTexture()创建纹理,然后在glMain()中使用glBindTexture()针对不同的图形选择不同的纹理即可。
CreateTexture()函数首先使用辅助库的函数auxDIBImageLoad()将对应文件的图形数据调入,成功后pBitmap就包含了纹理像素数据。然后调用glGenTextures()进行注册,再调用glBindTexture()绑定纹理,使用glTexImage2D为当前纹理设置数据。纹理滤波仍然使用线性滤波。
CreateTexture函数的的详细实现如下。
GLuint CreateTexture(LPSTR strTextureFileName)
{
GLuint tex; //纹理标识
AUX_RGBImageRec *pBitmap=0; //存放图像的数据结构
/*
在glaux.h中定义如下
typedef struct _AUX_RGBImageRec {
GLint sizeX, sizeY; //图像的大小
unsigned char *data; //像素数据
} AUX_RGBImageRec;
*/
if(!strTextureFileName) //如果文件名为空则返回
{
return FALSE;
}
pBitmap=auxDIBImageLoad(strTextureFileName); //把BMP文件调入pBitmap所指的内存
if(!pBitmap)
{
return FALSE;
}
glGenTextures( //为纹理分配内存
1, //纹理个数
&tex); //把其标识赋值于tex
glBindTexture( //绑定纹理
GL_TEXTURE_2D, //二维纹理
tex); //使用纹理
glTexImage2D( //为当前纹理设置像素数据
GL_TEXTURE_2D, //是二维纹理还是一维纹理
0, //纹理的细节等级
3, //纹理的每个像素包含几种颜色成份
pBitmap->sizeX, //图像的宽度
pBitmap->sizeY, //图像的高度
0, //纹理的边界宽度
GL_RGB, //图像的格式
GL_UNSIGNED_BYTE, //图像的数据类型
pBitmap->data); //图像的像素数据
if(pBitmap && pBitmap->data)
free(pBitmap->data);//释放pBitmap所占用的内存
if(pBitmap)
free(pBitmap);
return tex; //返回生成纹理的标识
}
glMain将glTranslatef(0.0f, 0.0f, -10.0f)改为glTranslatef(0.0f, 0.0f, -6.0f),这样看起来图像清楚一些。
运行程序后如图5-6所示,我们可以看到立方体的六个面都贴上了BMP图片,真实感大大增强,。
图5-7 BMP纹理