2013-08-01 92 views
2

简要说明:当我将两个纹理坐标应用于一个片段着色器时,我只看到第一个纹理。但是当我为两个纹理使用一个纹理坐标时,它工作正常,我可以看到两个纹理。OpenGL ES 2.0中具有不同纹理坐标的两个纹理

我使用图片过滤器并使用OpenGL ES 2.0制作过滤器。一些过滤器具有先进的纹理。第一个纹理是照片,第二个是窗饰。

这里是我的vertext着色器

attribute vec4 position; 

attribute vec4 inputTextureCoordinate; 
attribute vec4 inputTextureCoordinate2; 

varying vec2 textureCoordinate; 
varying vec2 textureCoordinate2; 

void main() { 
    gl_Position = position; 
    textureCoordinate = inputTextureCoordinate.xy; 
    textureCoordinate2 = inputTextureCoordinate2.xy; 
} 

这里是我的片段着色器

precision mediump float; 

uniform sampler2D inputImageTexture1; 
uniform sampler2D inputImageTexture2; 

varying vec2 textureCoordinate; 
varying vec2 textureCoordinate2; 

void main() { 
    mediump vec4 color1 = texture2D(inputImageTexture1, textureCoordinate); 
    mediump vec4 color2 = texture2D(inputImageTexture2, textureCoordinate2); 
    mediump vec3 colorResult = mix(color1.rgb, color2.rgb, 0.5); 
    gl_FragColor = vec4(colorResult, 1.0); 
} 

在我的代码我使用GLSurfaceView.Render实现。

坐标的初始化:

方法
static final float CUBE[] = {-1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f,}; 
public static final float COORDINATES1[] = {0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,}; 
public static final float COORDINATES2[] = {0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,}; 

... 

mGLCubeBuffer = ByteBuffer.allocateDirect(CUBE.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
mGLCubeBuffer.put(CUBE).position(0); 

mGLTextureCoordinates1 = ByteBuffer.allocateDirect(COORDINATES1.length * 4).order(ByteOrder.nativeOrder()) 
       .asFloatBuffer(); 
mGLTextureCoordinates1.clear(); 
mGLTextureCoordinates1.put(COORDINATES1).position(0); 

mGLTextureCoordinates2 = ByteBuffer.allocateDirect(COORDINATES2.length * 4).order(ByteOrder.nativeOrder()) 
       .asFloatBuffer(); 
mGLTextureCoordinates2.clear(); 
mGLTextureCoordinates1.put(COORDINATES2).position(0); 

onSurfaceCreate

方法
@Override 
public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
    GLES20.glClearColor(0, 0, 0, 1); 
    GLES20.glDisable(GLES20.GL_DEPTH_TEST); 
    GLES20.glDisable(GLES20.GL_DEPTH_BITS); 

    String vertexShader = RawResourceReader.readTextFileFromRawResource(mContext, R.raw.test_vertex); 
    String fragmentShader = RawResourceReader.readTextFileFromRawResource(mContext, R.raw.test_fragment); 
    mGLProgId = loadProgram(vertexShader, fragmentShader); 
    mGLAttribPosition = GLES20.glGetAttribLocation(mGLProgId, "position"); 
    mGLAttribTextureCoordinate = GLES20.glGetAttribLocation(mGLProgId, "inputTextureCoordinate"); 
    mGLAttribTextureCoordinate2 = GLES20.glGetAttribLocation(mGLProgId, "inputTextureCoordinate2"); 
    mGLUniformTexture1 = GLES20.glGetUniformLocation(mGLProgId, "inputImageTexture1"); 
    mGLUniformTexture2 = GLES20.glGetUniformLocation(mGLProgId, "inputImageTexture2"); 

    mTexture1 = loadTexture(mContext, R.drawable.photo); 
    mTexture2 = loadTexture(mContext, R.drawable.formula1); 
} 

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

    GLES20.glUseProgram(mGLProgId); 

    mGLCubeBuffer.position(0); 
    GLES20.glVertexAttribPointer(mGLAttribPosition, 2, GLES20.GL_FLOAT, false, 0, mGLCubeBuffer); 
    GLES20.glEnableVertexAttribArray(mGLAttribPosition); 

    //set first coordinates 
    mGLTextureCoordinates1.position(0); 
    GLES20.glVertexAttribPointer(mGLAttribTextureCoordinate, 2, GLES20.GL_FLOAT, false, 0, mGLTextureCoordinates1); 
    GLES20.glEnableVertexAttribArray(mGLAttribTextureCoordinate); 

    //set second coordinates 
    mGLTextureCoordinates2.position(0); 
    GLES20.glVertexAttribPointer(mGLAttribTextureCoordinate2, 2, GLES20.GL_FLOAT, false, 0, mGLTextureCoordinates2); 
    GLES20.glEnableVertexAttribArray(mGLAttribTextureCoordinate2); 

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexture1); 
    GLES20.glUniform1i(mGLUniformTexture1, 0); 

    GLES20.glActiveTexture(GLES20.GL_TEXTURE1); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexture2); 
    GLES20.glUniform1i(mGLUniformTexture2, 1); 

    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); 

    GLES20.glDisableVertexAttribArray(mGLAttribPosition); 
    GLES20.glDisableVertexAttribArray(mGLAttribTextureCoordinate); 
    GLES20.glDisableVertexAttribArray(mGLAttribTextureCoordinate2); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); 
} 

重要部分的loadTexture方法:

 GLES20.glGenTextures(1, textureHandle, 0); 
     // Bind to the texture in OpenGL 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]); 

     // Set filtering 
     GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 
     GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 
     GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
     GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 

     GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_CONSTANT_ALPHA); 
     GLES20.glEnable(GLES20.GL_BLEND); 

     // Load the bitmap into the bound texture. 
     GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 

     // Recycle the bitmap, since its data has been loaded into OpenGL. 
     bitmap.recycle(); 

请注意,在iOs上它工作正常,但有一些库。我试图使用库jp.co.cyberagent.android.gpuimage,但它有一些错误,并不能正确处理这个问题。

我想知道如何解决这个问题。它可能是一些我不知道的东西或别的东西。我是OpenGL的新手,希望能得到您的帮助。

+0

你为什么要启用混合?有了这样一个不寻常的blendFunc? – rotoglup

+0

我发现它是另一个问题的解决方案,我认为它可以帮助我解决问题。但现在没用了。 –

回答

2

您不能使用GLUtils.texImage2D()在Android上加载alpha纹理。这是Google真正需要更好记录的常见问题。问题在于Bitmap类将所有图像转换为预倍数格式,但这不适用于OpenGL ES,除非图像完全不透明。最好的解决方案是使用本机代码。这篇文章给出了这个更详细:

http://software.intel.com/en-us/articles/porting-opengl-games-to-android-on-intel-atom-processors-part-1

+0

我使用完全不透明的图像,并在片段着色器中设置Alpha通道。 –