- // =============================================================================
- // OpenGL1.5 - VCL Template (opengl15_vcl_template.zip)
- // =============================================================================
- // Copyright © 2003 by DGL - http://www.delphigl.com
- // =============================================================================
- // Contents of this file are subject to the GNU Public License (GPL) which can
- // be obtained here : http://opensource.org/licenses/gpl-license.php
- // =============================================================================
- // History :
- // Version 1.0 - Initial Release (Sascha Willems)
- // =============================================================================
- unit OpenGL15_MainForm;
- interface
- uses
- Windows,
- Messages,
- SysUtils,
- Classes,
- Graphics,
- Controls,
- Forms,
- Dialogs,
- dglOpenGL;
- type
- TGLForm = class(TForm)
- procedure FormCreate(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- procedure ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
- procedure FormKeyPress(Sender: TObject; var Key: Char);
- private
- { Private-Deklarationen }
- public
- RC : HGLRC;
- DC : HDC;
- ShowFPS : Boolean;
- FontBase : GLUInt;
- StartTick : Cardinal;
- Frames : Integer;
- FPS : Single;
- procedure GoToFullScreen(pWidth, pHeight, pBPP, pFrequency : Word);
- procedure BuildFont(pFontName : String);
- procedure PrintText(pX,pY : Integer; const pText : String);
- procedure ShowText;
- procedure Render;
- end;
- const
- NearClipping = 0.1;
- FarClipping = 1000;
- var
- GLForm: TGLForm;
- implementation
- {$R *.dfm}
- // =============================================================================
- // TForm1.GoToFullScreen
- // =============================================================================
- // Wechselt in den mit den Parametern angegebenen Vollbildmodus
- // =============================================================================
- procedure TGLForm.GoToFullScreen(pWidth, pHeight, pBPP, pFrequency : Word);
- var
- dmScreenSettings : DevMode;
- begin
- // Fenster vor Vollbild vorbereiten
- WindowState := wsMaximized;
- BorderStyle := bsNone;
- ZeroMemory(@dmScreenSettings, SizeOf(dmScreenSettings));
- with dmScreenSettings do
- begin
- dmSize := SizeOf(dmScreenSettings);
- dmPelsWidth := pWidth; // Breite
- dmPelsHeight := pHeight; // Höhe
- dmBitsPerPel := pBPP; // Farbtiefe
- dmDisplayFrequency := pFrequency; // Bildwiederholfrequenz
- dmFields := DM_PELSWIDTH or DM_PELSHEIGHT or DM_BITSPERPEL or DM_DISPLAYFREQUENCY;
- end;
- if (ChangeDisplaySettings(dmScreenSettings, CDS_FULLSCREEN) = DISP_CHANGE_FAILED) then
- begin
- MessageBox(0, 'Konnte Vollbildmodus nicht aktivieren!', 'Error', MB_OK or MB_ICONERROR);
- exit
- end;
- end;
- // =============================================================================
- // TForm1.BuildFont
- // =============================================================================
- // Displaylisten für Bitmapfont erstellen
- // =============================================================================
- procedure TGLForm.BuildFont(pFontName : String);
- var
- Font : HFONT;
- begin
- // Displaylisten für 256 Zeichen erstellen
- FontBase := glGenLists(96);
- // Fontobjekt erstellen
- Font := CreateFont(16, 0, 0, 0, FW_MEDIUM, 0, 0, 0, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
- ANTIALIASED_QUALITY, FF_DONTCARE or DEFAULT_PITCH, PChar(pFontName));
- // Fontobjekt als aktuell setzen
- SelectObject(DC, Font);
- // Displaylisten erstellen
- wglUseFontBitmaps(DC, 0, 256, FontBase);
- // Fontobjekt wieder freigeben
- DeleteObject(Font)
- end;
- // =============================================================================
- // TForm1.PrintText
- // =============================================================================
- // Gibt einen Text an Position x/y aus
- // =============================================================================
- procedure TGLForm.PrintText(pX,pY : Integer; const pText : String);
- begin
- if (pText = '') then
- exit;
- glPushAttrib(GL_LIST_BIT);
- glRasterPos2i(pX, pY);
- glListBase(FontBase);
- glCallLists(Length(pText), GL_UNSIGNED_BYTE, PChar(pText));
- glPopAttrib;
- end;
- // =============================================================================
- // TForm1.ShowText
- // =============================================================================
- // FPS, Hilfstext usw. ausgeben
- // =============================================================================
- procedure TGLForm.ShowText;
- begin
- // Tiefentest und Texturierung für Textanzeige deaktivieren
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_TEXTURE_2D);
- // In orthagonale (2D) Ansicht wechseln
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity;
- glOrtho(0,640,480,0, -1,1);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity;
- PrintText(5,15, FloatToStr(FPS)+' fps');
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_TEXTURE_2D);
- end;
- // =============================================================================
- // TForm1.FormCreate
- // =============================================================================
- // OpenGL-Initialisierungen kommen hier rein
- // =============================================================================
- procedure TGLForm.FormCreate(Sender: TObject);
- begin
- // Wenn gewollt, dann hier in den Vollbildmodus wechseln
- // Muss vorm Erstellen des Kontextes geschehen, da durch den Wechsel der
- // Gerätekontext ungültig wird!
- // GoToFullscreen(1600, 1200, 32, 75);
- // OpenGL-Funtionen initialisieren
- InitOpenGL;
- // Gerätekontext holen
- DC := GetDC(Handle);
- // Renderkontext erstellen (32 Bit Farbtiefe, 24 Bit Tiefenpuffer, Doublebuffering)
- RC := CreateRenderingContext(DC, [opDoubleBuffered], 32, 24, 0, 0, 0, 0);
- // Erstellten Renderkontext aktivieren
- ActivateRenderingContext(DC, RC);
- // Tiefenpuffer aktivieren
- glEnable(GL_DEPTH_TEST);
- // Nur Fragmente mit niedrigerem Z-Wert (näher an Betrachter) "durchlassen"
- glDepthFunc(GL_LESS);
- // Löschfarbe für Farbpuffer setzen
- glClearColor(0,0,0,0);
- // Displayfont erstellen
- BuildFont('MS Sans Serif');
- // Idleevent für Rendervorgang zuweisen
- Application.OnIdle := ApplicationEventsIdle;
- // Zeitpunkt des Programmstarts für FPS-Messung speichern
- StartTick := GetTickCount;
- end;
- // =============================================================================
- // TForm1.FormDestroy
- // =============================================================================
- // Hier sollte man wieder alles freigeben was man so im Speicher belegt hat
- // =============================================================================
- procedure TGLForm.FormDestroy(Sender: TObject);
- begin
- // Renderkontext deaktiveren
- DeactivateRenderingContext;
- // Renderkontext "befreien"
- wglDeleteContext(RC);
- // Erhaltenen Gerätekontext auch wieder freigeben
- ReleaseDC(Handle, DC);
- // Falls wir im Vollbild sind, Bildschirmmodus wieder zurücksetzen
- ChangeDisplaySettings(devmode(nil^), 0);
- end;
- // =============================================================================
- // TForm1.ApplicationEventsIdle
- // =============================================================================
- // Hier wird gerendert. Der Idle-Event wird bei Done=False permanent aufgerufen
- // =============================================================================
- procedure TGLForm.ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
- begin
- // In die Projektionsmatrix wechseln
- glMatrixMode(GL_PROJECTION);
- // Identitätsmatrix laden
- glLoadIdentity;
- // Viewport an Clientareal des Fensters anpassen
- glViewPort(0, 0, ClientWidth, ClientHeight);
- // Perspective, FOV und Tiefenreichweite setzen
- gluPerspective(60, ClientWidth/ClientHeight, 1, 128);
- // In die Modelansichtsmatrix wechseln
- glMatrixMode(GL_MODELVIEW);
- // Identitätsmatrix laden
- glLoadIdentity;
- // Farb- und Tiefenpuffer löschen
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
- Render;
- ShowText;
- // Hinteren Puffer nach vorne bringen
- SwapBuffers(DC);
- // Windows denken lassen, das wir noch nicht fertig wären
- sleep(1);
- Done := False;
- // Nummer des gezeichneten Frames erhöhen
- inc(Frames);
- // FPS aktualisieren
- if GetTickCount - StartTick >= 500 then
- begin
- FPS := Frames/(GetTickCount-StartTick)*1000;
- Frames := 0;
- StartTick := GetTickCount
- end;
- end;
- // =============================================================================
- // TForm1.FormKeyPress
- // =============================================================================
- procedure TGLForm.FormKeyPress(Sender: TObject; var Key: Char);
- begin
- case Key of
- #27 : Close;
- end;
- end;
- procedure TGLForm.Render;
- begin
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity;
- glTranslated(-0.25, -0.1, 0);
- glBegin(GL_QUADS);
- glColor3f(1, 0, 0); glVertex3f(0, 0, 0);
- glColor3f(0, 1, 0); glVertex3f(0.5, 0, 0);
- glColor3f(0, 0, 1); glVertex3f(0.5, 0.5, 0);
- glColor3f(1, 1, 0); glVertex3f(0, 0.5, 0);
- glEnd;
- SwapBuffers(DC);
- end;
- end.