OpenGL 紋理單元的使用步驟
OpenGL 紋理單元的使用步驟:
glActiveTexture 函式詳解
glBindTexture 函式詳解
glUniform1i 函式詳解
片元著色器
precision mediump float;
uniform sampler2D u_TextureUnit;
varying vec2 v_TextureCoordinates;
void main()
{
gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);
}
示例1:
//—————————使用紋理———————————
// Set the active texture unit to texture unit 0.
glActiveTexture(GL_TEXTURE0);
// Bind the texture to this unit.
glBindTexture(GL_TEXTURE_2D,
// Tell the texture uniform sampler to use this texture in the shader by telling it to read from texture unit 0.
glUniform1i(uTextureUnitLocation, 0);//將片元著色器中的uTextureUnitLocation紋理取樣器(sample2D)和紋理單元0對應起來。
glActiveTexture(GL_TEXTURE0)表示把活動的紋理單元設定為紋理單元0,呼叫glBindTexture將textureId指向的紋理繫結到紋理單元0,最後,呼叫
//—————————使用紋理———————————
示例2:
//獲取shader裡面uniform變數的地址
int tex1_location=glGetUniformLocation(m_uProgram, "tex1");
int tex2_location=glGetUniformLocation(m_uProgram, "tex2");
int tex3_location=glGetUniformLocation(m_uProgram, "tex3");
//對這幾個紋理取樣器變數進行設定
glUniform1i( (GLint)tex1_location, 0);//對應0號紋理單元
glUniform1i( (GLint)tex2_location, 1);//對應1號紋理單元
glUniform1i( (GLint)tex3_location, 2);//對應2號紋理單元
//後面渲染的時候,設定三成紋理
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_2D, texture1Id);
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, texture2Id);
glActiveTexture(GL_TEXTURE0 + 2);
glBindTexture(GL_TEXTURE_2D, texture3Id);
//所以glActiveTexture第幾層,並不表示是shader裡面第幾個取樣器,
//中間有glUniform1i進行紋理層和取樣器地址進行繫結
glBindTexture
void glBindTexture(GLenum target, GLuint texture );
函式引數的含義:
target —— 紋理被繫結的目標,它只能取值GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D或者GL_TEXTURE_CUBE_MAP;
texture —— 紋理的名稱,並且,該紋理的名稱在當前的應用中不能被再次使用。
紋理名稱與相應的紋理內容位於當前GL rendering上下文的共享物件空間中。
glBindTexture的使用方法實際上體現在兩個地方:
首先是載入紋理時,將載入的紋理與紋理分配號繫結在一起。也就是給當前的紋理分配相應的紋理號。
其次載入多個紋理之後,需要在多個紋理之間進行繫結,先使用glActiveTexture函式啟用某個紋理單元然後需要使用glBindTexture函式進行紋理繫結。
二維紋理建立流程:建立紋理的過程主要是在GPU的記憶體中載入紋理圖片
1.先使用glGenTextures函式生成一個紋理ID
2.使用glBindTexture(GL_TEXTURE_2D,.)函式繫結此紋理ID到OpenGL的GL_TEXTURE_2D渲染上下文中
3.使用glTexParameterf函式設定此紋理的過濾引數
4.使用glTexImage2D函式將CPU記憶體影象資料傳輸到GPU記憶體中同時也設定當前紋理的紋理id為剛剛生成的紋理id。此步完成了紋理圖片在GPU記憶體中的載入。
5.glBindTexture(GL_TEXTURE_2D, 0); //將2D紋理繫結到預設的紋理,一般用於打破之前的紋理繫結關係,使OpenGL的紋理繫結狀態恢復到預設狀態,到此一個2維紋理建立完畢。
二維紋理使用流程:
1.先使用glGetUniformLocation函式獲取fragmentShader內的uniform紋理變數
2.使用glUniform1i將獲取的uniform紋理變數和某個紋理單元(紋理單元從0號紋理單元開始)對應起來
3.使用glActiveTexture函式啟用某個紋理單元(例如啟用0號紋理單元 0號紋理單元預設已經啟用) glActiveTexture啟用函式之後最好跟上glBindTexture繫結函式
4.使用glBindTexture函式將紋理繫結到使用glActiveTexture函式啟用的那個紋理單元。
注意此步glBindTexture函式的意義和建立紋理時使用的此函式的意義不同,建立紋理時glBindTexture函式的意思是將GPU內的紋理資料和紋理id對應起來,既建立紋理時為載入紋理到此紋理id處,
而此處的glBindTexture函式的意義是綁定當前紋理id到啟用的紋理單元。既此處為指定使用哪個紋理。
在繫結紋理前必須要確保此紋理單元已經啟用,0號紋理單元預設啟用。
此時OpenGL 的rendering渲染上下文中的紋理就是使用glBindTexture函式繫結的紋理單元了。
紋理單元能否同時工作?
紋理單元是可以同時工作的,多個紋理的shader中多個紋理是同時工作的,併發工作的。
glActiveTexture(GL_TEXTURE0); //在繫結紋理之前先啟用紋理單元
glBindTexture(GL_TEXTURE_2D, texture);
例如:
// 在程式開始時:分配好紋理編號,並載入紋理
glGenTextures( /* ... */ );
// 載入第一幅紋理
glBindTexture(GL_TEXTURE_2D, texture_ID_1);
glTexImage2D( /* ... */ );
...
// 載入第二幅紋理
glBindTexture(GL_TEXTURE_2D, texture_ID_2);
glTexImage2D( /* ... */ );
...
注意此時兩個紋理單元在同時工作
// 在繪製時,繫結並使用紋理,不需要再進行載入但需要繫結紋理
...
// 繫結第一幅紋理
glBindTexture(GL_TEXTURE_2D, texture_ID_1); // 指定第一幅紋理
// 繫結第二幅紋理
glBindTexture(GL_TEXTURE_2D, texture_ID_2); // 指定第二幅紋理