![]() |
![]() |
![]() |
Создание
консольного проекта
Для исследования
возможностей функций библиотек 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 использует
эти установки так, чтобы поместить изображение в центр окна и растянуть или
сжать его пропорционально размерам окна. Аффинные преобразования координат производятся
по формулам:
X w =(X+1)(width/2)+X 0
Y w =(Y+1)(height/2)+Y 0
В левой части
равенств стоят оконные координаты:
Как видно из
подстановки в формулу, точка с координатами (0,0) попадет в центр окна, а при
увеличении ширины или высоты окна (width или height) координаты изображения
будут увеличиваться пропорционально. Вызов
glMatrixMode
(GL_PROJECTION);
определяет
в качестве текущей матрицу проецирования, а вызов glLoadldentity делает ее равной
единичной матрице. Следующий за этим вызов
gluOrtho2D
(0.0,
double
(w), 0.0,
double
(h))
;
задает в качестве матрицы преобразования матрицу двухмерной ортографической (или параллельной) проекции. Изображение будет отсекаться конвейером OpenGL, если его детали вылезают из границ, заданных параметрами функции gluOrtho2D.
![]() |
![]() |
![]() |