1. 程式人生 > >OpenGL 紋理單元的使用步驟

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,

textureId);

// 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,呼叫glBindTexturetextureId指向的紋理繫結到紋理單元0,最後,呼叫

glUniform1i把選定的紋理單元傳遞給片元著色器中的u_TextureUnitsampler2D)。

//—————————使用紋理———————————

示例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_1DGL_TEXTURE_2DGL_TEXTURE_3D或者GL_TEXTURE_CUBE_MAP

texture —— 紋理的名稱,並且,該紋理的名稱在當前的應用中不能被再次使用。

紋理名稱與相應的紋理內容位於當前GL rendering上下文的共享物件空間中。

glBindTexture的使用方法實際上體現在兩個地方:

首先是載入紋理時,將載入的紋理與紋理分配號繫結在一起。也就是給當前的紋理分配相應的紋理號。

其次載入多個紋理之後,需要在多個紋理之間進行繫結,先使用glActiveTexture函式啟用某個紋理單元然後需要使用glBindTexture函式進行紋理繫結。

二維紋理建立流程:建立紋理的過程主要是在GPU的記憶體中載入紋理圖片

1.先使用glGenTextures函式生成一個紋理ID

2.使用glBindTexture(GL_TEXTURE_2D,.)函式繫結此紋理IDOpenGLGL_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); // 指定第二幅紋理