Как предотвратить повреждение рендеринга FBO при одновременном запуске нескольких процессов OpenGL?

Мне нужно иметь возможность рендерить с несколькими процессами одновременно, используя OpenGL.

Я использую FBO для рендеринга в текстуру. Я прочитал пиксели с помощью glGetTexImage () несколько раз в этом процессе (рендеринг мозаики).

Затем я запустил несколько программ для одновременного запуска и заметил, что иногда это работает, а иногда нет. Иногда целое изображение повреждено (повторяется только один фрагмент), иногда повреждена только небольшая часть. Ранее я также заметил, что по какой-то причине я не смог использовать текстуру FBO размером 4096×4096, и ошибки этого размера текстуры были такими же, как и ошибка мозаики «несколько процессов одновременно», поэтому я подумал, что это может быть связано с программа пытается получить текстуру, которая еще не полностью отрисована? Я также заметил, что чем меньше текстур я использую, тем больше процессов я могу запустить одновременно. Моя карта памяти GFX составляет 256 МБ, я думаю. Но даже с 8 процессорами с размером текстуры 1024×1024 он использует в худшем случае только 33 МБ памяти, так что это не может быть ограничением памяти моей карты 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 (). Но я до сих пор не уверен, почему, так что было бы хорошо узнать, что происходит под капотом, чтобы быть уверенным, что он не сделает такие ошибки в любой случай в будущем!

0

Решение

Сам FBO — просто абстрактный объект без собственного хранилища резервных изображений. По сути, само FBO состоит только из слотов, в которые вы можете подключать приемники изображений и источники. Текстуры могут выступать в качестве таковых, но существуют также буферы рендеринга, которые служат для той же цели, но не могут использоваться в качестве исходного образца текстурирования.

Вы можете читать обратно напрямую из привязанного FBO, используя glReadPixels.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector