
- •Содержание
- •Введение
- •1 Лабораторная работа №1 opengl и графические примитивы
- •1.1 Теоретические положения
- •1.1.1 Структура OpenGl-проекта
- •1.1.2 Работа с графическими примитивами
- •1.1.2.1 Точки
- •1.1.2.2 Линии
- •1.1.2.3 Треугольники
- •1.1.2.4 Четырехугольники и многоугольники
- •1.1.2.5 Массивы вершин и цветов
- •1.1.2.6 Область вывода
- •1.2 Практика
- •1.2.1 Общее задание
- •1.2.2 Варианты индивидуального задания
- •2 Лабораторная работа №2 Матрицы и геометрические преобразования
- •2.1 Теоретические положения
- •2.1.1 Системы координат OpenGl
- •2.1.2 Видовые преобразования
- •2.1.3 Ориентация
- •2.1.4 Трехмерные примитивы
- •2.2 Практика
- •2.2.1 Общее задание
- •2.2.2 Варианты индивидуального задания
- •3 Лабораторная работа №3 Проекции, источники света, материалы
- •3.1 Теоретические положения
- •3.1.1 Виды плоских проекций
- •3.1.1.1 Ортографическая проекция
- •3.1.1.2 Одноточечная перспективная проекция
- •3.1.2 Освещение объектов
- •3.1.2.1 Нормали и грани
- •3.1.2.2 Материалы
- •3.1.2.3 Источники света
- •3.1.2.3 Модели освещения и затенения
- •3.2 Практика
- •3.2.1 Общее задание
- •3.2.2 Варианты индивидуального задания
- •4 Лабораторная работа №4 Отсечение и прозрачность
- •4.1 Теоретические положения
- •4.1.1 Принадлежность пикселей контексту воспроизведения
- •4.1.2 Отсечение
- •4.1.3 Прозрачность
- •4.2 Практика
- •4.2.1 Общее задание
- •5 Лабораторная работа №5 Трафареты и глубина
- •5.1 Теоретические положения
- •5.1.1 Трафарет
- •5.1.2 Глубина
- •5.2 Практика
- •5.2.1 Общее задание
- •6 Лабораторная работа №6 Текстуры
- •6.1 Теоретические положения
- •6.1.2 Загрузка графического файла в память
- •6.1.3 Создание имени-идентификатора текстуры
- •6.1.4 Установка идентификатора в активное положение
- •6.1.5 Создание текстуры в памяти
- •6.1.6 Установка параметров текстуры
- •6.1.7 Установка параметров взаимодействия текстуры с объектом
- •6.1.8 Связывание координат текстуры с объектом
- •6.2 Практика
- •6.2.1 Общее задание
- •7 Список литературы
- •Приложение а
- •Приложение б шаблон opengl-проекта «basis»
- •Приложение в Синтаксис команд и типы данных OpenGl
- •Приложение г Пример двумерного рисунка
- •Приложение д Положение источников света
4.2 Практика
4.2.1 Общее задание
Создать OpenGL проект с именем «KGLab4» на основе шаблона проекта «Basis» (см. прил. Б). Включить рабочие файлы проекта «Basis» в новый проект с именем «KGLab4.сpp» «KGLab4.h». Установить любой цвет фона и заголовок окна, скомпоновать и запустить программу на выполнение.
Продемонстрировать работу теста отсечения и теста прозрачности в применении к объектам, созданным в лабораторной работе №3. (Задать собственный прямоугольник отсечения. Задать собственные значения альфа для некоторых частей составных фигур.)
5 Лабораторная работа №5 Трафареты и глубина
Цель работы: приобрести практический навык работы с тестами трафареты и глубина.
5.1 Теоретические положения
5.1.1 Трафарет
Наложение трафарета, подобно z-буферизации разрешает или блокирует рисование на пиксельном уровне. Рисование осуществляется в плоскости трафарета, для чего применяются примитивы, после этого воспроизведение образов осуществляется использованием буфера трафарета, чтобы замаскировать часть экрана. Наложение трафарета обычно используется в многопроходных алгоритмах воспроизведения для реализации специальных эффектов, таких как отбеливание, оконтуривание и стереовоспроизведение.
Тест трафарета позволяет отбросить фрагмент, базируясь на результате сравнения значения в буфере трафарета с задаваемым ссылочным значением. Выполнение теста разрешается и блокируется командами glEnable/glDisable с аргументом GL_STENCIL_TEST. Для проведения этого тестирования в OpenGL предусмотрены две команды, одна из которых отвечает за сравнение – glStencilFunc, а вторая позволяет определить действия, базирующиеся на результате проверки трафарета, – glStencilOp.
Рассмотрим каждую из них.
void glStencilFunc(
GLenum func,
Glint ref,
GLuint mask)
Эта команда позволяет определить в параметре func функцию сравнения значения хранящегося в буфере трафарета (stencil) с некоторым задаваемым (параметр ref). Сравнение, однако, осуществляется не прямо, а посредством некоторого дополнительного значения, определяемого дополнительным параметром (mask). Функция сравнения может принимать одно из восьми значений (таблица 5.1).
Таблица 5.1
Константа |
Тест завершается положительно |
GL_NEVER
GL_LESS
GL_EQUAL
GL_LEQUAL
GL_GREATER
GL_NOTEQUAL
GL_GEQUAL
GL_ALWAYS |
Никогда
Если (ref&mask)<(stencil&mask)
Если (ref&mask)=(stencil&mask)
Если (ref&mask)<=(stencil&mask)
Если (ref&mask)>(stencil&mask)
Если (ref&mask)≠(stencil&mask)
Если (ref&mask)>=(stencil&mask)
Всегда |
Параметр ref задает значение ссылки для тестирования трафарета и может принимать любые значения из диапазона [0,2 - 1], где n – число битовых плоскостей в соответствующем буфере. Параметр mask задает ссылку, которая поразрядно умножается (логическое И) на значение ссылки и на хранящееся значение трафарета.
Изначально тест трафарета заблокирован. Если буфера трафарета нет, то модификация трафарета не может произойти и это трактуется как положительный результат теста трафарета.
void glStencilOp(
GLenum fail,
GLenum zfail,
GLenum zpass)
Команда позволяет определить действия, которые выполнит OpenGL в случае отрицательного результата теста трафарета, а также те, которые будут выполнены по результатам проведения тестирования глубины. Параметр fail задает действие, которое будет выполняться, если тест трафарета дал отрицательный результат. Допускаются шесть символических констант (таблица 5.2).
Таблица 5.2
Константа |
Действие |
GL_KEEP GL_ZERO
GL_REPLACE
GLINCR
GLDECR
GLINVERT |
Сохранить текущее значение в буфере Установить значение буфера трафарета равным нулю Установить значение буфера трафарета значению ref, определенному командой glStencilFunc Увеличить текущее значение буфера трафарета и привести в соответствие с максимально допустимым значением 2m-1, где m – число плоскостей в буфере трафарета Уменьшить текущее значение буфера трафарета и привести в соответствие с нулем Поразрядно инвертировать текущее значение буфера трафарета |
Два других параметров zfail и zpass определяют действия, которые будут предприняты в случае положительного результата выполнения теста трафарета: zfail – в случае отрицательного, и zpass – в случае положительного завершения теста глубины. Допускаются те же символические константы, что и перечисленные в предыдущей таблице.
Предположим, что нужно «вырезать» в окружности прямоугольное окно, чтобы открыть доступ к находящемуся за ней изображению, аналогично тому, что изображено на рис 5.1.
Рис. 5.1 Трафарет
Каковы должны быть наши действия? Рассмотрим один из возможных вариантов.
Определить значение в буфере трафарета для фона, например, glClearStencil(0x01).
Нарисовать окружность, изменив для нее значение в буфере трафарета, например 0x02.
Определить прямоугольник «вырезки» , установив для него значение в буфере трафарета равным 0x01 – такое же, как у фона.
Нарисовать желаемый рисунок, определив в качестве параметров для успешного прохождения теста трафарета значение 0x01.
Таким образом, в буфере трафарета должно быть нарисовано что-то аналогичное рис. 5.2.
Рис. 5.2 Пример буфера трафарета
Фрагмент программы:
static void Int (void)
// Определяем цвет фона и создаем массивы вершин и цветов окружности
// Определяем значение, в которое будет присвоено буферу трафарета
/* Это значение для фона */ glClearStencil(Oxl);
/* Определяем значение маски трафарета */ glStencilMask(OxFF);
}
static void CALLBACK DrawScene (GLenum mode)
// Разрешаем проведение теста трафарета для изображения
//в правой части окна
if (mode == GLJTRUE)
glEnable(GL_STENCIL_TEST);
// Определяем функцию и значения для сравнения; окружность рисуется всегда
glStencilFunc(GL_ALWAYS, 0x02, 0x02);
// Определяем действия, которые будут выполняться в случае положительного результата – второй и третий аргумены; первый нас не интересует, т.к. тест всегда проходит; в результате замены для окружности в буфере трафарета будет храниться значение 0x02 – значение второго аргумента предыдущей команды
glStencilOp(GL_KEEP, GL_REPLACE,GL_REPLACE) ;
// Воспроизводим окружность
//Меняем параметры теста трафарета, прямоугольник вырезки рисоваться не должен
// Важно только изменить для него значение в буфере трафарета на 0x01
glStencilFunc(GL_ALWAYS, 0x01, 0x01);
// Определяем область вырезки
glBegin(GL_QUADS);
glEnd();
//Еще раз меняем параметры теста; следующий объект будет рисоваться только в тех oбластях, для которых значение в буфере трафарета равно 0x01
glStencilFunc(GL_EQUAL, 1, 1);
// Рисуем ромб
glShadeHodel(GL_FLAT);
glBegin(GL_QUADS);
glEnd();
glShadeModel(GL_SMOOTH);
// Блокируем тест трафарета
glDisable(GL_STENCIL_TEST);
}
static void CALLBACK Draw(void)
{// Очищаем не только буфер цвета, но и буфер трафарета
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// Рисуем в левой части окна тест трафарета заблокирован
DrawScene(GL_FALSE);
// Рисуем в правой части окна тест трафарета разрешен
glcolor3f(0.5f, 0.0f, 0.5f);
DrawScene(GL TRUE);
}