Opengl图像说明

加载位图文件

加载位图,也就是把位图读取到内存空间,实现纹理的创建,加载位图的函数说明一下:

AUX_RGBImageRec *LoadBMP(char *Filename)    // 根据位图文件的名称进行加载
{
FILE *File=NULL;         // 文件指针

if (!Filename)          // 如果没有指定位图文件名称就返回NULL
{
   return NULL;        
}

File=fopen(Filename,"r");       // 根据指定的位图文件名称,打开该位图文件

if (File)           // 如果位图文件存在
{
   fclose(File);         // 因为只是需要判断问题是否存在,而不需要对位图文件进行写操作,所以关闭位图文件
   return auxDIBImageLoad(Filename);    // 其实,只需要一个真正存在的位图文件的名称,实现加载位图文件,并返回一个指针
}

return NULL;          // 位图文件加载失败就返回NULL
}

上面实现加载位图的函数中,AUX_RGBImageRec是glaux.h中定义的类型,该类型的定义如下所示:

/*
** RGB Image Structure
*/

typedef struct _AUX_RGBImageRec {
    GLint sizeX, sizeY;
    unsigned char *data;
} AUX_RGBImageRec;

首先,AUX_RGBImageRec类型是一个RGB图像结构类型。该结构定义了三个成员:

sizeX —— 图像的宽度;
sizeY —— 图像的高度;
data; —— 图形所包含的数据,其实也就是该图形在内存中的像素数据的一个指针。

AUX_RGBImageRec类型的变量描述了一幅图像的特征。

上述函数中,调用了glaux.h库文件中的auxDIBImageLoad函数,其实它是一个宏,函数原型为auxRGBImageLoadW(LPCWSTR)或者auxRGBImageLoadA(LPCSTR),可以在该库文件中找到它的定义,如下所示:

/* AUX_RGBImageRec * APIENTRY auxRGBImageLoad(LPCTSTR); */
#ifdef UNICODE
#define auxRGBImageLoad auxRGBImageLoadW
#else
#define auxRGBImageLoad auxRGBImageLoadA
#endif
AUX_RGBImageRec * APIENTRY auxRGBImageLoadA(LPCSTR);
AUX_RGBImageRec * APIENTRY auxRGBImageLoadW(LPCWSTR);

#ifdef UNICODE
#define auxDIBImageLoad auxDIBImageLoadW
#else
#define auxDIBImageLoad auxDIBImageLoadA
#endif
AUX_RGBImageRec * APIENTRY auxDIBImageLoadA(LPCSTR);
AUX_RGBImageRec * APIENTRY auxDIBImageLoadW(LPCWSTR);

宏auxDIBImageLoad实现的功能就是:根据指定的位图名称,将该位图的信息加载到内存中,以便用来创建成为纹理。

创建纹理并加载纹理

用于创建并加载纹理的函数为LoadGLTextures,实现如下所示:

int LoadGLTextures()         // 根据加载的位图创建纹理
{
int Status=FALSE;         // 指示纹理创建是否成功的标志

AUX_RGBImageRec *TextureImage[6];     // 创建一个纹理图像数组,这里指定数组大小为6

memset(TextureImage,0,sizeof(void *)*6);           // 初始化纹理图像数组,为其分配内存

char *pictures[] = { // 创建一个位图名称数组,对应6幅位图
   "Data/No1.bmp",
   "Data/No2.bmp",
   "Data/No3.bmp",
   "Data/No4.bmp",
   "Data/No5.bmp",
   "Data/No6.bmp"
};
for(int i=0; i<6; 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;          // 创建纹理并加载,返回成功或者失败的标志Status
}

上述函数是创建和加载纹理的核心实现。

1、glGenTextures函数

其中,调用了glGenTextures函数,查看MSDN可以看到,声明如下所示:

void glGenTextures(
GLsizei n,         
GLuint * textures  
);

函数参数的含义:

n —— 生成的纹理的名称的个数;

textures —— 生成的纹理名称所存储位置的指针,也就是一个纹理数组的内存地址,或者说是数组首元素的内存地址。

函数被调用,会生成一系列纹理的名字,并存储到指定的数组中。

2、glBindTexture函数

glBindTexture函数实现了将调用glGenTextures函数生成的纹理的名字绑定到对应的目标纹理上。该函数的声明如下所示:

void glBindTexture(
GLenum target,  
GLuint texture  
);

函数参数的含义:

target —— 纹理被绑定的目标,它只能取值GL_TEXTURE_1D或者GL_TEXTURE_2D;

texture —— 纹理的名称,并且,该纹理的名称在当前的应用中不能被再次使用。

3、glTexImage2D函数

调用glTexImage2D函数,用来指定二维纹理图像。该函数的声明如下所示:

void glTexImage2D(
GLenum target,       
GLint level,         
GLint components,    
GLsizei width,       
GLsizei height,      
GLint border,        
GLenum format,       
GLenum type,         
const GLvoid *pixels
);

函数参数的含义:

target —— 指定目标纹理,必须为GL_TEXTURE_2D;

level —— 指定图像级别的编号,0表示基本图像,其它可以参考MSDN;

components —— 纹理中颜色组件的编号,可是是1或2或3或4;

width —— 纹理图像的宽度;

height —— 纹理图像的高度;

border —— 纹理图像的边框宽度,必须是0或1;

format —— 指定像素数据的格式,一共有9个取值:GL_COLOR_INDEX、GL_RED、GL_GREEN、GL_BLUE、GL_ALPHA、GL_RGB、GL_RGBA、GL_BGR_EXT、GL_BGRA_EXT、GL_LUMINANCE、GL_LUMINANCE_ALPHA ,具体含义可以参考MSDN;

type —— 像素数据的数据类型,取值可以为GL_UNSIGNED_BYTE, GL_BYTE, GL_BITMAP, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT, and GL_FLOAT;

pixels —— 内存中像素数据的指针。

4、glTexParameteri函数

glTexParameteri函数或者glTexParameterf函数用来设置纹理参数,声明如下所示:

void glTexParameterf(
GLenum target,
GLenum pname,
GLfloat param
);

void glTexParameteri(
GLenum target,
GLenum pname,
GLint param   
);

函数参数的含义:

target —— 目标纹理,必须为GL_TEXTURE_1D或GL_TEXTURE_2D;

pname —— 用来设置纹理映射过程中像素映射的问题等,取值可以为:GL_TEXTURE_MIN_FILTER、GL_TEXTURE_MAG_FILTER、GL_TEXTURE_WRAP_S、GL_TEXTURE_WRAP_T,详细含义可以查看MSDN;

param —— 实际上就是pname的值,可以参考MSDN。

另外,该类函数还有两个:

void glTexParameterfv(
GLenum target,        
GLenum pname,         
const GLfloat *params
);

void glTexParameteriv(
GLenum target,      
GLenum pname,       
const GLint *params
);

上述程序中调用如下:

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

功能就是实现线形滤波的功能,当纹理映射到图形表面以后,如果因为其它条件的设置导致纹理不能更好地显示的时候,进行过滤,按照指定的方式进行显示,可能会过滤掉显示不正常的纹理像素。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章