Jak zrobić kostkę w OpenGL (ze zdjęciami)

Spisu treści:

Jak zrobić kostkę w OpenGL (ze zdjęciami)
Jak zrobić kostkę w OpenGL (ze zdjęciami)

Wideo: Jak zrobić kostkę w OpenGL (ze zdjęciami)

Wideo: Jak zrobić kostkę w OpenGL (ze zdjęciami)
Wideo: How To Install Windows XP In Virtual Box - 2023 2024, Kwiecień
Anonim

OpenGL to potężne narzędzie do programowania 3D używane do rysowania złożonych trójwymiarowych scen z prostych prymitywów. W tym artykule dowiesz się, jak narysować prosty sześcian, który możesz obracać, aby zobaczyć w trzech wymiarach!

Do tego projektu będziesz potrzebować edytora kodu i pewnej znajomości programowania w C.

Kroki

Część 1 z 3: Konfiguracja wstępna

1994315 1 1
1994315 1 1

Krok 1. Zainstaluj OpenGL Aby rozpocząć, wykonaj następujące kroki, aby zainstalować OpenGL w swoim systemie

Jeśli masz już zainstalowany OpenGL, a także kompatybilny kompilator C, możesz pominąć ten krok i przejść do następnego.

1994315 2 1
1994315 2 1

Krok 2. Utwórz dokument

Utwórz nowy plik w swoim ulubionym edytorze kodu i zapisz go jako mycube.c

1994315 3 1
1994315 3 1

Krok 3. Dodaj #zawiera

Są to podstawowe dodatki, których będziesz potrzebować w swoim programie. Ważne jest, aby zdać sobie sprawę, że w rzeczywistości istnieją różne dodatki wymagane dla różnych systemów operacyjnych. Pamiętaj, aby uwzględnić je wszystkie, aby zapewnić, że Twój program jest wszechstronny i może działać dla każdego użytkownika.

    // Obejmuje #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif

1994315 4 1
1994315 4 1

Krok 4. Dodaj prototypy funkcji i zmienne globalne

Następnym krokiem jest zadeklarowanie prototypów funkcji.

    // Prototypy funkcji void display(); nieważne klawisze specjalne(); // Zmienne globalne double rotate_y=0; podwójna rotacja_x=0;

1994315 5 1
1994315 5 1

