на начало
На главную страницу
Форум   

Статья :: Подготовка сцены OpenGL

 

Подготовка сцены OpenGL

Считая, что данные о координатах точек изображаемой поверхности уже известны и расположены в контейнере m_cPoints, напишем коды функции DrawScene, которая создает изображение поверхности и запоминает его в виде списка команд OpenGL. Как вы помните, одним из технологических приемов OpenGL, которые ускоряют процесс передачи (rendering), является предварительная заготовка изображения, то есть запоминание и компиляция списка рисующих команд.

Напомним, что отображаемый график представляет собой криволинейную поверхность (например, равного уровня температуры). Ось Y, по которой откладываются интересующие пользователя значения функции, направлена вверх. Ось X направлена вправо, а ось Z — вглубь экрана. Часть плоскости (X, Z), для точек которой известны значения Y, представляет собой координатную сетку. Изображаемая поверхность расположена над плоскостью (X, Z), а точнее, над этой сеткой. Поверхность можно представить себе в виде одеяла, сшитого из множества лоскутов. Каждый лоскут мы будем задавать в виде четырехугольника, как-то ориентированного в пространстве. Все множество четырехугольников поверхности также образует сетку. Для задания последовательности четырехугольников в OpenGL существует пара команд:

glBegin (GL_QUADS) ;

// Здесь располагаются команды, задающие четырехугольники

glEnd() ;

Четырехугольник задается координатами своих вершин. При задании координат какой-либо вершины, например, командой givertex3f (х, у, z);, можно сразу же определить ее цвет, например, командой gicolor3f (red, green, blue);. Если цвета вершин будут разными, а режим заполнения равен константе GL_FILL, то цвета внутренних точек четырехугольника примут промежуточное значение. Конвейер OpenGL производит аппроксимацию цвета так, что при перемещении от одной вершины к другой он изменяется плавно.

Режим растеризации или заполнения промежуточных точек графического примитива задается командой glPolygonMode. OpenGL различает фронтальные (front-facing polygons), обратные (back-facing polygons) и двухсторонние многоугольники. Режим заполнения их отличается, поэтому первый параметр функции glPolygonMode должен определить тип полигона (GL_FRONT, GL_BACK или GL_FRONT_AND_BACK).

Второй параметр собственно и определяет режим заполнения. Он может принимать значение GL_POINT, GL_LINE или GL_FILL. Первый выбор даст лишь обозначение примитива в виде его вершин, второй — даст некий скелет, вершины будут соединены линиями, а третий заполнит все промежуточные точки примитива. По умолчанию принят режим GL_FILL и мы получаем сплошной лоскут.'Если в качестве первого параметра задать GL_FRONT_AND_BACK, то изменения второго параметра будут касаться обеих поверхностей одеяла. Другие сочетания дают на первый взгляд странные эффекты: так, если задать сочетание (GL_FRONT, GL_LINE), то лицевая сторона одеяла будет обозначена каркасом (frame view), а изнаночная по умолчанию будет сплошной (GL_FILL). Поверхность при этом будет полупрозрачна.

Мы решили оставить неизменным значение GL_FRONT_AND_BACK для первого параметра и дать пользователю возможность изменять режим заполнения (второй параметр glPolygonMode) по его желанию. Впоследствии внесем эту настройку в диалог свойств СОМ-объекта, а результат выбора пользователя будем хранить в переменной m_FillMode. С учетом сказанного введите коды реализации функции DrawScenel

//====== Подготовка изображения

void COpenGL::DrawScene()

{

//====== Создание списка рисующих команд

glNewListd, GL_COMPILE) ;

//====== Установка режима заполнения

//====== внутренних точек полигонов

glPolygonMode(GL_FRONT_AND_BACK, m_FillMode);

//====== Размеры изображаемого объекта

UINTnx = m_xSize-l, nz = m_zSize-l;

//====== Выбор способа создания полигонов

if (m_bQuad)

glBegin (GL QUADS);

//=== Цикл прохода по слоям изображения (ось Z) for (UINT z=0, i=0; z<nz; z++, i++)

//=== Связанные полигоны начинаются

//=== на каждой полосе вновь if (!m_bQuad)

glBegin(GL_QUAD_STRIP) ;

