현재 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을 출력하고 여전히 점선으로되어있을 때 다음에 무엇을 시도해야 할지를 알 수 없습니다.
시도 할 것들에 대한 의견을 보내 주시면 감사하겠습니다. 고맙습니다!
디더링을 켜보십시오 ('GLES20.glEnable (GLES20.GL_DITHER)'). – Jave
@Jave 지금 시도했지만 아무것도 변경되지 않았습니다. 생각해 줘서 고마워! – ronnerberg
그래도 일종의 색상 심도 문제로 보입니다. 또한 창과 표면 깊이를 모두 32 비트로 설정하려고 할 수 있습니다 : 'glview.setEGLConfigChooser (8, 8, 8, 8, 16, 0); 및'getWindow(). setFormat (PixelFormat.RGBA_8888); (그리고 아마도 윈도우와 OpenGL 모두에 디더를 추가하십시오) – Jave