2012-05-23 3 views
6

OpenGL es 2.0을 사용하여 Android 2d 게임을 프로그래밍하고 있습니다. 스프라이트를 백 버퍼에 그려 넣으면 FBO에 라이트를 그리고 다시 백 버퍼에 블렌드 해 봅니다. 프레임 버퍼에 FBO를 그릴 때, 색상이 없어도 쓰다 롭지 만, 삼성 Galaxy에서 프레임 레이트는 60에서 30으로 떨어집니다 (gpu로 adreno 205가 있음). 장면에 단일 스프라이트를 그리고 프래그먼트가 떨어지는 화면에 trasparent FBO 텍스처를 혼합하더라도 모든 곳을 검색하고 모든 것을 시도했습니다. 나는 그 전화기에 조명 효과로 다른 게임을 시도했고 잘 돌아 갔고, 거의 모든 게임이 그 전화기에서 훌륭했다. 나는 그들이 프레임 버퍼도 사용한다고 생각한다. Galaxy SII (말리 400gpu)에서 잘 실행됩니다. OpenGL을 처음 접해 보았으므로 어딘가에서 실수를 저지르고 있다고 생각합니다. 코드를 공유합니다.Framebuffer Android에서 OpenGL ES 2.0을 사용하면 텍스처에 FBO 렌더링이 매우 느립니다. 이유는 무엇입니까?

// Create a framebuffer and renderbuffer 
GLES20.glGenFramebuffers(1, fb, offset); 
GLES20.glGenRenderbuffers(1, depthRb, offset); 

// Create a texture to hold the frame buffer 
GLES20.glGenTextures(1, renderTex, offset); 
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTex[offset]); 

GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 
        screenWidth, screenHeight, 0, 
        GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, 
        null); 


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.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, 
         GLES20.GL_LINEAR); 
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, 
         GLES20.GL_LINEAR); 

//bind renderbuffer 
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depthRb[offset]); 

GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, 
          screenWidth, screenHeight); 

// bind the framebuffer 
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb[offset]); 

// specify texture as color attachment 
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, 
           GLES20.GL_TEXTURE_2D, renderTex[offset], 0); 

// specify depth_renderbufer as depth attachment 
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, 
           GLES20.GL_RENDERBUFFER, depthRb[0]); 

// Check FBO status. 
int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER); 

if (status == GLES20.GL_FRAMEBUFFER_COMPLETE) 
{ 
    Log.d("GLGame framebuffer creation", "Framebuffer complete"); 
} 


// set default framebuffer 
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); 

표면을 만들 때이 작업을 한 번 수행합니다. 맞는지 확실하지 않습니다. 내가 필요할 때 텍스쳐와 프레임 버퍼 ID를 그들에게로 바꾼다. 내 드로잉 코드 :

GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId); 
ShaderProgram program = glgame.getProgram(); 

//put vertices in the floatbuffer 
mTriangleVertices.put(vertices, 0, len); 
mTriangleVertices.flip(); 

GLES20.glVertexAttribPointer(program.POSITION_LOCATION, 2, GLES20.GL_FLOAT, false, 
          TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices); 

//preparing parameter for texture position 
mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET); 
GLES20.glEnableVertexAttribArray(program.POSITION_LOCATION); 

//preparing parameter for texture coords 
GLES20.glVertexAttribPointer(program.TEXTURECOORD_LOCATION, 2, GLES20.GL_FLOAT, 
          false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, 
          mTriangleVertices); 

//set projection matrix 
GLES20.glEnableVertexAttribArray(program.TEXTURECOORD_LOCATION); 
GLES20.glUniformMatrix4fv(program.MATRIX_LOCATION, 1, false, matrix, 0); 

//draw triangle with indices to form a rectangle 
GLES20.glDrawElements(GLES20.GL_TRIANGLES, numSprites * 6, GLES20.GL_UNSIGNED_SHORT, 
         indicesbuf); 

//clear buffers 
mTriangleVertices.clear(); 
mVertexColors.clear(); 

모두가 제대로 화면에 렌더링되는,하지만 난 FBO 텍스처를 그릴 바로 그 때 성능이 파괴된다. 도움 주셔서 대단히 감사합니다. 나는 이것에 열심히 노력했고 해결책을 찾지 못했습니다.

+0

늦게 답변을 드리지만 ICS에서 HD2와 유사한 작업을하고 있습니다. 60fps에서 아무 문제없이 렌더링 할 수 있지만 FBO를 사용하면 프레임 속도가 45로 내려 가고 다른 FBO를 사용하면 30으로 줄어 듭니다. –

+0

흠 ... 삼성에서 몇 가지 게임을 보았습니다. Galaxy w는 아무런 문제없이 작동하며 2d 조명에 프레임 버퍼를 사용하는 것처럼 보였습니다. 대신 코드가 느리게 실행됩니다. 내가 실수를하는지 궁금해. – mao

+0

galaxy는 sgx 칩셋을 사용합니다. 내가 전에 말했듯이 그 작은 gemem 및 타일 된 아키텍처와 관련된 때마다 프레임 버퍼를 바꿀 때마다 하나의 일반 mem에 복사해야합니다, 멀리 떨어져 첫 번째 호출로 바인딩 후 그것은 정상에서 다시 복사 할 필요가 없습니다 memem, thats framebuffers가 adreno 200에서 특히 느린 이유) :) adreno 장치가 있으면 프레임 버퍼를 사용하여 프레임 버퍼를 사용하는 응용 프로그램을 확인할 수 있습니다. 플러그를 꽂고 현재 프레임을 다운로드 한 다음 텍스처에서 fb를 확인하십시오. 만약 당신이 확실하게 찾을 수 있다면, – ZZZ

답변

12

Qualcomm docs에 따르면 모든 glbindframebuffer 다음에 glbular가 필요합니다. 타일링 된 아키텍처와 관련된 문제입니다. 프레임 버퍼를 전환하는 경우 데이터가 현재 프레임 버퍼를 저장하기 위해 기본 메모리에서 일반 메모리로 복사해야하고 slowmem에서 fast memem을 사용하면 새로 바인딩 된 프레임의 내용을 가져올 수 있습니다. glbind 직후에 데이터를 지우지 않아도 slowmem에서 fastmem으로 데이터를 복사하지 않고 시간을 절약 할 수 있지만 렌더링 파이프 라인을 자주 다시 설계해야하므로 데이터를 다시 읽지 않습니다. 앞뒤로 천천히 빠른 메모리 사이에, 그래서 각 바인딩 후 glclear 할 시도하고 도움이 될 것입니다, 당신은 또한 문제가 전화에 대한 추가 정보를 얻으려면 adreno 프로파일 러를 사용할 수 있지만 adreno200 도움이 될 것입니다 내가 두 버퍼를 얻으려고 블러와 나는 10fps로 끝나고있다. bindframebuffer 콜은 클리어되지 않으면 20msec까지 걸릴 수있다. uld는 2ms로 끝납니다.

+0

adreno 205에서 손을 다시 얻을 수있게 되 자마자 시도해 보겠습니다. 저는 Qualcomm 설명서를 찾았고이를 따라갈 것입니다. 당신의 도움을 주셔서 대단히 감사합니다! – mao

+0

[Here] (https://www.google.sk/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&ved=0CDEQFjAA&url=https%3A%2F%2Fdeveloper.qualcomm.com%2Fdownload%2Fadreno200performanceoptimizationopenglestipsandtrickksmarch10 .pdf & ei = DT6IUcaTMYXV4ASEwYHYAQ & usg = AFQjCNFbU3Vf2mT2sf7LTAJQ3xqijdyUAA & sig2 = JMoeTn8G1MQgor9ZGDdFQg & bvm = bv.45960087, d.bGE)는 Qualcomm 문서입니다. –

+1

프레임 버퍼의 내용을 유지하려면'glClear (0);'을 실행하면 문제를 해결할 수 있습니다. – Thomas

관련 문제