要使用纹理对象储存纹理数据需要以下四步
1 生成位图文件名称
glGenTextures(1, &ID);
2 创建纹理对象,即将纹理对象绑定到纹理数据
glBindTexture(GL_TEXTURE_2D, m_Texture.ID);
3 再次绑定纹理对象,即将其中的纹理映射到物体上
glBindTexture(GL_TEXTURE_2D, m_Texture.ID);
4 删除纹理对象
(1)纹理资源载入
Bmp位图文件主要分为四部分
位图文件头 :文件类型、存放位置信息,文件大小,
位图信息头
颜色表
定义位图的字节阵列
.h文件
#define BITMAP_ID 0x4D42 /**< 位图文件的标志 */
class CBMPLoader
{
public:
CBMPLoader();
~CBMPLoader();
bool LoadBitmap(char *file); /**< 装载一个bmp文件 */
void FreeImage(); /**< 释放图像数据 */
unsigned int ID; /**< 生成纹理的ID号 */
int imageWidth; /**< 图像宽度 */
int imageHeight; /**< 图像高度 */
unsigned char *image; /**< 指向图像数据的指针 */
};
.cpp文件
/** 构造函数 */
CBMPLoader::CBMPLoader()
{
/** 初始化成员值为0 */
image = 0;
imageWidth = 0;
imageHeight = 0;
}
/** 析构函数 */
CBMPLoader::~CBMPLoader()
{
FreeImage(); /**< 释放图像数据占据的内存 */
}
/** 装载一个位图文件 */
bool CBMPLoader::LoadBitmap(char *file)
{
FILE *pFile = 0; /**< 文件指针 */
/** 创建位图文件信息和位图文件头结构 */
BITMAPINFOHEADER bitmapInfoHeader;
BITMAPFILEHEADER header;
unsigned char textureColors = 0;/**< 用于将图像颜色从BGR变换到RGB */
/** 打开文件,并检查错误 */
pFile = fopen(file, "rb");
if (pFile == 0) return false;
/** 读入位图文件头信息 */
fread(&header, sizeof(BITMAPFILEHEADER), 1, pFile);
/** 检查该文件是否为位图文件 */
if (header.bfType != BITMAP_ID)
{
fclose(pFile); /**< 若不是位图文件,则关闭文件并返回 */
return false;
}
/** 读入位图文件信息 */
fread(&bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, pFile);
/** 保存图像的宽度和高度 */
imageWidth = bitmapInfoHeader.biWidth;
imageHeight = bitmapInfoHeader.biHeight;
/** 确保读取数据的大小 */
if (bitmapInfoHeader.biSizeImage == 0)
bitmapInfoHeader.biSizeImage = bitmapInfoHeader.biWidth *
bitmapInfoHeader.biHeight * 3;
/** 将指针移到数据开始位置 */
fseek(pFile, header.bfOffBits, SEEK_SET);
/** 分配内存 */
image = new unsigned char[bitmapInfoHeader.biSizeImage];
/** 检查内存分配是否成功 */
if (!image) /**< 若分配内存失败则返回 */
{
delete[] image;
fclose(pFile);
return false;
}
/** 读取图像数据 */
fread(image, 1, bitmapInfoHeader.biSizeImage, pFile);
/** 将图像颜色数据格式进行交换,由BGR转换为RGB */
for (int index = 0; index < (int)bitmapInfoHeader.biSizeImage; index += 3)
{
textureColors = image[index];
image[index] = image[index + 2];
image[index + 2] = textureColors;
}
fclose(pFile); /**< 关闭文件 */
return true; /**< 成功返回 */
}
bool CBMPLoader::Load(const char* fileName)
{
if(!LoadBitmap(fileName))
{
MessageBox(NULL,"载入位图文件失败!","错误",MB_OK);
exit(0);
}
/** 生成纹理对象名称 */
glGenTextures(1, &ID);
/** 创建纹理对象 ,将纹理对象绑定到纹理数据*/
glBindTexture(GL_TEXTURE_2D, ID);
/** 控制滤波 */
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_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
/** 创建纹理 */
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, imageWidth,
imageHeight, GL_RGB, GL_UNSIGNED_BYTE,
image);
return true;
}
/** 释放内存 */
void CBMPLoader::FreeImage()
{
/** 释放分配的内存 */
if(image)
{
delete[] image;
image = 0;
}
}
(2)纹理资源映射
以正方体盒子为例
void CPointView::DrawBox()
{
/** 获得场景中光照状态 */
GLboolean lp;
glGetBooleanv(GL_LIGHTING,&lp);
glDisable(GL_LIGHTING);
/** 设置材质属性 */
GLfloat mat_ambient[] = { 0.8f, 0.8f, 0.8f, 1.0f };
GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glPushMatrix();
glTranslatef(5.0f,2.0f,-10.0f);
glRotatef(rotatefVary,0,1,0);
glScalef(2.0f,2.0f,2.0f);
/** 选择纹理 */
glBindTexture(GL_TEXTURE_2D, m_Texture.ID);
/** 开始绘制四边形 */
glBegin(GL_QUADS);
/// 前侧面
glNormal3f( 0.0f, 0.0f, 1.0f); /**< 指定法线指向观察者 */
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
/// 后侧面
glNormal3f( 0.0f, 0.0f,-1.0f); /**< 指定法线背向观察者 */
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
/// 顶面
glNormal3f( 0.0f, 1.0f, 0.0f); /**< 指定法线向上 */
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
/// 底面
glNormal3f( 0.0f,-1.0f, 0.0f); /**< 指定法线朝下 */
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
/// 右侧面
glNormal3f( 1.0f, 0.0f, 0.0f); /**< 指定法线朝右 */
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
/// 左侧面
glNormal3f(-1.0f, 0.0f, 0.0f); /**< 指定法线朝左 */
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glPopMatrix();
if(lp) /** 恢复光照状态 */
glEnable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
}