OpenGL加载纹理深入详解。

//OpenGL进行纹理映射的基本流程:
1,首先要开启纹理映射的功能。
glEnable(GL_TEXTURE_2D); 
2,载入位图资源。
3,将位图资源转化成纹理。
4,释放位图资源。
5,使用纹理,绘图。
闲话不多说,直接上代码。

 


这里插一句,在OpenGL里面,申明一个纹理(位图转化成纹理)需要三个步骤:
1,首先我需要申明一个纹理对象的名称,调用glGenTextures函数,为这个纹理对象申明一个名称,
其实这里的名称,就有点类似于MFC里面的ID,glGenTextures函数有两个参数,第一个是你要申请名称
的个数,第二个是一个GLuint类型的数组指针,将申请的名称放在一个数组里面装起来,这个数组里面
的名称(其实本质上就是一个uint的数字,这里和MFC相似。)就表示了这个纹理,其实我也可以直接令
一个数字为这个纹理的名称,但是为了防止意外的重名,所以调用glGenTextures函数,向OpenGL声明一下。
简而言之,第一步就是什么一个纹理对象,并且给这个对象申请一个名字,就这个名字返回到数组里面。
 

2,调用glBindTexture函数,这个函数有两个参数,第一个是要绑定的纹理对象的类型,第二个是要绑定
 的纹理对象的名称,也就是glGenTextures函数申请的名字并返回到数组里面的数值。
 这个函数一共有三个功能:
 <1>,如果这个名字第一次使用,这个函数就会创建一个新的纹理对象,并与这个名字绑定,然后这个纹理
 对象成为活动纹理对象。
 <2>,如果这个名字已经绑定过了,那么直接让这个纹理成为当前的活动纹理。
 <3>,因为纹理对象的名字是一个无符号的整形,所以如果传的值为0的话,OpenGL就会停止使用纹理对象
  

3,到目前为止,我已经有了一个纹理对象,那么接下来我就需要为这个纹理对象填充位图资源了,调用
 glTexImage2D函数,这个函数一共有九个参数:
 ①,定义纹理的类型,②,区分多种分辨率的纹理,如果只有一种分辨率,那么这个值为0,③,位图的颜色
 成分,一般为3,④,纹理图片的宽度,⑤,纹理图片的高度,⑥,边框的大小,⑦和⑧是纹理的一些属性参数
 这里不做赘述,⑨,纹理的图像数据。
  

做完这些,一个纹理就生成了。回头再总结一下
 1,申请一个名称。
 2,为这个名称绑定一个对象。
 3,为这个对象设定一些数据。
 分别以三个函数实现。
 函数原型:
 void glGenTextures(GLsizei n, GLuint *textures)
 void glBindTexture(GLenum target, GLuint texture );
 void glTexImage2D(GLenum target, GLint level, GLenum internalformat,GLsizei width, GLsizei height,
 GLint border, GLenum format, GLenum type, const void* pixels);
 

 


载入一张纹理的具体细节
这里直接封装好的函数LoadGLTextures,直接调用就行了,下面我来介绍一下LoadGLTextures函数
 具体实现的细节。
1,首先申明一个AUX_RGBImageRec类型的指针,指着指向LoadBMP返回的对象,装下所需要的位图资源。
 TextureImage[0]=LoadBMP("*.bmp");这样的话,我就从外存加载了位图资源到内存里面。关于LoadBMP
 这个函数我就不做介绍了,其实我自已也不大懂,知道这么用就行了,大概就是个C语言的内存读取
 2,glGenTextures(1, &texture[0]);上面已经提到了,申请一个纹理名称(一个无符号整形数),存储在
 texture[0]里面。
 3,glBindTexture(GL_TEXTURE_2D, texture[0]);为这个名称绑定一个纹理。
 4,glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY,0, 
 GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);调用这个函数,将位图资源转化到纹理,其他
 的参数不管,主要记住TextureImage[0]->sizeX, TextureImage[0]->sizeY,TextureImage[0]->data这
 三个就行了,分别指定了位图资源的宽高和资源的来源。
 5,最后在纹理生成之后,释放这个位图资源,内存优化。
 

//源码
GLuint texture[1];
AUX_RGBImageRec *LoadBMP(char *Filename)
{
 FILE *File=NULL;

 if (!Filename)  
 {
  return NULL;         
 }

 File=fopen(Filename,"r");       

 if (File)           
 {
  fclose(File);         
  return auxDIBImageLoad(Filename);    
 }

 return NULL;          

int LoadGLTextures()         
{
 int Status=FALSE;         
 AUX_RGBImageRec *TextureImage[1];     

 memset(TextureImage,0,sizeof(void *)*1);            


 if (TextureImage[0]=LoadBMP("*.bmp"))
 {
  Status=TRUE;         

  glGenTextures(1, &texture[0]);     

  glBindTexture(GL_TEXTURE_2D, texture[0]);
  glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
 }

 if (TextureImage[0])         
 {
  if (TextureImage[0]->data)       
  {
   free(TextureImage[0]->data);     
  }

  free(TextureImage[0]);        
 }

 return Status;
}


//源码
GLuint texture[n];//用于装纹理名称的数组,如果要声明多个,修改n的值。
AUX_RGBImageRec *LoadBMP(char *Filename)//LoadBMP完全是个工具函数,直接抄着用就行了,不做赘述。
{
 FILE *File=NULL;

 if (!Filename)  
 {
  return NULL;         
 }

 File=fopen(Filename,"r");       

 if (File)           
 {
  fclose(File);         
  return auxDIBImageLoad(Filename);    
 }

 return NULL;
}
int LoadGLTextures()         
{
 int Status=FALSE;         
 AUX_RGBImageRec *TextureImage[n];//用于装位图资源的数组,如果要声明多个,修改n的值。    

 memset(TextureImage,0,sizeof(void *)*n);//初始化指针数组,这里是C语言实现的方法,
                                         //其实在C++里面直接new就行了。            

 char *pictures[] = {// 创建一个位图名称数组,对应n幅位图
  "Data/1.bmp",
   "Data/2.bmp",
   "Data/3.bmp",
   "Data/4.bmp",
   "Data/5.bmp",
   "Data/6.bmp"
   //...
 };

  for(int i=0; i
 {
  if (TextureImage[i]=LoadBMP(pictures[i]))// 加载位图i成功,修改状态标志变量Status为TRUE
  {
   Status=TRUE;        
   
   glGenTextures(1, &texture[i]);     // 为第i个位图创建纹理
   glBindTexture(GL_TEXTURE_2D, texture[i]);// 将生成的纹理的名称绑定到指定的纹理上
   glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[i]->sizeX, TextureImage[i]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[i]->data);
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  }
  
  if (TextureImage[i])         // 释放位图数组占用的内存空间
  {
   if (TextureImage[i]->data)      
   {
    free(TextureImage[i]->data);   
   }
   
   free(TextureImage[i]);       
  }
 }
 return Status;
}

//以上就是OpenGL加载位图资源的步骤,可能写的有点乱,但是如果认真看的话应该不难理解,先就这样了
//其他的比较难的我也就不多说了,(其实我也不会,╮(╯_╰)╭)。
//学一点总结一点。 。

 

你可能感兴趣的:(OpenGL)