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

Статья :: Штриховка полигонов

 

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

Теперь применим штриховку (stipple) к полигонам. Режим штриховки включается и выключается стандартным способом:

glEnable (GL_POLYGON_STIPPLE) ;

glDisable (GL_POLYGON_STIPPLE);

Bitmap-узор (pattern) штриховки надо предварительно подготовить в массиве такой размерности, чтобы заполнить bitmap площадью 32x32 = 1024 пиксела. Размерность массива с узором определяется так: 1024 бита можно разместить в 128 переменных по одному байту. Мы разместим их в 16 строках по 8 байт. Имеем 16 х х 8 х 8 = 1024 бита (или пиксела).

Массивы объявлены глобально. Адреса массивов с узором подаются на вход функции glPolygonStipple:

GLubyte gSpade[] = // Узор - пики

{

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0xlf, 0xff, Oxff, 0xf8, 0xlf, 0x00, 0x00, 0xf8,

0x01, OxcO, 0x03, 0x80, 0x00, 0x70, 0xOe, 0x00,

0x00,

0x20,

0x04,

0x00,

0x00,

0x30

, 0x0c,

0x00,

0x00,

0x10,

0x08,

0x00,

0x00,

0x18

, 0x18,

0x00,

0x07,

0хс4,

0x23,

0xe0,

0x0f,

0xf8

, 0xlf,

0xf0,

0x38,

0xlc,

0x38,

0xlc,

0x30,

0x00

, 0x00,

0x0c,

0x60,

0x00,

0x00,

0x06,

0x60,

0x00

, 0x00,

0x06,

0x60,

0x00,

0x00,

0x06,

0x60,

0x00

, 0x00,

0x06,

0x60,

0x00,

0x00,

0x06,

0x30,

0x00

, 0x00,

0x0c,

0x30,

0x00,

0x00,

0x0c,

0x18,

0x00

, 0x00,

0x18,

0х0е,

0x00,

0x00,

0x70,

0x03,

0x00

, 0x00,

0xc0,

0x00,

OxcO,

0x03,

0x00,

0x00,

0x70

, 0x0e,

0x00,

0x00,

0x18,

0x18,

0x00,

0x00,

0x0c

, 0x30,

0x00,

0x00,

0x07,

OxeO,

0x00,

0x00,

0x03

, 0xc0,

0x00,

0x00,

0x01,

0x80,

0x00,

0x00,

0x00

, 0x00,

0x00

GLubyte

gStripU =

// Другой узор -

полоса


0x66,

0x66,

0x66,

0x66,

0x33,

0x33

, 0x33,

0x33,

0x66,

0x66,

0x66,

0x66,

0x33,

0x33

, 0x33,

0x33,

0x66,

0x66,

0x66,

0x66,

0x33,

0x33

, 0x33,

0x33,

0x66,

0x66,

0x66,

0x66,

0x33,

0x33

, 0x33,

0x33,

0x66,

0x66,

0x66,

0x66,

0x33,

0x33

, 0x33,

0x33,

0x66,

0x66,

0x66,

0x66,

0x33,

0x33

, 0x33,

0x33,

0x66,

0x66,

0x66,

0x66,

0x33,

0x33

, 0x33,

0x33,

0x66,

0x66,

0x66,

0x66,

0x33,

0x33

, 0x33,

0x33,

0x66,

0x66,

0x66,

0x66,

0x33,

0x33

, 0x33,

0x33,

0x66,

0x66,

0x66,

0x66,

0x33,

0x33

, 0x33,

0x33,

0x66,

0x66,

0x66,

0x66,

0x33,

0x33

, 0x33,

0x33,

0x66,

0x66,

0x66,

0x66,

0x33,

0x33

, 0x33,

0x33,

0x66,

0x66,

0x66,

0x66,

0x33,

0x33

, 0x33,

0x33,

0x66,

0x66,

0x66,

0x66,

0x33,

0x33

, 0x33,

0x33,

0x66,

0x66,

0x66,

0x66,

0x33,

0x33

, 0x33,

0x33,

0x66,

0x66,

0x66,

0x66,

0x33,

0x33

, 0x33,

0x33,

Функцию 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() ;

}

 

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

страницы в данном разделе 
Урок 6. Графика OpenGL Графика OpenGL
Обзор возможностей библиотеки OpenGL Подключаемые библиотеки
Ограничения Microsoft Примитивы OpenGL
OpenGL — автомат с конечным числом состояний Конвейер передачи OpenGL
Основные этапы Анимация
Другие функции OpenGL Контекст передачи изображения
Подготовка окна Создание консольного проекта
Штриховка линий Штриховка полигонов
Как убирать внутренние линии Перспективная проекция
Вносим свет Интерактивное управление положением и ориентацией
Двойная буферизация Использование списков
Интерполяция цвета Строим икосаэдр
Как создать сферу Выбор способа вычисления нормалей
Рекурсивное деление Массивы вершин, нормалей и цветов
Создание сферы >  


Содержание сайта (выборка)
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, справочник программиста