Array ( )
Вход:




Главная | OpenGL | GLSL | AI | Сеть | Примеры | Библиотека

OpenGL: Туман






Дым - это очень полезный и красивый эффект, при этом совсем не сложный.
Исходные коды возьмите из урока "Камера: часть 5".

Переходим к редактированию main.cpp:

// После всех инклудов добавим 2 переменных:
float g_FogDensity = 0.2f;          // Плотность дыма
bool  g_bFog = true;                // Включен или выключен дым




// Изменяем функцию Init(); включим в ней дым. Прежде всего нужно выбрать
// цвет дыма. Так как это потенциально цвет RGBA, нужно установить 4 значения.
// По умолчанию они = (0,0,0,0), и нам нужно изменить их.
// Помещаем наши цвета в массив, т.к. ф-я glFogfv принимает их в таком виде.
 
float fogColor[4] = {0.0f,0.0f,1.0f,1.0f};

// Установим цвет мира таким же, как цвет тумана:
glClearColor(0, 0, 1, 1);  
 
// Передаём OpenGL массив цветов:
glFogfv(GL_FOG_COLOR, fogColor);

// Теперь, имея цвет дыма, установим его режим. Я выбрал GL_EXP2, но по умолчанию
// установлен GL_EXP. Ещё есть GL_LINEAR. Попробуйте все, чтобы наглядно понять их.
// Смысл в том, что они просчитываются по-разному. Мне кажется, что "экспотенциальный"
// дым выглядит лучше всего. Его формула: (f=e^(-density * Z), где Z - позиция камеры.

glFogi(GL_FOG_MODE, GL_EXP2);// Изменим плотность дыма. По умолчанию она равна единице, но мы начнем с 0.2f:
glFogf(GL_FOG_DENSITY, g_FogDensity);

// FOG_HINT - опция, устанавливающая, как именно будет отрисован дым.
// Нам всё равно, так мы и скажем %) GL_DONT_CARE даёт возможность OpenGL
// выбрать, рисовать вершинный и пикселный дым. На выбор есть 2 опции: GL_FASTEST и GL_NICEST
glHint(GL_FOG_HINT, GL_DONT_CARE);

// Это важная часть. Тут мы устанавливаем расстояние от нашей камеры, на котором будет
// начинатся дым. Пространство вне START и END будет окрашено цветом дыма. Я обычно ставлю
// дальнее значение таким же, как и дистанция взгляда. Минимальное по умолчанию 0,
// и мы не будем его изменять.
glFogf(GL_FOG_START, 0);

// значение END по умолчанию единица, увеличим его:
glFogf(GL_FOG_END, 10.0f);

// Наконец, инициализировав все необходимое, включим дым:
glEnable(GL_FOG);




// Следующие изменения нужно внести в функцию WinProc, в секцию WM_KEYDOWN:
case WM_KEYDOWN:
    switch (wParam)
    {
        // Ниже мы дадим возможность пользователю увеличивать и уменьшать
        // плотность дыма нажатием '+' и '-'. После увеличения плотности
        // нужно отослать новую информацию OpenGL вызовом glFogf().
        // В функцию передаётся флаг GL_FOG_DENSITY и новая плотность.

        case VK_ESCAPE:
            PostQuitMessage(0);
                break;

            case VK_ADD:    // Если нажат плюс
                g_FogDensity += 0.015f; // Увеличиваем плотность
                glFogf(GL_FOG_DENSITY, g_FogDensity);   // Передадим её OpenGL
                if(g_FogDensity > 1) g_FogDensity = 1;
                break;

            case VK_SUBTRACT:       // Если нажат минус
                g_FogDensity -= 0.015f; // Уменьшим плотность
                glFogf(GL_FOG_DENSITY, g_FogDensity);   // Передадим её OpenGL
                // Убедимся, что не менее 0:
                if(g_FogDensity < 0) g_FogDensity = 0;
                break;

            case 'F':   // Если нажата "F"
                g_bFog = !g_bFog;// Установим переключатель в противоположное

                if(g_bFog)  // если включен дым
                    glEnable(GL_FOG);
                else        // иначе
                    glDisable(GL_FOG);
                break;
        }
        break;
//////////////////////////////////////////


На этом всё. Пройдемся ещё раз по пунктам:

1) Нужно установить способ генерации дыма этой функцией:
glFogi(GL_FOG_MODE, GL_EXP2);

2) Передаём OpenGL массив цвета дыма:
glFogfv(GL_FOG_COLOR, fogColor);

3) Устанавливаем плотность дыма:
glFogf(GL_FOG_DENSITY, g_FogDensity);

4) Способ создания дыма (GL_NICEST/GL_FASTEST/GL_DONT_CARE):
glHint(GL_FOG_HINT, GL_DONT_CARE);

5) Передаём OpenGL ближнюю и дальнюю дистанции отрисовки дыма:
glFogf(GL_FOG_START, 0);
glFogf(GL_FOG_END, 10.0f);

6) И, наконец, включаем дым:
glEnable(GL_FOG);








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




Комментарии:

Войдите, чтобы оставить комментарий:












Яндекс.Метрика
 Яндекс цитирования.