Создание
консольного проекта
Для исследования
возможностей функций библиотек OpenGL целесообразно создать простой проект консольного
типа, в котором для работы с другим (Windows) окном будут использованы функции
дополнительной библиотеки OpenGL, описанной в файле GLAUX.LIB. Рассмотрим последовательность
шагов для создания нового проекта консольного типа.
- На странице VS Home Page
выберите команду Create New Project и в окне появившегося диалога New Project
выберите тип проекта Visual C++ Projects, а в качестве шаблона (в поле Templates)
— Managed C++ Empty Project.
- Задайте имя проекта
Console, желаемое местоположение папки с проектом и нажмите ОК.
- Поставьте фокус на элемент
Console в окне Solution Explorer, вызовите контекстное меню и выберите команду
Add > Add New Item.
- В окне диалога Add New
Item перейдите в список Templates и выберите строку C++File(.cpp).
- В поле Name того же диалога
задайте имя файла OG.cpp и нажмите кнопку Open.
Далее вы будете
вводить код в окно редактора Studio.Net (вкладка OG.cpp). Для того чтобы компоновщик
подключил все библиотеки OpenGL, произведите настройку проекта.
- Поставьте фокус на элемент
Console в окне Solution Explorer и дайте команду Project > Properties или
ее эквивалент View t Property Pages.
- В окне открывшегося диалога
Console Property Pages выберите элемент дерева Linker * Input.
- Переведите фокус в поле
Additional Inputs окна справа и добавьте в конец существующего текста имена
файлов с описаниями трех библиотек: OPENGL32.LIB GLU32.LIB GLAUX.LIB. Убедитесь
в том, что все имена разделены пробелами и нажмите ОК.
В новый пустой
файл OG.cpp поместите следующий код приложения, которое для создания Windows-окна
пользуется услугами библиотеки GLAUX.LIB. Для этого необходимо к проекту консольного
типа подключить файл Windows.h
1:
#
include
<Windows.h>
#
include
<math.h>
//======
Подключение заголовков библиотек OpenGL
#
include
<GL\gl.h>
#
include <GL\glu.h>
#
include
<GL\Glaux.h>
//=====Макроподстановка
для изображения одной линии
#define
Line(xl,yl,x2,y2) \
glBegin(GL_LINES);
\
glVertex2d
( (xl), (yl)); \
glVertex2d
((x2),(y2)); \
glEnd()
;
//======
Реакция на сообщение WM_PAINT
void
_stdcall OnDraw()
{
//======
Стираем буфер кадра (framebuffer)
glClear
(GL_COLOR__BUFFER_BIT) ;
//======
Выбираем черный цвет рисования
glColorSf
(0., 0., 0.);
//===
В 1-м ряду рисуем 3 линии с разной штриховкой
glEnable
(GL_LINE_STIPPLE);
glLineWidth
(2.);
glLineStipple
(1, 0x0101); // dot
Line
(50., 125., 150., 125.);
glLineStipple
(1, OxOOFF); // dash
Line
(150., 125., 250., 125.);
glLineStipple
(1, OxlC47); // dash/dot/dash
Line
(250., 125., 350., 125.);
//======
Во 2-м ряду то же, но шире в 6 раз
glLineWidth
(6.);
glLineStipple
(1, 0x0101); // dot
Line
(50., 100., 150., 100.);
glLineStipple
(1, OxOOFF); // dash
Line
(150., 100., 250., 100.);
glLineStipple
(1, OxlC47); // dash/dot/dash
Line
(250., 100., 350., 100.);
//==
Во 3-м ряду 7 линий являются частями
//==
полосы (strip). Учетверенный узор не прерывается
glLineWidth
(2.);
glLineStipple
(4, OxlC47); // dash/dot/dash
glBegin
(GL_LINE_STRIP);
for
(int i =1; i < 8; i++)
glVertex2d
(50.*i, 75.); glEnd() ;
//==
Во 4-м ряду 6 независимых, отдельных линий
//==
Тот же узор, но он каждый раз начинается заново
for
(i = 1; i < 7; i++)
{
Line
(50*1, 50, 50* (i+1), 50);
}
//======
во 5-м ряду 1 линия с тем же узором
glLineStipple
(4, OxlC47); // dash/dot/dash
Line
(50., 25., 350., 25.);
glDisable
(GL_LINE_STIPPLE); glFlush ();
}
//=====
Реакция на WM_SIZE
void
_stdcall OnSize (int w, int h)
{
glViewport
(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode
(GL_PROJECTION); glLoadldentity();
//======
Режим ортографической проекции
gluOrtho2D
(0.0, double(w), 0.0, double(h));
}
//======
Настройки
void
Init()
{
//======
Цвет фона - белый
glClearColor
(1., 1., 1., 0.);
//======
Нет интерполяции цвета при растеризации
glShadeModel
(GL_FLAT); }
void
main()
{
//===
Установка pixel-формата и подготовка окна OpenGL
auxInitDisplayMode
(AUX_SINGLE | AUX_RGB);
auxInitPosition
(200, 200, 550, 250);
auxInitWindow("My
Stipple Test");
Init()
;
auxReshapeFunc
(OnSize);
//
Кого вызывать при WM_SIZE auxMainLoop(OnDraw);
//
Кого вызывать при WM_PAINT
}
Функция main
содержит стандартную последовательность действий, которые производятся во всех
консольных приложениях OpenGL. С ней надо работать как с шаблоном приложений
рассматриваемого типа. Первые три строчки функции main устанавливают pixel-формат
окна OpenGL. Заботу о его выборе взяла на себя функция auxInitDisplayMode из
вспомогательной библиотеки. В параметре мы указали режим использования только
одного (front) буфера (бит AUX_SINGLE) и цветовую схему без использования палитры
(бит AUX_RGB).
В функции init
обычно производят индивидуальные настройки конечного автомата OpenGL. Здесь
мы установили белый цвет в качестве цвета стирания или фона окна и режим заполнения
внутренних точек полигонов. Константа GL_FLAT соответствует отсутствию интерполяции
цветов. Вызов функции auxReshapeFunc выполняет ту же роль, что и макрос ON_WM_SIZE
в MFC-приложении. Происходит связывание сообщения Windows с функцией его обработки.
Все функции обработки должны иметь тип void _stdcall. Вы можете встретить и
эквивалентное описание этого типа (void CALLBACK). Имена функций OnDraw и OnSize
выбраны намеренно, чтобы напомнить о Windows и MFC. В общем случае они могут
быть произвольными. Важно запомнить, что последним в функции main должен быть
вызов auxMainLoop.
В OnSize производится
вызов функции glviewport, которая задает так называемый прямоугольник просмотра.
Мы задали его равным всей клиентской области окна. Конвейер OpenGL использует
эти установки так, чтобы поместить изображение в центр окна и растянуть или
сжать его пропорционально размерам окна. Аффинные преобразования координат производятся
по формулам:
Xw=(X+1)(width/2)+X0
Yw=(Y+1)(height/2)+Y0
В левой части
равенств стоят оконные координаты:
- (X, Y) — это координаты
изображаемого объекта. Мы будем задавать их при формировании граничных точек
линий командами glvertex2d;
- (Хо, Yo) — это координаты
левого верхнего угла окна. Они задаются первым и вторым параметрами функции
glviewport;
- сомножители в формуле
(width и height) соответствуют третьему и четвертому параметрам (w, h) функции
glviewport и равны текущим значениям размеров окна.
Как видно из
подстановки в формулу, точка с координатами (0,0) попадет в центр окна, а при
увеличении ширины или высоты окна (width или height) координаты изображения
будут увеличиваться пропорционально. Вызов
glMatrixMode
(GL_PROJECTION);
определяет
в качестве текущей матрицу проецирования, а вызов glLoadldentity делает ее равной
единичной матрице. Следующий за этим вызов
gluOrtho2D
(0.0,
double(w), 0.0,
double(h))
;
задает в качестве
матрицы преобразования матрицу двухмерной ортографической (или параллельной)
проекции. Изображение будет отсекаться конвейером OpenGL, если его детали вылезают
из границ, заданных параметрами функции gluOrtho2D.