Krok 5. Skonfiguruj funkcję main()

    int main(int argc, char* argv){ // Inicjalizacja GLUT i przetwarzanie parametrów użytkownika glutInit(&argc, argv); // Zażądaj podwójnie buforowanego okna True Color z buforem Z glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

  • To stwierdzenie konfiguruje Twoje środowisko. Ważną rzeczą do zapamiętania podczas pisania programów OpenGL jest to, że musisz o wszystko prosić. Wymaga to lepszego zrozumienia działania programu i tego, co należy uwzględnić, aby uzyskać żądaną funkcjonalność. W tej linii ustawisz wyświetlacz z podwójnym buforowaniem, kolorem RGB i buforem Z.
  • Podwójne buforowanie to technika stosowana w programach graficznych w celu wyeliminowania problemu wynikającego z tego, jak obrazy są wyświetlane na ekranie. Za każdym razem, gdy przerysujesz scenę, wyświetlacz musi zostać najpierw wymazany, a następnie narysowane zostaną nowe informacje. Bez podwójnego buforowania zaobserwujesz efekt migotania, gdy ekran jest wielokrotnie wymazywany i przerysowywany.
  • Ten problem został rozwiązany przez dodanie drugiego bufora do rysowania. Dzięki tej metodzie obraz jest rysowany do pierwszego bufora, a ten bufor jest wyświetlany. Następna ramka zostanie narysowana do drugiego bufora, a kiedy to zrobisz, dwa bufory zamienią się miejscami. Natychmiast zobaczysz drugi bufor, ale ukryty przed nami, pierwszy bufor jest usuwany i przerysowywany z trzecią klatką, która zostanie zamieniona po zakończeniu.
  • Chcesz również włączyć Kolor RGB system w twoim oknie.
  • Buforowanie Z w ten sposób uzyskujesz pożądane efekty 3D. OpenGL używa trójwymiarowego układu współrzędnych z osiami x, y i z. Aby uzyskać efekt, że obiekt znajduje się bliżej ciebie, jego pozycja na osi z jest zwiększana, jednak aby pojawiać się dalej, jego pozycja na osi z jest zmniejszana.
1994315 6 1
1994315 6 1

Krok 6. Utwórz okno

Następnym krokiem jest: utwórz okno w którym narysujesz sześcian. W tym samouczku okno nazywa się „Awesome Cube”.

    // Utwórz okno glutCreateWindow("Niesamowita kostka");

1994315 7 1
1994315 7 1

Krok 7. Włącz test głębokości

OpenGL jest językiem ścisłym, ponieważ nie zakłada włączenia żadnych specjalnych funkcji. Aby Twój program poprawnie wyświetlał się w 3 wymiarach przy użyciu bufora Z, który oglądałeś wcześniej, musisz: włącz test głębokości. Kontynuując eksplorację OpenGL, odkryjesz wiele funkcji, które będziesz musiał włączyć, w tym oświetlenie, tekstury, celowanie i wiele więcej.

    // Włącz test głębokości bufora Z glEnable(GL_DEPTH_TEST);

1994315 8 1
1994315 8 1

Krok 8. Dodaj funkcje zwrotne

Oto funkcje zwrotne, dla których napisałeś wcześniej prototypy. Za każdym razem, gdy przechodzimy przez główną pętlę, te funkcje będą wywoływane. Funkcja wyświetlania ponownie rysuje scenę na podstawie wszelkich zmian zmiennych, które zostały wprowadzone od poprzedniego wywołania. Funkcja specialKeys pozwala nam na interakcję z programem.

    // Funkcje zwrotne glutDisplayFunc(display); glutSpecialFunc(specialKeys);

1994315 9 1
1994315 9 1

Krok 9. Uruchom MainLoop

Spowoduje to przywołanie głównej funkcji, dopóki nie zamkniesz programu, aby umożliwić animacje i interakcję użytkownika.

    // Przekaż kontrolę do GLUT dla zdarzeń glutMainLoop(); // Powrót do systemu operacyjnego return 0; }

Część 2 z 3: Funkcja wyświetlania ()

1994315 10 1
1994315 10 1

Krok 1. Zrozum cel tej funkcji

Cała praca związana z rysowaniem sześcianu zostanie wykonana w tej funkcji. Ogólną ideą stojącą za kostką jest narysowanie wszystkich sześciu boków osobno i umieszczenie ich w odpowiedniej pozycji.

Koncepcyjnie każda strona zostanie narysowana poprzez zdefiniowanie czterech rogów i pozwolenie OpenGL na połączenie linii i wypełnienie ich zdefiniowanym kolorem. Poniżej znajdują się kroki, aby to zrobić

1994315 11 1
1994315 11 1

Krok 2. Dodaj glClear()

Pierwszym krokiem, który musisz wykonać w tej funkcji, jest: wyczyść kolor i bufor Z. Bez tych kroków stare rysunki mogą być nadal widoczne pod nowymi rysunkami, a narysowane obiekty nie będą znajdować się we właściwym miejscu na ekranie.

    void display(){ // Wyczyść ekran i bufor Z glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

1994315 12 1
1994315 12 1

Krok 3. Dodaj glBegin() i glEnd()

OpenGL definiuje obiekty jako kombinacje różnych wielokątów. Używając glPoczątek() skutecznie odłożysz ołówek, który narysuje kształt. Aby podnieść ołówek i rozpocząć nowy kształt, musisz użyć gLend() Komenda. W tym samouczku będziesz używać GL_POLYGON do rysowania każdej strony sześcianu, ale możliwe jest użycie innych opcji parametrów, takich jak GL_LINE, GL_QUAD lub GL_TRIANGLE, aby utworzyć inne kształty.

  • Tutaj zaczniesz od przodu swojej kostki. Później dodasz kolor na wszystkich 6 bokach.
  • // Wielokolorowa strona - FRONT glBegin(GL_POLYGON); // Wierzchołki zostaną dodane w następnym kroku glEnd();

1994315 13 1
1994315 13 1

Krok 4. Dodaj glVertex3f()

Po stwierdzeniu, że chcesz rozpocząć swój wielokąt, musisz: zdefiniuj wierzchołki obiektu. glVertex ma wiele form w zależności od tego, co chcesz zrobić ze swoim obiektem.

  • Pierwszy to liczba wymiarów, w których pracujesz. 3 powyżej w glVertex3f mówi, że rysujesz w 3 wymiarach. Możliwa jest również praca w 2 lub 4 wymiarach. f powyżej w glVertex3f mówi, że pracujesz z liczbami zmiennoprzecinkowymi. Możesz również użyć krótkich, liczb całkowitych lub podwójnych.
  • Zauważ, że te punkty są zdefiniowane w a przeciwnie do ruchu wskazówek zegara sposób. W tej chwili nie jest to bardzo ważne, ale kiedy zaczniesz pracować z oświetleniem, teksturami i celowaniem, stanie się to niezwykle ważne, więc przyzwyczaj się teraz do definiowania punktów przeciwnie do ruchu wskazówek zegara.
  • Dodaj dodaj wierzchołki między wierszami glBegin() i glEnd().
  • // Wielokolorowa strona - 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

Krok 5. Dodaj glColor3f()

glColor działa w podobny sposób jak glVertex. Możesz zdefiniować punkty jako krótkie, całkowite, podwójne lub zmiennoprzecinkowe. Każdy kolor ma wartość od 0 do 1. Wszystkie zera sprawiają, że punkt jest czarny, a wszystkie jedynki powodują, że punkt jest biały. 3 w glColor3f() odnosi się do systemu kolorów RGB bez kanału alfa. Alfa koloru określa jego przezroczystość. Aby zmienić poziom alfa, użyj glColor4f() z ostatnim parametrem o wartości od 0 do 1 dla nieprzezroczystego do przezroczystego.

  • Kiedy wywołasz glColor3f(), każdy wierzchołek narysowany od tego punktu będzie miał ten kolor. Dlatego, jeśli chcesz, aby wszystkie cztery wierzchołki były czerwone, po prostu ustaw kolor raz w dowolnym momencie przed poleceniami glVertex3f(), a wszystkie wierzchołki będą czerwone.
  • Strona przednia zdefiniowana poniżej pokazuje, jak zdefiniować nowy kolor dla każdego wierzchołka. Gdy to zrobisz, zobaczysz interesującą właściwość kolorów OpenGL. Ponieważ każdy wierzchołek wielokąta ma swój własny kolor, OpenGL automatycznie połączy kolory! Następny krok pokaże, jak przypisać cztery wierzchołki tego samego koloru.
  • //Wielokolorowa strona - FRONT glBegin(GL_POLYGON); glColor3f(1.0, 0.0, 0.0); glVertex3f (0,5, -0,5, -0,5); // P1 jest czerwony glColor3f(0.0, 1.0, 0.0); glVertex3f (0,5, 0,5, -0,5); // P2 jest zielony glColor3f(0.0, 0.0, 1.0); glVertex3f (-0,5, 0,5, -0,5); // P3 jest niebieskie glColor3f(1.0, 0.0, 1.0); glVertex3f (-0,5, -0,5, -0,5); // P4 jest fioletowy glEnd();

1994315 15 1
1994315 15 1

Krok 6. Zajmij się innymi stronami

Ustal, jakie będzie położenie każdego wierzchołka dla pozostałych pięciu boków sześcianu, ale dla uproszczenia zostały one obliczone dla Ciebie i są zawarte w funkcja końcowego wyświetlania() poniżej.

    // Biała strona - BACK 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(); // Fioletowa strona - PRAWY 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(); // Zielona strona - LEWA 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(); // Niebieska strona - 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(); // czerwona strona - BOTTOM 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(); glutSwapBufory(); }

  • Chcemy również dodać dwie ostatnie linijki kodu dla tej funkcji. To są glFlush();

    oraz glutSwapBufory();

    które dają nam efekt podwójnego buforowania, o którym dowiedziałeś się wcześniej.

Część 3 z 3: Interaktywność użytkownika

1994315 16 1
1994315 16 1

Krok 1. Dodaj specialKeys()

Prawie gotowe, ale w tej chwili możesz narysować sześcian, ale nie masz możliwości jego obrócenia. Aby to zrobić, będziesz utwórz klawisze specjalne() funkcja pozwalająca nam naciskać klawisze strzałek i obracać kostkę!

  • Ta funkcja jest powodem, dla którego zadeklarowałeś zmienne globalne rotate_x i rotate_y. Po naciśnięciu prawego i lewego klawisza strzałki, rotate_y będzie zwiększany lub zmniejszany o 5 stopni. Podobnie, gdy naciśniesz klawisze strzałek w górę i w dół, wartość rotate_x zmieni się odpowiednio.
  • void specialKeys(int key, int x, int y) { // Strzałka w prawo - zwiększ obrót o 5 stopni jeśli (key == GLUT_KEY_RIGHT) rotate_y += 5; // Strzałka w lewo - zmniejsz obrót o 5 stopni w przeciwnym razie jeśli (key == GLUT_KEY_LEFT) rotate_y -= 5; inaczej if (klucz == GLUT_KEY_UP) rotate_x += 5; w przeciwnym razie if (klucz == GLUT_KEY_DOWN) rotate_x -= 5; // Poproś o aktualizację wyświetlania glutPostRedisplay(); }

1994315 17 1
1994315 17 1

Krok 2. Dodaj glRotate()

Twoim ostatnim stwierdzeniem jest dodanie stwierdzenia, które spowoduje rotację twojego obiektu. Wróć do funkcji display() i przed stroną FRONT dodaj te linie:

    // Resetowanie transformacji glLoadIdentity(); // Obróć, gdy użytkownik zmieni rotate_x i rotate_y glRotatef(rotate_x, 1.0, 0.0, 0.0); glRotatef(obrót_y, 0.0, 1.0, 0.0); // Wielokolorowa strona - FRONT ….

  • Najpierw zauważ, że składnia glRotatef() jest podobny do glColor3f() i glVertex3f(), ale zawsze wymaga 4 parametrów. Pierwszym parametrem jest stopień rotacji, który ma być zastosowany. Kolejne trzy parametry określają, wokół której osi należy się obracać, przy czym pierwszy to oś x, drugi to oś y, a trzeci to oś z. Teraz wystarczy tylko obrócić się wokół osi x i y.
  • Wszystkie przekształcenia, które piszesz w swoim programie, wymagają wierszy podobnych do tego. Koncepcyjnie można o tym myśleć jako o obróceniu obiektu wokół osi x o wartość określoną przez obrót_x, a następnie obrócenie wokół osi y przez obrót_y. Jednak OpenGL łączy wszystkie te instrukcje w jedną transformację macierzy. Za każdym razem, gdy wywołujesz funkcję wyświetlania, budujesz macierz transformacji i glLoadIdentity() zapewnia, że w każdym przejściu zaczniesz od nowej matrycy.
  • Inne funkcje transformacji, które możesz zastosować, to glTranslatef() i glScalef(). Funkcje te są podobne do funkcji glRotatef() z wyjątkiem tego, że przyjmują tylko 3 parametry, wartości x, y i z, aby przetłumaczyć lub przeskalować obiekt.
  • Aby uzyskać poprawny efekt przy zastosowaniu wszystkich trzech przekształceń do jednego obiektu, należy zastosować je w odpowiedniej kolejności. Zawsze zapisuj je w kolejności glTranslate, glRotate, a następnie glScale. OpenGL zasadniczo stosuje przekształcenia w sposób oddolny. Aby to zrozumieć, spróbuj sobie wyobrazić, jak wyglądałaby prosta kostka 1x1x1 z przekształceniami, gdyby OpenGL zastosował je od góry do dołu i gdyby OpenGL zastosował je od dołu do góry.
1994315 18 1
1994315 18 1

Krok 3. Dodaj następujące polecenia, aby przeskalować sześcian o 2 wzdłuż osi x, 2 wzdłuż osi y, obrócić sześcian o 180 stopni wokół osi y i przesunąć sześcian o 0,1 wzdłuż osi x

Upewnij się, że ułożyłeś je oraz poprzednie polecenia glRotate() we właściwej kolejności, jak opisano powyżej. (Jeśli nie masz pewności, robi się to w końcowym kodzie na końcu samouczka).

    // Inne przekształcenia 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

Krok 4. Skompiluj i uruchom swój kod

Zakładając, że używasz gcc jako kompilatora, uruchom te polecenia z terminala, aby skompilować i przetestować swój program.

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

1994315 20 1
1994315 20 1

Krok 5. Sprawdź swój pełny kod

Powinno być tak:

    // // Plik: mycube.c // Autor: Matt Daisley // Utworzono: 25.04.2012 // Projekt: Kod źródłowy do tworzenia kostki w OpenGL // Opis: Tworzy okno OpenGL i rysuje kostkę 3D // / Że użytkownik może obracać za pomocą klawiszy strzałek // // Sterowanie: Strzałka w lewo - Obróć w lewo // Strzałka w prawo - Obróć w prawo // Strzałka w górę - Obróć w górę // Strzałka w dół - Obróć w dół // ------ -------------------------------------------------- -- // Zawiera // -------------------------------------------- --------------- #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif // ------------- ---------------------------------------------- // Prototypy funkcji / / -------------------------------------------------- --------- nieważne wyświetlanie(); nieważne klawisze specjalne(); // ------------------------------------------------ ---------- // Zmienne globalne // ---------------------------------- ------------------------ podwójna rotacja_y=0; podwójna rotacja_x=0; // ------------------------------------------------ ---------- // display() Funkcja wywołania zwrotnego // -------------------- --------------------------- void display(){ // Wyczyść ekran i bufor Z glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // Resetowanie transformacji glLoadIdentity(); // Inne przekształcenia // glTranslatef(0.1, 0.0, 0.0); // Nieuwzględnione // glRotatef(180, 0.0, 1.0, 0.0); // Nieuwzględnione // Obróć, gdy użytkownik zmieni rotate_x i rotate_y glRotatef(rotate_x, 1.0, 0.0, 0.0); glRotatef(obrót_y, 0.0, 1.0, 0.0); // Inne przekształcenia // glScalef(2.0, 2.0, 0.0); // Nieuwzględnione //Wielokolorowa strona - FRONT glBegin(GL_POLYGON); glColor3f(1.0, 0.0, 0.0); glVertex3f (0,5, -0,5, -0,5); // P1 jest czerwony glColor3f(0.0, 1.0, 0.0); glVertex3f (0,5, 0,5, -0,5); // P2 jest zielony glColor3f(0.0, 0.0, 1.0); glVertex3f (-0,5, 0,5, -0,5); // P3 jest niebieskie glColor3f(1.0, 0.0, 1.0); glVertex3f (-0,5, -0,5, -0,5); // P4 jest fioletowy glEnd(); // Biała strona - BACK 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(); // Fioletowa strona - PRAWY 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(); // Zielona strona - LEWA 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(); // Niebieska strona - 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(); // czerwona strona - BOTTOM 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(); glutSwapBufory(); } // ----------------------------------------------- ----------- // specialKeys() Funkcja wywołania zwrotnego // ------------------------------ ---------------------------- void specialKeys(int key, int x, int y) { // Strzałka w prawo - zwiększ obrót o 5 stopień if (klucz == GLUT_KEY_RIGHT) obrót_y += 5; // Strzałka w lewo - zmniejsz obrót o 5 stopni w przeciwnym razie jeśli (key == GLUT_KEY_LEFT) rotate_y -= 5; inaczej if (klucz == GLUT_KEY_UP) rotate_x += 5; w przeciwnym razie if (klucz == GLUT_KEY_DOWN) rotate_x -= 5; // Poproś o aktualizację wyświetlania glutPostRedisplay(); } // ----------------------------------------------- ----------- // główna funkcja // ------------------------------- --------------------------- int main(int argc, char* argv){ // Zainicjuj GLUT i przetwórz parametry użytkownika glutInit(&argc, argv); // Zażądaj podwójnie buforowanego okna True Color z buforem Z glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // Utwórz okno glutCreateWindow("Niesamowita kostka"); // Włącz test głębokości bufora Z glEnable(GL_DEPTH_TEST); // Funkcje zwrotne glutDisplayFunc(display); glutSpecialFunc(specialKeys); // Przekaż kontrolę do GLUT dla zdarzeń glutMainLoop(); // Powrót do systemu operacyjnego return 0; }

Zalecana: