紋理只是一種能夠應用到場景中的三角形上的圖像數據。它經過過濾的紋理單元(texel,相當于基于紋理的像素)填充到實心區域。
簡單的說就是加載圖片,底層是使用紋理實現的
一、紋理 常用API 解析
紋理對象
紋理對象允許我們一次加載一個以上紋理狀態(包含紋理圖像)。以及在它們之間進行快速切換。紋理狀態是由當前綁定的紋理對象維護的。而紋理對象時一個無符號整數標識的。
//使用函數分配紋理對象
//指定紋理對象的數量 和 指針 (指針指向一個無符號整形數組,有紋理對象標識符填充)
void glGenTextures(GLsizei n, GLunint * textTures);
//綁定紋理狀態
//參數target:GL_TEXTURE_1D、GL_TEXTURE_3D、GL_TEXTURE_3D
//參數texture:需要綁定的紋理對象
void glBindTexture(GLenum target, GLunit texture)
//刪除綁定紋理對象
//紋理對象 以及 紋理對象指針 (指針指向一個無符號整形數組,有紋理對象標識符填充)
void glDeleteTextures(GLsizei n, GLunit *textures);
//測試紋理對象是否有效
//如果texture是一個已經分配空間的紋理對象,那么這個函數會返回GL_TRUE,否則會返回GL_FALSE。
GLboolean glIsTexture(GLunit texture);
讀取TGA 紋理
//讀取TGA 紋理
//參數1: 紋理文件名稱
//參數2: 文件寬度地址
//參數3:文件高度地址
//參數4:文件組件地址
//參數5:文件格式地址
//返回值:pBits,指向圖像數據的指針
GLbyte *gltReadTGABits(const char *szFileName, GLint *iWidth, GLint *iHeight, GLint *iComponents, GLenum *eFormat);
讀取像素圖
//參數1: x,矩陣左下角的窗口坐標
//參數2:y,矩陣左下角的窗口坐標
//參數3:width,矩陣的寬,像素為單位
//參數4:height,矩陣的高,像素為單位
//參數5:format,OpenGL的像素格式,
//參數6:type,解釋參數pixels指向的數據,告訴OpenGL使用緩存區中的什么數據類型來存儲顏色分量,像素數據的數據類型
//參數7:pixels,指向圖形數據的指針
void glReadPixels(GLint x, GLint y, GLSizei width, GLSizei height, GLenum format, GLenum type, const void * pixels);
glReadBuffers(mode); ->指定讀取的緩存
glWriteBuffers(mode); ->指定寫入的緩存
紋理參數設置
//參數1:target,指定這些參數將要應用在那個紋理模式上,比如GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D。
//參數2:pname,指定需要設置那個紋理參數
//參數3:param,設定特定的紋理參數的值
glTexParameterf(GLenum target,GLenum pname,GLFloat param);
glTexParameteri(GLenum target,GLenum pname,GLint param);
glTexParameterfv(GLenum target,GLenum pname,GLFloat *param);
glTexParameteriv(GLenum target,GLenum pname,GLint *param);
- 放大/縮小過濾方式
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
例子:
///紋理縮小時,使用鄰近過濾
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
///紋理放大時,使用線性過濾
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
可以使用的幾種情況
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
-
S/T軸環繞方式
環繞方式
環繞方式效果
參數1:GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D
參數2:GL_TEXTURE_WRAP_S、GL_TEXTURE_T、GL_TEXTURE_R,針對s,t,r坐標
參數3:GL_REPEAT、GL_CLAMP、GL_CLAMP_TO_EDGE、GL_CLAMP_TO_BORDER
GL_REPEAT:OpenGL 在紋理坐標超過1.0的?向上對紋理進?重復;
GL_CLAMP:所需的紋理單元取自紋理邊界或TEXTURE_BORDER_COLOR. GL_CLAMP_TO_EDGE環繞模式強制對范圍之外的紋理坐標沿著合法的紋理單元的最后一行或者最后一
列來進行采樣。
GL_CLAMP_TO_BORDER:在紋理坐標在0.0到1.0范圍之外的只使?用邊界紋理單元。邊界紋理單元是作為圍繞基本圖像的額外的行和列,并與基本紋理圖像一起加載的。
glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAR_S,GL_CLAMP_TO_EDGE);
glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAR_T,GL_CLAMP_TO_EDGE);
載入紋理
//target:GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D 。
//Level :指定所加載的mip貼圖層次。一般我們都把這個參數設置為0。
//internalformat:每個紋理單元中存儲多少顏色成分。
//width、height、depth 參數:指加載紋理的寬度、高度、深度。
//border參數:允許為紋理貼圖指定一個邊界寬度。
//format參數:gltReadTGABits函數中,通過 eFormat 參數返回圖片的顏色格式
//type參數:OpenGL 數據存儲方式,一般使用 GL_UNSIGNED_BYTE
//data參數:圖片數據指針
void glTexImage1D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLint border,GLenum format,GLenum type,void *data);
void glTexImage2D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,void * data);
void glTexImage3D(GLenum target,GLint level,GLint internalformat,GLSizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,void *data);
更新紋理
void glTexSubImage1D(GLenum target, GLint level, GLint xOffset, GLsizei width, GLenum format, GLenum type, const GLvoid *data);
void glTexSubImage2D(GLenum target, GLint level, GLint xOffset, GLsizei width, GLenum format, GLenum type, const GLvoid *data);
void glTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLsizei width, GLenum format, GLenum type, const GLvoid *data);
插入替換紋理
void glCopyTexSubImage1D(GLenum target, GLint level, GLint xOffset, GLint x, GLint y, GLsize width);
void glCopyTexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint x, GLint y, GLsize width);
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint x, GLint y, GLsize width);
壓縮方式
通用壓縮方式
- 判斷壓縮 與 選擇壓縮方式
GLint comFlag;
//判斷紋理是否被成功壓縮 glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_COMPRESSED,&comFlag);
//根據選擇的壓縮紋理格式,選擇最快、最優、?行選擇的算法方式選擇壓縮格式。
glHint(GL_TEXTURE_COMPRESSION_HINT,GL_FASTEST);
glHint(GL_TEXTURE_COMPRESSION_HINT,GL_NICEST);
glHint(GL_TEXTURE_COMPRESSION_HINT,GL_DONT_CARE);
- 加載壓縮紋理
void glCompressedTexImage1D(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLint border,GLsizei imageSize,void *data);
void glCompressedTexImage2D(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLint heigth,GLint border,GLsizei imageSize,void *data);
void glCompressedTexImage3D(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLsizei heigth,GLsizei depth,GLint border,GLsizei imageSize,void *data);
target:`GL_TEXTURE_1D`、`GL_TEXTURE_2D`、`GL_TEXTURE_3D`。
Level:指定所加載的mip貼圖層次。?一般我們都把這個參數設置為0。 internalformat:每個紋理理單元中存儲多少顏色成分。
width、height、depth參數:指加載紋理理的寬度、?度、深度。==注意!==這些值必須是2的整數次?。(這是因為OpenGL舊版本上的遺留下的一個要求。當然現在已經可以?持不是2的整數次方。但是開發者們還是習慣使用以2的整數次方去設置參數。)
border參數:允許為紋理貼圖指定?個邊界寬度。
format、type、data參數:與我們在講glDrawPixels 函數對于的參數相同
glGetTexLevelParameter函數提取的壓縮紋理格式
glGetTexLevelParameter函數提取的壓縮紋理格式
GL_EXT_texture_compression_s3tc壓縮格式
GL_EXT_texture_compression_s3tc壓縮格式
二、紋理坐標解析
為了能夠把紋理映射(Map)到三角形上,我們需要指定三角形的每個頂點各自對應紋理的哪個部分。這樣每個頂點就會關聯著一個紋理坐標(Texture Coordinate),用來標明該從紋理圖像的哪個部分采樣(采樣:采集片段顏色)。之后在圖形的其它片段上進行片段插值(Fragment Interpolation)。
2D紋理坐標在x和y軸上,范圍為0到1之間。使用紋理坐標獲取紋理顏色叫做采樣(Sampling)。紋理坐標起始于(0, 0),也就是紋理圖片的左下角,終始于(1, 1),即紋理圖片的右上角