Где расположены файлы opengl
В этой главе вы познакомитесь с самой главной частью программного кода - начальной инициализацией. На мой взгляд, это очень сложная тема. Я решил оставить ее на конец книги, когда вы уже будете знакомы с OpenGL. В противном случае, если бы я поместил эту главу в самом начале, я боюсь вы многого не поняли бы. Да и вообще, может не стали бы читать эту книжку.
2.8 Анимация
Давайте оживим нашего снеговика и добавим интерактивность. Для этого надо отрисовывать кадры и реагировать на внешние события от клавиатуры или мыши. Для отрисовки кадров их надо как-то различать. Для этого мы в функции display вводим переменную time типа int с модификатором static. Создайте новый проект и в функцию display введите следующее: "static int time=0;". Модификатор static означает, что значение переменной будет сохраняться при выходе из функции. Начальное значение мы устанавливаем в ноль. Если функция display не зависит от времени, то счетчик кадров можно и не вести. Теперь добавьте следующие строчки:
Запустив приложение, вы увидите, что снеговик пополз вдоль оси Х. Вот так вы можете делать анимацию. Т.е. теперь координаты объектов вычисляются в зависимости от времени. Я привел простой пример. Вообще говоря, для программирования сложной графики вам понадобится вычислять координаты каждого отдельного объекта в зависимости от времени.
Далее мы рассмотрим пример с более сложной анимацией. Здесь вращается тор и его ось вращения. Я приведу исходный текст с подробными комментариями. Пример программы "Гироскоп":
Исходный файл смотрите здесь. Исполняемый файл здесь.
Как вы, наверное, догадались, надо создать очередной проект, скопировать туда мой шаблон, добавить его в проект, указать библиотеки opengl32.lib glu32.lib glaux.lib в Project->Setting->Link->Settings->Link->Object/library modules:, вставить этот код в функцию display. Еще вам нужно в начале функции display вставить строку static int time=0; и закомментировать строчку glEnable(GL_LIGHTING) в функции main.
Запустив это приложение, вы увидите, как оно работает. Теперь закомментируйте соответствующие друг другу вызовы glPushMatrix и glPopMatrix и посмотрите на результат. Я бы рекомендовал такой способ для изучения и понимания работы программы: вы комментируете куски кода и смотрите, что получается.
Для того, чтобы реагировать на клавиатуру или мышь, вы должны определить функцию, которая будет вызываться при поступление событий от клавиатуры или мыши. Для кнопки клавиатуры вы определяете функцию со следующим прототипом void CALLBACK FunctionName(void) и устанавливаете ее как обработчик определенной кнопки - auxKeyFunc(key_code, FunctionName); key_code смотри в glaux.h. Пример: auxKeyFunc(AUX_LEFT, FunctionName) Здесь вы устанавливаете FunctionName как функцию, которая будет вызываться при нажатии на клавиатуре клавиши "стрелка влево".
Для мыши вы устанавливаете свою функцию обработки событий мыши вызовом функции auxMouseFunc(int button,int action,AUXMOUSEPROC). Переменная button может принимать значения - AUX_LEFTBUTTON, AUX_MIDDLEBUTTON, AUX_RIGHTBUTTON. Переменная action принимает следующие значения - AUX_MOUSEDOWN, AUX_MOUSEUP, AUX_MOUSELOC. Функция AUXMOUSEPROC должна иметь прототип - void CALLBACK FunctionName(AUX_EVENTREC *event), где AUX_EVENTREC определено как
Для более детальной информации смотрите справочные руководства и исходные тексты библиотеки OpenGL Auxiliary library. Эта книга об OpenGL, а не о программировании интерфейсов пользователя. Поэтому, за подобной информацией вам придется лезть в соответствующие справочные руководства по Win API, MFC, Java и т.п.
В FunctionName вы можете изменить какую-нибудь глобальную переменную, и, соответственно, функция display будет рисовать кадры в зависимости от этой переменной.
2.5 Упражнение: "Cписок трехмерных фигур"
Используя список функций из предыдущего упражнения, нарисуйте эти фигуры в два столбца. Слева проволочные. Справа сплошные.
Примечание: тут хочу заметить, что в версии glaux.lib от фирмы Microsoft имеется следующий баг: цилиндр и конус рисуются всегда либо проволочными, либо сплошными. Если вы первый цилиндр/конус в программе нарисовали проволочным, то далее все цилиндры/конусы будут проволочными. Соответственно, если первой была сплошная фигура, то далее все будут сплошные. Поэтому, не стоит паниковать. Это ошибка Microsoft. Могу также вас порадовать, что ниже я расскажу, как обойти эту проблему.
Исходный файл смотрите здесь. Исполняемый файл здесь.
7.4 MFC-приложение - MFC AppWizard
Этот тип приложения обладает всеми достоинствами и недостатками WinAPI-приложения, рассмотренного выше, так как MFC - это библиотека классов С++, т.е. надстройка над WinAPI. Кто-нибудь, конечно, скажет, что приложение на плюсах немеряно большое, работает медленно и MFC для ленивых. В общем, тут у каждого свое мнение. Каждый по-своему прав. Тем не менее, я считаю, что для каждой задачи требуется свой инструмент. Где-то лучше использовать MFC, где-то WinAPI. Кричать, что первое или второе является незаменимым средством на все случаи жизни было бы неверным. У MFC есть свои особенности, отнести которые к достоинствам или недостаткам однозначно нельзя. В зависимости от решаемой задачи они идут в плюс или минус. Согласитесь, что глупо забивать сапожный гвоздь кувалдой или же скобу сапожным молотком.
- Запустите MSVisualC++6.0
- Щелкните меню File->New->MFC AppWizard(exe).
- Выберете каталог и имя проекта задайте mfc, щелкните OK.
- Step1: Поставьте переключатель на Single document, далее OK.
- Step3: Уберите флажок ActiveX Controls, далее OK.
- Щелкните Finish.
- Щелкните Build->Set Active Configuration и установите тип проекта MFC - Win32 Release
- Далее щелкаете Project->Settings->Link->Object/library modules: и добавьте туда opengl32.lib, glu32.lib и glaux.lib
В CMFCView объявите закрытую(private) переменную hGLRC типа HGLRC. Там же объявите функцию int SetWindowPixelFormat(HDC) и открытую(public) функцию display. Вот, что должно получиться:
Вставьте код этой функции в файл MFCView.cpp. Код возьмите из предыдущего раздела. Отредактируйте функцию CMFCView::PreCretaeWindow следующим образом:
Добавьте также функцию display сюда:
Теперь запустите View->Class Wizard и добавьте обработчик WM_CREATE,WM_DESTROY и WM_SIZE в класс CMFCView. Отредактируйте их следующим образом:
Исходный файл смотрите здесь. Исполняемый файл здесь.
2.3 Упражнение: "Трехмерные фигуры"
Замените функцию auxSolidSphere на функцию, из указанных ниже с соответствующими параметрами. Значения параметров устанавливайте порядка единицы - 0.5-1.7. Если вы укажете слишком маленький размер, фигуру будет плохо видно; если слишком большой, то она получится урезанной. Это связано с тем, что ее край, как бы вылезет из монитора.
- auxSolidCube(width) // куб
- auxSolidBox(width, height, depth) // коробка
- auxSolidTorus(r,R) // тор
- auxSolidCylinder(r,height) // цилиндр
- auxSolidCone(r,height) // конус
- auxSolidIcosahedron(width) // многогранники
- auxSolidOctahedron(width)
- auxSolidTetrahedron(width)
- auxSolidDodecahedron(width)
- auxSolidTeapot(width) // рисует чайник
С помощью выше указанных функций вы можете рисовать сплошные фигуры. Если вам надо нарисовать проволочную, то вместо Solid пишите Wire.
2.4 Переход к новым координатам
Продолжим рисовать трехмерные фигуры. В предыдущем параграфе вы научились рисовать примитивные трехмерные объекты. Но проблема в том, что они рисуются только в начале координат, т.е. в точке (0,0,0). Для того чтобы изобразить сферу в точке ( x0,y0,z0 ), надо переместить начало координат в эту точку, т.е. надо перейти к новым координатам. Эта процедура довольно распространенная при программировании графики и анимации. Часто, бывает очень удобно, сместить координаты в новую точку и повернуть их на требуемый угол, и ваши расчеты резко упростятся. Конкретный пример мы рассмотрим ниже, когда научимся программировать анимацию. А пока вы узнаете, как переходить к новым координатам. Для перехода к новым координатам в OpenGL есть две функции:
Первая функция сдвигает начало системы координат на ( D x, D y, D z ). Вторая - поворачивает на угол j против часовой стрелки вокруг вектора (x0,y0,z0). Теперь, стоит сказать еще о двух очень важных функциях:
Они предназначены для сохранения и восстановления текущих координат. Я не стал здесь приводить пример на то, как неудобно переходить от одной системы координат к другой и помнить все ваши переходы. Гораздо удобнее с помощью glPushMatrix() сохранить текущие координаты, потом сдвигаться, вертеться, как вам угодно, а после, вызовом glPopMatrix вернуться к старым координатам. Итак, настало время поэкспериментировать. Создайте новый проект, повторив пункты из раздела 2.2. Только назовите его sphere2. Сначала мы рассмотрим сдвиг координат. Вставьте в функцию display следующий код:
Теперь откомпилируйте и запустите вашу программу.
Меню Build->Execute Sphere.exe
Исходный файл смотрите здесь. Исполняемый файл здесь.
В общем-то, из комментариев многое понятно. Обращаю ваше внимание только на два последних вызова auxSolidSphere. Перед вызовом glPopMatrix сфера рисуется в точке (2,0,0), а после, в точке (0,0,0).
2.9 Упражнение:" Игра Арканоид"
Напишите игру "Arconoid" - летающий шарик, снизу подставка, пользователь стрелками или мышкой управляет подставкой и отбивает шарик.
Исходный файл смотрите здесь. Исполняемый файл здесь.
7.6 Java-апплеты GL4Java
Теперь немного теории о том, как такие библиотеки устроены. Вообще, из Java-апплетов нельзя обращаться к локальному диску пользователя. И тут, у вас может возникнуть вопрос, как же так получается, что из Интернета все-таки можно загрузить апплет и он будет работать с динамическими библиотеками установленными на вашем компьютере? Ведь в одном случае это может быть OpenGL, а в другом - вирус, делающий низкоуровневое форматирование вашего диска и перезаписывающий BIOS. Ответ очень прост, у вас на машине имеются доверительные динамические библиотеки и java-классы, которые с ними взаимодействуют. Просто одних библиотек недостаточно. Из самого java-апплета вы можете загрузить только java-классы на машине пользователя, к которым прописан CLASSPATH. Последним, в свою очередь, разрешено взаимодействовать с динамическими библиотеками. В результате, получается когда вы загружаете java-апплет с использованием OpenGL, то вся графика делается не на уровне виртуальной java-машины, а на уровне opengl32.dll, функционирование которой мало чем отличается от выполнения обычного исполняемого файла. Такие плагины, вообще говоря, являются потенциальной дырой для проникновения в вашу систему из вне. Если вы работаете в многопользовательской операционной системе с разграничением доступа, то не запускайте подозрительных программ от имени администратора. Например, в Unix или WindowsNT, если вы запустите какой-нибудь вирус от имени пользователя, отформатировать жесткий диск ему не удастся, прав у пользователя таких нет. Администраторов лопухов, я здесь не рассматриваю.
Теперь рассмотрим пример. У меня, среди прилагающихся программ, в директории template вы найдете поддиректории GL4Java. Здесь я приведу целиком исходный код с подробными комментариями.
Html-код для запуска данного апплета выглядит следующим образом:
Исходный файл смотрите здесь. Html файл здесь.
Расположение файла OpenGl32.dll
Файл находиться по пути C:\Windows\System32 и C:\Windows\SysWOW64. Кроме того, он может быть в корне папки самой игры или программы.
2. Обновите систему Windows 11/10 до последней версии, так как файл OpenGl32.dll идет по умолчанию с версии 1909 и нужен он для собственных приложений UWP.
3. Вы можете попросить друга, чтобы он вам скинул файл, а вы в свою очередь закиньте его по правильному пути, который указан выше. Не скачивайте отдельно файл со сторонних сайтов, так как высок риск скачать вирус. Кроме того, отдельно файл OpenGl32.dll можно скачать с серверов Mcirosoft при помощи winbindex .
4. Обновите драйверы видеокарты Amd, Nvidia или Intel, так как OpenGl распространяется и через графические драйвера.
5. Скачайте и установите openal с официального сайта, который включает в себя библиотеку OpenGl32.dll для Windows 11/10.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Open with Desktop
- View raw
- Copy raw contents Copy raw contents
Copy raw contents
Copy raw contents
Урок 3 - Вращающийся куб с текстурой
Этот урок будет немного сложнее предыдущего, но зато интересней, в нем будет рассмотрен следующий материал:
- Системы координат OpenGL
- Работа с матрицами, подготовка и передача их в шейдерную программу
- Создание простой текстуры и передача ее в шейдер
- Создание вершинного и индексного буфера для геометрии куба
- Вывод вращающегося куба на экран
Системы координат OpenGL
Координаты объекта, в режиме FFP (Fixed Function Pipeline) в предыдущих версиях OpenGL, проходили следующие преобразования системы координат:
- Локальные координаты преобразуются матрицей ModelView в видовые (eye space)
- Видовые преобразуются матрицей Projection в однородные (clip space)
- Однородные (X,Y,Z,W) преобразуются в нормализованные (X/W, Y/W, Z/W, 1)
- Нормализованные преобразуются параметрами glViewport и glDepthRange в экранные ( screen space )
Разработчикам также была облегчена работа с матрицами преобразований. В частности разработчик мог использовать стек матриц в различных режимах работы с матрицами. Режим работы задавался с помощью функции glMatrixMode , например можно было задать режим GL_MODELVIEW или GL_PROJECTION , который давал доступ к модельно-видовой ( ModelView ) и проекционной ( Projection ) матрицам, соответственно. Для работы со стеком матриц предназначались функции glPushMatrix и glPopMatrix . Однако в OpenGL версии 3 и выше все эти функции были объявлены устаревшими и исключены из API.
В OpenGL 3.3 за первые два пункта преобразований координат теперь отвечает разработчик: используя шейдерную программу он должен перевести локальные координаты объекта в однородные. Каким образом он это сделает - неважно, он может эмулировать старую схему или придумать что-то свое, главное получить однородные координаты.
Однородные координаты называются так неспроста, они переводят все имеющиеся координаты в единое пространство, ограниченное по всем осям системы координат параметром W . В итоге, после перевода однородных координат в нормализованные, любые координаты вершин, которые необходимо отобразить, находятся в пределах [-1, 1] по всем трем осям нормализованной системы координат. Если координаты вершины не попадают в этот интервал - вершина отбрасывается.
Зачастую разработчики графических приложений разбивают первый этап преобразования из локальных координат в видовые на два:
- Трансформация координат матрицей объекта ( ModelMatrix )
- Трансформация координат матрицей наблюдателя ( ViewMatrix )
Такое разбиение очень удобно - у каждого объекта есть матрица преобразований, которая переводит локальную систему координат в мировую и есть наблюдатель, положение которого задано в мировых координатах. Таким образом мы можем оперировать неким дополнительным пространством - мировым ( world ), это пространство служит для описания сцены и расположения на ней объектов и наблюдателей.
Терминология обозначения матриц и систем координат одна из многих причин путаниц при работе с разными графическими API, например в DirectX матрица перевода локальной системы координат объекта в мировые называется не ModelMatrix , а WorldMatrix .
Кстати, в OpenGL правая система координат, т.е. построенная по правилу правой руки. В начальном положении ось Z направлена на нас, ось X направлена вправо и ось Y направлена вверх, относительно экрана монитора.
Работа с матрицами
В этом и последующих уроках будет использоваться подход к матрицам описанный выше, для описания объекта на сцене необходимо будет задать три матрицы: ModelMatrix , ViewMatrix и ProjectionMatrix .
Матрицы ViewMatrix и ProjectionMatrix обычно привязаны к специальному объекту - камере. Матрица ViewMatrix меняется если наблюдатель изменил свое положение или направление взгляда. Матрица ProjectionMatrix меняется гораздо реже, например при переключении из меню приложения к сцене и т.п.
Матрица ModelMatrix закреплена за объектом, она меняется при движении объекта или его вращении.
Для того, чтобы передать матрицу в шейдерную программу надо сделать несколько действий:
- Указать в шейдере тип принимаемой матрицы - uniform matN matrixName
- После сборки шейдерной программ ( link ) получить индекс юниформа ( location )
- Передать матрицу в шейдерную программу используя одну из функций glUniformMatrix
Передавать все три матрицы в шейдерную программу весьма расточительно - необходимо будет вычислять матрицу преобразования локальных координат в видовые на каждую вершину объекта, поэтому обычно итоговую матрицу преобразований вычисляют в самом приложении, отдельно для каждого объекта, и передают ее в шейдерную программу перед выводом этого объекта на экран.
В этом уроке мы будем выводить на экран вращающийся куб, для этого нам потребуется рассчитать матрицу вращения ModelMatrix :
Функция Matrix4Rotation строит матрицу вращения для углов поворота по трем осям координат (x, y, z) . Если вас интересует подробное описание построение матрицы поворота, то рекомендую ознакомиться с детальным The Matrix and Quaternions FAQ. Отдельно на этой теме мы в уроке останавливаться не будем.
Помимо этого мы отодвинем точку наблюдения от куба, чтобы видеть его полностью, для этого нам понадобиться построить матрицу переноса ViewMatrix :
Функция Matrix4Translation строит матрицу переноса по трем координатным осям (x, y, z) . Опять же детальную информацию вы можете получить в The Matrix and Quaternions FAQ.
Также нам понадобиться матрица проекции ProjectionMatrix , о которой было рассказано в предыдущем уроке. Также как и там мы будем использовать перспективную матрицу проекции, построенную при помощи функции Matrix4Perspective .
Однако это еще не все, как уже было сказано выше, нам необходимо рассчитать итоговую матрицу преобразований координат прежде чем передавать ее в шейдерную программу, для композиции трансформаций используется матричное умножение:
Функция Matrix4Mul перемножает матрицы A и B и помещает результат в матрицу M . Надеюсь как выполняется матричное умножение знает каждый из вас и подробно объяснить смысл производимых в функции действий вам не надо :)
Стоит также вспомнить, что умножение матриц операция ассоциативная, т.е. A*(B*C) = (A*B)*C , поэтому мы можем вычислить часть выражения заранее, а часть в случае необходимости.
В данном уроке мы не будем менять матрицу проекции и матрицу наблюдателя, поэтому их мы можем объединить заранее и не вычислять постоянно:
Для вращения куба нам необходимо построить матрицу вращения:
Для передачи матрицы в шейдерную программу нам необходим узнать ее индекс:
После получения итоговой матрицы и ее индекса мы можем передать ее в шейдерную программу:
Очень частая проблема, которая приводит к путанице в среде разработчиков графических приложений - формат самих матриц и формат расположения их в памяти.
Формат матрицы можно определить по формату векторов, это либо row-vector матрица (используется вектор-строка), либо column-vector матрица (используется вектор-столбец). Соответственно при использовании row-vector необходимо вектор умножать на матрицу, а при использовании column-vector умножать матрицу на вектор.
По формату расположения в памяти матрицы также делятся на два типа: row-major матрица (матрица в памяти записана по строкам) и column-major матрица (матрица в памяти записана по столбцам). Стоит отметить, что переход между форматами осуществляется путем транспонирования матрицы.
По историческим причинам OpenGL использует column-major матрицы, соответственно ожидая на входе в свои функции именно этот формат, однако такой формат неудобен, поэтому в этих уроках используется row-major формат расположения в памяти, а при передачи в шейдерную программу функцией glUniformMatrix устанавливается флаг transpose , которые переводит матрицу в column-major формат.
Загрузка и создание текстуры
Тема текстур в OpenGL очень объемная, существуют различные типа текстур для разных целей. В этом уроке мы создадим самую простую и наиболее часто используемую текстуру - двумерную текстуру, в OpenGL такая текстура обозначается как GL_TEXTURE_2D .
Изображение для текстуры в этом уроке хранится в формате TGA. Этот очень простой формат, местами даже проще чем BMP. Для загрузки изображения из этого формата и создания текстуры используется функция TextureCreateFromTGA :
Добавить к кооментариям исходного кода приведенного выше практически нечего, используя функцию TextureCreateFromTGA полчаем готовую для исопльзования текстуру:
Функция glActiveTexture задает активный текстурный юнит видеокарты, который мы будем использовать. Привязка текстуры к активному текстурному юниту осуществляется функцией glBindTexture .
Теперь необходимо сообщить шейдерной программе в каком текстурном юните распологается наша текстура:
Теперь шейдерная программа знает какой текстурный юнит использовать. Максимальное количество доступных текстурных юнитов можно узнать используя функцию glGetIntegerv с параметром GL_MAX_TEXTURE_IMAGE_UNITS .
Геометрия куба и буферы для ее хранения
Также ккак и в прошлом уроке для тругольника мы вручную зададим геометрию куба, однако в этот раз не будем задавать цвет вершин, а назначим им текстурные координаты:
Конечно мы можем рисовать куб используя прямоугольники, однак обычно геометрия моделей представлена в виде граней ( face ), которые представляют собой треугольники. Для того чтобы нарисовать куб треугольниками не дублируя вершин на понадобиться индексный буфер, в котором последовательно идут по три индекса для каждого из треугольников, котоыре мы будем рисовать:
Индексы определяют номера вершин в вершинном буфере, которые будет использоваться при выводе объекта на экран.
Теперь необходимо создать VBO для хранения вершин куба и индексного буфера, также не забываем про VAO, в котором будут хранится все созданные связи между VBO и вершинными атрибутами в шейдерной программе:
Обратите внмание, что вершинный буфер задается параметром GL_ARRAY_BUFFER , а индексный буфер задается параметром GL_ELEMENT_ARRAY_BUFFER .
С VAO может быть связан только один индексный буфер, в отличии от вершинных буферов, которых может быть несколько. Таким образом предопагается, что VAO будет использоваться для вывода на экран одной модели, в данном случае - куба.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Open with Desktop
- View raw
- Copy raw contents Copy raw contents
Copy raw contents
Copy raw contents
Подготовка к первому проекту OpenGL: настройка GLFW, CMake и GLAD
Первое, что нам нужно сделать, прежде чем мы начнем программировать графику, — это создать контекст OpenGL и окно приложения для рисования. Однако данные операции являются специфичными для каждой операционной системы, поэтому OpenGL целенаправленно пытается абстрагироваться от них. Это означает, что мы самостоятельно должны создать окно, определить контекст и обрабатывать пользовательский ввод.
К счастью, существует довольно много библиотек, которые обеспечивают необходимый нам функционал, при этом некоторые из них специально нацелены на работу с OpenGL. Эти библиотеки избавят нас от всей специфической работы, связанной с особенностями конкретной операционной системы. Одними из наиболее популярных библиотек являются: GLUT, SDL, SFML и GLFW. На этих уроках мы будем использовать библиотеку GLFW. Вы также можете использовать и любую другую библиотеку из предоставленного списка, т.к. установка и настройка для большинства из них аналогична установке и настройке GLFW.
GLFW (англ. "Graphics Library FrameWork") — это библиотека, написанная на языке Си, специально предназначенная для работы с OpenGL. Библиотека GLFW предоставит нам все необходимые инструменты, которые потребуется для рендеринга на экран различных объектов. Благодаря этому мы сможем создавать контексты OpenGL, определять параметры окна и обрабатывать пользовательский ввод, что вполне коррелирует с нашими целями.
Основное внимание на этом и следующем уроках уделяется тому, чтобы разобраться с библиотекой GLFW, создать корректный контекст OpenGL и простое окно, в котором мы и будем рисовать наши объекты. На этом уроке мы пошагово рассмотрим установку библиотеки GLFW, а также процесс сборки и компиляции программы в связке с GLFW.
Примечание: На момент написания данной статьи в качестве среды разработки мы будем использовать Microsoft Visual Studio 2019 (обратите внимание, что наши действия будут аналогичными и с более старыми версиями Visual Studio). Если же вы используете более старую версию Visual Studio (или вообще другую среду разработки), то можете быть спокойны, т.к. процесс установки и настройки GLFW аналогичен в большинстве IDE.
Библиотеку GLFW можно скачать с официального сайта. Стоит отметить, что GLFW уже имеет предварительно скомпилированные бинарные и заголовочные файлы для Visual Studio 2010-2019, но для полноты картины их мы использовать не будем, а вместо этого вручную скомпилируем GLFW из исходного кода. Это делается для того, чтобы вы сами прочувствовали процесс компиляции библиотек с открытым исходным кодом, поскольку не каждая подобная библиотека будет предоставлять возможность скачать предварительно скомпилированные бинарные файлы. Итак, давайте загрузим пакет с исходным кодом.
Примечание: Мы будем собирать все библиотеки в формате 64-битных бинарных файлов, поэтому убедитесь, что скачиваете и используете именно 64-битные бинарные файлы.
После загрузки пакета с файлами исходного кода, извлеките и откройте его содержимое. Нас интересуют следующие вещи:
- библиотека, которая будет получена в результате компиляции;
- папка include .
Компиляция библиотек из исходного кода гарантирует, что полученная нами библиотека идеально подойдет для нашего процессора и операционной системы, в то время как предварительно скомпилированные бинарные файлы не всегда могут этим похвастаться (иногда они вообще недоступны для вашей системы). Однако проблема проектов, распространяющихся под эгидой открытого программного обеспечения, заключается в том, что не все используют одну и ту же IDE или систему сборки для разработки своего приложения, а это значит, что предоставленные файлы проекта/решения могут быть несовместимы с настройками IDE у других людей. Следовательно, каждый конечный пользователь должен настроить свой собственный проект/решение с учетом полученных *.с / *.cpp и *.h / *.hpp файлов, что почти всегда является довольно трудоемким и громоздким процессом. Но не спешите расстраиваться, для решения данной проблемы уже существует удобный инструмент сборки проектов под названием CMake.
CMake — это инструмент, который, с использованием заранее определенных сценариев, может из коллекции файлов исходного кода сгенерировать файлы проектов/решений под выбранную пользователем IDE (например, для Visual Studio, Code::Blocks или Eclipse). Он позволит нам из исходного пакета файлов GLFW создать файл проекта под среду разработки Visual Studio 2019, а затем данный файл мы сможем использовать для компиляции библиотеки. Но сначала нам нужно его скачать, а затем установить.
После установки CMake у вас будет 2 варианта:
- запустить CMake из командной строки;
- запустить Cmake через графический интерфейс.
Поскольку мы не стремимся всё усложнять, то остановимся на варианте с использованием графического интерфейса. Для работы с CMake нам потребуется указать папку с файлами исходного кода проекта (в нашем случае glfw-3.3.2 ) и папку назначения для бинарных файлов. Для папки исходного кода мы собираемся выбрать корневую папку загруженного исходного пакета GLFW, а для папки сборки мы создадим новый каталог build :
После того, как мы прописали пути для исходной и целевой папок, нам нужно нажать кнопку Configure , чтобы CMake cмог просмотреть исходные файлы GLFW и выбрать необходимые параметры для сборки.
В следующем окне необходимо задать используемую версию Visual Studio. Т.к. работать мы будем в Visual Studio 2019, то выбираем опцию Visual Studio 16 2019 :
Далее CMake отобразит возможные варианты сборки библиотеки. Можно оставить значения по умолчанию и снова нажать кнопку Configure , чтобы сохранить настройки:
После установки параметров мы нажимаем кнопку Generate , в результате чего в папке build будут созданы необходимые файлы проекта.
Теперь, зайдя в папку build , среди всего прочего можно увидеть файл с именем GLFW.sln , открываем его с помощью Visual Studio 2019:
Поскольку CMake сгенерировал файл проекта, который уже содержит соответствующие параметры конфигурации, нам остается лишь построить решение. При этом CMake должен был автоматически настроить вариант компилирования решения в виде 64-битной библиотеки. Благодаря этому мы получим скомпилированный файл библиотеки с именем glfw3.lib , который будет находиться в папке build/src/Debug .
После того, как мы создали библиотеку, нужно убедиться, что IDE знает, где найти данный файл, а также другие подключаемые файлы нашей программы OpenGL. Решить этот вопрос можно двумя способами:
- Способ №1: Можно скопировать содержимое папки include проекта GLFW в соответствующую папку include вашей IDE или компилятора, а также скопировать полученный файл glfw3.lib в соответствующую папку /lib вашей IDE или компилятора. Данный способ вполне рабочий, но мы его не рекомендуем, так как новая установка IDE или компилятора приведет к тому, что вам заново придется подключать необходимые файлы.
- Способ №2: Вы можете создать новую папку, которая будет содержать все заголовочные файлы и файлы из сторонних библиотек, на которую вы впоследствии сможете ссылаться из своей IDE или компилятора. Например, можно создать папку, в которой будут находиться папки Lib и Includ e. В них мы будем хранить все наши библиотечные и подключаемые файлы, которые собираемся использовать для наших OpenGL-проектов. Получается, что все сторонние библиотеки будут организованы в одном месте (и их можно будет совместно использовать на нескольких компьютерах). Однако, каждый раз при создании нового проекта, мы должны будем указывать IDE соответствующие пути к этим папкам.
Как только необходимые файлы будут сохранены в выбранном вами месте, мы сможем приступить к созданию нашего первого OpenGL-GLFW-проекта.
Наш первый проект
Для начала давайте откроем Visual Studio и создадим новый проект. Для этого нужно выбрать тип проекта C++ , а далее — Пустой проект (не забудьте дать проекту подходящее имя):
Теперь у нас есть рабочее пространство для создания нашего самого первого OpenGL-приложения!
Для того, чтобы наш проект мог использовать GLFW, нам нужно связать с ним полученную библиотеку. Это можно сделать, указав в настройках линкера, что мы хотим использовать библиотеку glfw3.lib , но проект пока не знает где её искать, т.к. все подобные файлы мы переместили в другую папку. Таким образом, сначала мы должны добавить эту папку в наш проект.
Для этого нажмите правой кнопкой мышки на имя проекта в Обозреватель Решений > Свойства . В появившемся окне выберите Каталоги VC++ > Каталоги библиотек ":
Здесь вы можете добавить свои собственные каталоги, чтобы проект знал, где искать необходимые файлы. Это можно сделать, вставив вручную путь до каталога или щелкнув по соответствующей строке и выбрав пункт , в результате чего откроется следующее окно:
Здесь вы можете добавить столько дополнительных каталогов, сколько захотите, и с этого момента IDE при поиске файлов библиотек также будет просматривать и эти директории. Поэтому, как только вы подключите папку Lib из проекта GLFW, вы сможете использовать все файлы библиотек из этой папки. Аналогично обстоят дела и с добавлением папки Include для заголовочных файлов.
Поскольку для VS были указаны все необходимые файлы, то мы, наконец, можем связать GLFW с нашим проектом, перейдя в раздел Компоновщик > Ввод :
Чтобы связать библиотеку нам нужно указать для компоновщика её имя. Так как библиотека называется glfw3.lib , то мы добавляем название этого файла в раздел Дополнительные зависимости (вручную или же через пункт ) и с этого момента при запуске процесса компиляции GLFW будет связан с нашим проектом. В дополнение к GLFW мы также должны добавить ссылки на библиотеку OpenGL, но данные действия будут отличаться в зависимости от (вашей) используемой операционной системы:
- Библиотека OpenGL в Windows. Если вы используете операционную систему Windows, то необходимый нам файл библиотеки opengl32.lib , входящий в пакет Microsoft SDK, уже есть вместе с Visual Studio и не требует отдельной установки. Поскольку мы используем компилятор VS и работаем под операционной системой Windows, то всё, что вам нужно сделать — это добавить название файла opengl32.lib к общему списку параметров компоновщика.
- Библиотека OpenGL в Linux. Если вы работаете в операционной системе Linux, то вам нужно подключить библиотеку libGL.so с помощью ключей –lGL , добавляемых к параметрам вашего компоновщика. Если вы не можете найти данную библиотеку, то вам, вероятно, необходимо установить любой из пакетов Mesa, NVidia или AMD dev.
Затем, после добавления библиотек GLFW и OpenGL в настройки компоновщика, вы сможете подключить заголовочные файлы GLFW следующей строкой кода:
Примечание: Для пользователей Linux, использующих компилятор GCC, помочь скомпилировать проект помогут следующие параметры командной строки:
Неправильное линкование соответствующих библиотек приведет к возникновению ошибок.
На этом установка и настройка GLFW завершена.
Поскольку OpenGL на самом деле является лишь стандартом/спецификацией, то производитель драйверов должен реализовать спецификацию для драйвера, поддерживаемого конкретной видеокартой. Из-за того, что существует множество различных версий драйверов OpenGL, расположение большинства OpenGL-функций во время компиляции не известно и должно быть запрошено во время выполнения программы. Задача разработчика состоит в том, чтобы получить расположение нужных ему функций и сохранить их в виде указателей на функции для последующего использования. Получение мест расположений этих функций зависит от конкретной операционной системы.
В Windows это выглядит примерно следующим образом:
Как вы наверняка могли заметить, данный код выглядит несколько сложным, к тому же разработчикам придется каждый раз проходить через этот громоздкий процесс, совершая эти действия для каждой функции, которая может понадобиться, и которая еще не была объявлена. К счастью, есть решение — библиотека GLAD.
GLAD — это библиотека с открытым исходным кодом, которая управляет всей той громоздкой работой, о которой мы говорили выше. GLAD имеет несколько иную настройку конфигурации, чем большинство распространенных библиотек с открытым исходным кодом. Она использует веб-сервис, где мы можем сообщить GLAD, для какой версии OpenGL мы хотели бы определить и загрузить все соответствующие функции OpenGL.
Перейдите в веб-сервис GLAD, убедитесь, что в поле Language выбран язык C/C++ и в разделе API выберите версию OpenGL — 3.3 (именно её мы и будем использовать; хотя более новые версии также подойдут). Кроме того, убедитесь, что в поле Profile установлено Core :
Также параметр Generate a loader должен быть отмечен галочкой. Пункт Extensions мы пока пропустим, остается нажать кнопку Generate , чтобы создать нужные нам файлы библиотеки:
К этому моменту GLAD предоставит вам возможность скачать zip-архив, содержащий в себе две подключаемые папки и файл glad.c . Вам нужно скопировать обе эти папки ( glad и KHR ) в свою папку с подключаемыми файлами (или добавьте дополнительный элемент, указывающий на эти папки в свойствах проекта), а также добавить файл glad.c в свой проект.
После выполнения этих шагов вы сможете использовать следующую директиву include:
Теперь, при попытке скомпилировать проект, у вас не должно возникать никаких ошибок.
На следующем уроке мы рассмотрим использование GLFW, настройку контекста OpenGL и создание окна. Обязательно убедитесь, что все ваши include и library каталоги являются корректными и что имена библиотек в настройках компоновщика соответствуют указанным библиотекам.
Начнем с самого главного, установим необходимое программное обеспечение. Я предполагаю, что Windows у Вас уже установлен и работает, в противном случае вы купили не ту книгу. Во-первых, установите MSVisualC++6.0 и jdk113 или выше, если вам интересно узнать о написание java-апплетов с использованием OpenGL. Впрочем java понадобится вам только в седьмой главе. Во-вторых, нам понадобится реализация библиотеки OpenGL. Она входит в поставку Windows95/NT - это библиотеки opengl32.dll & glu32.dll. Вы также можете взять библиотеки OpenGL от Silicon Graphics. Инструкция по установке там прилагается. Вам придется скопировать opengl.dll и glu.dll в windows\system и положить opengl.lib, glu.lib в подкаталог Lib, где установлено MSVisualC++. В-третьих, вам понадобятся четыре моих программы-шаблона, которые представляют собой начальный скелет, который мы потом будем наполнять функциональностью. Где взять OpenGL от Silicon Graphics, Magician, jdk и мои программы-шаблоны, смотри в приложение 'А'.
7.3 Windows-приложение - Win32 Application
Достоинством является непосредственное взаимодействие с WinAPI. Начальная инициализация несколько усложняется, но зато вы имеете полноценное windows-приложение. Такой тип приложения подходит для написания серьезных больших программ. Кто-нибудь, конечно, скажет, что приложение непереносимо. Вам нужно написать работающее приложение для windows, а не неработающее, но переносимое приложение.
По поводу переносимости, хочу заметить следующее. В стандарте по языку Си сказано, что код на языке Си может быть платформенно независимым и платформенно зависимым. Из этого следует, что для обеспечения переносимости большой программы, вам придется делать несколько вариантов и затачивать ее под конкретные платформы. Код, относящийся к OpenGL, практически переносим. Непереносима только начальная инициализация. Конечно, вы можете попробовать Java-приложение, но тут возникают свои сложности. Так что, выбор за вами.
Создайте проект Win32 Application. Инструкции смотри в предыдущем разделе. Только имена дайте win и win.c. Теперь будем писать файл win.c. Внесите комментарии, заголовочные файлы и функции display и resize, см. предыдущий раздел. Из функций display и resize уберите слово CALLBACK. А в функции display замените auxSwapBuffers() на
После включения заголовочных файлов объявите следующие глобальные переменные.
Теперь вставьте код функции, которая устанавливает параметры контекста воспроизведения OpenGL.
Информацию о структуре PIXELFORMATDESCRIPTOR смотрите в справочнике. Я пользуюсь MSDN. Сейчас MSDN входит в MS Developer Studio. Редактировать параметры этой структуры вам вряд ли придется. А если придется, то я не смогу тут описать все. Перевести справочник я, конечно, могу, но это вам вряд ли поможет. Книга не предназначена для этого. Здесь рассматриваются конкретные примеры и упражнения.
И последнее, осталось написать функцию WinMain.
Исходный файл смотрите здесь. Исполняемый файл здесь.
2.7 Упражнение: "Снеговик"
Используя функцию glRotate, нарисуйте снеговика. Три сферы, шапка - конус, нос - тоже конус, глаза - сфера, рот можно квадратным сделать - glBox.
Исходный файл смотрите здесь. Исполняемый файл здесь.
Примечание: Имеется еще один баг в glaux.lib от Microsoft. Кажется, последний из обнаруженных мной. Функция aux[Solid/Wire]Cylinder прежде, чем нарисовать цилиндр, сдвигает и поворачивает координаты. Так что, если вы уже сместили и повернули координаты, то цилиндр нарисуется совсем не там, где вы рассчитывали. Люди из Microsoft, конечно же, будут уверять, что это особенность, и предложат вам скачать очередной ServicePack.;-) А я ниже расскажу, как более правильно рисовать цилиндры и конусы. Если вам некогда ждать, то далее приведен исправленный код этих функций. Большинство из вас сейчас пропустят его и перейдут к следующему очень интересному разделу - "Анимация". И правильно сделаете. К исправлению ошибок вернетесь, когда немного освоитесь. Но я все же решил привести код по исправлению ошибок Microsoft именно здесь. Можете пересобрать glaux.lib, заменив соответствующий код в файле shapes.c. Где взять исходники, смотрите в приложение 'A'. По-моему, они есть в MSDN.
2.10 Резюме
На этом эта глава книги закончена. Вы научились рисовать трехмерные объекты и делать интерактивную анимацию, используя эти объекты. Этого, в общем-то, достаточно для написания примитивных программ. В следующей главе мы научимся рисовать примитивные объекты: точки, линии, ломаные и многоугольники.
7.5 Java-апплеты - Magician Library
Достоинством данного типа приложения, конечно же, является переносимость( для тех платформ, для которых существует плагин) и незаменимое средство для web-программирования. Вы можете украсить свой web-сервер апплетами с трехмерной графикой. К вашим услугам все возможности OpenGL и объектно-ориентированного программирования. Недостатком является сложность программирования на языке Java. За короткое время(три месяца) работы с этим языком на меня свалилось очень много элементарных проблем: отсутствие форматированного ввода/вывода, непонятное поведение апплета - в разных броузерах по-разному; устаревшие методы, которые одним компилятором воспринимались нормально, а другой выдавал предупреждение, и прочие мелкие проблемы. Вообще, писать java-приложения, т.е. самостоятельные программы, я бы не советовал. Воспользуйтесь альтернативой - OpenGL Auxilary Library, рассмотренной в самом начале этой главы. Также можно воспользоваться аналогом GLAUX библиотекой GLUT, о которой пойдет речь ниже. Если же вам необходимо переносимое приложение, то возьмите его из примеров к Magician Library. Для java-апплетов - программ, исполняющихся в web-броузерах, альтернативы нет. Поэтому я и рассматриваю здесь программирование апплетов. У этого типа приложений имеются очень серьезные недостатки. Для запуска апплетов требуется плагин размером около двух мегабайт. Главным образом это связано с тем, что библиотека Magician осуществляет связку между классами Java и длл-модулями от Silicon Graphics, которые не входят в поставку Windows. Работают такие апплеты крайне нестабильно, во всяком случае на момент времени июнь 1999 года было много проблем. И самый главный недостаток, эта библиотека платная, если вы хотите распространять ее со своими коммерческими приложениями, то вам нужно купить лицензию. У меня на сайте находится пробная версия этой библиотеки. Сейчас вышла еще одна библиотека OpenGL для работы с java-апплетами, она называется GL4Java. Далее я ее рассмотрю.
Подробно описывать построение java-апплета, я думаю, излишне после рассмотренных здесь трех примеров приложений. Я лишь приведу здесь свой шаблонный файл template.java с комментариями.
Исходный файл смотрите здесь. Html файл здесь.
2.6 Поворот координат
Теперь рассмотрим вращение координат. Создайте новый проект с именем Rotate. Переименуйте glaux.c в rotate.c В функцию display вставьте следующий код:
Как видите, конус повернулся в абсолютных координатах. Так что, для того, чтобы нарисовать фигуру не в начале координат, надо:
- сохранить текущие координаты
- сдвинуть(glTranslated), повернуть(glRotated)
- нарисовать то, что хотели
- вернуться к старым координатам
Вызовы glPushMatrixglPopMatrix могут быть вложенными, т.е.:
Естественно число вызовов glPopMatrix должно соответствовать числу вызовов glPushMatrix, иначе у вас сцена улетит в неизвестном направление. Максимально допустимая глубина вложенности glPushMatrix/glPopMatrix определяется следующим образом:
Спецификация на OpenGL гарантирует, что глубина стека не может быть меньше 32.
2.2 Давайте что-нибудь изобразим
Самым простым объектом, с помощью которого можно увидеть всю мощь OpenGL, является сфера. Давайте попытаемся ее изобразить. Для этого надо создать новый проект в VisualC++, выполните следующие действия:
- Запустите MSVisualC++6.0
- Щелкните меню File->New->Win32 Console Application.
- Выберете каталог и имя проекта, впишите - sphere, щелкните OK.
Я все свои проекты держу на диске D в каталоге Projects. Projects ветвится дальше на подкаталоги с базами данных, утилитами, графикой и Java-приложениями. В общем, старайтесь присваивать разумные имена и вести разумную структуру каталогов. Это очень серьезная проблема.
Исходный файл смотрите здесь. Исполняемый файл здесь.
Теперь поясню назначение тех двух функций, что вы вставили в пункте 9. Функция glColor3d устанавливает текущий цвет, которым будут рисоваться фигуры. Тут нужно пояснить, как устанавливается цвет и общую философию в названии функций OpenGL. Цвет устанавливается четырьмя параметрами: красный, синий, зеленый и прозрачность. Эти параметры варьируют в диапазоне от нуля до единицы. Четвертый параметр нам пока не нужен, поэтому мы вызвали glColor с тремя параметрами. В этом случае, значение четвертого параметра, прозрачности, по умолчанию считается равным единице, т.е. абсолютно непрозрачным, ноль - будет абсолютно прозрачным. Так как в языке Си нет перегрузки функций, то применяется следующий синтаксис вызова функций - FuncionName[n=число параметров][тип параметров]. Доступны следующие типы:
- b - GLbyte байт
- s - GLshort короткое целое
- i - GLint целое
- f - GLfloat дробное
- d - GLdouble дробное с двойной точностью
- ub - GLubyte беззнаковый байт
- us - GLushort беззнаковое короткое целое
- ui - GLuint беззнаковое целое
- v - массив из n параметров указанного типа
В нашем случае - glColor3d - означает, что в функцию передается три параметра типа GLdouble. Также можно было вызвать glColor3i, т.е. три параметра типа GLint. Если тип параметров короткое целое, целое, байт или длинное, то компонента цвета приводится к диапазону [0,1]. Приведение к этому диапазону осуществляется по следующим образом. В случае беззнакового типа наибольшее возможное значение приводится к единице, ноль к нулю. В случае знакового максимальное значение приводится к единице или к минус единице, а минус единица будет приведена к единице. Мудрено, сразу и не поймешь. На практике вы будете пользоваться одним из трех случаев, рассмотренных в качестве примера ниже. Например, для беззнакового байта приведение будет осуществлено по следующей формуле: значение_переменной_хранимой_в_байте/255, т.к. 255 максимальное число, хранимое в одном байте. Функция glColor3dv означает, что в качестве параметров передается массив из трех элементов типа GLdouble. Например:
Функция auxSolidSphere - рисует сферу в начале координат и единичным радиусом. Освещение, создание ламп и установка положения камеры мы рассмотрим чуть позже, а пока давайте получше освоимся и почувствуем насколько здесь все просто. Первую программу под моим руководством вы уже написали. Теперь выполните самостоятельные упражнения.
7.7 Библиотека GLUT
Так получилось, что все примеры к этой книги я написал с использованием библиотеки GLAUX. Библиотека GLUT не менее, а может даже и более универсальная, чем GLAUX. Ее реализация доступна в исходных кодах на языке Си, и она собирается под самые различные платформы и реализации OpenGL. При написание программ для Windows недостатком является отсутствие библиотеки glut32.dll в стандартной поставке Windows. В следствие чего вам придется вместе со своей программой распространять еще и файл glut32.dll, который занимает около 150Кб. В то время как, с библиотекой GLAUX такой необходимости нет, ваш исполняемы файл будет работать на любой машине, где установлена операционная система Windows. Отмечу еще, что GLUT предоставляет больше возможностей по взаимодействия с операционной системой. Вы, например, можете создавать меню. Но в библиотеки GLUT нет таких функций, как [Solid/Wire]Box, [Solid/Wire]Cylinder. Правильные многогранники рисуются одного размера. Стоит еще заметить, что в ней нет ошибки Microsoft, когда у нас не получалось нарисовать на экране два конуса так, чтобы один из них был проволочный, а другой сплошной. Среди прилагающихся программ вы найдете приложение shapes_glut. Сравните с рисунком из упражнения "Рисуем трехмерные объекты".
Исходный файл смотрите здесь. Исполняемый файл здесь.
Я вам, вкратце, обрисовал все ЗА и ПРОТИВ, а вы уже сами решайте, что вам использовать в каждом конкретном случае. Для того чтобы создать приложение c использованием библиотеки GLUT выполните следующие действия:
- Cоздайте новый проект - "Консольное приложение Win32"
- В меню Build->Set Active Configuration выберите Release
- Далее Project->Settings->Link->Objetc/library modules: впишите следующие библиотеки opengl32.lib glu32.lib glut32.lib.
- Скопируйте мой шаблон glut.c и подключите его Project->Add To Project->Files
Далее я привожу исходный текст шаблонного файла glut.c с комментариями. Места выделенные серым цветом отличаются от того, что было в glaux.c, все остальное тоже самое.
При запуске игр и программ в Windows 11 и Windows 10 вы можете столкнуться с ошибкой, что запуск невозможен, так как на компьютере отсутствует opengl32.dll, либо он не предназначен для работы Windows или содержит ошибку. Вот известные мне игры и программы, которые используют OpenGL: PUBG, Minecraft, Doom, Adobe Photoshop, Blender, Google Earth.
OpenGl32.dll - это библиотека широко известной программы OpenGL для написания визуализации, обычно для игр. Дополнительные функции GPU помогают в аппаратном ускорении, и это значит, что функции рендеринга выполняются более эффективно по сравнению с функциями, выполняемыми на CPU. Тем самым вы заметите уменьшенную задержку, увеличение производительности и пропускную способностью.
7.2 Консольное приложение - Win32 Console Application
Здесь, как я уже говорил, начальная инициализация самая простая. Библиотека сделает за вас большинство действий. От вас потребуется совсем немного по сравнению с другими типами приложений. Итак, давайте для начала создадим проект. Общепризнанно, что тремя наилучшими компиляторами считаются GNU C, Microsoft C и Watcom C. Inprise (Borland) отпадает. Компиляторами других фирм я не пользовался. Все мои задачи решались вышеуказанными четырьмя компиляторами. Правда, должен заметить, что с 1997 года я практически прекратил пользоваться компилятором фирмы Borland. Лишь изредка, когда нужно было перекомпилировать старые утилиты, написанные еще для MSDOS. Эта книга для начинающих, и я хочу сделать ее понятной большинству читателей. Поэтому я не буду рассматривать проекты для GNU C или Watcom C. Не хочу здесь городить непонятные многим начинающим makefile'ы. Однако, в конце данной главы будет разобрано приложение для UNIX, там уже от makefile'ов никуда не деться. Теперь вернемся к нашим баранам.
- Запустите MSVisualC++6.0
- Щелкните меню File->New->Win32 Console Application.
- Выберете каталог и имя проекта задайте glaux, щелкните OK.
- Выберете An Empty Project, щелкните Finish.
- Создайте новый текстовый файл и сохраните его с именем glaux.c.
- Присоедините его к проекту. Project->Add To Project->Files
- Щелкните Build->Set Active Configuration и установите тип проекта glaux - Win32 Release
- Далее щелкаете Project->Settings->Link->Object/library modules: и добавьте туда opengl32.lib, glu32.lib и glaux.lib
Проект у нас теперь есть, давайте писать glaux.c. Файл, в котором находится исходный код программы, желательно начинать с комментария. Это необязательно, но этого требует хороший стиль. В комментариях можно указать имя автора, способ связи - обычно, адрес электронной почты. Далее, можно кратко описать, что находится в этом файле. Неплохо вести некоторый дневник здесь же: что и когда вы добавили. У меня эти комментарии выглядят так:
Теперь надо включить заголовочные файлы:
Давайте напишем функцию main(). Я посчитал, что наиболее правильно и понятно будет дать код и прокомментировать его подробно. У меня функция main() выглядит так:
Вот и все с функцией main(). Осталось написать код функции resize и функции display. Вставьте следующий код перед функцией main().
Здесь нужно сделать пояснения по поводу glMatrixMode. Функции glOrtho и glFrustum работают с матрицей, отвечающей за тип проекции. Они просто загружают соответствующую матрицу. Вы можете установить свой тип проекции, если вам это понадобится. Сначала вы говорите, что будете изменять матрицу проекции - glMatrixMode с параметром GL_PROJECTION. Потом, с помощью glLoadMatrix загружаете соответствующую матрицу. Функции glTranslate/glRotate работают с матрицей вида. Ее мы загружаем последней строкой - glMatrixMode( GL_MODELVIEW ).
В параметрах контекста воспроизведения мы установили AUX_DOUBLE. Это значит, что рисоваться все будет сначала в буфер. Для того, что бы скопировать содержимое буфера на экран, вызывается функция auxSwapBuffers(). Если вы программировали анимацию для MSDOS или Windows, то наверняка использовали такой прием, чтобы избавиться от мерцания на экране. В функции display мы сначала очищаем буфер. Цвет, которым заполняется буфер при очищении, можно установить в функции main() вызовом glClearColor(r,g,b).
Исходный файл смотрите здесь. Исполняемый файл здесь.
Читайте также: