Chapter 4
Полезные и бесполезные мелочи

4.4  Прозрачность

     С помощью четвертого компонента цвета можно получать различные эффекты наложения объктов друг на друга, наложения цветов и т.п. Здесь я расскажу о наиболее нужном и распрострененном эффекте - прозрачности объектов. Для того, чтобы разрешить обрабатывать четвертый компонент цвета вы должны вызвать функцию glEnable с аргументом GL_ALPHA_TEST. Для получения требуемого эффекта прозрачности нужно разрешить наложение цветов - glEnable(GL_BLEND) и установить алгоритм, по которуму будут смешиваться два цвета - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA). Учтите, что эти режимы очень затормаживают вывод изображения, поэтому я не рекомендую устанавливать эти режимы глобально, для воспроизведения всех объектов. Выделите из ваших объектов те, которым требуется этот режим, включайте и отключайте его своевременно. Именно поэтому, эти тесты я разместил в функции display. Создайте новый проект с именем transperence и отредактируйте функцию display, как показано ниже.

void CALLBACK display(void)
{
 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

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

  glColor4d(1,0,0, 1);
  auxSolidSphere( 1 );

  glColor4d(0,1,0, 0.6);
  auxSolidCylinder(2,3);

  glDisable(GL_BLEND);
  glDisable(GL_ALPHA_TEST);

  auxSwapBuffers();
}

     В заключение, добавлю, что если вы поменяете местами создание цилиндра и сферы, то никакого эффекта прозрачности не увидите. Это не баг, а фича - так задумано. Секрет прост: вы должны сначала рисовать дальние объекты, а потом ближние. Связано это с тем, что выполняется тест глубины. Теперь смотрите, что получается. Если вы сначала рисуете сферу(она удалена), а потом цилиндр, то выполняется это следующим образом.

  1. Создаем сферу.
  2. Выполняется тест глубины успешно, т.к. цилиндра пока нет.
  3. В буфере рисуется сфера.
  4. Создаем цилиндр.
  5. Выполняется тест глубины успешно, т.к. стенка цилиндра ближе, чем сфера.
  6. В буфере рисуется цилиндр, он закрывает сферу с учетом прозрачности.

Теперь смотрим, что происходит, если сначала нарисовать цилиндр, потом сферу.

  1. Создаем цилиндр.
  2. Выполняется тест глубины успешно.
  3. В буфере рисуется цилиндр.
  4. Создаем сферу.
  5. Выполняется тест глубины аварийно, т.к. сфера создается за цилиндром.
  6. В буфере ничего не рисуется.

В последнем случае вы увидите один цилиндр.


Исходный файл смотрите здесь. Исполняемый файл здесь.