繁体   English   中英

同时运行多个OpenGL进程时如何防止FBO渲染损坏?

[英]How to prevent FBO rendering corrupting when running multiple OpenGL processes at same time?

我需要能够使用OpenGL同时渲染多个进程。

我正在使用FBO渲染为纹理。 我在那个过程中(平铺渲染)多次读取了glGetTexImage()的像素。

然后,我启动了多个程序以同时运行,并注意到有时它可以工作,有时却不能。 有时整个图像已损坏(仅重复一个图块),有时仅一小部分已损坏。 我还早些时候注意到,由于某种原因,我无法使用4096x4096大小的FBO纹理,并且该纹理大小的错误与此“一次处理多个”平铺错误相同,因此我认为这可能与程序试图获得尚未完全渲染的纹理? 我还注意到,我使用的纹理越小,可以同时运行更多的进程。 我认为我的GFX卡内存为256 MB。 但是,即使有8个进程的1024x1024大小的纹理大小,它在最坏的情况下也仅使用33 MB的内存,因此这不能成为我的GFX卡内存限制。

切片错误看起来好像没有获取新的切片像素数据,因此它再次使用了旧缓冲区。

我该怎么做才能防止渲染损坏?

这是我的渲染代码结构:

for(y...){
    for(x...){
        // set viewport & translatef

        glBindFramebuffer(GL_FRAMEBUFFER, fboId);
        // glclear()
        render_tile();
        glFlush();
        glBindFramebuffer(GL_FRAMEBUFFER, 0);

        glBindTexture(GL_TEXTURE_2D, textureId);
        glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
        glBindTexture(GL_TEXTURE_2D, 0);
        copy_tile_pixels_to_output_image();
    }
}

这是FBO初始化(仅显示与opengl相关的命令):

// texture:
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);

// FBO:
glGenFramebuffers(1, &fboId);
glBindFramebuffer(GL_FRAMEBUFFER, fboId);

glGenRenderbuffers(1, &rboId);
glBindRenderbuffer(GL_RENDERBUFFER, rboId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, TEXTURE_WIDTH, TEXTURE_HEIGHT);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rboId);

checkFramebufferStatus(); // will exit if errors found. none found, however.

glBindFramebuffer(GL_FRAMEBUFFER, 0);

编辑:正如datenwolf所注意到的,通过使用glReadPixels()可以解决问题。 但是我仍然不确定为什么,因此最好了解幕后发生的事情,以确保将来在任何情况下都不会犯此类错误!

FBO本身只是一个抽象对象,没有其自己的后备图像存储。 基本上,FBO本身仅包含可用于插入图像接收器和信号源的插槽。 纹理可以起到这种作用,但也有渲染缓冲区,它们的用途相同,但不能用作纹理采样源

您可以使用glReadPixels从绑定的FBO直接回读。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM