Opengl之纹理映射

要使用纹理对象储存纹理数据需要以下四步

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);

}





你可能感兴趣的:(Opengl之纹理映射)