Области применения смешения цветов
В практических целях применяются не все возможные комбинации множителей смешения. В большинстве программ используются комбинации из небольшого набора. Ниже перечислены некоторые наиболее распространенные из них. 1) Допустим, требуется сформировать изображение, состоящее из перекрывающихся изображений двух разных сцен (с прозрачностью 50%). Сначала надо установить множитель source=GL_ONE и нарисовать первую сцену. Затем надо задать множители source=destination=GL_SRC_ALPHA и нарисовать вторую сцену с установленным альфа=0.5. Если надо получить смешение 75% первого изображения и 25% второго, то сначала надо нарисовать первое изображение, и затем – второе с альфа=0.25. При этом должны быть заданы множители GL_SRC_ALPHA (source) и GL_ONE_MINUS_SRC_ALPHA (destination). Эта пара множителей образует, вероятно, самую распространенную комбинацию при смешения цветов. 2) Для смешения в одинаковой пропорции трех различных изображений надо установить множитель destination=GL_ONE и множитель source=GL_SRC_ALPHA. Затем следует нарисовать каждое изображение с альфа=0.33. В данном случае каждое изображение будет иметь только треть исходной яркости, что особенно заметно в тех местах, где изображения не перекрываются. 3) Предположим, в графическом редакторе требуется реализовать кисть, которая позволяет при каждом мазке понемногу добавлять в изображение текущий цвет (скажем, каждый мазок добавляет по 10% цвета, при этом 90% изображения убирается). Для этого надо рисовать образ кисти с альфа=10% при установленных множителях source=GL_SRC_ALPHA и destination =GL_ONE_MINUS_SRC_ALPHA. Аналогичным образом можно реализовать инструмент "стерка", постепенно добавляющий к изображению цвет фона. 4) Допустим, надо нарисовать изображение с тремя полупрозрачными поверхностями, перекрывающимися произвольным образом, а позади них расположен непрозрачный фон. Пусть самая дальняя поверхность пропускает 80% света, следующая – 40%, а ближайшая к наблюдателю – 90%. Рисование этой сцены начинается с рисования фона с множителями source и destination по умолчанию. Затем надо задать множители source=GL_SRC_ALPHA и destination= GL_ONE_MINUS_SRC_ALPHA. После этого надо сначала нарисовать дальнюю поверхность с альфа=0.2, затем среднюю с альфа=0.6 и ближнюю с альфа=0.1.
Пример использования смешения цветов Ниже приведена функция display() из программы 6.3, в которой смешение цветов применяется для имитации прозрачности объектов. Смешение цветов и обработка альфа-компоненты замедляют работу OpenGL, поэтому их лучше включать только на время рисования прозрачных объектов, а затем отключать.
void CALLBACK display() { 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); glFlush(); } Фрагмент программы 6.3. Рисование полупрозрачного цилиндра.
При смешении цветов крайне важно, чтобы сначала рисовались дальние объекты, а затем ближние. Это объясняется тем, как в OpenGL выполняется тест глубины на основе z -буфера. Например, в программе 6.3 сначала рисуется сфера (более далекий объект), а затем цилиндр. При этом OpenGL выполняет следующие действия: 1) функция display() создает сферу; 2) для видимой части сферы тест глубины проходит успешно, т.к. сфера никакими объектами не закрывается; 3) в буфере рисуется сфера; 4) функция display() создает цилиндр; 5) для видимой части цилиндра тест глубины проходит успешно, т.к. поверхность цилиндра к наблюдателю ближе, чем сфера; 6) в буфере рисуется цилиндр, причем он накладывается на сферу с установленными параметрами смешения цветов и получается эффект прозрачности. Теперь рассмотрим, что происходит, если изменить порядок рисования объектов:
1) функция display() создает цилиндр; 2) для видимой части цилиндра тест глубины проходит успешно; 3) в буфере рисуется цилиндр; 4) функция display() создает сферу; 5) для всех вершин сферы тест глубины выполняется неудачно, т.к. сфера полностью закрыта цилиндром; 6) сфера в буфере не рисуется.
Туман Компьютерные изображения иногда выглядят нереально резкими и качественными. Резкость краев объектов уменьшается с помощью сглаживания. Еще одно средство для создания реалистичных изображений – добавление "тумана", который делает объекты менее четкими по мере увеличения расстояния от наблюдателя. Термином "туман" (fog) в OpenGL обозначается целая группа атмосферных эффектов, таких, как дымка, пасмурность, копоть и т.п. Например, туман часто используется в авиационных симуляторах. При включенном тумане цвет более далеких объектов постепенно переходит в цвет тумана. OpenGL позволяет задать цвет и плотность тумана (она определяет скорость, с которой образы объектов расплываются с расстоянием). Расчет тумана уменьшает скорость работы программы.
Использование тумана Для использования тумана сначала надо включить его, а затем настроить свойства. Включение выполняется вызовом glEnable(GL_FOG), а определение свойств –вызовами функции glFog*(): void glFog{if}{v}(GLenum pname, TYPEparam); Она позволяет выбрать цвет, плотность (density) и уравнение для расчета множителя тумана f, на который будет умножается цвет в цветовом буфере. Есть три возможных уравнения: GL_EXP: GL_EXP2: GL_LINEAR: У функции glFog*() параметр pname выбирает изменяемое свойство – GL_FOG_MODE (уравнение для расчета множителя), GL_FOG_COLOR (цвет), GL_FOG_DENSITY (плотность), GL_FOG_START (дальность начала тумана) или GL_FOG_END (дальность завершения тумана). Для свойства GL_FOG_MODE допустимы перечисленные выше значения GL_EXP (по умолчанию), GL_EXP2 или GL_LINEAR. Значения по умолчанию других параметров: density=1, start=0, end=1. Применение тумана показано в программе 6.4. Она рисует пять желтых чайников (из полированного золота), расположенных на разном расстоянии от наблюдателя. По нажатию левой кнопки мыши программа меняет уравнение для расчета множителя тумана.
#include <iostream.h>
#include <windows.h> #include <math.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glaux.h>
GLint fogMode;
void CALLBACK cycle_fog(AUX_EVENTREC*) { if (fogMode == GL_EXP) { fogMode = GL_EXP2; cout << "Fog mode is GL_EXP2\n"; } else if (fogMode == GL_EXP2) { fogMode = GL_LINEAR; cout << "Fog mode is GL_LINEAR\n"; glFogf(GL_FOG_START, 1.0); glFogf(GL_FOG_END, 5.0); } else if (fogMode == GL_LINEAR) { fogMode = GL_EXP; cout << "Fog mode is GL_EXP\n"; } cout.flush(); glFogi(GL_FOG_MODE, fogMode); }
void light_init() { float pos[] = { 0.0, 0.0, 1.0, 0.0 }; glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glLightfv(GL_LIGHT0, GL_POSITION, pos);
glEnable(GL_LIGHTING); glEnable(GL_LIGHT0);
glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE);
glEnable(GL_FOG); float fogColor[4] = { 0.5, 0.5, 0.5, 1.0 }; fogMode = GL_EXP; glFogi(GL_FOG_MODE, fogMode); glFogfv(GL_FOG_COLOR, fogColor); glFogf(GL_FOG_DENSITY, 0.35f); glClearColor(0.5, 0.5, 0.5, 1.0); }
void draw_red_teapot(float x, float y, float z) { float gold_amb[4] = { 0.25f, 0.22f, 0.06f, 1.00 }; float gold_diff[4] = { 0.35f, 0.31f, 0.09f, 1.00 }; float gold_spec[4] = { 0.80f, 0.72f, 0.21f, 1.00 }; float gold_shin = 83.2f;
glMaterialfv(GL_FRONT, GL_AMBIENT, gold_amb); glMaterialfv(GL_FRONT, GL_DIFFUSE, gold_diff); glMaterialfv(GL_FRONT, GL_SPECULAR, gold_spec); glMaterialf(GL_FRONT, GL_SHININESS, gold_shin);
glPushMatrix(); glTranslatef(x, y, z); auxSolidTeapot(1.0); glPopMatrix(); }
void CALLBACK display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); draw_red_teapot(-4.0, -0.5, -1.0); draw_red_teapot(-2.0, -0.5, -2.0); draw_red_teapot(0.0, -0.5, -3.0); draw_red_teapot(2.0, -0.5, -4.0); draw_red_teapot(4.0, -0.5, -5.0); glFlush(); }
void CALLBACK resize(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= (h*3)) glOrtho(-6.0, 6.0, -2.0*((float)h*3)/(float)w, 2.0*((float)h*3)/(float)w, 0.0, 10.0); else glOrtho(-6.0*(float)w/((float)h*3), 6.0*(float)w/((float)h*3), -2.0, 2.0, 0.0, 10.0);
gluLookAt(0,0,3, 0,0,0, 0,1,0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); }
void main() { auxInitDisplayMode(AUX_SINGLE | AUX_RGBA | AUX_DEPTH); auxInitPosition(0, 0, 450, 150); auxInitWindow("Лекция 6. Программа 6.4"); light_init(); auxMouseFunc(AUX_LEFTBUTTON, AUX_MOUSEDOWN, cycle_fog); auxReshapeFunc(resize); auxMainLoop(display); } Программа 6.4. Пять чайников в тумане.
Сводка результатов OpenGL позволяет задавать свойства материала, который приписывается объектам сцены. Значения этих свойств используются в модели освещения при вычислении цвета пикселей изображения сцены. Основными свойствами материала являются компоненты диффузного, рассеянного и зеркального отражения. Эти свойства напоминают свойства источников света. Кроме того, у материала есть свойство "блеск" и может быть свойство "излучаемый свет", который влияет только на вид объекта и не играет роли нового источника света. В лекции приведена таблица со свойствами материала, которые соответствуют некоторым реальным материалам.
Значения цвета в OpenGL задаются четырьмя компонентами RGBA. Четвертая компонента A (альфа) используется в служебных целях для расчета цвета пикселей в режиме смешения цветов. В лекции описано, как применить режим смешения цветов для реализации одного из наиболее распространенных эффектов освещения – прозрачности. Компьютерные изображения в некоторых случаях выглядят чересчур высококачественными и нереалистичными. Одно из простейших средств повышения реалистичности изображений – туман. OpenGL позволяет задать ряд свойств тумана, например, цвет и плотность. Когда туман включен, то по мере удаления от наблюдателя объекты постепенно расплываются и закрашиваются цветом тумана. Упражнения Упражнение 1 На основе фрагмента программы 6.1 напишите программу, рисующую 12 сфер с различными свойствами материала. Сферы должны располагаться в три строки, которые отличаются рассеянной составляющей: Cтрока 1 – рассеянная компонента отсутствует, т.е. равна {0.0, 0.0, 0.0, 0.0}; Cтрока 2 – серая рассеянная компонента, {0.7, 0.7, 0.7, 1.0}; Cтрока 3 – желтая рассеянная компонента, {0.8, 0.8, 0.2, 1.0}. Свойства материала в разных столбцах задаются аналогично фрагменту 6.1: Столбец 1 – синяя диффузная составляющая { 0.1, 0.5, 0.8, 1.0 }, зеркальная отсутствует, блеска нет; Столбец 2– синяя диффузная, белая зеркальная { 1.0, 1.0, 1.0, 1.0 } и малый блеск 5.0; Столбец 3 – синяя диффузная, белая зеркальная, большой блеск 100.0; Столбец 4 – синяя диффузная, нет зеркальной, нет блеска, но есть зеленоватая излучаемая компонента {0.3, 0.2, 0.2, 0.0}. Обратите внимание, как меняется вид сфер, например, светящиеся сферы выглядят довольно яркими и однородными (т.к. нет зеркальной составляющей).
Упражнение 2 Выполните программу 6.2 и затем добавьте в нее обработчики событий для изменения блеска и излучаемой компоненты.
Упражнение 3 На основе фрагмента программы 6.3 разработайте программу для рисования сферы внутри полупрозрачного цилиндра. Измените ее так, чтобы цилиндр и сфера рисовались внутри третьего объекта (например, полупрозрачной сферы).
Упражнение 4 Выполните программу 6.4. Выясните, как влияют на вид объектов режим автоматического вычисления нормалей и автоматической нормализации нормалей: glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); Попробуйте назначить объектам несколько различных материалов, приведенных в табл. 6.2.
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|