gl_FragColor и glReadPixels

Я все еще пытаюсь прочитать пиксели из фрагментного шейдера, и у меня есть несколько вопросов. Я знаю, что gl_FragColor возвращается с vec4, что означает RGBA, 4 канала. После этого я использую glReadPixels для чтения FBO и записи его в данные.

GLubyte *pixels = new GLubyte[640*480*4];
glReadPixels(0, 0, 640,480, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

Это нормально работает, но действительно имеет проблемы со скоростью. Вместо этого я хочу просто читать RGB, поэтому игнорируйте альфа-каналы. Я пытался:

GLubyte *pixels = new GLubyte[640*480*3];
glReadPixels(0, 0, 640,480, GL_RGB, GL_UNSIGNED_BYTE, pixels);

вместо этого, и это не сработало. Я думаю, это потому, что gl_FragColor возвращает 4 канала, и, может быть, мне стоит что-то сделать перед этим? На самом деле, поскольку мое возвращенное изображение (gl_FragColor) имеет оттенки серого, я сделал что-то вроде

float gray = 0.5 //or some other values
gl_FragColor = vec4(gray,gray,gray,1.0);

Так есть ли эффективный способ использовать glReadPixels вместо использования метода первых 4 каналов? Любое предложение? Кстати, это код opengl es 2.0.


person user2168    schedule 01.12.2011    source источник


Ответы (1)


В спецификации OpenGL ES 2.0 говорится, что существует два действующие формы звонка:

glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

or

GLint format, type;
glGetIntegerv(IMPLEMENTATION_COLOR_READ_FORMAT, &format);
glGetIntegerv(IMPLEMENTATION_COLOR_READ_TYPE, &type);
glReadPixels(x, y, w, h, format, type, pixels);

Возможные комбинации для format и type (рисунок взят из спецификации):

table

И реализация решит, что вам доступно.

Однако вполне вероятно, что если вы создадите поверхность рендеринга соответствующего формата, то это будет именно тот формат, который вы получите здесь. Посмотрите, можете ли вы изменить свой код, чтобы получить буфер кадра RGB (т.е. с 0 битами для альфа-канала). Или, может быть, вы захотите создать для этой цели закадровый объект фреймбуфера?

person Kos    schedule 01.12.2011
comment
Спасибо за ответ! Обязательно скоро попробую! Но не могли бы вы дать мне больше идеи или описания закадрового буфера кадра? Я немного новичок в графике, поэтому я не знаком с терминами. Возможно, ссылка на учебник? Еще раз спасибо! - person user2168; 01.12.2011
comment
Объект кадрового буфера (FBO) - это, по сути, вторичная цель рендеринга, которую вы создаете сами. Он может содержать буфер цвета, буфер глубины, альфа-буфер или что-то еще. Затем вы можете рисовать на нем (а не на экране, то есть в основном буфере кадров) и каким-то образом использовать результаты, например, в качестве текстуры для эффектов или для считывания пикселей (в вашем случае). - person Kos; 01.12.2011
comment
songho.ca/opengl/gl_fbo.html выглядит как хорошее практическое руководство с примером кода. (хотя для OpenGL; должно быть + - то же самое в ES 2). Также ознакомьтесь со спецификациями (см. Ссылку ранее; глава 4.4.3). - person Kos; 01.12.2011