Lektion 5 "3D Objekte"
- Download des Arbeitsbereiches
In dieser Lektion wird die letzte so erweitert werden, das "echte"
3D-Objekte entstehen und nicht nur einfache Grundformen die sich irgendwie drehen.
Dazu wird das Dreieck zur Pyramide, das Quadrat zum Würfel und auch das
8-Eck bekommt mehrere Seiten dazu.
Neue Variablen müssen nicht deklariert werden, also wird gleich DwawGlScene
bearbeitet.
int DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Die vorherige Szene wird vom Bildschirm gelöscht,
// damit die neuen nicht einfach über die alten
// Objekte gezeichnet werden
glLoadIdentity();
// modelview-Matrix wird zurückgesetzt
glTranslatef(-1.5f,-1.5f,-8.0f);
// Auf der X-Achse 1.5 Einheiten zurück (Nach links)
// Auf der Y-Achse 1.5 Einheiten zurück (Nach unten)
// Auf der Z-Achse 6 Einheiten zurück (In den Bildschirm hinnein.)
Da die 3D-Objekte etwas mehr Platz beanspruchen wird die obere Änderung
nltig. (Die Pyramide wird damit ein Stück nach unten geschoben, damit sie
nicht den Würfel verdeckt.)
Bei den Formen ist es wichtig, daß sich die Drehachse genau im Mittelpunkt
befinet. Wird also eine Form gezeichnet und vorher eine Drehachse eingestellt
so müssen alle Punkte dieses Objektes um einen Punkt 0,0,0 angelegt werden.
Dazu ein Beispiel:
Es wird eine Drehachse mit glRotatef() angelegt, danach ein Quadrat gezeichnet
mit den Koordinaten:
(0,0,0) für die untere linke Ecke
(1,0,0) für die untere rechte Ecke
(1,1,0) für die obere rechte Ecke
(0,1,0) für die obere linke Ecke
Die Kantenlänge beträgt also 1. Beim Ausführen wird man sehr
schnell feststellen müssen, das sich das Quadrat nur um eine seiner Kanten
dreht und nicht um seinen Mittelpunkt. Das Problem läßt sich recht
einfach lösen indem die Koordinaten um einen Mittelpunkt (0,0,0) herrum
angeornet werden. nämlich:
(-0.5, -0.5, 0) für die untere linke Ecke
(0.5, -0.5, 0) für die untere rechte Ecke
(0.5, 0.5, 0) für die obere rechte Ecke.
(-0.5, 0.5, 0) für die obere linke Ecke
Das gleiche gilt natürlich auch für 3-dimensionale Objekte.
Zuerst wird aber die Pyramide gezeichnet. Die Vorderseite kommt als allererstes,
die unteren Ecken dieses Dreiecks müssen auf der Z-Achse ein Stück
zurückgesetzt werden. Außerdem folgen alle Koordinaten der Seitenflächen
zwischen einem glBegin(GL_TRIANGLES); und einem glEnd();. OpenGL packt also
bei GL_TRIANGLES immer drei hintereinnanderstehende Koordinaten zu einem Dreieck
zusammen. Alle Dreiecke haben die gemeinsame Koordinate (0.0f, 1,0f, 0,0f) die
genau auf der Y-Achse liegt, um die die Pyramide ja insgesamt gedreh werden
soll.
glRotatef(rdreieck,0.0f,1.0f,0.0f);
// Die Pyramide soll um die Y-Achse rotiert werden
glBegin(GL_TRIANGLES);
// Es folgen die Koordinaten für mehrere Dreiecke
glColor3f(0.0f,0.0f,1.0f); // das vordere soll blau werden
glVertex3f( 0.0f, 1.0f, 0.0f); // oben (vorderes Dreieck)
glVertex3f(-1.0f,-1.0f, 1.0f); // links (vorderes Dreieck)
glVertex3f( 1.0f,-1.0f, 1.0f); // rechts (vorderes Dreieck)
glColor3f(1.0f,0.0f,0.0f); // das rechte soll rot werden
glVertex3f( 0.0f, 1.0f, 0.0f); // oben (rechtes Dreieck)
glVertex3f( 1.0f,-1.0f, 1.0f); // links (rechtes Dreieck)
glVertex3f( 1.0f,-1.0f, -1.0f); // rechts (rechtes Dreieck)
glColor3f(0.0f,1.0f,0.0f); // das hintere grün
glVertex3f( 0.0f, 1.0f, 0.0f); // oben (hinteres Dreieck)
glVertex3f( 1.0f,-1.0f, -1.0f); // links (hinteres Dreieck)
glVertex3f(-1.0f,-1.0f, -1.0f); // rechts (hinteres Dreieck)
glColor3f(1.0f,1.0f,0.0f); // und das linke gelb
glVertex3f( 0.0f, 1.0f, 0.0f); // oben (linkes Dreieck)
glVertex3f(-1.0f,-1.0f,-1.0f); // links (linkes Dreieck)
glVertex3f(-1.0f,-1.0f, 1.0f); // rechts (linkes Dreieck)
glEnd(); // Zeichenaktion beenden
glLoadIdentity(); // zurücksetzen
glLoadIdentity() muss malwieder aufgerufen werden, damit sich die
vorherige Rotation nicht mehr auf die nächsten Objekte auswirkt. Es wird
also nicht nur der Zeichner, sondern auch die Rotation zurückgesetzt.
glTranslatef(-0.5f,0.8f,-9.0f);
// 5 Einheiten nach links, 0.8 Einheiten nach unten,
// 9 Einheiten "in" den Schirm
glRotatef(rviereck,1.0f,1.0f,0.0f);
// Der Würfel soll um die X- und Y-Achse rotiert werden
glBegin(GL_QUADS); // Vierecke zeichnen
Und jetzt zu dem Würfel, bestehend aus 6 Quadraten (QUADS). Es wird mit der
oberen Fläche des Würfels angefangen. Die Y-Koordinate muss immer 1.0f
bleiben. Zuerst wird der obere rechten Punkt der oberen Fläche des Würfels
gezeichnet.
glColor3f(0.0f,1.0f,0.0f); // Mit Blau gehts los
glVertex3f( 1.0f, 1.0f,-1.0f); // oben rechts (OBEN)
glVertex3f(-1.0f, 1.0f,-1.0f); // oben links (OBEN)
glVertex3f(-1.0f, 1.0f, 1.0f); // unten links (OBEN)
glVertex3f( 1.0f, 1.0f, 1.0f); // unten rechts (OBEN)
Die untere Fläche des Würfels wird genauso gezeichnet, allerdings
eine Einheit unterhalb des Zentrums. Der Y-Wert ist immer -1.
glColor3f(1.0f,0.5f,0.0f); // Orange
glVertex3f( 1.0f,-1.0f, 1.0f); // oben rechts (UNTEN)
glVertex3f(-1.0f,-1.0f, 1.0f); // oben links (UNTEN)
glVertex3f(-1.0f,-1.0f,-1.0f); // unten links (UNTEN)
glVertex3f( 1.0f,-1.0f,-1.0f); // unten rechts (UNTEN)
Jetzt wird die vordere Seite des Würfels gezeichnet. Die Z-Achse ist immer
1.
glColor3f(1.0f,0.0f,0.0f); // Rot
glVertex3f( 1.0f, 1.0f, 1.0f); // oben rechts (VORNE)
glVertex3f(-1.0f, 1.0f, 1.0f); // oben links (VORNE)
glVertex3f(-1.0f,-1.0f, 1.0f); // unten links (VORNE)
glVertex3f( 1.0f,-1.0f, 1.0f); // unten rechts (VORNE)
Die hintere Fläche wird genauso dargestellt wie die vordere, aber weiter
in den Bildschirm hinein versetzt. Daher wird nur die Z-Koordinate verändert.
glColor3f(1.0f,1.0f,0.0f); // Gelb
glVertex3f( 1.0f,-1.0f,-1.0f); // oben rechts (HINTEN)
glVertex3f(-1.0f,-1.0f,-1.0f); // oben links (HINTEN)
glVertex3f(-1.0f, 1.0f,-1.0f); // unten links (HINTEN)
glVertex3f( 1.0f, 1.0f,-1.0f); // unten rechts (HINTEN)
Jetzt noch 2 weitere Flächen, die linke zuerst. (Und wie immer bleibt
eine Seite unverändert.)
glColor3f(0.5f,0.5f,0.5f); // Grau
glVertex3f(-1.0f, 1.0f, 1.0f); // oben rechts (LINKS)
glVertex3f(-1.0f, 1.0f,-1.0f); // oben links (LINKS)
glVertex3f(-1.0f,-1.0f,-1.0f); // unten links (LINKS)
glVertex3f(-1.0f,-1.0f, 1.0f); // unten rechts (LINKS)
Nun noch die letzte Seite des Würfels. Diese kann auch weggelassen werden
um eine Kiste zu zeichnen ;)
glColor3f(1.0f,0.0f,1.0f); // Violet
glVertex3f( 1.0f, 1.0f,-1.0f); // oben rechts (RECHTS)
glVertex3f( 1.0f, 1.0f, 1.0f); // oben links (RECHTS)
glVertex3f( 1.0f,-1.0f, 1.0f); // unten links (RECHTS)
glVertex3f( 1.0f,-1.0f,-1.0f); // unten rechts (RECHTS)
glEnd(); // Zeichenaktion beenden
glLoadIdentity(); // zurücksetzen
glTranslatef(3.0f,0.0f,-9.0f);
// 3 Einheiten nach rechts, 9 Einheiten "in" den Schirm
glRotatef(rachteck,0.0f,0.0f,1.0f);
// Die Firgur soll um die Z-Achse rotiert werden
Jetzt soll das Achteck 3-dimensional gezeichnet werden. Dazu werden an vier Seiten
des schon bestehenden Achtecks, Dreiecke angezeichnet, diese haben dann jeweils
zwei gemeinsame Koordinaten mit der Grundform, dem Achteck. Alle vier Dreiecke
haben eine gemeinsame Koordinate (den Mittelpunkt). Zur besseren Vorstellung am
besten das Programm ausführen. Das Ergebnis sieht etwas nach einem zu vier
Seiten geöffneten, achteckigen Zelt aus.
glBegin(GL_POLYGON); // Ein Polygon (in diesem Falle ein Achteck.)
// jede Ecke bekommt eine andere Farb
glColor3f(1.0f,0.0f,0.0f); // rot
glVertex3f(-0.5f, 1.5f, -1.0f); // obere Ecke links
glVertex3f( 0.5f, 1.5f, -1.0f); // obere Ecke recht
glColor3f(0.0f,0.0f,1.0f); // blau
glVertex3f( 1.5f, 0.5f, -1.0f); // rechte Ecke oben
glVertex3f( 1.5f,-0.5f, -1.0f); // rechte Ecke unten
glColor3f(0.0f,1.0f,0.0f); // grün
glVertex3f( 0.5f,-1.5f, -1.0f); // untere Ecke rechts
glVertex3f(-0.5f,-1.5f, -1.0f); // untere Ecke links
glColor3f(1.0f,1.0f,0.0f); // gelb
glVertex3f(-1.5f,-0.5f, -1.0f); // linke Ecke unten
glVertex3f(-1.5f, 0.5f, -1.0f); // linke Ecke oben
glEnd(); // Zeichenaktion beenden
glBegin(GL_TRIANGLES); //Dreiecke sollen gezeichnet werden
// jedes bekommt eine andere Farbe
glColor3f(1.0f,0.0f,0.0f); // rot
glVertex3f( 0.0f, 0.0f, 1.0f); // gemeinsamer Mittelpunkt
glVertex3f(-0.5f, 1.5f, -1.0f); // obere Ecke links
glVertex3f( 0.5f, 1.5f, -1.0f); // obere Ecke rechts
glColor3f(0.0f,0.0f,1.0f); // blau
glVertex3f( 0.0f, 0.0f, 1.0f); // gemeinsamer Mittelpunkt
glVertex3f( 1.5f, 0.5f, -1.0f); // rechte Ecke oben
glVertex3f( 1.5f,-0.5f, -1.0f); // rechte Ecke unten
glColor3f(0.0f,1.0f,0.0f); // grün
glVertex3f( 0.0f, 0.0f, 1.0f); // gemeinsamer Mittelpunkt
glVertex3f( 0.5f,-1.5f, -1.0f); // untere Ecke rechts
glVertex3f(-0.5f,-1.5f, -1.0f); // untere Ecke links
glColor3f(1.0f,1.0f,0.0f); // gelb
glVertex3f( 0.0f, 0.0f, 1.0f); // gemeinsamer Mittelpunkt
glVertex3f(-1.5f,-0.5f, -1.0f); // linke Ecke unten
glVertex3f(-1.5f, 0.5f, -1.0f); // linke Ecke oben
glEnd(); // Zeichenaktion beenden
Und auch die Drehwinkel müssen wieder bei jedem Durchgang geändert werden.
rdreieck -= 0.4f;
// Der Drehwinkel des Dreiecks soll bei
// jedem Durchgang um 0,4f verringert werden.
rviereck += 0.7f;
// Der Drehwinkel des Vierecks soll bei
// jedem Durchgang um 0,7f erhöht werden.
rachteck += 0.56f;
// Der Drehwinkel des Achtecks soll bei
// jedem Durchgang um 0,56f erhöht werden werden.
return TRUE; // Alles hat geklappt
}
Last but not least, die Namensänderung
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
(...) gekürzt
if (!CreateGLWindow("Opengl Tutorial 4 - 3D Objekte -
www.codeworx.org",640,480,16,fullscreen))
{
return 0; // Falls ein Fehler auftrat, beenden
}
(...)
Auch ein Arbeitsbereich ist
wieder verfügbar. Weiter zur nächsten
Lektion.