Подготовка изображения Разработаем
COGView: : DrawScene ()
{
//====== Создание списка рисующих команд
glNewList (1, 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++)
//====== Связанные полигоны начинаются
//====== на каждой полосе вновь
if (!m_bQuad)
glBegin (GLJ2UAD_STRIP) ;
//====== Цикл прохода вдоль оси X
for (UINT x=0; x<nx; x++)
// i, j, k, n — 4 индекса вершин примитива при
// обходе в направлении против часовой стрелки
int j = i + m_xSize, // Индекс узла с большим Z
k = j+1/ // Индекс узла по диагонали
n = i+1; // Индекс узла справа
//=== Выбор координат 4-х вершин из контейнера
float
xi = m_cPoints [i] .x,
yi = m_cPoints [i] .у,
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;
//====== Задание вектора нормали
glNorma!3f (vx,vy,vz);
// Ветвь создания несвязанных четырехугольников
if (m_bQuad)
{
//==== Обход вершин осуществляется
//==== в направлении против часовой стрелки
glColorSf (0.2f, 0.8f, l.f);
glVertexSf (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) ;
glColor3f (0.7f, 0.8f, l.f);
glVertexSf (xn, yn, zn) ;
}
else
//==== Ветвь создания цепочки четырехугольников
{
glColor3f (0.9f, 0.9f, l.0f);
glVertexSf (xn, yn, zn) ;
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). В связи с этим равны нулю компоненты az и bх векторов боковых сторон в формуле для нормали (см. раздел «Точное вычисление нормалей» в предыдущем уроке).