2012-03-06 123 views
2

我目前正在使用OpenGL ES 2.0开发Android游戏。我几乎所有的东西都使用纹理和顶点颜色,但是当我在纹理中使用透明度时,透明部分会变成虚线。下面是它的截图:Dotted transparency透明点虚线OpenGL ES 2.0

铃铛(蓝色圆圈)目前显示有3层飞机在他上面,眼睛,嘴巴和牙齿。所有图层都具有相同的尺寸和透明度,并且看起来像点数越多,我添加的图层越多。这是渲染器的onCreate方法:

mMVPMatrix = new float [16]; 
    mViewMatrix = new float [16]; 
    mProjectionMatrix = new float [16]; 
    mModelMatrix = new float [16]; 

    Matrix.setLookAtM(mViewMatrix, 0, 0.0f, 0.0f, mZoom, 0.0f, 0.0f, -0.1f, 0.0f, 1.0f, 0.0f); 
    Matrix.setIdentityM(mModelMatrix, 0); 

    mTexturePointer = new int [32]; 

    loadTextures(); 

    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
    mShaderPointer = loadProgram(); 

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

    GLES20.glUseProgram(mShaderPointer); 

    mMVPMatrixPointer = GLES20.glGetUniformLocation(mShaderPointer, "uMVPMatrix"); 
    mPositionPointer = GLES20.glGetAttribLocation(mShaderPointer, "a_position"); 
    mTexCoordPointer = GLES20.glGetAttribLocation(mShaderPointer, "a_texCoord"); 
    mSamplerPointer = GLES20.glGetUniformLocation(mShaderPointer, "s_texture"); 
    mColorPointer = GLES20.glGetAttribLocation(mShaderPointer, "a_color"); 

这是片段着色器:

   "precision mediump float;           \n" 
      + "uniform sampler2D s_texture;             \n" 
      + "                    \n" 
      + "varying vec4 v_color;              \n" 
      + "varying vec2 v_texCoord;              \n" 
      + "                    \n" 
      + "void main()                 \n" 
      + "{                   \n" 
      + "                    \n" 
      + "  vec4 final_color = vec4(texture2D(s_texture, v_texCoord).r * v_color.r, " 
      + "        texture2D(s_texture, v_texCoord).g * v_color.g, " 
      + "        texture2D(s_texture, v_texCoord).b * v_color.b, " 
      + "        texture2D(s_texture, v_texCoord).a + v_color.a);\n" 
      + "                    \n" 
      + "  //Set the Fragments colour            \n" 
      + "  gl_FragColor = final_color;            \n" 
      + "}                   \n"; 

和顶点着色器:

   "attribute vec4 a_position;  \n" 
      + "uniform mat4 uMVPMatrix;      \n" 
      + "            \n" 
      + "attribute vec2 a_texCoord;     \n" 
      + "attribute vec4 a_color;      \n" 
      + "            \n" 
      + "varying vec4 v_color;      \n" 
      + "varying vec2 v_texCoord;      \n" 
      + "            \n" 
      + "void main()         \n" 
      + "{           \n" 
      + " gl_Position = uMVPMatrix * a_position; \n" 
      + " v_texCoord = a_texCoord;     \n" 
      + " v_color = a_color;      \n" 
      + "}           \n"; 

最后但并非平局最少(此是每个对象的绘制方法):

GLES20.glViewport(0, 0, mScreenWidth, mScreenHeight); 

GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 

