Каркас OpenGL приложения с использованием GLUT

Тема в разделе "C++ / C# / .NET", создана пользователем Admin, 5 июл 2016.

  1. Гость, давай поддержим форум вместе, делись информацией с друзями через кнопки в блоке "Поделиться в социальных сетях"

    Скрыть объявление
  1. Admin

    Admin Администратор Команда форума

    Регистр:
    27 дек 2012
    Сообщения:
    1.300
    Лайки:
    1.053
    Дизлайки:
    0
    Баллы:
    100
    Пол:
    Мужской
    Сложность работы с OpenGL, как и с любой достаточно продвинутой технологией, состоит в том, что до написания первой строчки кода, рисующей что-либо на экране, требуется создать необходимые объекты, установить формат пиксела, проинициализировать вспомогательные буферы и т.д. Т.е. сообщить OpenGL, что, где и как мы собираемся рисовать.

    Во многих книгах первая глава, размером в несколько десятков страниц посвящена подробному разбору интеграции OpenGL в систему. Человеку, который хочет изучать графику, это обычно кажется невероятно скучным. Часто такое решение не является кроссплатформенным, в то время, как многие программы для научной визуализации создаются под Linux.

    Решением в данной ситуации является использование библиотеки GLUT. Она берет на себя работу по созданию окна, инициализации OpenGL, обработки сообщений от мыши и клавиатуры. Более того, используя библиотеку GLUT, такие функции, как включение аппаратного сглаживания, делаются в несколько строк кода.

    Прим. Существуют достаточно большие и сложные приложения, предназначенные для научной визуализации, созданные с использованием библиотеки GLUT. Так что эта библиотека используется не только в учебных целях, но и в ряде реальных продуктов, построенных на технологии OpenGL.
    Установка GLUT

    GLUT не идет по умолчанию в системе и в среде разработки. Вам потребуется найти и скачать последнюю версию по ссылке: GLUT Downloads. Скопируйте *.dll файлы в папку system, находящуюся в директории c Windows. Файлы *.lib положите в папку lib Visual C++, файл glut.h в папку Include\gl.

    Прим. Версию 3.6 можно скачать по ссылке: glutdlls36.zip

    К примеру, файлы могут располагаться таким образом:
    glut.dll
    glut32.dll
    C:\Windows\system

    glut.lib
    glut32.lib
    C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Lib

    glut.h
    C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Include\gl

    Код шаблона
    Перейдем непосредственно к рассмотрению шаблона. Файл main.cpp:

    #include "engine.h"

    Engine *engine;

    GLvoid display(GLvoid)
    {
    engine->Draw();
    glutSwapBuffers();
    }

    GLvoid reshape(GLsizei width, GLsizei height)
    {
    engine->Resize(width, height);
    }

    int main(int argc, char** argv)
    {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(800, 600);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("2.1. Каркас OpenGL приложения c использованием GLUT.");
    engine = new Engine();
    engine->Init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMainLoop();
    return 0;
    }


    Это весь код, который необходим, чтобы рисовать на экране средствами OpenGL. Команды OpenGL, которые отвечают за установку проекции и рисование вынесены в класс Engine, чтобы разделить приложение на логические части. Часть приложения из модуля main.cpp отвечает за диалог с системой, а класс Engine за вывод графики.

    Прим. Разработка графических приложений, как и любых других, требует не только кодирования, но и создания определенной структуры. В данном случае, это разделение графического движка и кода, отвечающего за связь с системой.

    Приведем небольшие комментарии по приведенному коду:

    glutInit(&argc, argv);

    Данная строка позволит библиотеке GLUT обработать специальные аргументы командной строки,
    предназначенные для неё. После вызова этой функции, те аргументы, которые касались библиотеки GLUT будут удалены из списка.

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(800, 600);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("2.1. Каркас OpenGL приложения c использованием GLUT.");

    Здесь создается окно и указываются некоторые параметры OpenGL. Для окна указывается размер, позиция левого верхнего угла и заголовок. GLUT_DOUBLE означает, что будет использоваться двойная буферизация; GLUT_RGB, что будет использоваться RGB модель цвета, а не индексированный цвет.

    engine = new Engine();
    engine->Init();

    Здесь создается движок нашего приложения и производится дополнительная настройка OpenGL.

    glutDisplayFunc(display);
    glutReshapeFunc(reshape);

    Здесь указываются функции нашего приложения, которые отвечают за перерисовку окна и изменение его размеров, соответственно.

    glutMainLoop();
    Основной цикл работы приложения, построенного на базе GLUT. В одной из последующих статей можно посмотреть, как выполнять свои действия во время этого цикла. Например, анимацию.

    return 0;

    По стандарту языка С функция main должна возвращать величину типа int. 0 означает, что приложение завершилось корректно.

    Содержание модуля Engine.cpp:
    Код:
    
    #include "engine.h"
    
    GLvoid Engine::SetProjectionMatrix(GLvoid){
          glMatrixMode(GL_PROJECTION);            // Действия будут производиться с матрицей проекции
          glLoadIdentity();                       // Текущая матрица (проекции) сбрасывается на единичную
          glFrustum(-1, 1, -1, 1, 3, 10);         // Устанавливается перспективная проекция
    }
    
    GLvoid Engine::SetModelviewMatrix(GLvoid){
          glMatrixMode(GL_MODELVIEW);             // Действия будут производиться с матрицей модели
          glLoadIdentity();                       // Текущая матрица (модели) сбрасывается на единичную
          glTranslatef(0.0, 0.0, -8.0);           // Система координат переносится на 8 единиц вглубь сцены
          glRotatef(30.0, 1.0, 0.0, 0.0);         // и поворачивается на 30 градусов вокруг оси x,
          glRotatef(70.0, 0.0, 1.0, 0.0);         // а затем на 70 градусов вокруг оси y
    }
    
    GLvoid Engine::Resize(GLsizei width, GLsizei height){
          if (height == 0)                                                 
          {
                height = 1;                                                     
          }
    
          glViewport(0, 0, width, height);                     // Устанавливается область просмотра
    
          Height = height;
          Width = width;
    
          SetProjectionMatrix();
          SetModelviewMatrix();
    }
    
    GLvoid Engine::Init(GLvoid){
          glClearColor(0.2f, 0.5f, 0.75f, 1.0f);               // Устанавливается синий фон
          glClearDepth(1.0f);                                  // Устанавливается значение для
                                                               // заполнения буфера глубины по умолчанию
          glEnable(GL_DEPTH_TEST);                             // Включается тест глубины
          glDepthFunc(GL_LEQUAL);                              // Устанавливается значение, используемое
                                                               // в сравнениях при использовании
                                                               // буфера глубины
    
          glShadeModel(GL_SMOOTH);                             // Включается плавное затенение
          glEnable(GL_LINE_SMOOTH);                            // Включается сглаживание линий
          glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);              // Выбирается самый качественный
                                                               // режим сглаживания для линий
          glEnable(GL_BLEND);                                  // Включается смешение цветов, необходимое
          glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);   // для работы сглаживания и задается
                                                               // способ смешения
    }
    
    GLvoid Engine::Draw(GLvoid)                                                 
    {
          glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  // Очищается буфер кадра и буфер глубины
          glPushMatrix();                                      // Запоминается матрица модели
    
          glColor3f(1.0f, 1.0f, 1.0f);                         // Задается текущий цвет примитивов
          glutWireCube(2.0f);                                  // Рисуется проволочный куб со стороной 2
    
          glPopMatrix();                                       // Восстанавливается матрица модели
    }