【问题标题】:How do I have to set up Textures that I can use them in an Android OpenGL-ES 2.0 fragment shader?如何设置可以在 Android OpenGL-ES 2.0 片段着色器中使用的纹理?
【发布时间】:2012-01-06 17:56:24
【问题描述】:

我尝试在 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:我正在 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);

【问题讨论】:

    标签: android opengl-es fragment-shader


    【解决方案1】:

    仅将这些纹理绑定到相应的单元是不够的。您还需要告诉着色器从哪里获取 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 年)以来的核心。
    • 不要期望您的代码可以一对一地移植到 OpenGL ES 2.0,它不知道旧的内置属性(如 glVertexPointerglTexCoordPointer),但这是一个不同的问题。

    【讨论】:

      猜你喜欢
      • 2011-11-23
      • 1970-01-01
      • 2014-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多