Prymitywy cd.:
Transkrypt
Prymitywy cd.:
Prymitywy cd.: Linie: glBegin(GL_LINES); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0, 0, 0); glVertex3f(1.0f, 1.0f, 0); glEnd(); Spowoduje wygenerowanie linii między vertexami na ekranie, jeżeli chcielibyśmy wygenerować więcej niż jedną linię należy wpisać kolejną parę glVertex3f(): glBegin(GL_LINES); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0, 0, 0); glVertex3f(1.0f, 1.0f, 0); glVertex3f(0, 0, 0); glVertex3f(-1.0f, 1.0f, 0); glEnd(); Łamane Umożliwiają kreślenie większej ilości linii, pierwsze dwa glVertex3f tworzą linię, każde kolejne wywołanie funkcji powoduje doklejenie kolejnej do końca poprzedniej: glBegin(GL_LINE_STRIP); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0, 0, 0); glVertex3f(1.0f, 1.0f, 0); glEnd(); glBegin(GL_LINE_STRIP); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0, 0, 0); glVertex3f(1.0f, 1.0f, 0); glVertex3f(-1.0f, 0.5f, 0); glEnd(); Łamana zamknięta Działa identycznie jak łamana, z tą różnicą, że dodawana jest automatycznie dodatkowa prosta łącząca ostatni punkt z pierwszym. glBegin(GL_LINE_LOOP); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0, 0, 0); glVertex3f(1.0f, 1.0f, 0); glVertex3f(-1.0f, 0.5f, 0); glEnd(); Wzorcowe Umożliwia rysowanie linii podanym wzorem. Aby to zrobić musimy włączyć GL_LINE_STIPPLE oraz wywołać funkcję o tej samej nazwie. Funkcja glLineStipple() przyjmuje dwa argumenty. Jeden odpowiada za powtarzalność wzoru – im mniejsza wartość tym częstsze powtarzanie wzoru. Drugi odpowiada za sam wzór – wartość jest przekształcana na wartość binarną, piksele pojawią się w miejscach jedynek. glEnable(GL_LINE_STIPPLE); glLineStipple(1,0x00FF); glBegin(GL_LINE_LOOP); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0, 0, 0); glVertex3f(1.0f, 1.0f, 0); glVertex3f(-1.0f, 0.5f, 0); glEnd(); glDisable(GL_LINE_STIPPLE); glLineStipple(5f, 0x00FF): Przykład własnego wzorca: --- - = 111010(2) = 3A(6) Kod: glEnable(GL_LINE_STIPPLE); glLineStipple(5.0f,0x003A); glBegin(GL_LINE_LOOP); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0, 0, 0); glVertex3f(1.0f, 1.0f, 0); glVertex3f(-1.0f, 0.5f, 0); glEnd(); glDisable(GL_LINE_STIPPLE); Wynik: Szerokość linii: glEnable(GL_LINE_STIPPLE); glLineStipple(5.0f,0x003A); glLineWidth(10.0f); glBegin(GL_LINE_LOOP); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0, 0, 0); glVertex3f(1.0f, 1.0f, 0); glVertex3f(-1.0f, 0.5f, 0); glEnd(); glDisable(GL_LINE_STIPPLE); Wielokąty. Punkty oraz proste zawsze widoczne są tak samo niezależnie od odległości obserwatora. Wielokąty za to mają różny „rozmiar” w zależności od położenia obserwatora. Samo tworzenie wielokątów nie różni się od tworzenia punktów bądź krzywych. Poniższy kod tworzy dowolny n-kąt: glBegin(GL_POLYGON); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(-0.3f, 0.0f, 0.0f); glVertex3f(-0.3f, 0.3f, 0.0f); glEnd(); glBegin(GL_POLYGON); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(-0.3f, 0.0f, 0.0f); glVertex3f(-0.3f, 0.3f, 0.0f); glVertex3f(0.0f, 0.3f, 0.0f); glEnd(); glBegin(GL_POLYGON); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(-0.3f, 0.0f, 0.0f); glVertex3f(-0.3f, 0.3f, 0.0f); glVertex3f(0.0f, 0.3f, 0.0f); glVertex3f(0.15f, 0.15f, 0.0f); glEnd(); Oczywiście nic nie stoi na przeszkodzie, aby każdy z wierzchołków miał inny kolor: glShadeModel(GL_SMOOTH); //Wartość domyslna glBegin(GL_POLYGON); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(-0.3f, 0.0f, 0.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(-0.3f, 0.3f, 0.0f); glColor3f(0.0f, 1.0f, 1.0f); glVertex3f(0.0f, 0.3f, 0.0f); glColor3f(1.0f, 1.0f, 0.0f); glVertex3f(0.15f, 0.15f, 0.0f); glEnd(); Można także zastosować tryb GL_FLAT zamiast GL_SMOOTH ale spowoduje to nadanie 1 koloru dla całego wielokąta bez płynnego przejścia. Drobna uwaga odnośnie obszaru rysowanego w oknie: Każdy obiekt jaki do tej pory rysowaliśmy miał współrzędne z przedziału -1 do 1. Nie oznacza to, że większe/mniejsze współrzędne są niedopuszczalne – po prostu do tej pory widok ustawiony mieliśmy tak, aby „widział” tylko taki przedział. Aby zwiększyć wielkość wystarczy zastosować funkcję glOrtho(); Np wywołanie (tuż pod glEnable(GL_DEPTH_TEST) zamiast pętli głównej) glOrtho(-10.0, 10, -10, 10, 100, -100); spowoduje ustawienie obszaru obserwowanego mający z lewej i na dole -10, a 10 z prawej oraz u góry. Wartość 100 i -100 oznacza jak daleko w tym widoku widoczne są bryły zanim zaczną być ignorowane. Trójkąty Jeden z najprostszych ale też najczęściej używanych prymitywów. W OpenGL możemy je generować na kilka sposobów: Listy trójkątów: Tworzymy je za pomocą glBegin(GL_TRIANGLES). Każde 3 kolejne vertexy stworzone wewnątrz stworzą nowy trójkąt: glBegin(GL_TRIANGLES); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(-0.3f, 0.0f, 0.0f); glVertex3f(-0.3f, 0.3f, 0.0f); glEnd(); glBegin(GL_TRIANGLES); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(-0.3f, 0.0f, 0.0f); glVertex3f(-0.3f, 0.3f, 0.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 0.3f, 0.0f); glVertex3f(-0.3f, 0.3f, 0.0f); glEnd(); Paski trójkątów: Powstają za pomocą GL_TRIANGLE_STRIP w funkcji glBegin. Działa on w ten sposób, że pierwsze 3 wierzchołki tworzą trójkąt. Kolejne trójkąty są tworzone ze współrzędnych wywołanych w kolejnym wierzchołku oraz 2 poprzednich. glBegin(GL_TRIANGLE_STRIP); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-0.3f, 0.0f, 0.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(-0.3f, 0.3f, 0.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(0.0f, 0.0f, 0.0f); glEnd(); Dodanie kolejnego wierzchołka: glBegin(GL_TRIANGLE_STRIP); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-0.3f, 0.0f, 0.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(-0.3f, 0.3f, 0.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(0.0f, 0.0f, 0.0f); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0.0f, 0.3f, 0.0f); glEnd(); I kolejny wierzchołek: glBegin(GL_TRIANGLE_STRIP); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-0.3f, 0.0f, 0.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(-0.3f, 0.3f, 0.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(0.0f, 0.0f, 0.0f); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0.0f, 0.3f, 0.0f); glColor3f(1.0f, 1.0f, 0.0f); glVertex3f(0.3f, 0.15f, 0.0f); glEnd(); Wachlarze trójkątów: Są podobne do pasków, tworzy się w nich 1 bazowy wierzchołek a następnie wyznacza współrzędne wierzchołków otaczających. Aby stworzyć wachlarz uruchamiamy funkcję glBegin ze stała GL_TRIANGLE_FAN. glBegin(GL_TRIANGLE_FAN); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(-0.5f, 0.3f, 0.0f); glVertex3f(-0.5f, 0.5f, 0.0f); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-0.3f, 0.6f, 0.0f); glColor3f(0.1f, 1.0f, 0.0f); glVertex3f(0.0f, 0.5f, 0.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(0.3f, 0.2f, 0.0f); glEnd(); Czworokąty OpenGL umożliwia rysowanie także czworokątów. Jest to rzadko stosowane ponieważ każdy czworokąt można zastąpić paskiem trójkątów do rysowania których karta graficzna jest zoptymalizowana – dwa trójkąty rysują się szybciej niż jeden czworokąt. Czworokąt tworzy się za pomocą stałej GL_QUADS. glBegin(GL_QUADS); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.5f, 0.0f, 0.0f); glVertex3f(0.5f, 0.5f, 0.0f); glVertex3f(0.0f, 0.5f, 0.0f); glEnd(); Możliwe jest także rysowanie pasków czworokątów za pomocą stałej GL_QUADS_STRIP -w tym przypadku kolejne czworokąty powstają z dwóch poprzednich wywołań glVertex3f oraz z dwóch nowych. glBegin(GL_QUAD_STRIP); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 0.5f, 0.0f); glVertex3f(0.5f, -0.2f, 0.0f); glVertex3f(0.5f, 0.7f, 0.0f); glVertex3f(1.0f, 0.0f, 0.0f); glVertex3f(1.0f, 0.5f, 0.0f); glEnd(); Powrót do WINAPI – Obsługa klawiatury Do obsługi zachowań klawiatury musimy znać symboliczne wartości tak zwanych Virtual Key Codes. Dla nas na razie najważniejsze będą: VK_SPACE - Naciśnięcie spacji VK_LEFT Strzałka w lewo - VK_RIGHT - Strzałka w prawo VK_UP - Strzałka w górę VK_DOWN - Strzałka w dół. Więcej kodów można znaleźć wpisując „Virtual Key Codes” w google. Tworząc domyślną aplikację openGL w Dev++ albo CodeBlocks mamy zaimplementowaną już obsługę jednego przycisku (ESC) w funkcji WindowProc: case WM_KEYDOWN: { switch (wParam) { case VK_ESCAPE: PostQuitMessage(0); break; } } Analogicznie dodawać możemy kolejne zdarzenia dla innych przycisków dopisując kolejne case'y do przypadku WM_KEYDOWN.