【问题标题】:How to setup the fragment shader for multiple textures on multiple objects in OpenGLES?如何在 OpenGLES 中为多个对象上的多个纹理设置片段着色器?
【发布时间】:2020-04-30 04:06:59
【问题描述】:

我尝试将纹理绑定到一个对象,将另一个纹理绑定到下一个对象。我在 stackoverflow 中问了几乎相同的问题,但当时的不同是,我只有一个纹理和多个对象。 How to bind texture just to one object in OpenGLES? 它适用于一个纹理和多个对象,但现在我有多个纹理和多个对象。我遵循了答案中的建议,但我坚信这次问题出在片段着色器上。

 @Override
public void onDrawFrame(GL10 gl) {
    GLES20.glClear(GL10.GL_COLOR_BUFFER_BIT);


    synchronized (mediaPlayerObject) {
        surfaceTextureMediaPlayer.updateTexImage();
        mediaPlayeUpdate = false;
    }


    vertexBuffer.position(0);
    GLES20.glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDETEXTURE, vertexBuffer);
    vertexBuffer.position(TEXTURE_COMPONENT_COUNT);
    GLES20.glVertexAttribPointer(aTextureCoordinatesLocation, TEXTURE_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDETEXTURE, vertexBuffer);

    GLES20.glEnableVertexAttribArray(aPositionLocation);
    GLES20.glEnableVertexAttribArray(aTextureCoordinatesLocation);

    GLES20.glUniform1i(textureUnitLocation2, 1);
    GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
    GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[1]);

    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
    GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);

    GLES20.glDisableVertexAttribArray(aPositionLocation);
    GLES20.glDisableVertexAttribArray(aTextureCoordinatesLocation);



    synchronized (camerObject) {
        surfaceTextureCamera.updateTexImage();
        cameraUpdate = false;
    }






    vertexBuffer2.position(0);
    GLES20.glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDETEXTURE, vertexBuffer2);
    vertexBuffer2.position(TEXTURE_COMPONENT_COUNT);
    GLES20.glVertexAttribPointer(aTextureCoordinatesLocation, TEXTURE_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDETEXTURE, vertexBuffer2);

    GLES20.glEnableVertexAttribArray(aPositionLocation);
    GLES20.glEnableVertexAttribArray(aTextureCoordinatesLocation);

    GLES20.glUniform1i(textureUnitLocation, 0);
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[0]);

    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
    GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);

    GLES20.glDisableVertexAttribArray(aPositionLocation);
    GLES20.glDisableVertexAttribArray(aTextureCoordinatesLocation);

这里是片段着色器:

    #extension GL_OES_EGL_image_external : require
precision mediump float;
uniform samplerExternalOES u_Texture;
uniform samplerExternalOES b_Texture;

varying vec2 v_TextureCoordinates;

void main() {

    gl_FragColor = texture2D(u_Texture, v_TextureCoordinates) * texture2D(b_Texture, v_TextureCoordinates);
}

【问题讨论】:

    标签: opengl-es glsl shader textures fragment-shader


    【解决方案1】:

    片段着色器中不需要第二个纹理采样器,因此删除b_Texture。将纹理对象绑定到纹理单元并将纹理单元的索引设置为纹理采样器统一就足够了:

    #extension GL_OES_EGL_image_external : require
    precision mediump float;
    uniform samplerExternalOES u_Texture;
    
    varying vec2 v_TextureCoordinates;
    
    void main() {
    
        gl_FragColor = texture2D(u_Texture, v_TextureCoordinates);
    }
    

    绘制第一个对象:

    GLES20.glUniform1i(textureUnitLocation, 1);
    GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
    GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[1]);
    
    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
    

    绘制第二个对象:

    GLES20.glUniform1i(textureUnitLocation, 0);
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[0]);
    
    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
    

    注意,没有必要使用 2 个不同的纹理单元。在这两种情况下,您都可以使用GL_TEXTURE0

    【讨论】:

    • 谢谢您,先生。有用。对于所有同样苦苦挣扎的人 - 检查您是否正确加载了纹理。
    猜你喜欢
    • 2011-11-23
    • 2017-12-09
    • 1970-01-01
    • 1970-01-01
    • 2014-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多