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() ;
}