Альфа-смешение текстур и примитивов - PullRequest
0 голосов
/ 07 октября 2018

У меня есть две текстуры и примитив треугольника (цвета для его вершин определяются glColor4f).

Текстура A выглядит следующим образом:

Texture A

Текстура B выглядит следующим образом:

Texture B

Примитив треугольника P выглядит следующим образом:

Primitive P

Когда я рендерим текстуру A, а затем текстуру BI получим ожидаемымрезультат, т. е. середина прямоугольника прозрачна.

Render A then Render B

Однако, если я отрисовываю примитив P, за которым следует текстура A, а затем текстура B, я получаюнеправильные цвета.P не чисто красный, а цвет текстуры все становится черным.

imageA->B">

Как это исправить, чтобы обеспечить надлежащую прозрачность и цвета.

Параметры текстуры:

    GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
    GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
    GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER));
    GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER));
    GLfloat debugColor[] = {1.0f, 0.0f, 1.0f, 1.0f};
    GL_CALL(glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, debugColor));

Функция смешивания:

GL_CALL(glEnable(GL_BLEND));
GL_CALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));

Отображение P, A и B:

        if(true)
        {
            // Render Primitive P

            GL_CALL(glBegin(GL_TRIANGLES));

            GL_CALL(glColor4f(1.0f, 0.0f, 0.0f, 1.0f));
            GL_CALL(glVertex2f(-0.5f, -0.5f));

            GL_CALL(glColor4f(1.0f, 0.0f, 0.0f, 1.0f));
            GL_CALL(glVertex2f(0.0f, 0.5f));

            GL_CALL(glColor4f(1.0f, 0.0f, 0.0f, 1.0f));
            GL_CALL(glVertex2f(0.5f, -0.5f));

            glEnd();
        }
        if(true)
        {
            // Render Texture A

            GL_CALL(glBindTexture(GL_TEXTURE_2D, textureId));
            GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imageWidth, imageHeight, 0,
                                 GL_RGBA, GL_UNSIGNED_BYTE, image));

            real32 screenPercentage = 0.25f;

            GL_CALL(glBegin(GL_TRIANGLES));

            // Lower triangle
            GL_CALL(glTexCoord2f(0.0f, 0.0f));
            GL_CALL(glVertex2f(-screenPercentage, screenPercentage));

            GL_CALL(glTexCoord2f(1.0f, 0.0f));
            GL_CALL(glVertex2f(screenPercentage, screenPercentage));

            GL_CALL(glTexCoord2f(1.0f, 1.0f));
            GL_CALL(glVertex2f(screenPercentage, -screenPercentage));

            //  Upper triangle
            GL_CALL(glTexCoord2f(0.0f, 0.0f));
            GL_CALL(glVertex2f(-screenPercentage, screenPercentage));

            GL_CALL(glTexCoord2f(1.0f, 1.0f));
            GL_CALL(glVertex2f(screenPercentage, -screenPercentage));

            GL_CALL(glTexCoord2f(0.0f, 1.0f));
            GL_CALL(glVertex2f(-screenPercentage, -screenPercentage));

            glEnd();
        }

        if(true)
        {
            // Render Texture B

            GL_CALL(glBindTexture(GL_TEXTURE_2D, textureId));
            GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, window[0].offscreenBuffer.width, window[0].offscreenBuffer.height, 0,
                                 GL_RGBA, GL_UNSIGNED_BYTE, window[0].offscreenBuffer.data));

            real32 screenPercentage = 1.0f;

            GL_CALL(glBegin(GL_TRIANGLES));

            // Lower triangle
            GL_CALL(glTexCoord2f(0.0f, 0.0f));
            GL_CALL(glVertex2f(-screenPercentage, screenPercentage));

            GL_CALL(glTexCoord2f(1.0f, 0.0f));
            GL_CALL(glVertex2f(screenPercentage, screenPercentage));

            GL_CALL(glTexCoord2f(1.0f, 1.0f));
            GL_CALL(glVertex2f(screenPercentage, -screenPercentage));

            // Upper triangle
            GL_CALL(glTexCoord2f(0.0f, 0.0f));
            GL_CALL(glVertex2f(-screenPercentage, screenPercentage));

            GL_CALL(glTexCoord2f(1.0f, 1.0f));
            GL_CALL(glVertex2f(screenPercentage, -screenPercentage));

            GL_CALL(glTexCoord2f(0.0f, 1.0f));
            GL_CALL(glVertex2f(-screenPercentage, -screenPercentage));

            glEnd();
        }

РЕДАКТИРОВАТЬ: После попытки решения @ Rabbid76:

        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        if(true)
        {
        // Render triangle with all vertices having color 1.0f, 0.0f, 0.0f, 1.0f 
        }
        if(true)
        {
        // Render texture A with color set to 1.0f, 1.0f, 1.0f, 1.0f and the appropriate texture u,v coordinates
        }

        if(true)
        {
            // Render texture B with color set to 1.0f, 1.0f, 1.0f, 1.0f and the appropriate texture u,v coordinates
        }

я получаю следующий результат:

enter image description here

Цвета все еще не правильные, хотя альфа всех трех сущностей равна 1,0f, а полой области - 0,0f

1 Ответ

0 голосов
/ 07 октября 2018

Если текстурирование включено, то по умолчанию цвет текселя умножается на текущий цвет, потому что по умолчанию режим текстурной среды (GL_TEXTURE_ENV_MODE) равен GL_MODULATE.См. glTexEnv.

Это приводит к тому, что цвет текстур текстуры «смешивается» с последним цветом, который вы установили с помощью glColor4f.
Когда вы визуализируете текстуру, тогда красный цвет треугольника все еще установлен, поэтому текстуры имеют красный оттенок.Каналы зеленого и синего цветов полностью теряются, и поскольку текстуры не имеют канала красного цвета, все, что осталось, - это черный цвет.

Чтобы решить проблему, перед установкой необходимо установить белый цвет.текстуры:

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

И отключите GL_TEXTURE_2D перед рендерингом треугольника, но включите его перед рендерингом текстур.
Обратите внимание, что всегда есть граница текстуры, нет ничего похожего на "нет текстуры"msgstr "объект текстуры по умолчанию 0 также является допустимым объектом.Это приводит к тому, что поиск текстуры дает полностью черный цвет, и это смешивается с красным цветом, который установлен glColor4f:

glDisable( GL_TEXTURE_2D );
if( true )
{
    // Render Primitive P
    .....
}

glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
glEnable( GL_TEXTURE_2D );
if ( true )
{
    // Render Texture A
    .....
}
...