protected void draw(GameRenderer aRenderer){ 
    if(mVisible){ 
     // Do the animation. 
     if(mAnimated) 
      animate(); 

     GLES20.glEnableVertexAttribArray(aRenderer.mPositionPointer); 
     GLES20.glEnableVertexAttribArray(aRenderer.mTexCoordPointer); 
     GLES20.glEnableVertexAttribArray(aRenderer.mColorPointer); 

     // Load the texture mapping. 
     mTexture.position(0); 
     GLES20.glVertexAttribPointer(aRenderer.mTexCoordPointer, 2, GLES20.GL_FLOAT, false, 2 * 4, mTexture); 

     // Load the vertex position. 
     mVertices.position(0); 
     GLES20.glVertexAttribPointer(aRenderer.mPositionPointer, 3, GLES20.GL_FLOAT, false, 3 * 4, mVertices); 

     // Load the vertex color. 
     mColor.position(0); 
     GLES20.glVertexAttribPointer(aRenderer.mColorPointer, 4, GLES20.GL_FLOAT, false, 4 * 4, mColor); 

     // Set the texture. 
     GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, aRenderer.mTexturePointer[mTextureId]); 
     GLES20.glUniform1i(aRenderer.mSamplerPointer, 0); 

     // Calculate stuff. 
     Matrix.multiplyMM(aRenderer.mMVPMatrix, 0, aRenderer.mViewMatrix, 0, aRenderer.mModelMatrix, 0); 
     Matrix.multiplyMM(aRenderer.mMVPMatrix, 0, aRenderer.mProjectionMatrix, 0, aRenderer.mMVPMatrix, 0); 

     GLES20.glUniformMatrix4fv(aRenderer.mMVPMatrixPointer, 1, false, aRenderer.mMVPMatrix, 0); 

     GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, mIndices); 

     GLES20.glDisableVertexAttribArray(aRenderer.mPositionPointer); 
     GLES20.glDisableVertexAttribArray(aRenderer.mTexCoordPointer); 
     GLES20.glDisableVertexAttribArray(aRenderer.mColorPointer); 
    } 
} 

的loadTexture()方法:

public void loadTextures(){ 

    Log.d("loadTextures()", "Loading textures"); 

    Bitmap tBitmap = null; 

    // Tell OpenGL to generate textures. 
    GLES20.glGenTextures(32, mTexturePointer, 0); 

    BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inTempStorage = new byte [16 * 1024]; 
    options.inScaled = false; 

    // TEXTURE 0 
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexturePointer[0]); 

    // Scale up if the texture if smaller. 
    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); 

    tBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ingame_boll_spritesheet_new_style, options); 

    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, tBitmap, 0); 

    tBitmap.recycle(); 
    // TEXTURE 1 
    GLES20.glActiveTexture(GLES20.GL_TEXTURE1); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexturePointer[1]); 

    // Scale up if the texture if smaller. 
    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); 

    tBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ingame_boll_mouth, options); 

    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, tBitmap, 0); 

    tBitmap.recycle(); 

    // And so on for all textures 

    Log.d("loadTextures()", "Loaded textures"); 

} 

我已经非常仔细地看了看和.pngs是没问题的。我尝试将顶点颜色alpha设置为-1,是的,纹理消失,但点仍然存在。当我禁用混合所有透明度变黑,点消失。我无法弄清楚接下来要做什么,当片段着色器输出alpha 0.0并且它仍然是虚线。

想要尝试的任何反馈意见。谢谢!

+0

尝试开启抖动('GLES20.glEnable(GLES20.GL_DITHER)')。 – Jave 2012-03-06 09:11:52

+0

@Jave现在尝试,但没有任何改变。尽管谢谢你的建议! – ronnerberg 2012-03-06 11:02:52

+1

虽然它看起来像某种颜色深度问题。你也可以尝试设置窗口和表面深度为32位:glview.setEGLConfigChooser(8,8,8,16,0);''和'getWindow().setFormat(PixelFormat.RGBA_8888);' (并且可能为窗口和opengl添加抖动) – Jave 2012-03-06 11:14:08

回答

1

这似乎是一个颜色深度问题。您应该在表面和窗口设置为32位模式,并看看是否有帮助:

glview.setEGLConfigChooser(8, 8, 8, 8, 16, 0); 

getWindow().setFormat(PixelFormat.RGBA_8888); 

它不应该是必要现在就抖动任何窗口,表面使用相同量的位,但有时它可以给出更好的结果,所以你可以尝试为window和openGL启用它。

0

你的“loadTextures()”函数是什么样的?这可能是一个glTexParameteri(...)问题,您可以在其中为纹理设置滤镜。 (插值可能不正确)

+0

对不起,错过了那个方法。原始帖子现在被编辑。谢谢。 – ronnerberg 2012-03-06 10:58:02