NeHe - Lektion 04 - Rotation

Lektion 4



Im letzten Tutorial habe ich Ihnen beigebracht, wie man Dreiecken und Quadraten Farbe hinzufügen kann. In diesem Tutorial werde ich Ihnen beibringen, wie man diese farbigen Objekte um eine Achse rotieren lassen kann.

Wie benutzen den Code aus dem letzten Tutorial und fügen an einigen Stellen Code ein. Ich werde die kompletten Code-Abschnitte noch mal aufschreiben, damit Sie es einfacher nachzuvollziehen können, wo was hinzugefügt wurde und was ersetzt werden muss.

Wir fangen mit dem Hinzufügen von zwei Variablen an, die die Rotatation des jeweiligen Objektes enthält. Das geschieht am Anfang des Programms, unter den anderen Variablen. Sie werden zwei neue Zeilen hinter 'bool fullscreen=TRUE;' sehen. Diese Zeile deklarieren zwei Fließkomma Variable, die wir benutzen können, um die Objekte mit sehr feiner Genauigkeit rotieren zu lassen. Fließkommazahlen können Dezimale Zahlen aufnehmen. Das bedeutet, dass wir nicht nur 1, 2, 3 für die Winkel benutzen können, wir können 1.1, 1.7, 2.3 oder sogar 1.015 für feine Genauigkeit verwenden. Sie werden feststellen, dass Fließkommazahlen notwendig bei der OpenGL Programmierung sind. Die neuen Variablen heißen rtri um das Dreieck rotieren zu lassen und rquad welche das Quadrat rotieren lässt.

#include    <windows.h>                    // Header Datei für Windows
#include    <gl\gl.h>                        // Header Datei für die OpenGL32 Library

#include    <gl\glu.h>                    // Header Datei für die GLu32 Library

#include    <gl\glaux.h>                    // Header File For The GLaux Library

HDC        hDC=NULL;                // Privater GDI Device Context
HGLRC        hRC=NULL;                // Permanenter Rendering Context
HWND        hWnd=NULL;                // Enthält unser Fenster-Handle

HINSTANCE    hInstance;                // Enthält die Instanz der Applikation


bool        keys[256];                // Array das für die Tastatur Routine verwendet wird

bool        active=TRUE;                // Fenster Aktiv Flag
bool        fullscreen=TRUE;                // Fullscreen Flag ist standardmäßig auf TRUE gesetzt

GLfloat        rtri;                    // Winkel für das Dreieck ( NEU )
GLfloat        rquad;                    // Winkel für das Quadrat ( NEU )

Nun müssen wir den DrawGLScene() Code modifizieren. Ich werde die komplette Prozedur neu schreiben. Das sollte Ihnen es einfacher machen, zu sehen, was für Änderungen ich am original Code vorgenommen habe. Ich werde erklären warum Zeilen modifiziert wurden und was die neuen Zeilen genau machen. Der folgende Code ist genau der selbe wie im letzten Tutorial.

int DrawGLScene(GLvoid)                    // Hier kommt der ganze Zeichnen-Kram hin
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // Löscht den Bildschirm und den Depth-Buffer
    glLoadIdentity();                    // Resettet die Ansicht (View)
    glTranslatef(-1.5f,0.0f,-6.0f);                // In den Bildschirm hineinbewegen und dann links

Die nächste Code-Zeile ist neu. glRotatef(Angle,Xvector,Yvector,Zvector) ist verantwortlich, um ein Objekt um eine Achse rotieren zu lassen. Sie werden diesen Befehl ziemlich häufig verwenden. Angle (=Winkel) ist eine Zahl (in der Regel in einer Variable gespeichert), die repräsentiert, wie weit das Objekt gedreht werden soll. Die Parameter Xvector, Yvector und Zvector präsentieren zusammen den Vektor um welchen die Rotation statt findet. Wenn Sie die Werte (1,0,0) verwenden, beschreiben Sie einen Vektor, der sich 1 Einheit entlängs der X-Achse nach rechts bewegt. Die Werte (-1,0,0) beschreiben einen Vektor der in die Richtung einer Einheit entlängs der X-Achse bewegt, aber diesmal nach links.

D. Michael Traub: hat die obige Erklärung der Xvector, Yvector und Zvector Parameter geliefert.

Um X, Y und Z-Rotation besser zu verstehen, werde ich sie anhand von Beispielen erklären...

