Этот урок покажет вам, как создавать прозрачные полигоны.
Этот эффект может быть очень красив, особенно если подключить текстуры.
Он позволяет вам сделать эффект воды, окон, частиц и многого другого.
В будущих уроках мы будем использовать прозрачность для создания эффекта частиц и маски частиц. Прозрачность будет работать по маске; если на текстуре фон черный — этот участок будет прозрачным.

В этом уроке мы создадим два вращающихся куба, один внутри другого. Внешний, бОльший куб будет прозрачным, а внутренний — нет.

Исходный код урока взят из первого — «Инициализация». Файлы main.h и init.cpp остаются без изменений.

Файл main.cpp:

// Для начала напишем новую функцию:

///////////////////////////////// CREATE CUBE \\\\*
/////
/////   Создаёт куб с нижним левым углом в координате X,Y,Z.
/////   Ширина и высота зависит от передаваемого в ф-ю радиуса.
/////
///////////////////////////////// CREATE CUBE \\\\*

void CreateCube(float x, float y, float z, int radius, int color)
{
glBegin(GL_QUADS);
// Эти вершины создают заднюю сторону:
glColor3ub(color, color, 255 color);       glVertex3f(x, y, z);
glColor3ub(255 color, color, 255 color); glVertex3f(x, y + radius, z);
glColor3ub(color, 255 color, 255 color); glVertex3f(x + radius, y + radius, z);
glColor3ub(color, 255 color, 255 color); glVertex3f(x + radius, y, z);

// Эти — переднюю
glColor3ub(color, color, 255 color);       glVertex3f(x, y, z + radius);
glColor3ub(255 color, color, 255 color); glVertex3f(x, y + radius, z + radius);
glColor3ub(color, 255 color, 255 color); glVertex3f(x + radius, y + radius, z + radius);
glColor3ub(color, 255 color, 255 color); glVertex3f(x + radius, y, z + radius);

// Эти — нижнюю
glColor3ub(color, color, 255 color);       glVertex3f(x, y, z);
glColor3ub(255 color, color, 255 color); glVertex3f(x, y, z + radius);
glColor3ub(color, 255 color, 255 color); glVertex3f(x + radius, y, z + radius);
glColor3ub(color, 255 color, 255 color); glVertex3f(x + radius, y, z);

// Эти — верхнюю
glColor3ub(color, color, 255 color);       glVertex3f(x, y + radius, z);
glColor3ub(255 color, color, 255 color); glVertex3f(x, y + radius, z + radius);
glColor3ub(color, 255 color, 255 color); glVertex3f(x + radius, y + radius, z + radius);
glColor3ub(color, 255 color, 255 color); glVertex3f(x + radius, y + radius, z);

// Эти — левую
glColor3ub(color, color, 255 color);       glVertex3f(x, y, z);
glColor3ub(255 color, color, 255 color); glVertex3f(x, y, z + radius);
glColor3ub(color, 255 color, 255 color); glVertex3f(x, y + radius, z + radius);
glColor3ub(color, 255 color, 255 color); glVertex3f(x, y + radius, z);

// А эти — правую.
glColor3ub(color, color, 255 color);       glVertex3f(x + radius, y, z);
glColor3ub(255 color, color, 255 color); glVertex3f(x + radius, y, z + radius);
glColor3ub(color, 255 color, 255 color); glVertex3f(x + radius, y + radius, z + radius);
glColor3ub(color, 255 color, 255 color); glVertex3f(x + radius, y + radius, z);

glEnd();
}

// Всё остальное будет происходить в функции RenderScene():

void RenderScene()
{
// Обьявим статические переменные вращения
static float rotX = 0.0f, rotZ = 0.0, rotY = 0.0f;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

gluLookAt(0, 0, 6,     0, 0, 0,     0, 1, 0);

/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

// Теперь нарисуем 2 куба внутри друг друга, и первому включим прозрачность.

glRotatef(rotX, 1.0f, 0.0f, 0.0f);      // Вращение по оси X
glRotatef(rotY, 0.0f, 1.0f, 0.0f);      // Вращение по оси Y
glRotatef(rotZ, 0.0f, 0.0f, 1.0f);      // Вращение по оси Z

// Это будет меньший куб внутри большего. Заметьте, мы передаём 255 как значение цвета
// в конце. Это просто создаст цвета, противоположные цветам большего куба,
// для лучшего восприятия.

CreateCube(0.5f, 0.5f, 0.5f, 1, 255);

// Включим прозрачность. Всё, отрисованное после этого, будет прозрачным.

glEnable(GL_BLEND); // Вкл. Blending

// Код ниже просто определяет, какой режим прозрачности нам нужен. Без этого
// ничего не заработает. Первый параметр указывает, как будут рассчитаны красный,
// зеленый, синий и альфа source-blending факторы. Следующий параметр указывает, как
// будут рассчитаны R,G,B и A destination-blending факторы. Мы просто выбираем
// значение один к одному.
// В будущих уроках мы рассмотрим некоторые другие флани, например, GL_SRC_COLOR.

glBlendFunc(GL_ONE, GL_ONE);    // Сделаем значение прозрачности 1:1

CreateCube(1, 1, 1, 2, 0);   // Это наш больший прозрачный куб.

// И последний шаг — выключить прозрачность. Это значит, что ничего, отрисованное
// позже, не будет прозрачным.

glDisable(GL_BLEND);        // Выключаем прозрачность

rotX += 0.3f;               // Увеличим вращение X
rotY += 0.3f;               // Увеличим вращение Y
rotZ += 0.8f;               // Увеличим вращение Z

SwapBuffers(g_hDC);
}

 

Вот и всё. Тоже ничего сложного. Давайте ещё раз повторим шаги:

1) Для включения прозрачности сначала вызываем: glEnable(GL_BLEND);

2) Простое включение прозрачности — ещё не всё. Дальше нам нужно указать технологию
рассчета прозрачности. В этом уроке мы просто указали значение 1 к 1: glBlendFunc(GL_ONE, GL_ONE);

3) Далее мы рендерим что-нибуть на экран, и этот обьект будет прозрачным.

4) Чтобы выключить прозрачность, вызываем: glDisable(GL_BLEND);

Вот и всё! Просто, да? Если мы выключили прозрачность, просто нужно включить её снова.
Нам не нужно вызывать glBlendFunc() снова, пока мы не хотим изменить факторы прозрачности.

Если вы не проходили урок текстурных матриц, советую вам обратить на него внимание.
Тогда вы сможете, совместив эти 2 урока, создать большой квадрат с текстурой воды и включить прозрачность. Это выглядит неплохо. А ещё можно увеличить количество полигонов в квадрате и заставить их двигаться… Может быть, я напишу об этом урок.

Надеюсь, этот урок помог вам освоить прозрачность.

Исходные коды к уроку