Prymitywy są to podstawowe figury geometryczne z których zbudowane są wszystkie obiekty w OpenGl.
Aby utworzyć taką figurę potrzebne są nam punkty, które będą stanowić ich wierzchołki. Wyróżniamy kilka rodzajów prymitywów:
Przejdźmy teraz do kodu. Na początku skopiuj katalog z projektem z poprzedniej lekcji i nazwij go np. Prymitywy.
Otwórz plik render.pas. Poszukaj procedure RenderFrame i usuń polecenia glRotate, glBegin, glEnd oraz wszystko między nimi.
W ten sposób usunęliśmy obiekt stworzony dla potrzeb poprzedniego artykułu, a uzyskaliśmy procedurę:
1 2 3 4 5 6 7 8 |
procedure RenderFrame; begin //Mgla Fog; //Obrót glTranslatef(0.0, 0.0, -12.0); glEnd(); end; |
Aby utworzyć jakikolwiek prymityw musimy zadeklarować jego rodzaj go jako parametr w poleceniu glBegin. Wyrózniamy :
– GL_POINTS – niezależne od siebie punkty
– GL_LINES – pary wierzchołków tworzą końce odcinków
– GL_LINE_STRIP – kolejne wierzchołki tworzą łamaną
– GL_LINE_LOOP – tak jak wyżej, tyle że pierwszy wierzchołek z ostatnim jest połączony segmentent
– GL_TRIANGLES – kolejne trójki wierzchołków wyznaczają trójkąty
– GL_TRIANGLE_STRIP – pas trójkątów
– GL_TRIANGLE_FAN – wachlarz trójkątów
– GL_QUADS – każde kolejne cztery wierzchołki wyznaczają czworokąt
– GL_QUAD_STRIP – pas czworokątów
– GL_POLYGON – kolejne wierzchołki wyznaczają wypukły wielokąt
Następnie po tym poleceniu tworzymy wierzchołki za pomocą :
1 |
glVertex3f(przesunięcie w X, przesunięcie w Y, przesunięcie w Z); |
Liczba wierzchołków jest zależna od rodzaju prymitywu oraz naszych potrzeb. Po zakończeniu
wpisujemy glEnd;
Oto przykład rysujący trójkąt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
procedure RenderFrame; begin //Obrót glTranslatef(0.0, 0.0, -12.0); // trójkąt glbegin(GL_TRIANGLES); // wierzchołek 1 glVertex3f(-5, -3, 2); // wierzchołek 2 glVertex3f(5, -3, 2); //wierzchołek 3 glVertex3f(0, 3, -20); glEnd(); end; |
Każdemu wierzchołkowi możemy przypisać określony kolor. Polecenie nadające go omówiliśmy w pierwszym artykule (glColor3f) :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
procedure RenderFrame; begin //Obrót glTranslatef(0.0, 0.0, -12.0); glbegin(GL_TRIANGLES); // kolor czerwony glColor3f(1.0, 0.0, 0.0); glVertex3f(-5, -3, 2); // kolor zielony glColor3f(0.0, 1.0, 0.0); glVertex3f(5, -3, 2); // kolor niebieski glColor3f(0.0, 0.0, 1.0); glVertex3f(0, 3, -20); glEnd(); end; |
Tablice dla prymitywów
A co zrobić, jeśli mamy obiekt składający się z np. 500 wierzchołków ? Możemy zapisywać każdy po kolei według powyższego przykładu, ale na szczęście nie musimy. OpenGL umożliwia tworzenie tablic zawierających pozycje wierzchołków, a następnie za pomocą jednego polecenia wyświetlenie prymitywu. Musimy stworzyć nowy rekord, który będzie zawierał pozycję wierzchołka. Nazwiemy go TVertex. Następnie zadeklarujemy tablicę zawierającą wierzchołki – vertex oraz utwórzmy procedurę, która będzie przypisywać im wartości. To wszystko wykonamy w pliku timer.pas. Oto listing tego pliku po dokonaniu zmian :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
unit timer; interface uses opengl; procedure FrameMath; procedure SetVertex; type TVertex = record X, Y, Z: GLFloat; end; var vertex : array[1..3] of TVertex; implementation uses Render; procedure SetVertex; begin Vertex[1].x := -1; Vertex[1].y := 1; Vertex[1].z := -1; Vertex[2].x := 1; Vertex[2].y := 1; Vertex[2].z := -1; Vertex[3].x := 0; Vertex[3].y := -1; Vertex[3].z := -1; // definiuje tablicę wierzchołków glVertexPointer(3, GL_FLOAT, 0, @Vertex); //uaktywnia tablicę z wierzchołkami glEnableClientState(GL_VERTEX_ARRAY); end; procedure FrameMath; begin t := t + 0.1; end; end. |
Do definiowania tablicy wierzchołków użyjemy polecenia:
1 |
glVertexPointer(liczba_wierzcholkow, typ_danych , przesunięcie, wskaźnik do tablicy); |
Aby uaktywnić tablicę:
1 |
glEnableClientState(rodzaj_tablicy); |
Jako rodzajn tablicy wybraliśmy GL_VERTEX_ARRAY. Oprócz niej możemy wywołac m.in. :
– GL_TEXTURE_COORD_ARRAY – przy definiowaniu tekstur
– GL_COLOR_ARRAY – przy definiowniu kolorów
Teraz otwórz plik api_func.pas. W uses dopisz timer oraz na początku procedury GLInit wywołaj
wcześniej utworzoną SetVertex. Fragment kodu z tego unitu :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
... uses Render, Timer; //Inicjacja OpenGl procedure GLInit(AWidth: GLsizei; AHeight: GLsizei); begin SetVertex; glEnable(GL_TEXTURE_2D); // Mapowanie tekstur 2D glClearColor(0, 0, 0, 0); // Kolor tla glClearDepth(1.0); // Czyszczenie bufora glEnable(GL_DEPTH_TEST); // Włącz testowanie głębokości glDepthFunc(GL_LEQUAL); // Rodzaj testowania głębokości : GL_LESS gluPerspective(45.0, AWidth / AHeight, 0.1, 500.0); // Ustawianie perspektywy glMatrixMode(GL_MODELVIEW); // ustawienie widoku modelu glLoadIdentity(); // Reset macierzy end; ... |
Pozostała nam wyświetlenie prymitywu utworzonego z wierzchołków zawartych w tablicy. Powracamy do procedury RenderFrame w render.pas. Dopiszmy polecenie :
1 |
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, @Indices); |
Pierwszy parametr zawiera rodzaj prymitywa, drugi liczbę wierzchołków, trzeci typ danych, a czwarty wskaźnik do tablicy identyfikatorów.
Kończąc artykuł zapraszam do zapoznania się ze źródłami.
Autor: Nakiel