X-Achse - Sie arbeiten an einer Kreissäge. Der Stab der direkt durch die Mitte des Sägeblatts geht, verläuft von links nach rechts (wie die X-Achse in OpenGl). Die scharfen Zähne rotieren um die X-Achse (den Stabe, der durch die Mitte des Sägeblatts verläuft) und scheint sich auf Sie zu oder weg von Ihnen zu bewegen, je nachdem in welche Richtung das Sägeblatt rotiert. Wenn Sie etwas in OpenGL auf der X-Achse rotieren lassen, wird es genauso rotieren.

Y-Achse - Stellen Sie sich vor, dass Sie inmitten eines Feldes stehen. Ein gewaltiger Tornado kommt direkt auf Sie zu. Das Zentrum des Tornados verläuft vom Himmel zum Boden (rauf und runter, genauso wie die Y-Achse in OpenGL). Der Schmutz und alles andere in dem Tornado rotiert um die Y-Achse (das Zentrum des Tornados) von links nach rechts oder von Rechts nach links. Wenn Sie etwas in OpenGL auf der Y-Achse rotieren lassen, wird es genauso rotieren.

Z-Achse - Sie schauen direkt auf einen Ventilator. Der Mittelpunkt des Ventilators zeigt auf Sie und weg von Ihnen (wie die z-Achse in OpenGL). Die einzelnen Blätter des Ventilators rotieren um die Z-Achse (Mittelpunkt des Ventilators) im Uhrzeigersinn oder gegen den Uhrzeigersinn. Wenn Sie etwas in OpenGL auf der Z-Achse rotieren lassen, wird es genauso rotieren.

Demnach würde die folgende Code-Zeile, wenn rtri gleich 7 ist, eine Rotation um 7 auf der Y-Achse (links nach recht) tätigen. Sie können ein wenig mit dem Code herum experimentieren. Ändern Sie die 0.0f in 1.0f und die 1.0f in 0.0f um das Dreieck auf der X und Y Achse zur selben Zeit rotieren zu lassen.

Es ist wichtig zu beachten, dass die Rotation in Grad vorgenommen wird. Wenn rtri einen Wert von 10 hat, würden wir um 10 Grad auf der Y-Achse rotieren.

    glRotatef(rtri,0.0f,1.0f,0.0f);                // Rotier das Dreieck auf der Y-Achse ( NEU )

Der nächste Code-Ausschnitt wurde nicht geändert. Er zeichnet ein farbverlaufenes Dreieck. Das Dreieck wird auf der rechten Seite des Bildschirms gezeichnet und wird auf seiner Y-Achse rotieren, was eine Rotation von links nach rechts bedeutet.

    glBegin(GL_TRIANGLES);                // Fange an ein Dreieck zu zeichnen
        glColor3f(1.0f,0.0f,0.0f);            // Setze den obersten Punkt des Dreeicks auf Rot
        glVertex3f( 0.0f, 1.0f, 0.0f);            // Erster Punkt des Dreiecks
        glColor3f(0.0f,1.0f,0.0f);            // Setze den linken Punkt des Dreiecks auf Grün
        glVertex3f(-1.0f,-1.0f, 0.0f);            // Zweiter Punkt des Dreiecks
        glColor3f(0.0f,0.0f,1.0f);            // Setze den rechten Punkt des Dreiecks auf Blau
        glVertex3f( 1.0f,-1.0f, 0.0f);            // Dritter Punkt des Dreiecks
    glEnd();                        // Fertig mit dem Zeichnen des Dreiecks

Sie werden im folgenden Code bemerken, dass wir ein weiteres glLoadIdentity() hinzugefügt haben. Wir machen das, um die Ansicht (View) zu resetten. Wenn wir die Ansicht nicht resetten und wir danach die Translation des Objekt nach dessen Rotation ausführen, würden Sie ziemlich unerwartete Ergebnisse erhalten. Da die Achsen rotiert wurden, zeigen sie wohl nicht mehr in die Richtung, in die Sie denken. Wenn wir also eine Verschiebung nach links auf der X-Achse haben, könnten wir statt dessen nach oben oder unten bewegen, abhängig davon, wie weit wir die jeweiligen Achsen rotiert haben. Versuchen Sie, die glLoadIdentity() Zeile herauszunehmen und schauen Sie, was passiert.

