Як зробити куб в OpenGL

Фото - Як зробити куб в OpenGL

OpenGL - це потужний інструмент для 3D-програмування, що дозволяє створювати складні тривимірні оточення і сцени з простих примітивів. Ця стаття навчить вас малювати куб, звичайний куб, який можна вертіти на всі боки!



Для цього проекту вам потрібно знання С і середовище розробки.




Частина 1 з 4: Первісна установка і main ()

1) Установка OpenGL

  • Почніть з цієї статті з установки OpenGL на ваш комп`ютер. Якщо OpenGL і компілятор С у вас вже є, можете пропустити цей крок.

2) Створення нового файлу

  • В улюбленому текстовому редакторі створіть новий файл і збережіть його як mycube.c

3) #includes

  • Власне, ось основні директиви #include, які нам знадобляться. Важливо пам`ятати, що директиви для різних операційних систем - різні, а тому вибирати треба все, щоб програму можна було запустити на будь-якій системі.

    // Includes#include #include #include #define GL_GLEXT_PROTOTYPES#ifdef __APPLE__#include #else#include #endif

4) Функціональні прототипи і глобальине змінні

  • Пора б і оголосити функціональні прототипи.

    // Функціональні прототипиvoid display();void specialKeys();// Глобальні змінніdouble rotate_y=0;double rotate_x=0;

  • Детальніше кожна з цих функцій і змінних буде пояснена трохи пізніше, а поки що важливо вже те, що ми їх оголосили.

5) Робота з функцією main ()

  • int main(int argc, char* argv[])// Ініціалізувавши GLUT і обробляємо користувальницькі параметриglutInit(argc,argv);// Запитувані вікно з підтримкою подвійної буферизації, z-буферизації і колірної схеми True ColorglutInitDisplayMode(GLUT_DOUBLE 

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

  • Вся робота з отрисовкой куба ляже на тендітні строчки цієї фукнции. У загальному і цілому, куб буде представлений як 6 окремих граней, розміщених у відповідних координатах.

  • Відповідно, кожна грань матиме по 4 сторони і 4 кута, що дозволить OpenGL з`єднати лінії і заповнити область між ними кольором. Про це ми теж розповімо.

1) glClear ()

  • Першим ділом, працюючи з цією функцією, нам треба очистити колір і Z-буфер. Без цього під новим малюнком буде виднітися старий, а намальовані програмою об`єкти будуть розташовані неправильно.

    void display()// Очищаємо екран і z-буферизациюglClear(GL_COLOR_BUFFER_BIT


  • Зверніть увагу на два останні рядки. Це функції glFlush () - і glutSwapBuffers () -, які і дають ефект подвійної буферизації.

Частина 3 з 4: Інтерактивність програми

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 градусівelse if (key == GLUT_KEY_LEFT)rotate_y -= 5;else if (key == GLUT_KEY_UP)rotate_x += 5;else if (key == GLUT_KEY_DOWN)rotate_x -= 5;// Запит оновлення екрануglutPostRedisplay();}

2) glRotate ()

  • Останнє, що ми зробимо, так це додамо рядок, яка дозволить нам обертати об`єкт. Поверніться до функції display () і перед описом ПЕРЕДНІЙ боку додайте:

    // Скидання трансформаційglLoadIdentity();// Обертання при зміні користувачем значень rotate_x і rotate_yglRotatef( 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 і у.

  • Для всіх трансформацій, які ми задаємо в програмі, потрібні аналогічні рядки. По суті, ми представляємо обертання об`єкта по осі х як зміна значення rotate_x, а обертання по осі у - як зміна значення rotate_y. Втім, OpenGL об`єднає всі в одну матрицю трансформації. Всякий раз, викликаючи функцію display, ми будемо створювати матрицю трансформації, і glLoadIdentity () дозволить нам починати щоразу з нової матриці.

  • Інші функції трансформації, яким ми могли скористатися, це glTranslatef () і glScalef (). Вони аналогічні glRotatef (), але лише з тим винятком, що вимагають лише 3 параметри: значення x, y і z для зміни і масштабування об`єкта.

  • Щоб все відображалося правильно, коли всі три трансформації застосовані до одного об`єкту, потрібно задавати трансформації у відповідному порядку, а саме glTranslate, glRotate, glScale - і ніколи інакше. OpenGL трансформує об`єкт, читаючи програму "знизу вгору". Щоб краще це зрозуміти, уявіть, як куб 1x1x1 буде виглядати після всіх трансформацій, якби OpenGL застосовував їх у тому порядку, як ті вказані (зверху вниз), а потім подумайте, як OpenGL обробить куб, читаючи інструкції знизу вгору.

  • Додайте наступні команди для двократного масштабування куба по осях х і у, для обертання куба на 180 градусів по осі у, а також для переміщення куба на 0.1 по осі х. Переконайтеся, що всі відповідні команди, включаючи раніше задані команди glRotate (), вказані в правильному порядку. Якщо боїтеся помилитися, дивіться фінальну версію програми

    // Інші трансформаціїglTranslatef( 0.1, 0.0, 0.0 );glRotatef( 180, 0.0, 1.0, 0.0 );glScalef( 2.0, 2.0, 0.0 );

Компіляція

  • Чим закінчується будь-який проект на OpenGL? Чим закінчиться ваш перший проект на OpenGL? Правильно, кнопкою compile and run your code (Компілювати і запустити). Припустимо, в якості компілятора у вас 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

Частина 4 з 4: Фінальний код

  • Отже, сталося! Готова ваша перша програма на OpenGL! Ось вихідний код від автора статті, в якому не переведені коментарі і все інше.

    //// File: mycube.c// Author: Matt Daisley// Created: 4/25/2012// Project: Source code for Make a Cube in OpenGL// Description: Creates an OpenGL window and draws a 3D cube// That the user can rotate using the arrow keys// // Controls: Left Arrow - Rotate Left// Right Arrow - Rotate Right// Up Arrow- Rotate Up// Down Arrow - Rotate Down // ------------------------------------------------ ---------;// Includes// ------------------------------------------------ ---------;#include #include #include #define GL_GLEXT_PROTOTYPES#ifdef __APPLE__#include #else#include #endif// ------------------------------------------------ ---------;// Function Prototypes// ------------------------------------------------ ---------;void display();void specialKeys();// ------------------------------------------------ ---------;// Global Variables// ------------------------------------------------ ---------;double rotate_y=0;double rotate_x=0;// ------------------------------------------------ ---------;// Display () Callback function// ------------------------------------------------ ---------;void display()// Clear screen and Z-bufferglClear(GL_COLOR_BUFFER_BIT// ------------------------------------------------ ---------;// SpecialKeys () Callback Function// ------------------------------------------------ ---------;void specialKeys( int key, int x, int y ) {// Right arrow - increase rotation by 5 degreeif (key == GLUT_KEY_RIGHT)rotate_y += 5;// Left arrow - decrease rotation by 5 degreeelse if (key == GLUT_KEY_LEFT)rotate_y -= 5;else if (key == GLUT_KEY_UP)rotate_x += 5;else if (key == GLUT_KEY_DOWN)rotate_x -= 5;// Request display updateglutPostRedisplay();}// ------------------------------------------------ ---------;// Main () function// ------------------------------------------------ ---------;int main(int argc, char* argv[])// Initialize GLUT and process user parametersglutInit(argc,argv);// Request double buffered true color window with Z-bufferglutInitDisplayMode(GLUT_DOUBLE