0

我需要能够使用 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() 消失了。但我仍然不确定为什么,所以最好知道引擎盖下发生了什么,以确保它在未来无论如何都不会犯这样的错误!

4

1 回答 1

0

FBO 本身只是一个抽象对象,没有自己的支持图像存储。基本上,FBO 本身只包含可以插入图像接收器和源的插槽。纹理可以充当这样的角色,但也有渲染缓冲区,它们具有相同的目的,但不能用作纹理样本源

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

于 2012-09-13T17:21:36.163 回答