Wurde die Szene resettet, verläuft X von links nach rechts, Y von oben nach unten und Z von innen nach aussen und wir führen die Verschiebung aus. Sie werden bemerken, dass wir nur 1.5 nach rechts bewegen, statt 3.0, wie wir es in der letzten Lektion gemacht haben. Wenn wir den Screen resetten, bewegt sich unser Fokus in den Mittelpunkt des Bildschirms. Das bedeutet, wir befinden uns nicht 1.5 Einheiten nach links, sondern wir sind wieder bei 0.0. Um also 1.5 Einheiten nach Rechts (vom Ursprung) zu kommen, müssen wir nicht erst 1.5 Einheiten nach links zu bewegen, um zum Mittelpunkt zu gelangen und dann erst 1.5 Einheiten nach rechts (insgesamt also 3.0), sondern wir müssen einfach nur vom Mittelpunkt aus nach rechts bewegen, was nur 1.5 Einheiten sind.

Nachdem wir uns zu unserem neuen Ziel auf der rechten Seite des Bildschirms bewegt haben, rotieren wir das Quadrat auf der X-Achse. Das hat zur Folge, dass das Qudrat auf und ab rotiert.

    glLoadIdentity();                    // Resette die aktuelle Modelview Matrix
    glTranslatef(1.5f,0.0f,-6.0f);                // 1.5 Einheiten nach links und dann 6 Einheiten in den Bildschirm hinein

    glRotatef(rquad,1.0f,0.0f,0.0f);            // Rotiere das Rechteck auf der X-Achse ( NEU )

Dieser Code-Ausschnitt bleibt der selbe. Er zeichnet ein blaues Quadrat. Das Qudrat wird auf der rechten Seite des Bildschirm gezeichnet.

    glColor3f(0.5f,0.5f,1.0f);                // Setzt die Farbe auf einen netten Blauton
    glBegin(GL_QUADS);                    // Fange an ein Quadrat zu zeichnen
        glVertex3f(-1.0f, 1.0f, 0.0f);            // Oben links des Quadrats
        glVertex3f( 1.0f, 1.0f, 0.0f);            // Oben rechts des Quadrats
        glVertex3f( 1.0f,-1.0f, 0.0f);            // Unten rechts des Quadrats
        glVertex3f(-1.0f,-1.0f, 0.0f);            // Unten links des Quadrats
    glEnd();                        // Quadrat fertig gezeichnet

Die nächsten beiden Zeilen sind neu. Stellen Sie sich rtri und rquad als Container vor. Am Anfang unseres Programms haben wir die Containter gemacht (GLfloat rtri, and GLfloat rquad). Als wir die Container erzeugt haben, haben Sie noch nichts enthalten. Die erste folgende Zeile ADDIERT 0.2 in diesen Container. Demnach enthält der Wert in dem rtri Container jedesmal nach diesem Code-Ausschnitt einen um 0.2 erhöhten Wert. Der rquad Container wird um 0.15 vermindert. Demnach enthält der rquad Container jedesmal einen um 0.15 verminderten Wert. Das Herunterzählen hat zur Folge, dass das Objekt in die entgegengesetzte Richtung rotiert, als wenn wir raufzählen würden.

Versuchen Sie das + in ein + in der folgenden Zeile zu ändern, um zu sehen, wie das Objekt in die andere Richtung rotiert. Versuchen Sie die Werte von 0.2 auf 1.0 zu ändern. Je höher die Zahl ist, um so schneller rotiert das Objekt. Je kleiner die Zahl, desto langsamer wird rotiert.

    rtri+=0.2f;                    // Inkrementiere die Rotations Variable für das Dreieck     ( NEU )
    rquad-=0.15f;                    // Dekrementiere die Rotations Variable für das Quadrat     ( NEU )
    return TRUE;                    // Weiter geht's
}

Zu guter letzt ändern Sie den Code um zwischen Fenster- und Fullscreen-Modus zu wechseln, so dass der Titel des Fensters korrekt ist.

            if (keys[VK_F1])            // Wurde F1 gedrückt?
            {
                keys[VK_F1]=FALSE;    // Wenn ja, setze die Taste auf FALSE
                KillGLWindow();        // Kill unser aktuelles Fenster

                fullscreen=!fullscreen;    // Wechsel zwischen Fullscreen und Fester-Modus
                // Erzeuge unser OpenGL-Fenster neu ( Modifiziert )
                if (!CreateGLWindow("NeHe's Rotation Tutorial",640,480,16,fullscreen))
                {
                    return 0;        // Beenden, wenn das Fenster nicht erzeugt wurde
                }
            }

