Как сделать куб в OpenGL (с изображениями)

Оглавление:

Как сделать куб в OpenGL (с изображениями)
Как сделать куб в OpenGL (с изображениями)

Видео: Как сделать куб в OpenGL (с изображениями)

Видео: Как сделать куб в OpenGL (с изображениями)
Видео: Как установить Windows XP на VirtualBox 2024, Марш
Anonim

OpenGL - это мощный инструмент трехмерного программирования, используемый для рисования сложных трехмерных сцен из простых примитивов. В этой статье вы узнаете, как нарисовать простой куб, который можно вращать и просматривать в трех измерениях!

Для этого проекта вам понадобится редактор кода и некоторые знания программирования на C.

Шаги

Часть 1 из 3: Начальная настройка

1994315 1 1
1994315 1 1

Шаг 1. Установка OpenGL Для начала выполните следующие шаги для установки OpenGL в вашей системе

Если у вас уже установлен OpenGL и совместимый компилятор C, вы можете пропустить этот шаг и перейти к следующему.

1994315 2 1
1994315 2 1

Шаг 2. Создайте документ

Создайте новый файл в своем любимом редакторе кода и сохраните его как mycube.c

1994315 3 1
1994315 3 1

Шаг 3. Добавьте #includes

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

    // Включает #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif

1994315 4 1
1994315 4 1

Шаг 4. Добавьте прототипы функций и глобальные переменные

Ваш следующий шаг - объявить несколько прототипов функций.

    // Прототипы функций void display (); void specialKeys (); // Глобальные переменные double rotate_y = 0; двойной rotate_x = 0;

1994315 5 1
1994315 5 1

