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

         

Создание консольного проекта


Для исследования возможностей функций библиотек 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.h1:

    #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.




    Содержание раздела