Framebuffer FBO渲染到纹理非常慢,在Android上使用OpenGL ES 2.0,为什么?

我正在使用opengl es 2.0编写Android 2d游戏.在我将精灵绘制到后备缓冲区后,我将灯光绘制到FBO并尝试将其再次混合到后台缓冲区.
当我将FBO绘制到帧缓冲区时,即使没有任何颜色也没有任何颜色,帧率在三星Galaxy w上从60降到30(它有一个adreno 205作为gpu).我到处搜索并尝试了所有内容,即使我在场景中绘制了一个精灵并将一个透明的FBO纹理混合到帧速率下降的屏幕上.我在手机上尝试了其他带有灯光效果的游戏,它们运行良好,几乎所有游戏都可以在手机上运行,​​我相信它们也使用了帧缓冲.
在Galaxy SII(mali 400 gpu)运行正常,我对opengl很新,所以我相信我在某个地方犯了一个错误,我分享了我的代码.

// 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纹理时,性能会被破坏.
非常感谢您的帮助.我在这方面努力工作并没有找到解决方案.

最佳答案
根据高通的文档,你需要每glbindframebuffer后glclear,这是关系到瓷砖架构的问题,如果您切换的帧缓冲区,数据需要从fastmem复制到正常的内存来保存当前帧缓冲区和slowmem快速MEM得到新绑定帧的内容,如果你正在glbind之后清除没有数据从slowmem复制到fastmem并且你节省了时间,但是你需要经常重新设计你的渲染管道,所以它会避免在慢速和慢速之间来回读取数据快速记忆,所以尝试在每次绑定后做glclear它应该有帮助,你也可以使用adreno探查器获取有关问题调用的其他信息,但我怀疑它将有助于adreno200我试图得到两个缓冲模糊和我以10fps结尾,bindframebuffer调用最多可能需要20毫秒,如果它没有被清除,如果是,它应该以2毫秒结束.

转载注明原文:Framebuffer FBO渲染到纹理非常慢,在Android上使用OpenGL ES 2.0,为什么? - 代码日志