이 문제는 제가 코딩을 잘못 하거나, 샘플 소스를 잘못 이용한 걸 수도 있지만,
경험의 유추했을 때 결론이 나와. 이렇게 글을 남깁니다.
혹시 잘못된 부분이 있으면 주저 말고 댓글을 달아주시면 감사하겠습니다.^^
Opengl es 2.0을 사용하여 개발하는 중.. 화면을 껏다가 다시 켜면..
뭔가 속도가 느려지다가 결국 Out of memory 오류와 함께 팅겨져 버립니다.
역시나 Out of memory 부분은 Texture 부분이 문제 이죠.
전 onSurfaceCreated 함수 내에 Texture를 셋팅 하는 소스를 코딩하였습니다.
loadTexture ( mContext.getResources().openRawResource( R.raw.background) ,"mBgTexId" );
디버깅을 해본 결과... 예전 Opengl es 1.1에서는 화면을 갱신 해도, onSurfaceCreated 함수가 불러지지 않았었습니다.
하지만, Opengl es 2.0으로 바뀌면서 static 메모리 함수로 바뀌고 나서
GLES20와 관련된 메모리 장치들이 초기화가 되는 것 같습니다.
더 웃긴 건... 초기화가 되면서, 메모리 Texture 버퍼들이 삭제가 되지 않는 점입니다.
결국.. 프로그램 실행 시 , 한번만 실행이 되었던 onSurfaceCreated 함수내에 예외 처리가 필요했습니다.
deleteTexture(texId);
texId = loadTexture ( mContext.getResources().openRawResource( R.raw.background) ,"mBgTexId" );
private void deleteTexture(int texId){
// 전에 저장되어 있는 texture 가 있는지 확인
if(texId == 0)
return;
int idArr[];
IntBuffer intbuf;
idArr = new int[]{texId};
intbuf = getIntBufferFromIntArray(idArr);
GLES20.glDeleteTextures(1, intbuf);
}
이렇게 계속 갱신 할때마다 Texture를 불러 올 경우, 매번 이미지를 불러와야 하므로 속도가 느려집니다.
결국, TextureBuffer를 저장 시켜놓고, 갱신 할때마다 TextureBuffer를 이용하는 쪽으로 수정하였습니다.
이럴 경우, Texture 설정 시간이 조금 걸리지만 그리 느려지는 현상이 줄어듭니다.
private int loadTexture ( InputStream is ,String strKey)
{
int[] textureId = new int[1];
// 기존의 존재하는지 확인
if(texBuffer.get(strKey) == null){
TexValue value = new TexValue();
Bitmap bitmap;
bitmap = BitmapFactory.decodeStream(is);
bitmap = Bitmap.createScaledBitmap(bitmap,getMinPowerByTwo(bitmap.getWidth()), getMinPowerByTwo(bitmap.getHeight()),false);
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(bitmap.getWidth() * bitmap.getHeight() * 4);
byteBuffer.order(ByteOrder.BIG_ENDIAN);
IntBuffer ib = byteBuffer.asIntBuffer();
int bitmapWidth = bitmap.getWidth();
int bitmapHeight = bitmap.getHeight();
int[] pixels = new int[bitmapWidth * bitmapHeight];
bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
bitmap.recycle();
bitmap = null;
for(int i=0; i<pixels.length; i++){
ib.put(pixels[i] << 8 | pixels[i] >>> 24);
}
value.bmpWidth = bitmapWidth;
value.bmpHeight = bitmapHeight;
value.texBuffer = byteBuffer;
// Buffer를 저장 시켜 놓는다.
texBuffer.put(strKey,value);
}
texBuffer.get(strKey).texBuffer.position(0);
GLES20.glGenTextures ( 1, textureId, 0 );
GLES20.glBindTexture ( GLES20.GL_TEXTURE_2D, textureId[0] );
GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR );
GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR );
GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE );
GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE );
GLES20.glTexImage2D ( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, texBuffer.get(strKey).bmpWidth, texBuffer.get(strKey).bmpHeight, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, texBuffer.get(strKey).texBuffer );
return textureId[0];
}
지금 이건 저의 경험을 토대로 나온 것들입니다.
뭔가 문제가 있다고 생각되시면 언제든지! 꼭! 댓글 부탁드립니다.
감사합니다.
'나의 플랫폼 > 안드로이드' 카테고리의 다른 글
[ Android Opengl es 2.0 ] RenderMonkey 사용 시 Opengl es 문제 (0) | 2011.10.21 |
---|---|
[ Android ] Android 4.0 변경 사항 (0) | 2011.10.20 |
[ Android ] Eclipse에 JavaDoc 설정하기 (0) | 2011.10.18 |
[ Android ] 타이틀 바 높이 확인 방법 (0) | 2011.10.13 |
[ Android Opengl es ] 화면이 하얗게 보이는 현상. (3) | 2011.10.12 |