#image #opengl-es #glsl #opengl-es-2.0
#изображение #opengl-es #glsl #opengl-es-2.0
Вопрос:
У меня есть изображение, похожее на исходный код:
.
Моя цель — отобразить это как результат:
.
Цвет должен быть переменным.
Возможно ли это сделать с помощью glEnable/glBlendFunc/glBlendFuncSeparate/glBlendEquationSeparate
?
Или я должен использовать шейдер (glsl)? Как бы выглядел этот шейдер?
Комментарии:
1. в GLSL это был бы простой фрагментный шейдер, в GL вам нужно сначала создать маску из вашего изображения (самостоятельно, не с помощью GL, который также состоит из двух вложенных
for
секций и однойif
), а затем использовать simpleglColor
…2. Кажется излишним использовать Open Gl ES только для этого. Если вы не хотите менять цвет в каждом кадре, я бы рекомендовал загрузить ваше изображение в растровый объект и использовать getPixels () / SetPixels (), чтобы изменить его так, как вы хотите. В противном случае, да, вам придется написать фрагментный шейдер для его обработки.
Ответ №1:
Для создания подобного рисунка я бы все равно посоветовал вам использовать шейдеры, но если нет, есть еще множество способов нарисовать это, но для этого потребуется выполнить как минимум 2 вызова draw.
Итак, лучший способ попросить меня нарисовать все эти рисунки только в альфа-канале. Это означает, что будут отрисованы только альфа-символы, в то время как цвета сохранятся в том виде, в каком они есть. Для этого вам нужно сначала очистить альфа-значение до нуля, поэтому, когда вы очищаете цветовой буфер, убедитесь, что альфа-компонент установлен на ноль glClearColor(0,0,0,0)
должно сделать. Теперь, прежде чем прекратить рисование, используйте цветовую маску, чтобы включить только альфа: glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE)
. Теперь рисуйте свои изображения с помощью glBlendFuncSeparate( GL_ZERO, GL_ONE, GL_ONE, GL_ONE)
. Это означает, что игнорируйте цвет вашей текстуры (ее RGB-часть) и используйте любой цвет, который был в буфере ранее, и это означает, что используйте альфа-значение текстуры и суммируйте его с тем, что уже было в буфере (последнее значение имеет больше смысла быть GL_ZERO
, но это предотвратило бы наложение). Теперь нарисуйте столько таких текстур, сколько захотите. У вас может быть только один, но он должен работать для любого количества из них.
Таким образом, на этом этапе ваш буфер будет иметь нулевую альфа везде, кроме тех мест, где вы нарисовали свои текстуры, а текстуры имели ненулевую альфа. Итак, пришло время нарисовать фактический цвет. Нам нужно повторно включить цветовую маску, чтобы отрисовать цвет so glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)
(альфа-части может быть присвоено значение false, но давайте сбросим и это значение). Теперь, чтобы нарисовать фактический цвет, нам нужно наложить части, имеющие альфа, поэтому давайте настроим смешивание на glBlendFuncSeparate(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE, GL_ZERO)
. Это означает, что мы будем применять цвет в зависимости от текущего альфа-состояния буфера. Если состояние равно 1, то будет применен полный цвет, если альфа равна 0, то тот же цвет останется таким, какой он есть, если 0.5, то будет смешан цвет, который ранее был в буфере, с новым цветом, что означает, что если у вас белый фон, вы можете захотеть очистить цвет до (1,1,1,0)
. Затем альфа будет заменена на любую новую альфа, значение которой будет установлено в цвете.
Теперь либо перерисуйте прямоугольник в полноэкранном режиме с отключенными текстурами и цветом, установленным на любой целевой цвет (фиолетовый), и все готово. Или вы можете перерисовать прямоугольник (ы) только там, где были нарисованы изображения.
Недостаточно просто? Как насчет этого:
- Установите чистый цвет на цвет ваших фигур
glClearColor(violet.r, violet.g, violet.b, 0.0)
Сохраняйте альфа-значение равным нулю - Очистить цветовой буфер
- Установите цветовую маску так, чтобы она отображалась только в альфа-формате
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE)
- Включить наиболее распространенную функцию смешивания
glBlend(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
- Рисуйте свои текстуры так же, как и любые другие
- Сброс цветовой маски по умолчанию
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)
Примечание: Эта последняя процедура будет работать только в том случае, если для вашего вида / экрана / холста включено смешивание. Если нет, то в большинстве случаев будет представлена только часть RGB, что приведет к тому, что весь экран будет иметь сплошной цвет.