G
Hallo,
ich lese gerade das Tutorial von http://www.codeworx.org/opengl_tuts.php . Aber in dem 6. Kapitel erklären die einige Dinge zu oberflächlich (aber das TUT ist top ;-), nur weiter zu empfehlen). Ich hab mir den Code schon genauer angesehen und wollte zum Verständnis ein 2 Fragen stellen.
1. Die Funktion:
AUX_RGBImageRec *LoadBMP(char *Filename)
hat 2 Sterne. Das bedeutet doch eigentlich das das Zeiger (Pointer) sind. Aber Pointer in einer "Funktionstitelleiste" hab ich noch nie gesehen und vorallem frage ich mich worauf die zeigen???. Könnte jemand ganz genau erklären warum das so ist??? (Mit logischer Begründung)
2. Am Ende des Ladevorgangs der Texturen kommt noch die Filtereinstellungen:
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
Gelten die für alle Texturen oder nur für die, die gerade geladen wird???
3. Bedanke mich für Antworten und Erklärungen. thx
Orginal Code:
// Tutorial 5 "Texture Mapping"
// gedownloaded von www.codeworx.org
// Version 1.0, Hans-Jakob Schwer, 25.11.2001
// Original von Jeff Molofee, neu kommentiert und übersetzt aus dem Englischen
#include <windows.h> // diverse Windowsfunktionen
#include <stdio.h> // Dateien sollen verwendet werden
#include <gl\glu.h> // Damit kann Glu32 genutzt werden.
#include <gl\gl.h> // Damit kann OpenGL32 genutzt werden.
#include <gl\glaux.h> // Und das Gleiche nochmal für Glaux
HGLRC hRC=NULL; // Der OpenGL Rendering Context
HDC hDC=NULL; // Geräte Kontext
HWND hWnd=NULL; // Verweist später auf den Windows Handle
HINSTANCE hInstance; // Die Instanz der Anwendung
bool keys[256]; // Vektor (Array) der den Status
// einzelner Tasten enthält
// (gedrückt/nicht gedrückt)
bool active=TRUE; // Wenn active FALSE ist, wurde das
// Fenster vom Benutzer minimiert.
bool fullscreen=TRUE; // Läuft das Programm im Vollbildmodus
// oder nicht?
GLfloat xrot; // Rotation um die X-Achse
GLfloat yrot; // Rotation um die Y-Achse
GLfloat zrot; // Rotation um die Z-Achse
GLuint texture[1]; // Texturspeicher
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
// WndProc wird deklariert
GLvoid ReSizeGLScene(GLsizei width, GLsizei height)
// Initialisierung des OpenGL-Fensters
{
if (height==0)
{
height=1;
}
// height darf nicht 0 sein, damit es im späteren
// Programmablauf nicht zu einer Division durch 0 kommt.
glViewport(0, 0, width, height);
// Hier wird der Mittelpunkt auf den die Perspektive zuläuft
// zurückgesetzt.
glMatrixMode(GL_PROJECTION);
// Hier wird die Projektionsmatrix festgelegt
glLoadIdentity();
// und angepasst
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
// Hier wird die das Verhältnis der Höhe zur Breite übergeben
// und der Verzerrungswinkel von 45 Grad übergeben
glMatrixMode(GL_MODELVIEW);
// Hier wird die sogenannte modelview-Matrix festgelegt
glLoadIdentity();
// und angepasst.
}
AUX_RGBImageRec *LoadBMP(char *Filename) // Lädt ein BMP
{
FILE *File=NULL; // Das File Handle
if (!Filename)
// Ist ein Dateiname übergeben worden?
{
return NULL; // offenbar nicht... Abbruch
}
File=fopen(Filename,"r");
// Versuch die Datei zu öffnen
if (File) // Existiert die Datei?
{
fclose(File); // Datei schließen
return auxDIBImageLoad(Filename);
// BMP laden und Zeiger (Pointer) zurückgeben,
// der auf die Bilddaten verweist
}
return NULL; // Laden hat nicht geklappt
}
int LoadGLTextures() // Bitmaps laden und konvertieren
{
int Status=FALSE;
// Status ersteinmal auf FALSE setzen
AUX_RGBImageRec *TextureImage[1];
// Speicherplatz für die Textur schaffen
memset(TextureImage,0,sizeof(void *)*1);
//Vorher sichergehen das dieser auch leer ist
if (TextureImage[0]=LoadBMP("Data/codeworx.bmp"))
// Bitmap laden
{
Status=TRUE; // hat geklappt.
glGenTextures(1, &texture[0]); // Textur wird erstellt
glBindTexture(GL_TEXTURE_2D, texture[0]);
//Es handelt sich um eine 2D Textur
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX,
TextureImage[0]->sizeY, 0, GL_RGB,
GL_UNSIGNED_BYTE, TextureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
// GL_LINEAR wird für GL_TEXTURE_MIN_FILTER genutzt
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
// GL_LINEAR wird für GL_TEXTURE_MAG_FILTER genutzt
}
if (TextureImage[0]) // Existiert TextureImage[0]?
{
if (TextureImage[0]->data) // enthält sie Bilddaten?
{
free(TextureImage[0]->data); // wenn ja, dann diese Bilddaten löschen
}
free(TextureImage[0]); // Und auch die Struktur an sich löschen.
}
return Status; // Status zurückgeben
}
int InitGL(GLvoid)
{
if (!LoadGLTextures())
{
return FALSE; // Texturen konnten nicht geladen werden...
}
glEnable(GL_TEXTURE_2D); // Texture Mapping aktivieren
glShadeModel(GL_SMOOTH);
// Das Smooth Shading wird aktiviert, das
// sehr schöne Farbübergänge auf Körpern ermöglicht.
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// In diesem Falle ein schwarzer Hintergrund
glClearDepth(1.0f);
// depht buffer zurückgesetzt
glEnable(GL_DEPTH_TEST);
// Aktivierung des depht Tests (dazu später mehr.)
glDepthFunc(GL_LEQUAL);
// Der Typ des Depht Tests wird festgelegt
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
// Perspektive wird festgelegt
return TRUE; // Initialisierung scheint geklappt zu haben!
}
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 wieder einmal zurückgesetzt
glTranslatef(0.0f,0.0f,-5.0f);
// Damit der Würfel auch zusehen ist, wird er um 5 Einheiten zurückgesetzt
glRotatef(xrot,1.0f,0.0f,0.0f); // Um die X Achse rotieren
glRotatef(yrot,0.0f,1.0f,0.0f); // Um die Y Achse rotieren
glRotatef(zrot,0.0f,0.0f,1.0f); // Um die Z Achse rotieren
glBegin(GL_QUADS);
// Das vordere QUAD
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// unten links an der Form und der Textur
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// unten rechts an der Form und der Textur
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
// oben rechts an der Form und der Textur
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
// oben links an der Form und der Textur
// Das hintere QUAD
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
// unten rechts an der Form und der Textur
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
// oben rechts an der Form und der Textur
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
// oben links an der Form und der Textur
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// unten links an der Form und der Textur
// Das obere QUAD
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
// oben links an der Form und der Textur
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
// unten links an der Form und der Textur
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
// unten rechts an der Form und der Textur
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
// oben rechts an der Form und der Textur
// Das untere QUAD
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
// oben rechts an der Form und der Textur
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// oben links an der Form und der Textur
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// unten links an der Form und der Textur
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// unten rechts an der Form und der Textur
// Das rechte QUAD
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// unten rechts an der Form und der Textur
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
// oben rechts an der Form und der Textur
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
// oben links an der Form und der Textur
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// unten links an der Form und der Textur
// Das linke QUAD
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
// unten links an der Form und der Textur
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// unten rechts an der Form und der Textur
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
// oben rechts an der Form und der Textur
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
// oben links an der Form und der Textur
glEnd();
xrot+=0.4f; // X Achsen Rotation
yrot+=0.6f; // Y Achsen Rotation
zrot+=0.1f; // Z Achsen Rotation
return true; // Alles hat geklappt!
}
GLvoid KillGLWindow(GLvoid)
{
if (fullscreen) // Kontrolle auf Vollbildmodus
{
ChangeDisplaySettings(NULL,0); // Zurück zum Desktop
ShowCursor(TRUE); // Der abgeschaltete Mauszeiger
// wird wieder angezeigt (Nicht
// vergessen ;)
}
if (hRC) // Rendering Context (RC) vorhanden?
{
if (!wglMakeCurrent(NULL,NULL)) // Kann der DC und RC überhaupt
// gelöscht werden?
{
MessageBox(NULL,"Entfernen des DC und RC fehlgeschlagen.","Fehler",MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hRC)) // Kann der RC gelöscht werden?
{
MessageBox(NULL,"Entfernen des RC fehlgeschlagen.","Fehler...",MB_OK | MB_ICONINFORMATION);
}
hRC=NULL; // Der RC wird NULL gesetzt, also entfernt
}
if (hDC && !ReleaseDC(hWnd,hDC))
// Kann der Device Context (DC) freigegeben werden?
{
MessageBox(NULL,"Freigabe des Device Context fehlgeschlagen.","Fehler",MB_OK | MB_ICONINFORMATION);
hDC=NULL; // Der DC wird entfernt
}
if (hWnd && !DestroyWindow(hWnd))
// Kann das Programmfenster geschlossen werden?
{
MessageBox(NULL,"Konnte hWnd nicht löschen.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hWnd=NULL; // Setze den hWnd auf NULL
}
if (!UnregisterClass("OpenGL",hInstance))
// Kann die Registrierung rückgängig gemacht werden?
{
MessageBox(NULL,"Konnte Klasse nicht entfernen.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hInstance=NULL; // Setze hInstance auf NULL
}
}
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
GLuint PixelFormat; // Speichert das Pixelformat
WNDCLASS wc; // wc wird eine Instanz der Fensterklasse
DWORD dwExStyle; // weitere Informationen
DWORD dwStyle; // Fensterinformationen
RECT WindowRect;
// Speicher für aktuelle Auflösung
WindowRect.left=(long)0;
// Die linke Seite des Rechtecks wirtd auf 0 gesetzt
WindowRect.right=(long)width;
// Hier wird die gewünschte Breite des Fensters gespeichert
WindowRect.top=(long)0;
// Die obere Seite wird auch auf 0 gesetzt
WindowRect.bottom=(long)height;
// Und hier wird die Höhe abgelegt
fullscreen=fullscreenflag;
// Hier wird fullscreen
// auf den Wert von fullscreenflag
// gesetzt, welches ja übergeben wurde
hInstance = GetModuleHandle(NULL);
// Die Instanz des Programmes bekommt ein
// Handle zugeordnet
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
// Bei Veränderungen in der Höhe und/oder Breite,
// soll ne gezeichnet werden
wc.lpfnWndProc = (WNDPROC) WndProc;
// WndProc behandelt die auftretenden Nachrichten
wc.cbClsExtra = 0; // Wird nicht benötigt
wc.cbWndExtra = 0; // und das auch nicht
wc.hInstance = hInstance; // Die Instanz wird festgelegt
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
// Lädt das Standardsymbol
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
// Lädt einen Cursor
wc.hbrBackground = NULL;
// Es soll kein bestimmter Hintergrund angezeigt werden
wc.lpszMenuName = NULL; // Auch ein Menü wird nicht benötigt.
wc.lpszClassName = "OpenGL"; // OpenGL wird der Name der Klasse
if (!RegisterClass(&wc)) // Versuch die Klasse zu registrieren
{
MessageBox(NULL,"Konnte die Fensterklasse nicht registrieren.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // FALSE zurückgeben und beenden
}
if (fullscreen) // Soll im Vollbildmodus gestartet werden
{
DEVMODE dmScreenSettings;
// Instanz von DEVMODE wird erzeugt
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
// Diese wird geleert
dmScreenSettings.dmSize=sizeof(dmScreenSettings);
// dmsize soll genauso groß wie die dmScreenSettings sein
dmScreenSettings.dmPelsWidth = width;
// Die drei Werte (height, width und bits)
// wurden der Prozedur übergeben und werden
// nun in dmScreenSettings gespeichert
dmScreenSettings.dmPelsHeight = height;
dmScreenSettings.dmBitsPerPel = bits;
dmScreenSettings.dmFields=DM_BITSPERPEL|
DM_PELSWIDTH|DM_PELSHEIGHT;
// Hier werden die drei Werte in einem Ausdruck gespeichert
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)
!=DISP_CHANGE_SUCCESSFUL)
{
// CDS_FULLSCREEN blendet zusätzlich die Startleiste aus
if (MessageBox(NULL,"Der gewünschte Vollbildmodus wird nicht unterstützt, soll stattdessen im Fenstermodus ausgegeben werden?","OpenGL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
{
fullscreen=FALSE;
// Der Benutzer möchte im Fenster weitermachen,
// dazu wird fullscreen auf FALSE gesetzt
}
else
{
return FALSE;
// Falls der Benutzer das Programm aus gegebenen
// Anlass beenden will, wird FALSE zurückgegeben.
}
}
}
if (fullscreen)
// Konnte in den Vollbildmodus geschaltet werden?
// (Wenn nicht, wird ja im Fenster weitergemacht!)
{
dwExStyle=WS_EX_APPWINDOW; // Fenstereigenschaften
dwStyle=WS_POPUP; // -"-
ShowCursor(FALSE); // Der Mauszeiger wird nicht angezeigt
}
else
{
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
// Das Fenster soll zusätzlich einen 3D Rahmen bekommen
dwStyle=WS_OVERLAPPEDWINDOW;
// Ein typisches Windowsfenster mit
// Minimieren, Maximieren, etc
}
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);
// Fenster wird angepasst
if (!(hWnd=CreateWindowEx( dwExStyle,
// Die erweiterten Eigenschaften des Fensters
"OpenGL", // Der Name der Klasse
title, // Der Titel des Fensters
WS_CLIPSIBLINGS | // Wird von OpenGL benötigt
WS_CLIPCHILDREN | // Wird auch von OpenGL benötigt
dwStyle, // auch Eigenschaften des Fensters
0, 0, // Die Position des zu erstellenden Fensters
WindowRect.right-WindowRect.left,
// Hier werden die ermittelten Werte für die Breite eingesetzt
WindowRect.bottom-WindowRect.top, // und hier für die Länge
NULL, // Es soll kein übergordnetes Fendster erstellt werden
NULL, // kein Menü
hInstance, // Die Instanz wird übergeben
NULL))) // Wird nicht benötigt
{
KillGLWindow(); // Grafikeinstellungen zurücksetzen
MessageBox(NULL,"Fenster konnte nicht erstellt werden.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
static PIXELFORMATDESCRIPTOR pfd=
// pdf ist jetzt ein PIXELFORMATDESCRIPTOR
{
sizeof(PIXELFORMATDESCRIPTOR),
// Die Größe muss natürlich stimmen
1, // Versionsnummer
PFD_DRAW_TO_WINDOW |
// Das Format muss in Fenster sichtbar sein können
PFD_SUPPORT_OPENGL |
// OpenGL muss unterstützt werden
PFD_DOUBLEBUFFER,
// Double Buffering muss unterstützt werden
PFD_TYPE_RGBA,
// Das RGBA (Rot,Grün,Blau,Alpha(Transparenz))
// muss unterstützt werden
bits,
// Die Farbtiefe, die schon
// übergeben wurde, wird hier benötigt
0, 0, 0, 0, 0, 0, // wird nicht benötigt
0, // kein Alpha Buffer
0, // Shift Bit ignoriert
0, // kein Accumulation Buffer
0, 0, 0, 0, // nicht benötigt
16, // 16Bit Z-Buffer (Depth Buffer)
0, // kein Stencil Buffer
0, // kein Auxiliary Buffer
PFD_MAIN_PLANE,
// Die Hauptebene auf die später gezeichnet wird
0, // unwichtig
0, 0, 0 // keine Ebenenmasken benötigt
};
if (!(hDC=GetDC(hWnd))) // Versuch, den DC zu bekommen
{
KillGLWindow();
// Alles rückgängig machen
MessageBox(NULL,"Konnte keinen DC erstellen.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // FALSE zurückgeben, beenden
}
if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))
// Kann Windows ein passendes finden?
{
// Falls keins gefunden werden kann:
KillGLWindow(); // Alles zurücksetzen
MessageBox(NULL,"Konnte kein passendes Pixelformat finden.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // FALSE zurück und Ende.
}
if(!SetPixelFormat(hDC,PixelFormat,&pfd))
// Kann das Pixelformat gesetzt werden?
{
KillGLWindow(); // Leider nicht, Fehlerpopup und raus
MessageBox(NULL,"Konnte Pixelformat nicht setzen.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // FALSE zurück und raus
}
if (!(hRC=wglCreateContext(hDC))) // Versuch den RC zu bekommen
{
KillGLWindow(); // Alles rückgängig machen
MessageBox(NULL,"Konnte keinen Rendering Context bekommen.","Fehler",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
if(!wglMakeCurrent(hDC,hRC)) // Versuch den RC zu aktivieren
{
KillGLWindow(); // hat nicht geklappt, also alles zurück
MessageBox(NULL,"Konnte den Rendering Context nmicht aktivieren.","Fehler",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
ShowWindow(hWnd,SW_SHOW); // Fenster anzeigen
SetForegroundWindow(hWnd); // Priorität des Programms wird erhöht
SetFocus(hWnd); // Tastatureingaben werden
// jetzt an das Programm geleitet
ReSizeGLScene(width, height); // Die Perspektive wird aktiviert
if (!InitGL()) // Initialisiere das OpenGL Fenster
{
KillGLWindow(); // Falls das nicht geklappt
// haben sollte alles rückgängig machen
MessageBox(NULL,"Initialisierung fehlgeschlagen.","Fehler",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // FALSE wird zurückgegeben
}
return TRUE; // Alles hat geklappt!!!
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) // Sind Nachrichten in der Nachrichtenschleife?
{
case WM_ACTIVATE: // Ist das Programm aktiv?
{
if (!HIWORD(wParam)) // Ist das Programm nicht minimiert?
{
active=TRUE; // active wird TRUE
}
else
{
active=FALSE; // Programm ist minimiert
}
return 0; // Rückgabe: 0
}
case WM_SYSCOMMAND: // Ist ein Systemkommando
// (wie z.B. "Bildschirmschoner
// soll gestartet werden") vorhanden?
{
switch (wParam) // wParam würde diesen Befehl enthalten
{
case SC_SCREENSAVE:
// Versucht Windows den Bildschirmschoner zu starten
case SC_MONITORPOWER:
// Soll der Monitor in den Stromsparmodus gehen?
return 0;
// Beide Fälle werden durch die Rückgabe von 0 verhindert
}
break; // Das wars.
}
case WM_CLOSE: // Ist eine WM_CLOSE Nachricht vorhanden?
{
PostQuitMessage(0);
// Die Nachricht zum Beenden wird "gepostet"
return 0; // und zurück.
}
case WM_KEYDOWN: // Drückt der Benutzer eine Taste???
{
keys[wParam] = TRUE;
// Der Wert im Array keys[] der dem Code
// der Taste entspricht, wird true gesetzt
return 0; // und zurück...
}
case WM_KEYUP: // Wurde eine Taste losgelassen?
{
keys[wParam] = FALSE;
// Wen ja, dann soll dieser Wert im Array keys[]
// auf FALSE gesetzt werden
return 0; // und zurück.
}
case WM_SIZE: // Die Fenstergröße wurde geändert
{
ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));
// LoWord ist die Breite, HiWord die Höhe,
// ReSizeGLScene() verändert dann die
// Größe des OpenGL-Fensters
return 0; // und zurück
}
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
BOOL done=FALSE;
if (MessageBox(NULL,"Soll im Vollbildmodus gestartet werden?","Vollbilmodus gewünscht?",MB_YESNO|MB_ICONQUESTION)==IDNO)
{
fullscreen=FALSE; // Falls nein gedrückt wurde,
// wird fullscreen false gesetzt
}
if (!CreateGLWindow("Opengl Tutorial 5 - Teture Mapping - www.codeworx.org",640,480,16,fullscreen))
{
return 0; // Falls ein Fehler auftrat, beenden
}
while(!done) // Solange done nicht TRUE ist:
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
// Sind Nachrichten vorhanden
{
if (msg.message==WM_QUIT)
// Liegt eine Nachricht zum beenden vpr?
{
done=TRUE; // Wenn dem so ist, wird done
// true und das Programm beendet
}
else
// Wenn nicht werden die anderen Nachrichten ausgewertet
{
TranslateMessage(&msg); // Umformen der Nachricht
DispatchMessage(&msg);
}
}
else // Falls keine Nachrichten bereit liegen
{
if (active) // Programm aktiv?
{
if (keys[VK_ESCAPE]) // Wurde ESC gedrückt?
{
done=TRUE; // Wenn ESC gedrückt wurde, beenden
}
else // ESC wurde nicht gedrückt
{
DrawGLScene(); // Die Szene ausgeben
SwapBuffers(hDC); // Die Puffer werden getauscht
}
}
if (keys[VK_F1]) // Wird F1 gedrückt?
{
keys[VK_F1]=FALSE;
// Es darf nicht gewartet werden bis F1 losgelassen wird,
// ansonsten könnte das Bild mehrmals hin und herschalten
KillGLWindow(); // Das aktuelle Fenster wird gelöscht
fullscreen=!fullscreen;
// fullscreen erhält seinen entgegengesetzten Wert
// (bei FALSE TRUE, und bei TRUE FALSE.)
if (!CreateGLWindow("openGL",640,480,16,fullscreen))
{
return 0; // Zurück falls ein Fehler auftrat
}
}
}
}
KillGLWindow(); // Das Fenster löschen.
return (msg.wParam); // Das Programm verlassen.
}
mfg