將紋理映射到3D模型是革命性技術,給人帶來照片般震撼逼真效果,簡單來講紋理映射就是將圖片附著於多邊形之上,這樣的圖片稱之為紋理,你可以將平鋪的地圖映射到球體上從而得到3D地球模型,下面以渲染木箱為例的演示程式:下載
生成紋理對像 | 簡介 |
void glGenTextures(GLsizei n,GLuint *textures); | 生成紋理並返回紋理『索引』即ID編號 |
n | 紋理個數 |
textures | 數組,返回紋理ID |
綁定紋理 | 簡介 |
void glBindTexture(GLenum target,GLuint texture); | 生成紋理之後要進行綁定 |
Target | GL_TEXTURE_1D:1維紋理
GL_TEXTURE_2D:2維紋理 |
Textures | 紋理ID數組 |
過濾紋理 | 簡介 |
void glTexParameteri(GLenum target,GLenum pname,GLint param); | 綁定之後要設定紋理過濾 |
target: | GL_TEXTURE_1D:1維紋理
GL_TEXTURE_2D:2維紋理 |
pname: | GL_TEXTURE_MIN_FILTER:縮小過濾
GL_TEXTURE_MAG_FILTER:放大過濾 GL_TEXTURE_WRAP_S:紋理S座標 GL_TEXTURE_WRAP_T:紋理T座標 |
param:
|
GL_REPEAT:重複(平鋪)紋理
GL_CLAMP:夾持紋理 GL_LINEAR:像素採樣線性插值(加權平均) GL_NEAREST:像素採樣最接近中心紋理 GL_NEAREST_MIPMAP_NEAREST:紋理鏈採樣使用NEAREST,過濾使用NEAREST GL_NEAREST_MIPMAP_LINEAR:紋理鏈採樣使用NEAREST,過濾使用LINEAR GL_LINEAR_MIPMAP_NEAREST:紋理鏈採樣使用LINEAR,過濾使用NEAREST GL_LINEAR_MIPMAP_LINEAR:紋理鏈採樣使用LINEAR,過濾使用LINEAR |
載入紋理 | 簡介 |
void glTexImage2D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLint format,GLenum type,const GLvoid *pixels); | 設定紋理過濾後需要把紋理載入OpenGL
type:最常用GL_UNSIGNED_BYTE(無符號8Bit) pixels:紋理數據 |
target: | GL_TEXTURE_1D:1維紋理
GL_TEXTURE_2D:2維紋理 |
level: | 紋理鏈索引,若只有單個紋理則設為0 |
internalformat: | 最常用GL_RGBA或GL_RGB |
width: | 紋理寬度 |
height: | 紋理高度 |
border: | 紋理是否有變框,0沒有邊框,1有邊框 |
format: | 最常用GL_RGBA或GL_RGB |
紋理座標與頂點座標 | 簡介 |
void glTexCoord2f (GLfloat s, GLfloat t); | 設定紋理座標(s,t), s軸紋理的x座標,t軸為紋理的y座標,紋理座標必需在頂點座標之前設定 |
void glVertex3f(GLfloat x,GLfloat y,GLfloat z); | 設定頂點座標,並與紋理座標匹配 |
定義紋理結構 | 簡介 |
typedef struct TEXTURE_TYP{ | 此結構用於保存紋理位圖信息 |
int width; | 紋理寬度 |
int height; | 紋理高度 |
int bitCount; | 位圖像素的bits (8BIT,16BIT,24BIT,32BIT) |
int size; | 紋理數據的大小 |
PALETTEENTRY paletteentry; | 位圖調色板 |
GLuint ID; | 紋理ID |
PBYTE images[32]; | mipmap紋理鏈 |
int count; | 紋理鏈個數 |
}TEXTURE, *TEXTURE_PTR; |
紋理映射代碼示例
1.啟用深度緩衝測試,可保證多邊形被正確繪製
glEnable(GL_DEPTH_TEST);
2.啟動漸變效果
glShadeModel(GL_SMOOTH);
3.啟動多邊形隱面裁剪(消除隱藏面)如果要穿越實體則無需啟動
glEnable(GL_CULL_FACE);
4.設背面為隱面
glCullFace(GL_BACK);
5.多邊形正面使用逆時針
glFrontFace(GL_CCW);
6.啟用2D紋理映射
glEnable(GL_TEXTURE_2D);
7.載入位圖紋理(.bmp圖檔)( .tga圖檔)
TEXTURE texture;
Load_File_Texture(&texture,path);
8.生成1個紋理
glGenTextures(1, &texture->ID);
9.綁定紋理
glBindTexture(GL_TEXTURE_2D, texture->ID);
10.放大紋理像素採樣最接近中心紋理
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
11.縮小紋理過濾像素採樣最接近中心紋理
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
12.載入紋理
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture->width, texture->height, 0, GL_RGB, GL_UNSIGNED_BYTE, texture->image[0]);
從指定的磁盤路徑載入紋理函式
bool Load_File_Texture(TEXTURE_PTR texture,const char * path)
{
char drive[_MAX_DRIVE] = { 0 };// 驅動器盤符
char dir[_MAX_DIR] = { 0 }; // 目錄
char fname[_MAX_FNAME] = { 0 };// 文件名
char ext[_MAX_EXT] = { 0 }; // 擴展名!
BITMAP_FILE bitmap;
TARGA_FILE targa;
PCX pcx;
if (texture == NULL || path == NULL)
return false;
//將路徑名分拆為組件!
_splitpath(path, drive, dir, fname, ext);
if (stricmp(ext, “.bmp”) == 0)// 載入位圖
{
Load_Bitmap(&bitmap, path);// 載入BMP文檔
Load_Bitmap_Texture(texture, &bitmap);// 載入紋理
}
else
if (stricmp(ext, “.tga”) == 0)// 載入位圖
{
Load_Targa(&targa, path); // 載入tga文檔
Load_Targa_Texture(texture, &targa);// 載入紋理
}
else
if (stricmp(ext, “.pcx”) == 0)// 載入位圖
{
Load_PCX(&pcx, path); // 載入PCX文檔
Load_PCX_Texture(texture, &pcx);// 載入紋理
}
return false;
}
激活紋理
void Bind_Texture(TEXTURE_PTR texture){
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture->ID);// 綁定紋理
}