Геометрические примитивы в OpenGL
Разбор кода Triangle
Цвета многоугольников
Мы использовали для закрашивания фигуры чередование цветов. В действительности цвета задаются для вершин, а не для многоугольников. Согласно модели затенения (закрашивания) OpenGL, многоугольник может закрашиваться сплошным цветом (используя текущий цвет, выбранный при задании командой glVertex2f(x, y); последней вершины) или гладко затеняться с градиентным переходом цветов друг в друга, заданных для составляющих его вершин (создается градиент).
Строка
// Устанавливаем неструктурированный цвет модели затенения glShadeModel(GL_FLAT);
приказывает OpenGL заполнять многоугольник сплошным цветом, который будет текущим на момент задания последней вершины многоугольника. Именно поэтому мы смогли так просто менять текущий цвет с одного на другой перед указанием новой вершины веера треугольников. Если внутри указанной функции использовать ключ GL_SMOOTH, то OpenGL затенит треугольники плавно, пытаясь интерполировать цвета точек, находящихся между вершинами с заданным цветом, примерно так...
Удаление скрытых поверхностей
При включении эффекта глубины OpenGL заботится о том, чтобы наблюдатель не видел тех частей объекта, которые должны быть заслонены частями переднего плана. Проверка глубины - это эффективная технология удаления скрытых поверхностей и OpenGL выполняет соответствующие уточнения рисунка.
Схема проверки глубины проста. Когда пиксел рисуется, ему присваивается значение (глубина z ), означающее расстояние до положения наблюдателя, и это значение запоминается в буфере глубины. Когда позже в этой же точке нужно нарисовать другой пиксел, глубина z этого пиксела сравнивается с значением глубины ранее записанного пиксела. Если значение z нового пиксела больше, значит новая точка находится ближе к наблюдателю и заменяет предыдущую. В противном случае новый пиксел не рисуется и его значение глубины не запоминается. Глубины каждого изображенного на экране пиксела хранятся в участке памяти, называемом буфером глубины.
Чтобы активизировать проверку глубины, нужно вызывать такую функцию
glEnable(GL_DEPTH_TEST);
а для деактивизации - функцию
glDisable(GL_DEPTH_TEST);
В нашей программе включение/выключение проверки глубины выполняется с помощью флага bDepth.
Буфер глубины является в некотором смысле аналогом буфера цвета, только в буфере цвета содержатся коды цвета отображаемых на экране пикселов, а в буфере глубины - их глубина. При каждой новой визуализации сцены нужно обязательно очищать буфер глубины от значений глубин пикселов старой сцены, как и в буфере цвета - стирать атрибуты старого изображения. Это мы в нашей программе делаем командой
// Очистить окно и буфер глубины glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Проверка глубины просто необходима при создании трехмерных объектов из сплошных многоугольников для правильной их визуализации.
Отбор
Отбор (culling) является технологией выборочного отображения объекта за счет исключения из списка претендентов на визуализацию тех поверхностей, которые и так ни при каких условиях не будут видны. Это существенно повышает быстродействие процесса. Одной из разновидностей отбора является отбор задних граней многоугольников - удаление задних сторон поверхностей. OpenGL определяет лицевую и обратную стороны граней по направлению обхода. Как только OpenGL перед отображением грани обнаруживает, что многоугольник имеет направление обхода, противоположное установленному для лицевых граней, то эта грань считается невидимой и не обрабатывается для визуализации.
В нашей программе Triangle мы установили направление обхода для видимых граней по часовой стрелке и с таким же направлением обхода рисовали основание конуса. Но в таком случае лицевая сторона веера всех многоугольников, составляющих основание конуса, получилась направлена внутрь конуса. А обратная сторона веера всех треугольников основания направлена наружу и считается невидимой. Поэтому при включении отбора не обрабатывается системой, то есть остается невизуализированной. Чтобы исправить положение, нужно непосредственно перед рисованием второго веера треугольников изменить направление обхода командой
// Устанавливаем направление обхода против часовой стрелки glFrontFace(GL_CCW);
После этого веер треугольников основания конуса, повернутого к зрителю, будет считаться OpenGL лицевой стороной и все будет хорошо!
Отбор включен. Веер сформирован изначально как с противоположным видимому обходом (невидимой гранью внуть конуса) |
Отбор включен. Веер основания сформирован изначально как направленный лицевой стороной внутрь конуса |
|
Отбор выключен. Веер сформирован изначально как с противоположным видимому обходом (невидимой гранью внуть конуса, а лицевой - наружу) |
Отбор выключен. Веер основания сформирован изначально как направленный лицевой стороной внутрь конуса, но для наблюдателя визуализируется так, как будто внутренняя закрашенная сторона основания просвечивается наружу через это основание |
Отбор задних граней полезен при рисовании замкнутых, сплошных объектов или твердых тел. Технология визуализации при выключенном отборе позволяет сделать отображаемой и внутреннюю и наружную грани многоугольника, что полезно при рендеринге незамкнутых прозрачных объектов.
Каркасный режим и режим с заливкой
По умолчанию многоугольники рисуются в режиме сплошной заливки ( fill ). Но можно указать, чтобы они отображались как контуры граней или точки вершин. Функция glPolygonMode() устанавливает эти режимы отображения. Любой из режимов можно применить отдельно к рисованию лицевой или обратной сторонам граней или сразу к двум сторонам каждого многоугольника. В нашем коде это выглядит так
// Включить/Выключить каркас задней стенки if(bOutline) glPolygonMode(GL_BACK,GL_LINE); else glPolygonMode(GL_BACK,GL_FILL);