Шаг 5. Настройте функцию main ()

    int main (int argc, char * argv ) {// Инициализируем GLUT и обрабатываем пользовательские параметры glutInit (& argc, argv); // Запрос окна истинного цвета с двойной буферизацией с Z-буфером glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

  • Это утверждение настраивает вашу среду. При написании программ OpenGL важно помнить, что вы должны просить обо всем. Это требует от вас лучшего понимания того, как работает ваша программа, и того, что вам нужно включить, чтобы получить желаемую функциональность. В этой строке вы настроите дисплей с двойной буферизацией, цветом RGB и Z-буфером.
  • Двойная буферизация - это метод, используемый в графических программах для устранения проблемы, возникающей из-за того, как изображения выводятся на экран. Каждый раз, когда вы перерисовываете сцену, сначала нужно стереть дисплей, а затем будет отображена новая информация. Без двойной буферизации вы будете наблюдать эффект мерцания, когда экран будет постоянно стираться и перерисовываться.
  • Эта проблема устраняется добавлением второго буфера для рисования. С помощью этого метода изображение помещается в первый буфер, и этот буфер отображается вам. Следующий кадр будет отрисован во втором буфере, и когда это будет сделано, два буфера поменяются местами. Вы сразу увидите второй буфер, но, скрытый от нас, первый буфер стирается и перерисовывается с третьим кадром, который будет заменен по завершении.
  • Вы также хотите включить Цвет RGB система в вашем окне.
  • Z-буферизация вот как вы получаете желаемые 3D-эффекты. OpenGL использует трехмерную систему координат с осями x, y и z. Чтобы создать эффект, что объект находится ближе к вам, его положение по оси z увеличивается, однако, чтобы он казался дальше, его положение по оси z уменьшается.
1994315 6 1
1994315 6 1

Шаг 6. Создайте окно

Следующий шаг - создать окно внутри которого вы нарисуете куб. В этом уроке окно называется «Удивительный куб».

    // Создание окна glutCreateWindow ("Awesome Cube");

1994315 7 1
1994315 7 1

Шаг 7. Включите проверку глубины

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

    // Включить проверку глубины Z-буфера glEnable (GL_DEPTH_TEST);

1994315 8 1
1994315 8 1

Шаг 8. Добавьте функции обратного вызова

Вот прототипы функций обратного вызова, для которых вы написали ранее. Эти функции будут вызываться каждый раз при прохождении основного цикла. Функция отображения перерисовывает сцену на основе любых изменений переменных, которые были внесены с момента предыдущего вызова. Функция specialKeys позволяет нам взаимодействовать с программой.

    // Функции обратного вызова glutDisplayFunc (display); glutSpecialFunc (specialKeys);

1994315 9 1
1994315 9 1

Шаг 9. Запустите MainLoop

Это вызовет основную функцию до тех пор, пока вы не закроете программу, чтобы разрешить анимацию и взаимодействие с пользователем.

    // Передаем управление событиям GLUT glutMainLoop (); // Вернуться в ОС return 0; }

Часть 2 из 3: Функция display ()

1994315 10 1
1994315 10 1

Шаг 1. Разберитесь в назначении этой функции

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

Концептуально каждая сторона будет нарисована, определив четыре угла и позволив OpenGL соединить линии и залить их определенным вами цветом. Ниже приведены шаги для этого

1994315 11 1
1994315 11 1

Шаг 2. Добавьте glClear ()

Первый шаг, который вам нужно сделать в этой функции, - это очистить буфер цвета и Z. Без этих шагов старые рисунки все еще могут быть видны под новыми рисунками, а нарисованные объекты не будут находиться в правильном месте на экране.

    void display () {// Очистить экран и Z-буфер glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

1994315 12 1
1994315 12 1

Шаг 3. Добавьте glBegin () и glEnd ()

OpenGL определяет объекты как комбинации различных полигонов. С помощью glBegin () вы положите карандаш, чтобы нарисовать фигуру. Чтобы поднять карандаш и начать новую форму, вы должны использовать glEnd () команда. В этом руководстве вы будете использовать GL_POLYGON для рисования каждой стороны куба, но можно использовать другие параметры параметров, такие как GL_LINE, GL_QUAD или GL_TRIANGLE, для создания других форм.

  • Здесь вы начнете с передней части куба. Позже вы добавите цвет ко всем 6 сторонам.
  • // Разноцветная сторона - FRONT glBegin (GL_POLYGON); // Вершины будут добавлены на следующем шаге glEnd ();

1994315 13 1
1994315 13 1

Шаг 4. Добавьте glVertex3f ()

После того, как вы заявили, что хотите начать свой многоугольник, вам нужно определить вершины объекта. glVertex имеет несколько форм в зависимости от того, что вы хотите делать с вашим объектом.

  • Во-первых, в скольких измерениях вы работаете. 3 выше в glVertex3f говорят, что вы рисуете в 3-х измерениях. Также можно работать в 2 или 4 измерениях. F выше в glVertex3f говорит, что вы работаете с числами с плавающей запятой. Вы также можете использовать короткие, целые или двойные числа.
  • Обратите внимание, что эти точки определены в против часовой стрелки манера. На данный момент это не очень важно, но когда вы начнете работать с освещением, текстурами и отбраковкой, это станет невероятно важным, поэтому возьмите за привычку определять свои точки против часовой стрелки.
  • Добавьте вершины между линиями glBegin () и glEnd ().
  • // Разноцветная сторона - FRONT glBegin (GL_POLYGON); glVertex3f (-0,5, -0,5, -0,5); // P1 glVertex3f (-0,5, 0,5, -0,5); // P2 glVertex3f (0.5, 0.5, -0.5); // P3 glVertex3f (0.5, -0.5, -0.5); // P4 glEnd ();

1994315 14 1
1994315 14 1

Шаг 5. Добавьте glColor3f ()

glColor работает аналогично glVertex. Вы можете определять точки как короткие, целые, двойные или плавающие. Каждый цвет имеет значение от 0 до 1. Все 0 делают точку черной, а все единицы делают точку белой. Число 3 в glColor3f () относится к цветовой системе RGB без альфа-канала. Альфа цвета определяет его прозрачность. Чтобы изменить альфа-уровень, используйте glColor4f () с последним параметром, имеющим значение от 0 до 1 для непрозрачного или прозрачного.

  • Когда вы вызываете glColor3f (), каждая вершина, нарисованная с этой точки, будет этого цвета. Следовательно, если вы хотите, чтобы все четыре вершины были красными, просто установите цвет один раз в любое время перед командами glVertex3f (), и все вершины будут красными.
  • Определенная ниже лицевая сторона показывает, как определить новый цвет для каждой вершины. Когда вы это сделаете, вы увидите интересное свойство цветов OpenGL. Поскольку каждая вершина многоугольника имеет свой цвет, OpenGL автоматически смешивает цвета! Следующий шаг покажет, как присвоить четырем вершинам один и тот же цвет.
  • // Разноцветная сторона - FRONT glBegin (GL_POLYGON); glColor3f (1.0, 0.0, 0.0); glVertex3f (0,5, -0,5, -0,5); // P1 красный glColor3f (0.0, 1.0, 0.0); glVertex3f (0,5, 0,5, -0,5); // P2 зеленый glColor3f (0.0, 0.0, 1.0); glVertex3f (-0,5, 0,5, -0,5); // P3 синий glColor3f (1.0, 0.0, 1.0); glVertex3f (-0,5, -0,5, -0,5); // P4 фиолетовый glEnd ();

1994315 15 1
1994315 15 1

Шаг 6. Обработайте остальные стороны

Определите расположение каждой вершины для других пяти сторон куба, но для простоты они были вычислены для вас и включены в таблицу final display () функция ниже.

    // Белая сторона - НАЗАД glBegin (GL_POLYGON); glColor3f (1.0, 1.0, 1.0); glVertex3f (0,5, -0,5, 0,5); glVertex3f (0,5, 0,5, 0,5); glVertex3f (-0,5, 0,5, 0,5); glVertex3f (-0,5, -0,5, 0,5); glEnd (); // Фиолетовая сторона - ПРАВА glBegin (GL_POLYGON); glColor3f (1.0, 0.0, 1.0); glVertex3f (0,5, -0,5, -0,5); glVertex3f (0,5, 0,5, -0,5); glVertex3f (0,5, 0,5, 0,5); glVertex3f (0,5, -0,5, 0,5); glEnd (); // Зеленая сторона - ЛЕВАЯ glBegin (GL_POLYGON); glColor3f (0,0, 1,0, 0,0); glVertex3f (-0,5, -0,5, 0,5); glVertex3f (-0,5, 0,5, 0,5); glVertex3f (-0,5, 0,5, -0,5); glVertex3f (-0,5, -0,5, -0,5); glEnd (); // Синяя сторона - TOP glBegin (GL_POLYGON); glColor3f (0,0, 0,0, 1,0); glVertex3f (0,5, 0,5, 0,5); glVertex3f (0,5, 0,5, -0,5); glVertex3f (-0,5, 0,5, -0,5); glVertex3f (-0,5, 0,5, 0,5); glEnd (); // Красная сторона - НИЖНИЙ glBegin (GL_POLYGON); glColor3f (1.0, 0.0, 0.0); glVertex3f (0,5, -0,5, -0,5); glVertex3f (0,5, -0,5, 0,5); glVertex3f (-0,5, -0,5, 0,5); glVertex3f (-0,5, -0,5, -0,5); glEnd (); glFlush (); glutSwapBuffers (); }

  • Мы также хотим добавить две последние строки кода для этой функции. Эти glFlush ();

    а также glutSwapBuffers ();

    которые дают нам эффект двойной буферизации, о котором вы узнали ранее.

Часть 3 из 3. Взаимодействие с пользователем

1994315 16 1
1994315 16 1

Шаг 1. Добавьте specialKeys ()

Вы почти закончили, но на данный момент вы можете нарисовать куб, но не можете его повернуть. Для этого вам нужно создать specialKeys () функция, позволяющая нам нажимать клавиши со стрелками и вращать куб!

  • Именно поэтому вы объявили глобальные переменные rotate_x и rotate_y. Когда вы нажимаете клавиши со стрелками вправо и влево, rotate_y будет увеличиваться или уменьшаться на 5 градусов. Точно так же, когда вы нажимаете клавиши со стрелками вверх и вниз, rotate_x изменится соответствующим образом.
  • void specialKeys (int key, int x, int y) {// Стрелка вправо - увеличить поворот на 5 градусов if (key == GLUT_KEY_RIGHT) rotate_y + = 5; // Стрелка влево - уменьшить поворот на 5 градусов иначе if (key == GLUT_KEY_LEFT) rotate_y - = 5; иначе, если (ключ == GLUT_KEY_UP) rotate_x + = 5; иначе, если (клавиша == GLUT_KEY_DOWN) rotate_x - = 5; // Запросить обновление дисплея glutPostRedisplay (); }

1994315 17 1
1994315 17 1

Шаг 2. Добавьте glRotate ()

Ваше последнее утверждение - добавить оператор, который будет вращать ваш объект. Вернитесь к функции display () и перед ПЕРЕДНЕЙ стороной добавьте следующие строки:

    // Сбросить преобразования glLoadIdentity (); // Поворот, когда пользователь изменяет rotate_x и rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0); glRotatef (rotate_y, 0,0, 1,0, 0,0); // Разноцветная сторона - ПЕРЕДНЯЯ….

  • Сначала обратите внимание, что синтаксис glRotatef () похож на glColor3f () и glVertex3f (), но всегда требует 4 параметра. Первый параметр - это применяемая степень вращения. Следующие три параметра определяют, вокруг какой оси вращаться: первая - ось x, вторая - ось y, а третья - ось z. Сейчас вам нужно только вращать вокруг оси x и y.
  • Для всех преобразований, которые вы пишете в своей программе, нужны строки, подобные этой. Концептуально вы можете думать об этом как о вращении вашего объекта вокруг оси x на величину, определяемую параметром rotate_x, а затем вращение вокруг оси y с помощью rotate_y. Однако OpenGL объединяет все эти операторы в одно матричное преобразование. Каждый раз, когда вы вызываете функцию отображения, вы строите матрицу преобразования и glLoadIdentity () гарантирует, что вы будете начинать с новой матрицы на каждом проходе.
  • Другие функции преобразования, которые вы можете применить, - это glTranslatef () и glScalef (). Эти функции похожи на glRotatef () за исключением того, что они принимают только 3 параметра, значения x, y и z для перемещения или масштабирования объекта.
  • Чтобы получить правильный эффект при применении всех трех преобразований к одному объекту, вам необходимо применить их в правильном порядке. Всегда пишите их по порядку glTranslate, glRotate, затем glScale. OpenGL по существу применяет преобразования снизу вверх. Чтобы понять это, попробуйте представить, как будет выглядеть простой куб 1x1x1 с преобразованиями, если OpenGL применяет их сверху вниз и если OpenGL применяет их снизу вверх.
1994315 18 1
1994315 18 1

Шаг 3. Добавьте следующие команды, чтобы масштабировать куб на 2 по оси x, на 2 по оси y, повернуть куб на 180 градусов вокруг оси y и сдвинуть куб на 0,1 вдоль оси x

Убедитесь, что эти и предыдущие команды glRotate () расположены в правильном порядке, как описано выше. (Если вы не уверены, это сделано в окончательном коде в конце руководства.)

    // Другие преобразования glTranslatef (0.1, 0.0, 0.0); glRotatef (180, 0,0, 1,0, 0,0); glScalef (2.0, 2.0, 0.0);

1994315 19 1
1994315 19 1

Шаг 4. Скомпилируйте и запустите свой код

Предполагая, что вы используете gcc в качестве компилятора, запустите эти команды из вашего терминала, чтобы скомпилировать и протестировать вашу программу.

    В Linux: gcc cube.c -o cube -lglut -lGL./ mycube На Mac: gcc -o foo foo.c -framework GLUT -framework OpenGL./ mycube В Windows: gcc -Wall -ofoo foo.c -lglut32cu - lglu32 -lopengl32./ mycube

1994315 20 1
1994315 20 1

Шаг 5. Проверьте свой полный код

Должно получиться так:

    // // Файл: mycube.c // Автор: Мэтт Дэйсли // Дата создания: 25.04.2012 // Проект: Исходный код для создания куба в OpenGL // Описание: Создает окно OpenGL и рисует 3D-куб / / Что пользователь может вращать с помощью клавиш со стрелками // // Элементы управления: Стрелка влево - Повернуть влево // Стрелка вправо - Повернуть вправо // Стрелка вверх - Повернуть вверх // Стрелка вниз - Повернуть вниз // ------ -------------------------------------------------- -- // Включает в себя // ------------------------------------------- --------------- #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif // ------------- --------------------------------------------- // Прототипы функций / / ------------------------------------------------- --------- void display (); void specialKeys (); // ------------------------------------------------ ---------- // Глобальные переменные // ---------------------------------- ------------------------ двойной rotate_y = 0; двойной rotate_x = 0; // ------------------------------------------------ ---------- // Функция обратного вызова display () // ------------------------------- --------------------------- void display () {// Очистить экран и Z-буфер glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Сброс преобразований glLoadIdentity (); // Другие преобразования // glTranslatef (0.1, 0.0, 0.0); // Не включается // glRotatef (180, 0.0, 1.0, 0.0); // Не включено // Поворот, когда пользователь изменяет rotate_x и rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0); glRotatef (rotate_y, 0,0, 1,0, 0,0); // Другие преобразования // glScalef (2.0, 2.0, 0.0); // Не входит // Разноцветная сторона - FRONT glBegin (GL_POLYGON); glColor3f (1.0, 0.0, 0.0); glVertex3f (0,5, -0,5, -0,5); // P1 красный glColor3f (0.0, 1.0, 0.0); glVertex3f (0,5, 0,5, -0,5); // P2 зеленый glColor3f (0.0, 0.0, 1.0); glVertex3f (-0,5, 0,5, -0,5); // P3 синий glColor3f (1.0, 0.0, 1.0); glVertex3f (-0,5, -0,5, -0,5); // P4 фиолетовый glEnd (); // Белая сторона - НАЗАД glBegin (GL_POLYGON); glColor3f (1.0, 1.0, 1.0); glVertex3f (0,5, -0,5, 0,5); glVertex3f (0,5, 0,5, 0,5); glVertex3f (-0,5, 0,5, 0,5); glVertex3f (-0,5, -0,5, 0,5); glEnd (); // Фиолетовая сторона - ПРАВА glBegin (GL_POLYGON); glColor3f (1.0, 0.0, 1.0); glVertex3f (0,5, -0,5, -0,5); glVertex3f (0,5, 0,5, -0,5); glVertex3f (0,5, 0,5, 0,5); glVertex3f (0,5, -0,5, 0,5); glEnd (); // Зеленая сторона - ЛЕВАЯ glBegin (GL_POLYGON); glColor3f (0,0, 1,0, 0,0); glVertex3f (-0,5, -0,5, 0,5); glVertex3f (-0,5, 0,5, 0,5); glVertex3f (-0,5, 0,5, -0,5); glVertex3f (-0,5, -0,5, -0,5); glEnd (); // Синяя сторона - TOP glBegin (GL_POLYGON); glColor3f (0,0, 0,0, 1,0); glVertex3f (0,5, 0,5, 0,5); glVertex3f (0,5, 0,5, -0,5); glVertex3f (-0,5, 0,5, -0,5); glVertex3f (-0,5, 0,5, 0,5); glEnd (); // Красная сторона - НИЖНИЙ glBegin (GL_POLYGON); glColor3f (1.0, 0.0, 0.0); glVertex3f (0,5, -0,5, -0,5); glVertex3f (0,5, -0,5, 0,5); glVertex3f (-0,5, -0,5, 0,5); glVertex3f (-0,5, -0,5, -0,5); glEnd (); glFlush (); glutSwapBuffers (); } // ----------------------------------------------- ----------- // Функция обратного вызова specialKeys () // ------------------------------ ---------------------------- void specialKeys (int key, int x, int y) {// Стрелка вправо - увеличить поворот на 5 градус if (key == GLUT_KEY_RIGHT) rotate_y + = 5; // Стрелка влево - уменьшить поворот на 5 градусов иначе if (key == GLUT_KEY_LEFT) rotate_y - = 5; иначе, если (ключ == GLUT_KEY_UP) rotate_x + = 5; иначе, если (клавиша == GLUT_KEY_DOWN) rotate_x - = 5; // Запросить обновление дисплея glutPostRedisplay (); } // ----------------------------------------------- ----------- // основная функция // ------------------------------- --------------------------- int main (int argc, char * argv ) {// Инициализируем GLUT и обрабатываем пользовательские параметры glutInit (& argc, argv); // Запрос окна истинного цвета с двойной буферизацией с Z-буфером glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // Создаем окно glutCreateWindow ("Awesome Cube"); // Включить проверку глубины Z-буфера glEnable (GL_DEPTH_TEST); // Функции обратного вызова glutDisplayFunc (display); glutSpecialFunc (specialKeys); // Передаем управление событиям GLUT glutMainLoop (); // Возврат в ОС return 0; }

Рекомендуемые: