Я хотел бы отобразить цветную текстуру в сером цвете. Сделать это в ES 2.0 с помощью шейдера проще простого, но возможно ли это сделать в ES 1.x?
ОБНОВИТЬ
Благодаря @datenwolf я делаю это так:
GLfloat weights_vector[4] = {0.2126, 0.7152, 0.0722, 1.0};
GLfloat additions_vector[4] = {0.5, 0.5, 0.5, 0.0};
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
/* First part */
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, weights_vector);
/* Second part */
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, additions_vector);
Первая часть отображается нормально, если я оставлю ее саму по себе, но если я добавлю вторую, она использует «черный» в качестве предыдущего цвета, и поэтому я получаю только серые пиксели. Я делаю это неправильно здесь?
ВТОРОЕ ОБНОВЛЕНИЕ
Если я попытаюсь использовать GL_TEXTURE0
вместо GL_PREVIOUS
, я действительно получу тот же результат, что и GL_TEXTURE
. Однако, если я использовал GL_TEXTURE1
, я получаю даже не серые пиксели, а черные. Я теряюсь здесь...
ТРЕТЬЕ ОБНОВЛЕНИЕ
Сейчас работает вторая часть. Надо было просто использовать название предыдущей текстуры, как предложил @datenwolf!
Однако вывод по-прежнему не был правильным, поскольку он был инвертирован. Я исправил это, добавив:
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_ONE_MINUS_SRC_COLOR);
Сейчас слишком темно. И я не могу понять это правильно. Пробовал и не получилось:
- умножение весов на два
- добавление 0,5
- модуляция всего изображения на 2
- умножая веса на 2 и затем вычитая на 0,5
ЧЕТВЕРТОЕ ОБНОВЛЕНИЕ (извините, что так много)
Я начинаю подозревать, что это невозможно из-за смещения и умножения в DOT3_RGB
. Правильный способ сделать это в объединителе:
- Добавьте 0.5 к входной текстуре
- Рассчитать весовые коэффициенты: weight_new = (weight_real + 2.0) / (4.0);
- Do a
GL_DOT3_RGB
Например, вместо использования:
GLfloat weights_vector[4] = {0.30, 0.59, 0.11, 0.0};
Использовать:
GLfloat weights_vector[4] = {0.575, 0.6475, 0.5275, 0.0};
Это действительно дает почти правильный результат, но часть контраста теряется из-за первого шага и того факта, что числа зажаты в диапазоне [-1.0, 1.0]
Зачем расчеты? Ну, по API:
Поэтому я не вижу никакого другого способа, отличного от того, который я показал, и из-за ограничения точности. Конечно, я мог бы сначала разделить ввод на 2,0, затем добавить 0,5, сделать точку3, а затем снова умножить на 2, таким образом фактически имея все значения в диапазоне [-1,0, 0,0]. Но я боюсь, что это все равно потеряет точность из-за разделения.
Я подозреваю, что DOT не был предназначен для этой цели, скорее, только для бампмэппинга или чего-то в этом роде. Очень жаль. Надеюсь, я ошибаюсь, но я не понимаю, как.