Lektion 12: Display-Listen
In diesem Tutorial werde ich euch erklären wie man Display-Listen verwendet.
Sie machen euren Code nicht nur schneller sondern verringern auch noch die Anzahl
der Zeilen die ihr schreiben müsst.
Wenn ihr also zum Beispiel das Spiel "Asteroids" machen wollen würdet. Jedes
Level fängt mit mindestens 2 Asteoriden an. Du setzt dich also an deine Grafikaufzeichnungen
*g* und entwirfst einen 3D Asteroiden. Wenn du dich entschieden hast wie er
aussehen soll erstellst du den Asteroiden in OpenGL aus Vierecken und Polygonen.
Der Asteorid ist z.B. octagonal (8-seitig). Wenn du schlau bist erstellst du
den Körper innerhalb einer Schleife. dann hast du trotzdem mindesten 18 oder
mehr Zeilen Code. Den Asteroiden jedesmal neu zu erstellen wenn er auf dem Bildschirm
gezeichnet werden soll geht ganz schön auf die Performance. Wenn später einmal
komplexere Objekte zu zeichnen sind wisst ihr was ich meine.
So, wie löst man nun dieses Problem ? Mit Display-Listen !!! Wenn man Display-Listen
verwendet erstellt man das Objekt nur ein mal. Du kannst es texturieren, färben,
was auch immer. Dann gibt man der Liste einen Namen. Da es sich um einen Asteroiden
handelt nennen wir die Liste "Asteroid". Nun, wenn wir einen texturierten und
gefärbten Asteroiden zeichnen wollen ist alles was wir tun müssen glCallList(asteroid);
aufzurufen. Der schon vorher erstellte Asteroid erscheint auf dem Bildschirm.
Da der Asteroid schon in der Display-Liste erstellt wurde muss OpenGL nicht
erst rausfinden wie er aufgebaut ist. Er wurde schon im Speicher vorgebaut.
Dies nimmt dem Prozessor einiges an Arbeit ab und erlaubt eurem Programm um
einiges schneller zu laufen.
Seit ihr bereit zu lernen ? :-) Wir nennen diese Demo "Die Q-Bert Display-Listen
Demo". Am Ende wirst du einen Q-Bert auf dem Bildschrim haben, bestehend aus
15 Würfel. Jeder Würfel besteht aus einem Deckel(TOP) und einer BOX. Der Deckel
wird eine eigene Display-Liste bekommen so das wir ihn dunkler zeichnen können.
Die BOX ist einfach ein Würfel ohne Deckel. :-)
Der Code baut auf Tutorial 6 auf. Ich habe den grössten Teil des Programms
nochmal geschrieben, so ist es einfacher zu sehen wo ich etwas verändert habe.
Die folgenden Zeilen sind Standart in fast jedem Tutorial.
#include <windows.h> // Header File For Windows
#include <stdio.h> // Header File For Standard Input/Output
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
#include <gl\glaux.h> // Header File For The GLaux Library
HDC hDC=NULL; // Private GDI Device Context
HGLRC hRC=NULL; // Permanent Rendering Context
HWND hWnd=NULL; // Holds Our Window Handle
HINSTANCE hInstance; // Holds The Instance Of The Application
bool keys[256]; // Array Used For The Keyboard Routine
bool active=TRUE; // Window Active Flag Set To TRUE By Default
bool fullscreen=TRUE;
// Fullscreen Flag Set To Fullscreen Mode By Default
Nun definieren wir vier Variablen. Als erstes schaffen wir Platz für eine Textur.
Dann brauchen wir zwei neue Variablen für unsere 2 Display-Listen. Diese Variablen
agieren als Pointer, welche auf die Speicherposition der Display-Listen im Ram
verweisen. Wir nennen sie box und top.
Danach haben wir 2 Variablen, genannt xloop und yloop, welche die Position
des Würfels auf dem Bildschirm bestimmen. Und noch 2 Variablen xrot und yrot
um den Würfel auf der X-Achse und auf der Y-Achse rotieren zu lassen.
GLuint texture[1]; // Storage For One Texture
GLuint box; // Storage For The Display List
GLuint top; // Storage For The Second Display List
GLuint xloop; // Loop For X Axis
GLuint yloop; // Loop For Y Axis
GLfloat xrot; // Rotates Cube On The X Axis
GLfloat yrot; // Rotates Cube On The Y Axis
Als nächstes erschaffen wir unsere zwei Farb-Arrays. Das erste enthält die
Werte für helles Rot, Orange, Gelb, Grün und Blau. Jeder Wert innerhalb der
{} enthält den jeweiligen Rot, Grün und Blau Anteil. Jede Gruppe von {} entspricht
einer bestimmten Farbe.
Das zweite Farb-Array enthält Dunkelrot, Dunkelorange, Dunkelgelb, Dunkelgrün
und Dunkelblau. Die dunklen Farben werden dazu benutzt den Deckel der Boxen
zu zeichnen. Der Deckel soll dann also dunkler sein als der Rest der Box.
static GLfloat boxcol[5][3]= // Array For Box Colors
{
// Bright: Red, Orange, Yellow, Green, Blue
{1.0f,0.0f,0.0f},
{1.0f,0.5f,0.0f},
{1.0f,1.0f,0.0f},
{0.0f,1.0f,0.0f},
{0.0f,1.0f,1.0f}
};
static GLfloat topcol[5][3]= // Array For Top Colors
{
// Dark: Red, Orange, Yellow, Green, Blue
{.5f,0.0f,0.0f},
{0.5f,0.25f,0.0f},
{0.5f,0.5f,0.0f},
{0.0f,0.5f,0.0f},
{0.0f,0.5f,0.5f}
};
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
// Declaration For WndProc
Nun wollen wir unsere erste Display-Liste erstellen. Wie du gleich bemerken wirst,
ist jeglicher Code für die Box in unserer ersten Liste während der Code für den
Deckel in der zweiten steckt. Ich versuche das jetzt so detailrech wie möglich
zu erläutern.
GLvoid BuildLists()
// Build Box Display List
{
Wir beginnnen indem wir OpenGL sagen das wir 2 Listen bauen wollen. Die Funktion
glGenLists(2) stellt den Platz für 2 Listen bereit und gibt einen Pointer zurück,
der auf die erste Liste zeigt. Die Variable 'box' enthält die Position der ersten
Liste. Immer wenn wir nun 'box' aufrufen wird die Liste Nummer eins gezeichnet.
box=glGenLists(2);
// Building Two Lists
Nun stellen wir unsere erste Liste mal zusammen. Den Platz für 2 Listen haben
wir bereits geschaffen, und wir wissen das 'box' auf die Stelle im Speicher
zeigt wo wir die erste Liste speichern werden. Das einzigste was wir jetzt noch
machen müssen ist OpenGL mitzuteilen wie die Liste aussieht und welche Art von
Liste wir haben möchten.
Dafür benutzen wir die Funktion glNewList() . Du wirst bemerken das 'box' der
erste Parameter ist. Dies sagt OpenGL das die Liste an der Position gespeichert
wird auf die 'box' zeigt. Der zweite Parameter ist GL_COMPILE welcher OpenGL
sagt, dass das Objekt im Speicher bereits erstellt werden soll so das OpenGL
nicht jedesmal wenn wir es zeichnen herrausfinden muss wie es aussieht.
GL_COMPILE ist ähnlich dem Programmieren. Wenn du ein Programm schreibst und
es in den Compiler lädts, musst du es jedesmal compilieren um es auszuführen.
Wenn es aber schon compiliert ist und als .EXE datei vorhanden musst du es einfach
nur noch anklicken um es auszuführen. Wenn OpenGL die Liste einmal compiliert
hat kann es sie beliebig benutzen, ohne sie jedesmal neu zu compilieren. Daher
kommt der Geschwindigkeitsvorteil wenn wir Display-Listen verwenden.
glNewList(box,GL_COMPILE);
// New Compiled box Display List
Der nächste Abschnitt zeichnet die Box ohne Deckel. Es wird Nichts auf dem
Bildschirm erscheinen sondern Alles in der Display-Liste gespeichert werden.
Du kannst jeden Befehl den du willst zwischen glNewList() und glEndList() einfügen.
Du kannst die Farbe setzen, die Textur wechseln etc. das einzigste was du nicht
machen kannst, ist die Display-Liste während der Laufzeit verändern. Wenn die
Liste einmal gebaut wurde kannst du sie nicht mehr ändern.
Wenn du z.B. die Zeile glColo3ub(rand()%255,rand()%255,rand()%255) in den unteren
Code einfügen würdest, könnte man denken das jedesmal wenn du das Objekt auf
dem Bildschirm zeichnest es eine andere Farbe haben wird. Aber dadurch, dass
die Liste nur einmal erstellt wird, wird die Farbe natürlich nicht gewechselt.
Was auch immer das Objekt für eine Farbe hatte als es erstellt wurde, kann diese
dann nicht mehr geändert werden.
Wenn du die Farbe der Display-Liste ändern möchtest musst du dies tun, bevor
du die Liste zeichnest. Ich werden dies später ausführlicher erklären.
glBegin(GL_QUADS);
// Start Drawing Quads
// Bottom Face
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
// Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// Bottom Right Of The Texture and Quad
// Front Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
// Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
// Top Left Of The Texture and Quad
// Back Face
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
// Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
// Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
// Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Bottom Left Of The Texture and Quad
// Right face
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
// Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
// Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Bottom Left Of The Texture and Quad
// Left Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
// Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
// Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
// Top Left Of The Texture and Quad
glEnd();
// Done Drawing Quads
Wir sagen OpenGL das wir fertig mit unserer Liste sind mit dem Befehl glEndList()
.Alles was innerhalb von glNewList() und glEndList() steht ist Teil der Display-Liste,
alles was davor oder danach steht ist logischer Weise nicht Teil der Liste.
glEndList();
// Done Building The box List
Nun machen wir unsere zweite Liste. Um heraus zu finden wo die zweite Liste im
Speicher abgelegt wird nehmen wir die alte Display-Liste und addieren eins hinzu.
Der folgende Code setzt 'top' auf die Position der zweiten Liste.
top=box+1;
// top List Value Is box List Value +1
Jetzt wissen wir wo die zweite Liste gespeichert wird und erstellen sie einfach
mal. Das geschiet genauso wie auch bei der ersten Display-Liste, nur teilen wir
diesmal OpenGl mit die Liste an der Position 'top' und nicht 'box' zu speichern.
glNewList(top,GL_COMPILE);
// New Compiled top Display List
Der fogende Abschnitt zeichnet den Deckel der Box. Dieser besteht einfach aus
einem Quadrat auf der Z-Ebene.
glBegin(GL_QUADS);
// Start Drawing Quad
// Top Face
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
// Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
// Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
// Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
// Top Right Of The Texture and Quad
glEnd();
// Done Drawing Quad
Wieder sagen wir OpenGL das wir fertig sind mit unserer Liste mit dem Befehl glEndList().
Das wars schon. Wir haben nun erfolgreich 2 Display-Listen erstellt.
glEndList();
// Done Building The top Display List
}
Der Bitmap/Textur Code ist der selbe wie in den Tutorials zuvor. Wir brauchen
eine Textur die wir auf alle 6 Seiten des Würfels packen können. Ich hab mich
entschieden eine mipmapped Textur zu nehmen da das ganze dann einfach besser aussieht.
Ich hasse es wenn man die einzelnen Pixel erkenne kann :-) Die Textur die wir
laden werden heisst 'cube.bmp' aus dem Verzeichnis data. Gehe im Quelltext zu
LoadBMP und ändere die zeile wie folgt:
if (TextureImage[0]=LoadBMP("Data/Cube.bmp"))
// Load The Bitmap
Die Resizing Routine aus Lektion 6 wird nicht verändert.
Die Initialisierungsroutine erfährt ein paar kleine Veränderungen. Ich habe
die Zeile BuildList() hinzu gefügt. Dadurch wird die Funktion aufgerufen die
unsere Display-Listen erstellt. Wichtig ist das BuildList() erst nach LoadGLTextures()
aufgerufen wird. Es ist wichtig zu wissen in welcher Reihenfolge Dinge passieren
müssen. Zuerst müssen wir unsere Textur laden damit wenn unsere Listen erstellt
werden die Objekte bereits mit den Texturen verknüpft werden können.
int InitGL(GLvoid)
// All Setup For OpenGL Goes Here
{
if (!LoadGLTextures())
// Jump To Texture Loading Routine
{
return FALSE;
// If Texture Didn't Load Return FALSE
}
BuildLists();
// Jump To The Code That Creates Our Display Lists
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
lDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
Die nächsten Zeilen ermöglichen einfach und schnell Lichteffekte einzubinden.
Light0 ist meistens auf den Grafikkarten schon vordefiniert, dies erspart uns
den Ärger selbst ein Licht zu erstellen. Danach aktivieren wir Light0 natürlich
noch. Wenn die Sache mit Light0 auf eurer Videokarte nicht funktionieren sollte
(der Bildschirm bleibt Schwarz) deaktiviere das Licht einfach wieder.
Die letze zeile GL_COLOR_MATERIAL ermöglicht es uns Licht auf Texturen zu sehen.
Wenn wir diese Funktion nicht aktivieren behalten die Texturen ihre ursprüngliche
Farbe und glColor3f(r,g,b) wird auf sie keine Effekt haben. Es ist also wichtig
diese Funktion zu aktivieren.
glEnable(GL_LIGHT0);
// Quick And Dirty Lighting (Assumes Light0 Is Set Up)
glEnable(GL_LIGHTING);
// Enable Lighting
glEnable(GL_COLOR_MATERIAL);
// Enable Material Coloring
Letztendlich lassen wir die Perspektive noch "schön" aussehen und leifern ein
TRUE zurück damit unser Programm weiss das alles gut gegangen ist.
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
// Nice Perspective Correction
return TRUE;
// Initialization Went OK
Nun zum Zeichnen. Wie üblich werde ich ein bisschen Mathe abfordern. Keine
Sinus- oder Cosinusfunktionen aber schon nicht ganz einfach :-) Erstmal löschen
wir den Bildschirm- und den Tiefenspeicher.
Dann verknüpfen wir den Würfel mit einer Textur. Ich hätte dies auch in der
Diplay-Liste direkt machen können, aber so kann ich die Textur nach belieben
wechseln. Wenn ich die Zeile glBindTexture(GL_TEXTURE_2D, texture[0]) in die
Liste geschrieben hätte, würde die der Würfel mit dieser Textur erstellt werden
und sie auch permanent behalten.
int DrawGLScene(GLvoid)
// Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Clear The Screen And The Depth Buffer
glBindTexture(GL_TEXTURE_2D, texture[0]);
// Select The Texture
Nun zum schönen Teil. Wir haben eine Schleife, genannt yloop. Sie wird benutzt
um die Würfel auf der Y-Achse von oben nach unten anzuordnen. Wir wollen 5 Reihen
von oben nach unten erstellen also nehmen wir unsere Schleife von 1 bis 6 (was
5 Durchläufe ergibt).
for (yloop=1;yloop<6;yloop++)
// Loop Through The Y Plane
{
Wir haben auch eine andere Schleife namens xloop. Sie wird dazu benutzt die Würfel
auf der X-Achse auszurichten. Die Anzahl der Würfel von links nach rechts ist
abhängig davon, in welcher Reihe wir uns befinden. Wenn wir uns in der obersten
Reihe befinden läuft die Schleife nur von 0 bis 1 ( ein Würfel wird gezeichnet).
Die nächte Reihe läuft von 0 bis 2 ( zwei Würfel werden gezeichnet), usw.
for (xloop=0;xloop
// Loop Through The X Plane
{
Wir setzen unseren Sichtweise wieder zurück.
glLoadIdentity();
// Reset The View
Die nächste Zeile bewegt uns zu einem bestimmten Punkt auf dem Bildschirm.
Es sieht verwirrend aus, aber so schlimm ist es gar nicht. Auf der X-Achse passiert
folgendes:
Wir bewegen uns um 1,4 Einheiten so das die Pyramide in der Mitte des Bildschirms
steht. Dann multiplizieren wir xloop mit 2,8 und addieren 1,4 dazu. (wir multiplizieren
mit 2,8 damit die Würfel nicht direkt aufeinander stehen (2,8 ist die ungefähre
Breite eines Würfels der um 45° gedreht wurde)). Zum Schluss subtrahieren wir
yloop*1,4. Dies bewegt die Würfel nach links in abhängigkeit der zeile in der
wir uns befinden. Wenn wir uns nicht nach links bewegen würden, würde die Pyramide
nicht wirklich wie eine Pyramide aussehen.
Auf der Y-Achse subtrahieren wir yloop von 6 ansonsten würde die Pyramide verkehrt
herum aufgebaut werden. Danach multiplizieren wir das ergebnis mit 2,4. Sonst
wären die Würfel wieder direkt aufeinander, diesmal auf der Y-Achse (2,4 entspricht
ungefähr der Höhe des Würfels). Dann ziehen wir 7 ab so dass die Pyramide unten
am Bildschirm anfängt und sich nach oben aufbaut.
Letztendlich bewegen wir die Pyramide noch 20 Einheiten auf der Z-Achse nach
hinten. Auf diese Art passt die Pyramide wunderbar auf den Bilschrim.
// Position The Cubes On The Screen
glTranslatef(1.4f+(float(xloop)*2.8f)-
(float(yloop)*1.4f),
((6.0f-float(yloop))*2.4f)-7.0f,-20.0f);
Nun rotieren wir um die X-Achse. Wir drehen den Würfel um 45° minus 2mal yloop.
Der Perspektiven-Modus dreht den Würfel für uns schon automtisch, also rechne
ich minus um dies wieder zu kompensieren. Es ist nicht die beste möglichkeit
dies zu tun, aber es funktioniert :-)
Zum Schluss addieren wir xrot dazu. Dies gibt uns die Tastaturkontrolle über
die Drehung. (es macht Spass damit zu spielen).
Nachdem wir uns auf der X-Achse gedreht haben, rotieren wir nun auf der Y-Achse
um 45° und addieren yrot um die Tastaturkontrolle zu bekommen.
glRotatef(45.0f-(2.0f*yloop)+xrot,1.0f,0.0f,0.0f);
// Tilt The Cubes Up And Down
glRotatef(45.0f+yrot,0.0f,1.0f,0.0f);
// Spin Cubes Left And Right
Da die Farbe bereits gesetzt ist, ist alles was wir noch tun müssen den Würfel
zu zeichnen. Anstatt den ganzen Code aufzuschreiben der nötig wäre um einen
Würfel zu zeichnen rufen wir einfach unsere Display-Liste auf. Dies geschiet
durch den Befehl glCallList(box). box teilt OpenGL mit das es sich um die Display-Liste
box handelt. Diese Liste enthält den Würfel ohne Deckel.
Die Box wird in der Farbe gezeichnet die wir mit glColor3fv() ausgewählt haben
und an der Position an die wir sie verschoben haben.
glRotatef(45.0f-(2.0f*yloop)+xrot,1.0f,0.0f,0.0f);
// Tilt The Cubes Up And Down
glRotatef(45.0f+yrot,0.0f,1.0f,0.0f);
// Spin Cubes Left And Right
Nun suchen wir eine dunklere Farbe für den Deckel der Box. Wenn du wirklich einen
Q-Bert machen wollen würdest bräuchtest du nur jedesmal die Farbe zu ändern wenn
Q-Bert auf die Box springt. Die Farbe ist abhängig von der Reihe (yloop-1).
glColor3fv(topcol[yloop-1]);
// Select The Top Color
Das einzigste was jetzt noch übriggeblieben ist, ist die top Liste aufzurufen.
Das wird einen dunkleren Deckel auf die Box setzen. So einfach.
glCallList(top);
// Draw The Top
}
}
return TRUE;
// Jump Back
}
Die restlichen Veränderungen sind alle in der Funktion WinMain(). Der Code wird
direkt nach SwapBuffers(hDC) eingefügt. Er überprüft ob entweder links, rechts,
oben oder unten gedrückt wurde und bewegt die Würfel entsprechend.
SwapBuffers(hDC);
// Swap Buffers (Double Buffering)
if (keys[VK_LEFT])
// Left Arrow Being Pressed?
{
yrot-=0.2f;
// If So Spin Cubes Left
}
if (keys[VK_RIGHT])
// Right Arrow Being Pressed?
{
yrot+=0.2f;
// If So Spin Cubes Right
}
if (keys[VK_UP])
// Up Arrow Being Pressed?
{
xrot-=0.2f;
// If So Tilt Cubes Up
}
if (keys[VK_DOWN])
// Down Arrow Being Pressed?
{
xrot+=0.2f;
// If So Tilt Cubes Down
}
Wie in allen Tutorials wird auch noch der Name des Fensters angepasst.
if (keys[VK_F1])
// Is F1 Being Pressed?
{
keys[VK_F1]=FALSE; // If So Make Key FALSE
KillGLWindow(); // Kill Our Current Window
fullscreen=!fullscreen;
// Toggle Fullscreen / Windowed Mode
// Recreate Our OpenGL Window
if (!CreateGLWindow("NeHe's Display List Tutorial",
640,480,16,fullscreen))
{
return 0; // Quit If Window Was Not Created
}
}
}
}
Nach diesem Tutorial solltet ihr ein gutes Verständnis haben wie Display-Listen
funktionieren, wie sie erstellt und schliesslich auch benutzt werden. Display-Listen
sind grossartig. Sie vereinfachen nicht nur den Code in komplexen Projekten
sondern geben zusätzlich auch noch ein wenig Geschwindigkeit die benötigt wird
um hohe Frameraten zu erreichen.
Ich hoffe euch hat dieses Tutorial Spass gemacht. Wenn ihr noch irgendwelche
Fragen habt oder euch einfach einige Sachen noch nicht ganz klar sind mailed
mir.
Die Source Codes und Ausführbaren Dateien zu den Kursen liegen auf der Neon
Helium Website
Übersetzung von Delax & ChaosAngel/ Sundancer
Inc.
(Präsentiert von www.codeworx.org)