2012-01-06 59 views
2

我嘗試訪問1片段着色器中的2個紋理。如何設置紋理以便我可以在Android OpenGL-ES 2.0片段着色器中使用它們?

爲此,我有2個紋理我設置了下面的代碼:

glEnableClientState(GL_VERTEX_ARRAY); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

glVertexPointer(2, GL_FLOAT, 0, vbuff); 
glTexCoordPointer(2, GL_FLOAT, 0, tbuff); 

glActiveTextureARB(GL_TEXTURE0_ARB); 
glBindTexture(GL_TEXTURE_2D, texture0); 
glEnable(GL_TEXTURE_2D); 

glActiveTextureARB(GL_TEXTURE1_ARB); 
glBindTexture(GL_TEXTURE_2D, texture1); 
glEnable(GL_TEXTURE_2D); 

我嘗試使其與下面的片段着色器結合:

uniform sampler2D tex0; 
uniform sampler2D tex1; 
void main() 
{ 
    vec4 texval1 = texture2D(tex0, TextureCoordOut); 
    vec4 texval2 = texture2D(tex1, TextureCoordOut); 
    gl_FragColor = 0.5*(texval1 + texval2) 
} 

不知怎的,這並不工作,它只顯示第二個紋理。 PS:我在Windows7上開發着色器,但想在Android設備上使用C++代碼和着色器與Android NDK。

編輯:我得到它的工作,我在這裏發佈的代碼,讓其他人可能從中受益:

頂點着色器

varying vec2 TextureCoordOut; 
void main() 
{ 
    gl_Position = ftransform(); 
    TextureCoordOut = vec2(gl_MultiTexCoord0); 
} 

片段着色器

varying mediump vec2 TextureCoordOut; 
uniform sampler2D tex0; 
uniform sampler2D tex1; 
void main() 
{ 
    gl_FragColor = texture2D(tex0, TextureCoordOut) * texture2D(tex1, TextureCoordOut); 
} 

渲染

glEnableClientState(GL_VERTEX_ARRAY); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

glVertexPointer(2, GL_FLOAT, 0, vbuff); //2 dimensional vertex buffer 
glTexCoordPointer(2, GL_FLOAT, 0, tbuff); // 2 dimensional textures 
glColor4f(1, 1, 1, 1); 

glActiveTexture(GL_TEXTURE0);  glBindTexture(GL_TEXTURE_2D, mapid1); 
glActiveTexture(GL_TEXTURE1);  glBindTexture(GL_TEXTURE_2D, mapid2); 

glUseProgram(shader); 

glUniform1i(glGetUniformLocation(gfx.prog, "tex0"), 0); //GL_TEXTURE0 
glUniform1i(glGetUniformLocation(gfx.prog, "tex1"), 1); //GL_TEXTURE1 

render.... 

glDisableClientState(GL_VERTEX_ARRAY); 
glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

回答

7

僅僅將這些紋理綁定到相應的單元是不夠的。你還需要告訴着色器在哪裏採用sampler2D制服的紋理。這是由相應的整數均勻值設置爲你想要使用的紋理單元進行:

//get uniform locations (either init code or render code) 
int locTex0 = glGetUniformLocation(program, "tex0"); 
int locTex1 = glGetUniformLocation(program, "tex1"); 

...  

//bind textures to texture units 
glActiveTexture(GL_TEXTURE1); 
glBindTexture(GL_TEXTURE_2D, texture1); 
glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, texture0); 

//bind program and specify texture units for each sampler2D uniform 
glUseProgram(program); 
glUniform1i(locTex0, 0); //use texture bound to GL_TEXTURE0 
glUniform1i(locTex1, 1); //use texture bound to GL_TEXTURE1 

... 
draw 

當然這是假定你知道如何使用着色器,並指定統一的值。

一些補充說明:

  • 當使用一個片段着色器,你不需要調用glEnable(GL_TEXTURE_2D),因爲着色器決定自己是否使用紋理與否。
  • 不要使用那些ARB版本的函數和常量,至少不要使用像GL 1.2或1.3(〜15年)以來的核心技術那樣的老式和已建立的東西,例如多紋理。
  • 不要指望你的代碼是1對1的便攜式OpenGL ES 2.0,它不知道舊的內置屬性(如glVertexPointerglTexCoordPointer),但這是一個不同的問題。
+0

非常感謝,這真的幫我搞定了! – HardCoder 2012-01-07 10:52:18

相關問題