Как использовать glReadPixels (), чтобы вернуть измененное изображение из FBO?

Коротко: мне нужен быстрый способ изменить размер изображения буфера, а затем вернуть мне пиксели, чтобы сохранить их в файл и т. Д.

В настоящее время я сначала использую glReadPixels (), а затем сам просматриваю пиксели, чтобы изменить их размер с помощью собственной функции изменения размера.

Есть ли способ ускорить это изменение размера, например, заставить OpenGL работать за меня? Я думаю, что мог бы использовать glGetTexImage () с включенным miplevel и mipmapping, но, как я заметил ранее, эта функция прослушивается на моей карте GFX, поэтому я не могу ее использовать.

Мне нужен только один средний уровень, который может быть любым от 1 до 4, но не все из них, чтобы сохранить память GPU. Так можно ли создать только один средний уровень желаемого размера?

Замечания: Я не думаю, что могу использовать мультисэмплинг, потому что мне нужен рендеринг с точностью до пикселя для трафаретных тестов, поэтому, если бы я рендерил его с мультисэмплингом, это сделало бы размытые пиксели, и они потерпели бы неудачу при тестировании и маскировании трафарета, и результат был бы неправильным (AFAIK). Редактировать: я только хочу масштабировать буфер цветов (RGBA)!

3

Решение

Если у вас есть OpenGL 3.0 или альтернативно EXT_framebuffer_blit доступны (очень вероятно — все карты nVidia примерно с 2005 года, все карты ATI с 2008 года есть, и даже графические карты Intel HD претендуют на его поддержку), тогда вы можете glBlitFramebuffer[EXT] в меньший кадровый буфер (с соответственно меньшим прямоугольником) и сделать графическую карту сделать работу.
Обратите внимание, что вы никогда не сможете безопасно перемасштабировать внутри одного и того же мошенника, даже если вы скажете: «Мне не нужен оригинал», потому что перекрывающиеся блиты не определены (позволил, но не определено).

Или, конечно, вы можете просто нарисовать полноэкранный четырехугольник с помощью простого пиксельного шейдера (прореживание анизо, если ты хочешь).

На самом деле, так как вы упоминаете трафарет в своем последнем абзаце … если это трафарет (или глубину), которую вы хотите изменить, тогда вам, безусловно, нужно нарисовать полноэкранный четырехугольник с помощью шейдера, поскольку в противном случае он, скорее всего, не даст желаемого результата. Обычно один выбирает max фильтрация, а не интерполяция в таком случае (например, какой разумный, значимый результат может интерполировать значение трафарета 0 и значение 10 дает — требуется что-то еще, например, «любой ненулевой» или «максимальное значение в области выборки») ,

2

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

Создайте кадровый буфер желаемого целевого размера и нарисуйте исходное изображение с текстурированным квадратом с полным размером буфера. Затем прочитайте содержимое измененного кадрового буфера, используя glReadPixels.

Psuedocode:

unbind_texture(OriginalSizeFBOattachmentColorTex);

glBindFramebuffer(OriginalSizeFBO);
render_picture();

glBindFramebuffer(TargetSizeFBO); // TargetSizeFBO used a Renderbuffer color attachment
glBindTexture(OriginalSizeFBOattachmentColorTex);
glViewport(TargetSize);
render_full_viewport_quad_with_texture();

glReadPixels(...);
2

По вопросам рекламы [email protected]