//=== Цикл прохода вдоль оси X

for (UINT x=0; x<nx; х++, i++)

{

// i, j, k, n — 4 индекса вершин примитива при

// обходе в направлении против часовой стрелки

int j = i + m_xSize,

// Индекс узла с большим Z

k = j+1, // Индекс узла по диагонали

n = i+1; // Индекс узла справа

// Выбор координат 4-х вершин из контейнера

float

xi = m_cPoints [i] . х,

yi = m_cPoints [i] .y,

zi = m_cPoints [i] . z,

xj = m_cPoints [ j ] .x,

yj = m_cPoints [ j ] .y,

zj = m_cPoints [ j ] .z,

xk = m_cPoints [k] .x,

yk = m_cPoints [k] . y,

zk = m_cPoints [k] . z,

xn = m_cPoints [n] .x,

yn = m_cPoints [n] .y,

zn = m_cPoints [n] . z,

//=== Координаты векторов боковых сторон

ах = xi-xn,

ay = yi-yn,

by = yj-yi,

bz = zj-zi,

//=== Вычисление вектора нормали

vx = ay*bz,

vy = -bz*ax,

vz = ax*by,

//=== Модуль нормали

v = float (sqrt (vx*vx + vy*vy + vz*vz) ) ;

//====== Нормировка вектора нормали

vx /= v;

vy /= v;

vz /= v;

//====== Задание вектора нормали

glNormalSf (vx,vyfvz);

// Ветвь создания несвязанных четырехугольников

if (m_bQuad)

{

//====== Обход вершин осуществляется

//=== в направлении против часовой стрелки

glColorSf (0.2f, 0.8f, l.f);

glVertex3f (xi, yi, zi);

glColor3f <0.6f, 0.7f, l.f);

glVertexSf (xj, уj, zj);

glColorSf (0.7f, 0.9f, l.f);

glVertexSf (xk, yk, zk);

glColorSf (0.7f, 0.8f, l.f);

glVertexSf (xn, yn, zn); }

else

// Ветвь создания цепочки четырехугольников

{

glColor3f (0.9f, 0..9f, l.Of);

glVertexSf (xi, yi, zi);

glColorSf (0.5f, 0.8f, l.0f);

glVertexSf (xj, уj, zj);

}

}

//====== Закрываем блок команд GL_QUAD_STRIP

if (!m_bQuad)

glEnd(); }

//====== Закрываем блок команд GL_QUADS

if (m_bQuad) glEnd() ;

//====== Закрываем список команд OpenGL

glEndList ();

}

Для осмысления алгоритма надо учитывать, что количество узлов сетки вдоль того или иного направления (X или Z) на единицу больше количества промежутков (ячеек). Кроме того, надо иметь в виду, что при расчете освещения OpenGL учитывает направление нормали (перпендикуляра) к поверхности. Реалистичность изображения во многом достигается благодаря аккуратному вычислению нормалей. Нормаль является характеристикой вершины (узла сетки).

 

Подготовка сцены OpenGL

страницы в данном разделе 
Урок 9. Трехмерная графика в проекте ATL Трехмерная графика в проекте ATL
Требования OpenGL Введение методов в интерфейс IOpenGL
Ручная коррекция класса Введение обработчиков сообщений Windows
Управление цветом фона Подготовка сцены OpenGL
Файловые операции Установка освещения
Страницы свойств Конструируем облик страницы свойств
Взаимодействие классов Создание контейнера на базе MFC
Класс-оболочка Управление с помощью объекта класса-оболочки


Содержание сайта (выборка)
Apache
Протоколы TCP/IP (принципы, протоколы и архитектура)



PHP, PELR, JSP
PHP
JavaServer Pages (JSP)

Базы данных
Основы mysql
СУБД INFORMIX
СУБД POSTGRES
Основы проектирования реляционных баз данных

HTML, javascript
Спецификация HTML 4.01
Каскадные Таблицы Стилей, Уровень 2
Клиентский JavaScript. Справочник.
JavaScript руководство пользователя
Серверный JavaScript 1.4. Руководство по Использованию.

Паскаль, C, C++, C#
GCC (примеры)
FAQ Валентинa Озеровa DELPHI
C



 
© faq.pp.ru, справочник программиста