program Spielfeld;
uses
Windows,
Messages,
OpenGL;
const
WND_TITLE = '
Spielfeld 4-Gewinnt';
FPS_TIMER = 1;
// Timer zur FPS berechnung
FPS_INTERVAL = 1000;
// Zeit zwischen FPS-Updates
var
h_Wnd : HWND;
// Handle aufs Fenster
h_DC : HDC;
// Device Context
h_RC : HGLRC;
// OpenGL Rendering Context
Keys :
Array[0..255]
of Boolean;
// Tasten-Status des Keyboards
FPSCount : Integer = 0;
// Frame-Zähler (für FPS berechnen)
ElapsedTime : Integer;
// Programmlaufzeit
Finished : Boolean;
Angle : double;
Angle1 : double;
Scale1 : double;
Scale2 : double;
Rotate : double;
{$R *.RES}
{------------------------------------------------------------------}
{ Konvertiert Integers in Strings }
{------------------------------------------------------------------}
function IntToStr(Num : Integer) :
String;
// vermeidet die Benutzung von SysUtils und spart so 100K
begin
Str(Num, result);
end;
{...OpenGL Quelltext...}
{------------------------------------------------------------------}
{ Message-Behandlung des Programs festlegen }
{------------------------------------------------------------------}
function WndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
stdcall;
begin
case (Msg)
of
WM_CREATE:
begin
end;
WM_CLOSE:
begin
PostQuitMessage(0);
Result := 0
end;
WM_KEYDOWN:
// Taste als 'pressed' markieren
begin
keys[wParam] := True;
Result := 0;
end;
WM_KEYUP:
// Taste als 'up' markieren
begin
keys[wParam] := False;
Result := 0;
end;
WM_SIZE:
// Größe anpassen
begin
glResizeWnd(LOWORD(lParam),HIWORD(lParam));
Result := 0;
end;
WM_TIMER :
// Hier werden alle benutzten Timer behandelt
begin
if wParam = FPS_TIMER
then
begin
FPSCount :=Round(FPSCount * 1000/FPS_INTERVAL);
// FPS berechnen...
SetWindowText(h_Wnd, PChar(WND_TITLE + '
[' + IntToStr(FPSCount) + '
FPS]'));
//... und ausgeben!
FPSCount := 0;
Result := 0;
end;
end;
else
Result := DefWindowProc(hWnd, Msg, wParam, lParam);
// Standard-Behandlung aller anderen Messages
end;
end;
{---------------------------------------------------------------------}
{ Freigabe aller Fenster, Zeiger, Variablen }
{---------------------------------------------------------------------}
procedure glKillWnd(Fullscreen : Boolean);
begin
if Fullscreen
then begin // Wenn Vollbild in Standardauflösung zurückkehren
ChangeDisplaySettings(devmode(
nil^), 0);
ShowCursor(True);
end;
// Freigabe des Device und Rendering Contexts.
if (
not wglMakeCurrent(h_DC, 0))
then
MessageBox(0, '
Release of DC and RC failed!', '
Error', MB_OK
or MB_ICONERROR);
// Löscht Rendering Context
if (
not wglDeleteContext(h_RC))
then begin
MessageBox(0, '
Release of rendering context failed!', '
Error', MB_OK
or MB_ICONERROR);
h_RC := 0;
end;
// Gibt Device Context fre
if ((h_DC > 0)
and (ReleaseDC(h_Wnd, h_DC) = 0))
then begin
MessageBox(0, '
Release of device context failed!', '
Error', MB_OK
or MB_ICONERROR);
h_DC := 0;
end;
// Schließt das Fenster
if ((h_Wnd <> 0)
and (
not DestroyWindow(h_Wnd)))
then begin
MessageBox(0, '
Unable to destroy window!', '
Error', MB_OK
or MB_ICONERROR);
h_Wnd := 0;
end;
// Entfernt window class Registrierung
if (
not UnRegisterClass('
OpenGL', hInstance))
then begin
MessageBox(0, '
Unable to unregister window class!', '
Error', MB_OK
or MB_ICONERROR);
hInstance := 0;
end;
end;
{--------------------------------------------------------------------}
{ Erstellt ein Fenster mit Passendem OpenGL Rendering Context }
{--------------------------------------------------------------------}
function glCreateWnd(Width, Height : Integer; Fullscreen : Boolean; PixelDepth : Integer) : Boolean;
var
wndClass : TWndClass;
// Fenster Klasse
dwStyle : DWORD;
// Fenster Stil
dwExStyle : DWORD;
// Erweiterter Fenster Stil
dmScreenSettings : DEVMODE;
// Bildschirm Einstellungen (fullscreen, etc...)
PixelFormat : GLuint;
// OpenGL Einstellungen (Pixelformat)
h_Instance : HINST;
// aktuelle Instanz
pfd : TPIXELFORMATDESCRIPTOR;
// Einstellungen für das OpenGL Fenster
begin
h_Instance := GetModuleHandle(
nil);
// Instanz für's Fenster holen
ZeroMemory(@wndClass, SizeOf(wndClass));
// Daten in wndClass löschen
with wndClass
do // Setup der Fenster Klasse
begin
style := CS_HREDRAW
or // Neuzeichenen wenn Fenster-Breite geändert
CS_VREDRAW
or // Neuzeichenen wenn Fenster-Höhe geändert
CS_OWNDC;
// Device Context exlusiv
lpfnWndProc := @WndProc;
// WndProc wird als Window Procedure gesetzt
hInstance := h_Instance;
hCursor := LoadCursor(0, IDC_ARROW);
lpszClassName := '
OpenGL';
end;
if (RegisterClass(wndClass) = 0)
then // Fenster Klasse registrieren
begin
MessageBox(0, '
Failed to register the window class!', '
Error', MB_OK
or MB_ICONERROR);
Result := False;
Exit
end;
// Das oben definierte Fenster wird erstellt
h_Wnd := CreateWindowEx(dwExStyle,
// Erweiterter Fenster Stil
'
OpenGL',
// Name der Klasse
WND_TITLE,
// Fenster Titel (caption)
dwStyle,
// Fenster Stil
0, 0,
// Fenster Position
Width, Height,
// Größe des Fensters
0,
// Keine Paren-Windows
0,
// Kein Menü
h_Instance,
// die Instanz
nil);
// Kein Parameter für WM_CREATE
if h_Wnd = 0
then
begin
glKillWnd(Fullscreen);
MessageBox(0, '
Unable to create window!', '
Error', MB_OK
or MB_ICONERROR);
Result := False;
Exit;
end;
{...OpenGL Quelltext...}
{--------------------------------------------------------------------}
{ Main message loop for the application }
{--------------------------------------------------------------------}
function WinMain(hInstance : HINST; hPrevInstance : HINST;
lpCmdLine : PChar; nCmdShow : Integer) : Integer;
stdcall;
var
msg : TMsg;
appStart : DWord;
begin
Finished := False;
// Das Programm wird initialisiert (Fenster erstellen!)
if not glCreateWnd(800, 600, FALSE, 32)
then
begin
Result := 0;
Exit;
end;
appStart := GetTickCount();
// Die Zeit zum Programmstart nehmen
// Main message loop:
while not finished
do
begin
if (PeekMessage(msg, 0, 0, 0, PM_REMOVE))
then // Nach Windows-Messages suchen
begin
if (msg.
message = WM_QUIT)
then // Falls WM_QUIT dabei ist sind wir fertig
finished := True
else
begin // Ansonsten wird die Message an das Programm weitergegeben
TranslateMessage(msg);
DispatchMessage(msg);
end;
end
else
begin
Inc(FPSCount);
// FPS Zähler erhöhen
ElapsedTime := GetTickCount() - appStart;
// Programmlaufzeit berechnen
glDraw();
// Szene zeichnen
SwapBuffers(h_DC);
// Szene ausgeben
ProcessKeys;
// Tastatureingaben verarbeiten
end;
end;
glKillWnd(FALSE);
Result := msg.wParam;
end;
begin
WinMain( hInstance, hPrevInst, CmdLine, CmdShow );
end.