我正在使用opengl es 2.0编程一个android 2d游戏。在我把我的精灵画到后缓冲区后,我把灯光画到一个FBO,并试图再次将其混合到后缓冲区。
当我将fbo绘制到帧缓冲区时,即使没有任何颜色的trasparent,三星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,这是一个与平铺架构相关的问题,如果你要切换帧缓冲区,数据需要从fast mem复制到普通内存以保存当前帧缓冲区,从slowmem复制到fastmem以获取新的绑定帧,如果在glbind之后清除,没有数据从slowmem复制到fastmem,并且节省了时间,但是需要经常重新设计渲染管道,这样可以避免在慢速和快速内存之间来回读取数据,所以每次绑定后尝试执行glclear,它将显示如果需要帮助,您也可以使用Adreno Profiler获取有关有问题调用的其他信息,但我怀疑它是否有助于Adreno200。我正在尝试为Blur获取两个缓冲区,并且以10fps结束。如果未清除,则BindFrameBuffer调用可能需要20毫秒,如果是,则应以2毫秒结束。

07-28 01:50
查看更多