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

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

кроки

Частина 1 з 3:
первісна установка
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 з 3:
    Функція display ()
    1. Зрозумійте призначення функції display (). Вся робота по отрисовке куба ляже на тендітні рядки цієї функції. Ідея в цілому така: ви намалюєте шість окремих граней куба і розмістіть їх у відповідних позиціях.
    • Для кожної грані ви задасте чотири кути, а OpenGL з`єднає їх лініями і виконає заливку обраним вами кольором. Нижче буде розказано, як це зробити.
  • 2. Додайте функцію glClear (). Насамперед, працюючи з цією функцією, нам треба очистити колір і z-буфер. Без цього під новим малюнком буде виднітися старий, а намальовані програмою об`єкти будуть розташовані неправильно.
    void display () GL_DEPTH_BUFFER_BIT)-
  • 3. Додайте glBegin () і glEnd (). Об`єкти в OpenGL - це комбінації різних багатокутників. команда glBegin () дозволить нам з вами намалювати об`єкт - це як би олівець, яким ви малюєте фігуру, не відриваючи його від паперу. Щоб відірвати олівець від листа і почати малювати щось нове, потрібна команда glEnd (). У даній статті ми будемо використовувати GL_POLYGON для відтворення кожної грані куба, хоча для створення інших форм можна скористатися і іншими параметрами, такими як GL_LINE, GL_QUAD або GL_TRIANGLE.
  • Почніть з передньої сторони куба. Пізніше ми додамо колір до кожної з шести граней.
  • // Багатобарвна сторона - ПЕРЕДНЯЯglBegin (GL_POLYGON) - // Вершини додамо в наступному шагеglEnd ()-
  • 4. Додайте функцію glVertex3f (). Тепер, коли ви пояснили програмі, що хочете почати малювати багатокутник, потрібно задати вершини об`єкта. У функції glVertex є кілька форм, використання яких залежить від того, що ви маєте намір робити зі своїм об`єктом.
  • Перше - у скількох вимірах ви будете працювати? Цифра 3 в in glVertex3f вказує на три виміри. Втім, можна працювати і в 2, і в 4 вимірах. Буква f, в свою чергу, вказує на те, що ми працюємо з цифрами з плаваючою комою. Втім, тут ви можете використовувати і дані типів integer, double або short.
  • Зауважте, що всі точки задаються проти годинникової стрілки. Поки це ще не дуже важливо, але коли ви почнете працювати над освітленням, текстурування, обробкою нецільових граней, то звичка прописувати все проти годинникової стрілки вам дуже придасться.
  • Додайте вершини між лініями glBegin () і glEnd ().


  • // Багатобарвна сторона - ПЕРЕДНЯЯglBegin (GL_POLYGON) -glVertex3f (-0.5, -0.5, -0.5) - // P1glVertex3f (-0.5,0.5, -0.5) - // P2glVertex3f (0.5,0.5, -0.5) - // P3glVertex3f (0.5, -0.5, -0.5) - // P4glEnd ()-
  • 5. Додайте функцію glColor3f (). glColor діє багато в чому аналогічно glVertex. Точки можна задати даними типів short, integer, double або float. У кожного кольору є значення від 0 до 1. Всі нулі - це чорний колір, всі одиниці - відповідно, білий. Цифра 3 в glColor3f () вказує на колірну схему RGB без альфа-каналу. Альфа-канал кольору відповідає за його прозорість. Щоб змінити значення альфа-каналу, використовуйте glColor4f () з останнім параметром від 0 до 1, тобто від непрозорості до прозорості.
  • Викликаючи glColor3f (), ми отрісовиваємих кожну вершину від зазначеної точки в зазначеному кольорі. Іншими словами, якщо всі чотири вершини повинні бути червоними, то просто один-єдиний раз задайте значення кольору до виклику команд glVertex3f (), і всі вони будуть червоними.
  • На прикладі заданої нижче передньої сторони можна побачити, як задається новий колір кожної вершини. Коли ви це робите, то можете познайомитися з цікавою особливістю квітів OpenGL. Так як кожна вершина багатокутника має свій колір, OpenGL автоматично змішує кольори! Код, розміщений далі, показує, як створити чотири вершини з однаковим кольором.
  • // Багатобарвна сторона - ПЕРЕДНЯЯ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 ()-
  • 6. Намалюйте інші грані куба. Краще, звичайно, якщо ви самі знайдете місце розташування інших граней куба і кожної з вершин, але заради простоти ми розрахували їх для вас. Код наведено в фінальної функції 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 () - // Синя сторона - ВЕРХНЯЯ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:
    інтерактивність програми
    1. Додайте функцію specialKeys (). В принципі, все вже майже готове, однак куб тільки промальовується і не обертається. Для цього треба створити функцію specialKeys (), яка дозволить обертати куб, натискаючи на клавіші-стрілки!
    • Саме заради цієї функції були оголошені глобальні змінні rotate_x і rotate_y. Коли ви будете натискати на клавіші-стрілки «вліво» і «вправо», значення rotate_y буде збільшуватися або зменшуватися на п`ять градусів. Аналогічним чином будемо мінятися і значення 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 (), але завжди вимагає вказівки чотирьох параметрів. Перший - кут обертання в градусах. Наступні три - осі, за якими йде обертання, в порядку x, y, z. Поки що нам потрібно обертати куб по двох осях, x і у.
  • Для всіх трансформацій, які ми задаємо в програмі, потрібні аналогічні рядки. По суті, ми представляємо обертання об`єкта по осі х як зміна значення rotate_x, а обертання по осі у - як зміна значення rotate_y. Втім, OpenGL об`єднає всі в одну матрицю трансформації. Всякий раз, викликаючи функцію display, ви будете створювати матрицю трансформації, і glLoadIdentity () дозволить починати кожен раз з новою матриці.
  • Інші функції трансформації, яким ви могли скористатися, - це glTranslatef () і glScalef (). Вони аналогічні glRotatef (), за винятком того, що вимагають лише трьох параметрів: значення x, y і z для зміни і масштабування об`єкта.
  • Щоб все відображалося правильно, коли всі три трансформації застосовані до одного об`єкту, потрібно задавати трансформації у відповідному порядку, а саме glTranslate, glRotate, glScale - і ніколи інакше. OpenGL трансформує об`єкт, читаючи програму від низу до верху. Щоб краще це зрозуміти, уявіть, як куб 1x1x1 буде виглядати після всіх трансформацій, якби OpenGL застосовував їх у тому порядку, як ті вказані (зверху вниз), а потім подумайте, як OpenGL обробить куб, читаючи інструкції від низу до верху.
  • 3. Додайте наступні команди для двократного масштабування куба по осях х та у, для обертання куба на 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)-
  • 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
  • 5. Перевірте фінальний код. Ось фінальний код, створений автором статті, в якому не перекладені коментарі.
    //// 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 []) GLUT_DEPTH) - // Create windowglutCreateWindow ( "Awesome Cube") - // Enable Z-buffer depth testglEnable (GL_DEPTH_TEST) - // Callback functionsglutDisplayFunc (display) -glutSpecialFunc (specialKeys) - // Pass control to GLUT for eventsglutMainLoop () - // Return to OSreturn 0-
  • Cхоже