2011-05-22 247 views
0

我想在OpenGL ES 2.0中制作透明对象。这是一个动态壁纸,我使用GLWallpaperService作为基础类。我以这种方式建立的OpenGL:不工作OpenGL ES着色器,每帧调用glLinkProgram?

GLES20.glEnable(GLES20.GL_DEPTH_TEST); 
GLES20.glDepthFunc(GLES20.GL_GEQUAL); 
GLES20.glClearDepthf(0.0f); 
GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f); 

着色我使用的PowerVR样品OGLES2AlphaTest采取了alpha测试,其中我的HTC Desire设备上正常工作。 这里是着色器代码:在onDrawFrame()我得到不正确的结果开始

public void onDrawFrame(GL10 glUnused) { 
    //GLES20.glLinkProgram(mProgram); 

    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 
    GLES20.glUseProgram(mProgram); 
    checkGlError("glUseProgram"); 

    GLES20.glDisable(GLES20.GL_BLEND); 

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID); 

    mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); 
    GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices); 
    checkGlError("glVertexAttribPointer maPosition"); 
    mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET); 
    GLES20.glEnableVertexAttribArray(maPositionHandle); 
    checkGlError("glEnableVertexAttribArray maPositionHandle"); 
    GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices); 
    checkGlError("glVertexAttribPointer maTextureHandle"); 
    GLES20.glEnableVertexAttribArray(maTextureHandle); 
    checkGlError("glEnableVertexAttribArray maTextureHandle"); 

    long time = SystemClock.uptimeMillis() % 4000L; 
    float angle = 0.090f * ((int) time); 
    time = SystemClock.uptimeMillis();// % 4000L; 
    angle = 0.030f * ((int) time); 
    // Matrix.setRotateM(mMMatrix, 0, angle, 0, 0, 1.0f); 
    Matrix.setRotateM(mMMatrix, 0, angle, 0, 1.0f, 0); 
    Matrix.scaleM(mMMatrix, 0, 0.075f, 0.075f, 0.075f); 
    Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0); 
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0); 

    GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0); 
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, numPolys); 
    checkGlError("glDrawArrays"); 
} 

没有GLES20.glLinkProgram(mProgram);(不正确的透明度):

private final String mVertexShader = "uniform highp mat4 uMVPMatrix;\n" + 
     "attribute highp vec4 aPosition;\n" + 
     "attribute highp vec2 aTextureCoord;\n" + 
     "varying mediump vec2 vTextureCoord;\n" + 
     "void main() {\n" + 
     " gl_Position = uMVPMatrix * aPosition;\n" + 
     " vTextureCoord = aTextureCoord;\n" + 
     "}\n"; 

private final String mFragmentShader = "precision mediump float;\n" + 
     "varying mediump vec2 vTextureCoord;\n" + 
     "uniform sampler2D sTexture;\n" + 
     "void main() {\n" + 
     " vec4 base = texture2D(sTexture, vTextureCoord);\n" + 
     " if(base.a < 0.5){ discard; }\n" + 
     " gl_FragColor = base;\n" + 
     "}\n"; 

private int createProgram(String vertexSource, String fragmentSource) { 
    int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource); 
    if (vertexShader == 0) { 
     return 0; 
    } 

    int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource); 
    if (pixelShader == 0) { 
     return 0; 
    } 

    int program = GLES20.glCreateProgram(); 
    if (program != 0) { 
     GLES20.glAttachShader(program, vertexShader); 
     checkGlError("glAttachShader"); 
     GLES20.glAttachShader(program, pixelShader); 
     checkGlError("glAttachShader"); 
     GLES20.glLinkProgram(program); 
     int[] linkStatus = new int[1]; 
     GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0); 
     if (linkStatus[0] != GLES20.GL_TRUE) { 
      Log.e(TAG, "Could not link program: "); 
      Log.e(TAG, GLES20.glGetProgramInfoLog(program)); 
      GLES20.glDeleteProgram(program); 
      program = 0; 
     } 
    } 
    return program; 
} 

private int loadShader(int shaderType, String source) { 
    int shader = GLES20.glCreateShader(shaderType); 
    if (shader != 0) { 
     GLES20.glShaderSource(shader, source); 
     GLES20.glCompileShader(shader); 
     int[] compiled = new int[1]; 
     GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0); 
     if (compiled[0] == 0) { 
      Log.e(TAG, "Could not compile shader " + shaderType + ":"); 
      Log.e(TAG, GLES20.glGetShaderInfoLog(shader)); 
      GLES20.glDeleteShader(shader); 
      shader = 0; 
     } 
    } 
    return shader; 
} 

代码渲染帧http://imgur.com/kESeO

当我在onDrawFrame()开头添加了GLES20.glLinkProgram(mProgram);它正确渲染,但性能很差,glLinkProgram()是耗时的功能。这里是正确的渲染截图:http://imgur.com/sw83z

请解释我做错了什么,显然我不必在每一帧重绘时调用glLinkProgram()

+0

你从哪里获得属性/统一位置?特别是maPositionHandle,maTextureHandle和muMVPMatrixHandle?请在您分配这些代码的地方发布代码。 每次你重新链接 - 这些都需要重新分配。我在上面的代码中看不到上面指定的这些内容,以及它们是否准确。 检查这些位置句柄以确保它们不是-1(只需检查它们是否有效)。 – Kaa 2011-12-22 19:21:06

回答

0

该不良行为的原因与glLinkProgram()无关。我修改了一些其他的GL初始化参数(目前无法回想),现在它工作得很好。