如何设置可以在Android OpenGL ES 2.0片段着色器中使用的纹理?

如何设置可以在Android OpenGL ES 2.0片段着色器中使用的纹理?,android,opengl-es,fragment-shader,Android,Opengl Es,Fragment Shader,我尝试在1个片段着色器中访问2个纹理 为此,我使用以下代码设置了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); glBindTe

我尝试在1个片段着色器中访问2个纹理

为此,我使用以下代码设置了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:我在Windows 7上开发了着色器,但是希望在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);

仅仅将这些纹理绑定到各自的单元是不够的。您还需要告诉着色器从何处获取其
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版本的函数和常量,至少不要用于像multitexturing这样的古老而成熟的东西,multitexturing是自GL 1.2或1.3(约15年)以来的核心
  • 不要期望您的代码能够1:1移植到OpenGL ES 2.0,因为OpenGL ES 2.0不知道旧的内置属性(如
    glVertexPointer
    glTexCoordPointer
    ),但这是一个不同的问题