gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:35:41 30 4
gpt4 key购买 nike

我正在使用 opengl es 2.0 编写 Android 2d 游戏。在我将 Sprite 绘制到后备缓冲区后,我将灯光绘制到 FBO 并尝试再次将其混合到后备缓冲区。当我将 FBO 绘制到帧缓冲区时,即使是透明的,没有任何颜色,在 Samsung Galaxy w(它有一个 adreno 205 作为 gpu)上,帧率从 60 下降到 30。我到处搜索并尝试了所有方法,即使我在场景中绘制了一个 Sprite 并将透明的 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 纹理时性能就被破坏了。非常感谢您的帮助。我为此付出了很多努力,但没有找到解决方案。

最佳答案

根据 qualcomm 文档,您需要在每个 glbindframebuffer 之后进行 glclear,这是一个与平铺架构相关的问题,如果您正在切换帧缓冲区,则需要将数据从 fastmem 复制到普通内存以保存当前帧缓冲区,并从 slowmem 复制到 fast mem 来获取新绑定(bind)帧的内容,以防你在 glbind 之后清除没有数据从 slowmem 复制到 fastmem 并且你节省了时间,但是你需要经常重新设计你的渲染管道,所以它会避免来回读取数据在慢速和快速内存之间,所以尝试在每次绑定(bind)后执行 glclear,它应该会有所帮助,您还可以使用 adreno profiler 获取有关有问题的调用的其他信息,但我怀疑它是否会对 adreno200 有所帮助我正在尝试获取两个缓冲区以进行模糊处理我以 10fps 结束,如果未清除 bindframebuffer 调用最多可能需要 20 毫秒,如果已清除,则应在 2 毫秒结束。

关于android - Framebuffer FBO 渲染到纹理非常慢,在 Android 上使用 OpenGL ES 2.0,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10729352/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com