2012-03-06 8 views
2

현재 OpenGL ES 2.0을 사용하는 Android 용 게임을 개발 중입니다. 텍스처와 정점 색상으로 거의 모든 작업을 할 수 있지만 텍스처에서 투명도를 사용하면 투명 부분이 점선으로 표시됩니다. 여기에 스크린 샷이 나와 있습니다 : Dotted transparency투명도 점선 OpenGL ES 2.0

표시된 볼 (파란색 원)은 현재 그 위에 눈, 입, 치아의 3 개의 평면이 있습니다. 모든 레이어는 동일한 크기와 투명도를 가지고 있으며 더 많은 레이어를 추가할수록 도트 효과가 악화되는 것처럼 보입니다.

   "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"; 

그리고 버텍스 쉐이더 :

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"); 

이 조각 쉐이더입니다 :

   "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"; 

그리고 마지막으로 추첨 (이이 렌더러의에서 onCreate 방법 각 개체의 그리기 방법입니다.) :

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); 
    } 
} 
(210)

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는 문제가되지 않습니다. 버텍스 색상 알파를 -1로 설정하려고 시도했지만 텍스처가 사라졌지만 점선이 그대로 남아 있습니다. 블렌딩을 비활성화하면 모든 투명도가 검은 색으로 표시되고 점선이 사라집니다. 프래그먼트 쉐이더가 알파 0.0을 출력하고 여전히 점선으로되어있을 때 다음에 무엇을 시도해야 할지를 알 수 없습니다.

시도 할 것들에 대한 의견을 보내 주시면 감사하겠습니다. 고맙습니다!

+0

디더링을 켜보십시오 ('GLES20.glEnable (GLES20.GL_DITHER)'). – Jave

+0

@Jave 지금 시도했지만 아무것도 변경되지 않았습니다. 생각해 줘서 고마워! – ronnerberg

+1

그래도 일종의 색상 심도 문제로 보입니다. 또한 창과 표면 깊이를 모두 32 비트로 설정하려고 할 수 있습니다 : 'glview.setEGLConfigChooser (8, 8, 8, 8, 16, 0); 및'getWindow(). setFormat (PixelFormat.RGBA_8888); (그리고 아마도 윈도우와 OpenGL 모두에 디더를 추가하십시오) – Jave

답변

1

색상 심도 문제입니다.

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

getWindow().setFormat(PixelFormat.RGBA_8888); 

창 표면이 동일한 금액을 사용하는 지금은 아무것도 디더링 할 필요는 없습니다를 :이 도움이 경우 32 비트 모드로 표면과 창을 설정하고 볼 수 그러나 때로는 더 나은 결과를 줄 수 있으므로 창과 OpenGL 모두에서 사용할 수 있습니다.

0

"loadTextures()"기능은 어떻게 생겼습니까? 텍스처에 대한 필터링을 설정하는 glTexParameteri (...) 문제 일 수 있습니다. (보간이 올바르지 않을 수 있습니다)

+0

죄송합니다, 그 방법을 놓치 셨습니다. 원본 게시물이 수정되었습니다. 고맙습니다. – ronnerberg