glReadPixels из FBO не работает с мультисэмплингом - PullRequest
7 голосов
/ 19 апреля 2009

У меня есть объект FBO с вложением цвета и глубины, к которому я рендерил, а затем считал с помощью glReadPixels(), и я пытаюсь добавить к нему поддержку мультисэмплинга.
Вместо glRenderbufferStorage() я звоню glRenderbufferStorageMultisampleEXT() и для цветного, и для глубинного вложения. Кажется, что объект кадрового буфера был успешно создан и объявлен завершенным.
После рендеринга я пытаюсь читать с него с glReadPixels(). Когда количество сэмплов равно 0, то есть отключение мультисэмплинга работает отлично, и я получаю изображение, которое хочу. когда я устанавливаю число выборок на что-то другое, скажем, 4, буфер кадра все еще создается нормально, но glReadPixels() завершается с ошибкой INVALID_OPERATION

У кого-нибудь есть идея, что здесь может быть не так?

РЕДАКТИРОВАТЬ: код glReadPixels:

glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, ptr);

где ptr указывает на массив width * height uints.

Ответы [ 2 ]

24 голосов
/ 29 апреля 2009

Я не думаю, что вы можете читать из FBO с несколькими выборками с помощью glReadPixels (). Вам необходимо выполнить переход от мультисэмплового FBO к обычному FBO, связать нормальное FBO и затем прочитать пиксели из нормального FBO.

Примерно так:

// Bind the multisampled FBO for reading
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, my_multisample_fbo);
// Bind the normal FBO for drawing
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, my_fbo);
// Blit the multisampled FBO to the normal FBO
glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
//Bind the normal FBO for reading
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, my_fbo);
// Read the pixels!
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1 голос
/ 04 мая 2009

Вы не можете прочитать мультисэмпловый буфер напрямую с помощью glReadPixels, так как это вызовет ошибку GL_INVALID_OPERATION. Вам нужно перейти на другую поверхность, чтобы графический процессор мог выполнить уменьшенную выборку. Вы можете переместиться в буфер, но существует проблема «теста корабля владельца пикселя». Лучше всего сделать еще один FBO. Давайте предположим, что вы сделали еще один FBO, и теперь вы хотите блит. Это требует GL_EXT_framebuffer_blit. Как правило, когда ваш драйвер поддерживает GL_EXT_framebuffer_multisample, он также поддерживает GL_EXT_framebuffer_blit, например, серии nVidia Geforce 8.

 //Bind the MS FBO
 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, multisample_fboID);
 //Bind the standard FBO
 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fboID);
 //Let's say I want to copy the entire surface
 //Let's say I only want to copy the color buffer only
 //Let's say I don't need the GPU to do filtering since both surfaces have the same dimension
 glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
 //--------------------
 //Bind the standard FBO for reading
 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID);
 glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, pixels);

Источник: Мультисэмпл GL EXT framebuffer

...