Применение яркости и контраста с OpenGL ES - PullRequest
6 голосов
/ 02 октября 2009

Я хочу изменить яркость и контраст текстуры на iPhone. Я просматривал пример, предоставленный яблоком ( GLImageProcessing ), но он может выполнять только один (вызов обоих методов в образце перезаписывает предыдущий результат).

Яркость прекрасно работает:

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
if (brightness >= 1.0f) {
    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
    glColor4f(brightness-1, brightness-1, brightness-1, brightness-1);
} else {
    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_SUBTRACT);
    glColor4f(1-brightness, 1-brightness, 1-brightness, 1-brightness);
}
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

Как мне добавить контраст к текстуре после этого? В качестве альтернативы было бы лучше перейти на OpenGL ES 2.0 и сделать это с шейдерами?

Вот код для контраста в образце от яблока:

glActiveTexture(GL_TEXTURE0);
glVertexPointer  (2, GL_FLOAT, sizeof(V2fT2f), &quad[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &quad[0].s);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);

glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD_SIGNED);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, 2);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);

glColor4f(h, h, h, 0.75 - 0.5 * h); // 2x extrapolation
validateTexEnv();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

// Restore state
glDisable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, 1);
glActiveTexture(GL_TEXTURE0);

Как вы, вероятно, можете догадаться, мой опыт работы с OpenGL (ES) довольно ограничен, поэтому все, что указывает мне правильное направление, высоко ценится

Ответы [ 3 ]

7 голосов
/ 05 октября 2009

Это намного проще сделать с фрагментным шейдером, по крайней мере в OpenGL 2.1 (я не использовал OpenGL ES). Книга "Язык шейдеров OpenGL" охватывает обработку изображений в главе 19. Они дают шейдеры для регулировки яркости и контрастности. Вот моя версия, которая объединяет два с половиной:

uniform sampler2D Texture;
uniform float Brightness;
uniform float Contrast;
uniform vec4 AverageLuminance;

void main(void)
{
   vec4 texColour = texture2D(Texture, gl_TexCoord[0].st);
   gl_FragColor = mix(texColour * Brightness, 
      mix(AverageLuminance, texColour, Contrast), 0.5);
}

Редактировать: некоторые подробности для полноты ...

Яркость и контраст имеют базовое значение 1,0, поэтому, передавая их для обоих, текстура остается неизменной. Значение меньше 1,0 уменьшит яркость, а значение больше 1,0 увеличит ее. Значение менее 1,0 для контраста сделает текстуру более серой (менее контрастной), а значение более 1,0 сделает ее менее серой (более контрастной).

Вы можете передать (0,5, 0,5, 0,5, 1,0) для AverageLuminance для быстрого и грязного значения серого, но лучшие результаты будут получены при расчете правильной средней яркости для вашей текстуры.

1 голос
/ 11 октября 2009

Вы можете визуализировать изображение с отрегулированной яркостью в текстуру кадрового буфера того же размера, а затем выполнить настройку контрастности при визуализации этой текстуры на экране.

Image -> [Brightness] -> Texture -> [Contrast] -> Screen

Полезное чтение кадровых буферов и рендеринга в текстуру:

0 голосов
/ 10 октября 2009

Мой GL немного ржавый, но из примера кода они оба создают текстуру, чтобы смешаться с существующей сценой. Поэтому вы можете просто создать обе текстуры, убедившись, что они не растоптали друг друга, и , а затем смешают их обе на месте. Они делают разные вещи, поэтому я сомневаюсь, что вы сможете объединить их в одну и ту же текстуру. Сначала я бы заказал контраст, поскольку это более сложная смесь.

...