Туман
Еще одна мелочь, которую мы рассмотрим - это включение тумана. За основу возьмем нашего снеговика. Надо сказать, что ведет туман себя довольно странно. Если его цвет установить белым, то при увеличении плотности тумана снеговик становится полностью белым, причем даже те его места, которые изначально были черными, т.к. не освещались. Когда я установил цвет тумана темно-серым - (0.25, 0.25, 0.25), то при увеличении плотности не освещенные его части как им и положено оставались черными, а видимые теряли яркость. Я скорее охарактеризовал бы средство тумана, как средство для изменения яркости, потому как на реальный туман, это к сожалению, не похоже. Итак, создайте новый проект с именем fog, скопируйте snowman.c в fog.c. Для того чтобы включить туман и поэкспериментировать с его влиянием на изображение мы добавим две функции, которые будут обрабатывать события от стрелок вверх\вниз на клавиатуре. Код этих функций выглядит так, включите его сразу после включения заголовочных файлов:
float density; void CALLBACK Key_UP(void ) { density+=(float)0.1; glFogf(GL_FOG_DENSITY, density); } void CALLBACK Key_DOWN(void ) { density-=(float)0.1; glFogf(GL_FOG_DENSITY, density); }
Я также ввел глобальную переменную density, в ней хранится плотность тумана. При нажатие стрелок вверх\вниз будет вызываться соответствующая функция и будет изменено значение тумана. Снеговик у нас все время перерисовывается, поэтому при следующей отрисовке кадра значение тумана обновится. Теперь надо отредактировать функцию main, добавленный код выделен серым фоном:
void main() { float pos[4] = {3,3,3,1}; float dir[3] = {-1,-1,-1}; float fogcolor[4] = {0.25,0.25,0.25,1}; // цвет тумана auxInitPosition( 50, 10, 400, 400); auxInitDisplayMode( AUX_RGB | AUX_DEPTH | AUX_DOUBLE ); auxInitWindow( "Snowman" ); auxIdleFunc(display); auxReshapeFunc(resize); auxKeyFunc(AUX_UP, Key_UP); // устанавливаем обработчик auxKeyFunc(AUX_DOWN, Key_DOWN); // стрелок вверх/вниз glEnable(GL_FOG); // разрешаем туман glGetFloatv(GL_FOG_DENSITY, &density); // получаем значение плотности glFogfv(GL_FOG_COLOR, fogcolor); // устанавливаем цвет тумана glEnable(GL_ALPHA_TEST); glEnable(GL_DEPTH_TEST); glEnable(GL_COLOR_MATERIAL); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glLightfv(GL_LIGHT0, GL_POSITION, pos); glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir); auxMainLoop(display); }
Я полагаю здесь все ясно, прокомментирую тут только одну функцию:
glGetFloatv(GL_FOG_DENSITY, &density);
С помощью этой функции я получаю значение плотности тумана, установленное по умолчанию. Первый аргумент этой функции указывает OpenGL значение какого параметра мы хотим получить. Второй аргумент - это адрес в памяти куда будет записано значение данного параметра.