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.