Используя альфа из текстуры, чтобы нарисовать сплошной цвет - PullRequest
8 голосов
/ 14 ноября 2010

Как я могу использовать OpenGLES 1.1 (iPhone) для рисования текстуры, но только с помощью альфы, чтобы нарисовать какой-нибудь цвет?

Результат должен быть точно такой же альфа-маской из исходной текстуры, с одним сплошным цветом внутри вместо исходных цветов.

Я использую glDrawArrays с glCoordPointer и glVertexPointer.

Я думаю, что делаю два прохода, один с текстурой и один со сплошным цветом к этому. Я просто не могу найти инверсию glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);.

Редактировать: после еще одного осмотра, я думаю, что этого можно достичь, используя glTexEnvf. Это просто вопрос поиска правильных аргументов.

Ответы [ 3 ]

8 голосов
/ 04 декабря 2010

Как уже упоминалось, glTexEnv - это путь.

Чтобы заменить RGB-компоненты вашей текстуры и оставить ее нетронутой альфа, вы можете попробовать что-то вроде этого (этот код использует красный в качестве цвета замены):

glColor4f( 1.0f, 0.0f, 0.0f, 1.0f );

glActiveTexture( GL_TEXTURE_0 );
glEnable( GL_TEXTURE_2D );
glBindTexture(GL_TEXTURE_2D, spriteTexture);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);

glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);

// ... draw as usual

Вот некоторые объяснения.

При использовании GL_COMBINE вы полностью контролируете, как ввод / вывод различных этапов текстуры объединяются вместе. В этом случае мы указываем, что мы хотим заменить (GL_REPLACE) компоненты RGB этапа текстуры 0 на то, что происходит на предыдущем этапе (GL_PREVIOUS), который в этом случае является одним цветом (устанавливается с помощью glColor4f).

Мы не установили ничего особенного для альфа-компонента, так как хотим нормального поведения. Добавление следующих строк имело бы такой же эффект, как если бы оно не было включено (поведение по умолчанию):

glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);   
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
2 голосов
/ 14 ноября 2010

Если вы можете использовать OpenGL ES 2.0, вы можете сделать это с помощью специального фрагментного шейдера. Если вы используете платформу, основанную на 1.1, или ориентированы на устройства, которые не поддерживают 2.0, это не сильно поможет. Но если вы можете, вот как вы это делаете:

uniform lowp sampler2D sampler; // which texture unit to use
uniform lowp vec4 solidColor;

varying highp vec2 fragmentTexCoord;

void main()
{
    // Get the color with an alpha of zero
    vec4 color = vec4(1,1,1,0) * solidColor;
    // Get the alpha from the texture, zero the r,g,b components
    vec4 alpha = vec4(0,0,0,1) * texture2D(sampler, fragmentTexCoord);
    // their sum is the solid color with the alpha mask of the texture
    gl_FragColor = color + alpha;
}

Если вы можете убедиться, что у solidColor альфа равна нулю, вы можете пропустить шаг умножения.

0 голосов
/ 30 ноября 2010

glBlendFunc(source_factor, dest_factor) переводится как:

dest= source*source_factor + dest*dest_factor

То есть glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA) это:

dest= source*0 + dest*(1 - source.alpha)

Второй проход (не обратный) должен быть glBlendFunc(GL_SRC_ALPHA, GL_ONE):

dest= source*source.alpha + dest

, так как вы уже применили альфа-маску в первом проходе. Хотя вам все еще нужно выяснить, как применять постоянный цвет с альфа-каналом вместо исходной текстуры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...