Иллюстрированный самоучитель по Visual Studio .NET

Штриховка линий. Штриховка полигонов.

Функцию OnDraw замените целиком. Так же поступайте и дальше. Следите лишь за изменениями в функциях main, OnSize и init, которые понадобятся при радикальной смене режима передачи (rendering). Позже мы перейдем к передаче трехмерной графики, а пока режим тот же – двухмерная графика:

void _stdcall OnDraw()
{
//====== Стираем окно
glClear (GL_COLOR_BUFFER_BIT);
//====== Цвет фона (синеватый)
glColor3f (0.3f, 0.3f, 1.);
//== Рисуем сначала unstippled rectangle (без узора)
//== Rect – это тоже полигон
glRectf (20., 20., 115., 120.);
glColor3f (1., 0., 0.); // Меняем цвет на красный
glEnable (GL_POLYGON_STIPPLE); // Включаем штриховку
glPolygonStipple (gStrip); // Задаем узор
glRectf (120., 20., 215., 120.); // Рисуем
glColorSf (O.,0.,0.); // Меняем цвет на черный
glPolygonStipple (gSpade);
// Меняем узор glRectf (220., 20., 315., 120.);
glPolygonStipple (gStrip); // Меняем узор
glColor3f (0., 0.6f, 0.3f);
glRectf (320., 20., 415., 120.);
//== Готовимся заполнить более сложный, невыпуклый
//== (nоn convex) полигон
glPolygonStipple (gSpade);
glColorSd (0.6, O.f, 0.3f);
//======= Шесть вершин по три координаты
float c[6][3] =
{
420.,120.,0.,
420.,70.,0.,
470.,20.,0., 520., 70.,0.,
520.,120.,0.,
470.,100.,0.
};
//== Здесь мы специально выбираем nоn convex полигон,
//== чтобы увидеть как плохо с ним обходится OpenGL
glBegin (GL_POLYGON);
for (int i=0; i<6; i++)
glVertex3fv(c[i]);
glEnd();
glDisable (GL_POLYGON_STIPPLE);
glFlush ();
}

Запустите и убедитесь в том, что последний полигон потерял одну точку. Затем замените цикл задания его вершин на:

for (int i=5; i>=0; i--) glVertex3fv(c[i]);

Здесь мы изменили порядок обхода вершин и начали с вогнутой вершины. Запустите и убедитесь в том, что теперь в полигоне есть все шесть вершин. OpenGL не гарантирует точную передачу вогнутых полигонов. Поэтому для надежной передачи их надо предварительно разбивать на выпуклые части. Если этими частями будут треугольники, то процесс разбиения называется tessellation (мозаика). Есть специальные функции для тесселяции полигонов. Их рассмотрение выходит за рамки этой книги. Попробуйте самостоятельно задать рассмотренный выше полигон в виде двух выпуклых четырехугольников. Для этого посмотрите справку по функции glBegin с параметром GL_QUADS.

Полигоны можно рисовать либо закрашенными (режим – GL_FILL), либо в скелетном виде (GL_LINE), либо в виде намеков (GL_POINT). Испробуйте все режимы на примере невыпуклой звезды. При рисовании точками попробуйте предварительно дать команду glPointSize (5):

void _stdcall OnDraw()
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3d (1.,0.4, 1.);
//=== 2 угла, характеризующие звезду и
//=== 2 характерные точки
double pi = 4. * atan(l.),
al = pi / 10., a2 = 3. * al,
xl = costal), yl = sin(al)',
x2 = cos(a2), y2 = sin(a2);
//=== Мировые координаты вершин нормированной звезды
double с[5][3] =
{
0., 1., 0.,
-х2, – у2, 0.,
xl, yl, 0.,
-xl, yl, 0.,
х2, – у2, 0.,
};
//====== Оконные координаты
for (int i=0; i<5; i+t)
{
c[i][0] = 250 + 100*c[i][0];
c[i][l] = 100 + 100*c[i] [1];
}
//=== Режим заполнения полигона – скелетный
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
//=== Задаем вершины полигона
glBegin(GL_POLYGON);
for (i=0; i<5; i++)
glVertex3dv(c[i]);
glEnd();
glFlush();
}
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.