In diesem Tutorial habe ich so detailiert wie möglich versucht zu erklären, welche Schritte notwendig sind, um Objekte um eine Achse rotieren zu lassen. Spielen Sie ein wenig mit dem Code herum, versuchen Sie Objekte um die Z-Achse, die x & Y Achse oder alle drei rotieren zu lassen :) Wenn Sie Anmerkungen oder Fragen haben, schreiben Sie mir bitte eine E-Mail. Wenn Sie denken, ich habe etwas nicht korrekt kommentiert oder der Code könnte an einigen Stellen besser gemacht werden, lassen Sie es micht wissen. Ich möchte das beste OpenGL Tutorial machen. Ich bin an Ihrem Feedback interessiert.

Jeff Molofee (NeHe)

* DOWNLOAD Visual C++ Code für diese Lektion.

* DOWNLOAD ASM Code für diese Lektion. ( Conversion by Foolman )
* DOWNLOAD Borland C++ Builder 6 Code für diese Lektion. ( Conversion by Christian Kindahl )
* DOWNLOAD BeOS Code für diese Lektion. ( Conversion by Rene Manqueros )
* DOWNLOAD C# Code für diese Lektion. ( Conversion by Sabine Felsinger )
* DOWNLOAD VB.Net CsGL Code für diese Lektion. ( Conversion by X )
* DOWNLOAD Code Warrior 5.3 Code für diese Lektion. ( Conversion by Scott Lupton )
* DOWNLOAD Cygwin Code für diese Lektion. ( Conversion by Stephan Ferraro )
* DOWNLOAD D Language Code für diese Lektion. ( Conversion by Familia Pineda Garcia )
* DOWNLOAD Delphi Code für diese Lektion. ( Conversion by Michal Tucek )
* DOWNLOAD Dev C++ Code für diese Lektion. ( Conversion by Dan )
* DOWNLOAD Euphoria Code für diese Lektion. ( Conversion by Evan Marshall )
* DOWNLOAD Game GLUT Code für diese Lektion. ( Conversion by Milikas Anastasios )
* DOWNLOAD Genu Code für diese Lektion. ( Conversion by Louis-Charles Dumais )
* DOWNLOAD GLUT Code für diese Lektion. ( Conversion by Andy Restad )
* DOWNLOAD Irix Code für diese Lektion. ( Conversion by Lakmal Gunasekara )
* DOWNLOAD Java Code für diese Lektion. ( Conversion by Jeff Kirby )
* DOWNLOAD Java/SWT Code für diese Lektion. ( Conversion by Victor Gonzalez )
* DOWNLOAD Jedi-SDL Code für diese Lektion. ( Conversion by Dominique Louis )
* DOWNLOAD JoGL Code für diese Lektion. ( Conversion by Kevin J. Duling )
* DOWNLOAD LCC Win32 Code für diese Lektion. ( Conversion by Robert Wishlaw )
* DOWNLOAD Linux Code für diese Lektion. ( Conversion by Richard Campbell )
* DOWNLOAD Linux/GLX Code für diese Lektion. ( Conversion by Mihael Vrbanec )
* DOWNLOAD Linux/SDL Code für diese Lektion. ( Conversion by Ti Leggett )
* DOWNLOAD LWJGL Code für diese Lektion. ( Conversion by Mark Bernard )
* DOWNLOAD Mac OS Code für diese Lektion. ( Conversion by Anthony Parker )
* DOWNLOAD Mac OS X/Cocoa Code für diese Lektion. ( Conversion by Bryan Blackburn )
* DOWNLOAD MASM Code für diese Lektion. ( Conversion by Nico (Scalp) )
* DOWNLOAD Power Basic Code für diese Lektion. ( Conversion by Angus Law )
* DOWNLOAD Pelles C Code für diese Lektion. ( Conversion by Pelle Orinius )
* DOWNLOAD Perl Code für diese Lektion. ( Conversion by Cora Hussey )
* DOWNLOAD Python Code für diese Lektion. ( Conversion by John Ferguson )
* DOWNLOAD REALbasic Code für diese Lektion. ( Conversion by Thomas J. Cunningham )
* DOWNLOAD Scheme Code für diese Lektion. ( Conversion by Jon DuBois )
* DOWNLOAD Solaris Code für diese Lektion. ( Conversion by Lakmal Gunasekara )
* DOWNLOAD Visual Basic Code für diese Lektion. ( Conversion by Ross Dawson )
* DOWNLOAD Visual Fortran Code für diese Lektion. ( Conversion by Jean-Philippe Perois )
* DOWNLOAD Visual Studio .NET Code für diese Lektion. ( Conversion by Grant James )



Deutsche Übersetzung: Joachim Rohde
Der original Text ist hier zu finden.
Die original OpenGL Tutorials stammen von NeHe's Seite.