im Moment habe ich etwas Zeit, und möchte daher diese nutzen um ein kleines Tutorien zu der OpenGL machen, dem Thema, mit welchem ich mich derzeit auch wieder beschäftige.
Ich bin nicht allzu geübt im schreiben von Lehrtexten, und bitte darum zu tiefste um pardon wenn ich mich wohl ein wenig schwer ausdrücke. Wie mir mal jemand so schön hat zu teil werden lassen, man muss zu erst schlechte Ergebnisse produzieren, bevor man zu guten, oder gar sehr guten Resultaten tendiert.
Ich verwende die Programmiersprache Delphi, aber der größten teil lässt sich analog zu anderen sprachen wie C++ übersetzten.
Obwohl die OpenGL Plattform unabhängig ist beziehe ich mich auf die Entwicklung unter Windows, welches, auch wenn es noch so „nicht gut“ ist, für die Delphi Entwicklung die beste Plattform ist. Im Zuge dessen verwende ich auch die WinAPI für tastaturabfragen und Win32 Forms (Delphi Designer Forms).
Desweiteren versuche ich, sofern mir dies gelingen mag,
Tutorial Inhalt:
1. Über die OpenGL
2. Voraussetzungen
3. Das Projekt (Template)
4. Schlusswort
Aber ich möchte euch vorwahnen, laut Word sind es mehr als 3.500 Wörter.
[Über die OpenGL]
Ich denke ein großteil von euch ist bereits die Begrifflichkeit OpenGL duch lesen, hören oder irgend eine andere Kommunikationsmöglichket zu Ohren gekommen.
Der begriff OpenGL steht für Open Graphics Library, und obwohl diese eigentlich fem. ist, wird oft auf den Artikel, die, verzichtet, und einfach nur als OpenGL benannt. Dabei handelt es sich um eine API (zu deutsch: Programmierschnittstelle) zur Hardwarebeschleunigten Visualisierung von 2D und 3D Grafiken. Das heißt soviel wie mit der Grafikkarte zeichnen.
Im Gegensatz zu z.b. GDI welches
Ich könnte jetzt große teile von Wikipedia wiedergeben, aber ich denke, ihr könnt, sofern es euch näher interresiert es selbstständig recherchieren.
Link: OpenGL
Entsprechende Header für die Nutzung der OpenGL lassen sich für nahezu jede Sprache finden, ja sogar für z.b. Autoit, auch wenn sich darüber streiten lässt mit welchen Sprachen es sinnvoller wäre, mit welchen eher weniger, wobei die Sprache letztlich nur das werkzeug ist, und bei der OpenGL Entwicklung nahezu irrelevant ist, die Codes für die Render prozeduren sind sogar nahezu identisch.
OpenGL findet an sehr vielen stellen Einsatz, nicht nur lediglich, wie viele fälschlicherweise annehmen, in der Spieleentwicklung.
OpenGL wird auch oftmals z.b. zum Visualisieren von z.b. Diagrammen verwendet, oder einfach zur verschönerung in normalen GUI Projekten verwendet.
So verwendet Apfel z.b. bei dem allseits beliebten, und auch für iUser unabdinglichen Programm iTunes für den Coverflow OpenGL. Generell verwendet Apfel in sehr vielen Anwendungen OpenGL, z.b. für Spiegelungen bei iChat.
Der begriff OpenGL steht für Open Graphics Library, und obwohl diese eigentlich fem. ist, wird oft auf den Artikel, die, verzichtet, und einfach nur als OpenGL benannt. Dabei handelt es sich um eine API (zu deutsch: Programmierschnittstelle) zur Hardwarebeschleunigten Visualisierung von 2D und 3D Grafiken. Das heißt soviel wie mit der Grafikkarte zeichnen.
Im Gegensatz zu z.b. GDI welches
Ich könnte jetzt große teile von Wikipedia wiedergeben, aber ich denke, ihr könnt, sofern es euch näher interresiert es selbstständig recherchieren.
Link: OpenGL
Entsprechende Header für die Nutzung der OpenGL lassen sich für nahezu jede Sprache finden, ja sogar für z.b. Autoit, auch wenn sich darüber streiten lässt mit welchen Sprachen es sinnvoller wäre, mit welchen eher weniger, wobei die Sprache letztlich nur das werkzeug ist, und bei der OpenGL Entwicklung nahezu irrelevant ist, die Codes für die Render prozeduren sind sogar nahezu identisch.
OpenGL findet an sehr vielen stellen Einsatz, nicht nur lediglich, wie viele fälschlicherweise annehmen, in der Spieleentwicklung.
OpenGL wird auch oftmals z.b. zum Visualisieren von z.b. Diagrammen verwendet, oder einfach zur verschönerung in normalen GUI Projekten verwendet.
So verwendet Apfel z.b. bei dem allseits beliebten, und auch für iUser unabdinglichen Programm iTunes für den Coverflow OpenGL. Generell verwendet Apfel in sehr vielen Anwendungen OpenGL, z.b. für Spiegelungen bei iChat.
[Voraussetzungen]
OpenGL Entwicklung bringt natürlich zwangsläufig auch Programmieren mit sich. Wer nicht vor hat zu programmieren, und immer noch denkt das Source etwas mit Valve zu tun hat, der kann über diesen link:
diesen Artikel verlassen.
Wie bereits erwähnt gibt es Header für nahezu jede sprache, z.b. Pascal/Delphi, C/C++, Objective-C, Python, Autoit, Visual Basic und C#, Java, sogar fürs web als WebGL.
Welche Sprache ihr wählt ist relativ wurst, allerdings würde ich bei meiner Sprachwahl, gerade zur spiele Entwicklung auf folgende Faktoren achten:
OOP, objekt orientiertes programmieren ist grade bei so was sehr nützlich und erleichtert das leben ungemein
Kompiliert, kompilierte sprachen sind meist schneller
System unabhängig, falls man doch mal vor hat auf anderen Plattformen zu entwickeln (Mac OS ist ja im kommen)
Naja was da von meinen oben erwähnten sprachen über bleibt ist C/C++ und Pascal/Delphi.
Natürlich könnt ihr eure sprache frei wählen, und es gibt noch viel, viel, viel mehr sprachen, nur diese sind mir auf anhieb, innerhalb von 10 sekunden, eingefallen.
Theoretisch könntet ihr, nachdem ihr die absoluten Grundlagen gelernt habt, direkt am anfang eurer Programmierer Entwicklung, noch im ersten Jahr, direkt mit der Spieleentwickung, und generell mit OpenGL anfangen. Allerdings werdet ihr euch alles dabei selbst Steine in den Weg legen, euren Code unverständlich machen, und euch nur selbst peinigen.
Ich empfehle, dass man einiges über die Sprache wissen sollte, wissen sollte wie man Probleme am effektivsten und schnellsten löst, sowie (falls die Möglichkeit vorhanden) sich schon einigermaßen ordentlich mit OOP beschäftigt haben.
Als ein Beispiel aus Delphi: man sollte z.b. wissen was Sets sind, was Records sind, was Typisierung ist, was Enumerale sind, wie man eine TList verwendet, und mit Pointern umzugehen hat, denn das kann viel Arbeit und Zeit ersparen.
Die Entwicklung mit der OpenGL ist nicht schwer, ich würde es Lediglich als anders beschreiben. Man muss sich mit der Materie auseinander setzten, um die Funktionsweisen zu verstehen. Solltet ihr an dem Punkt angelangt sein, wo ihr das erste mal denkt ihr könnt es, dann darf ich euch die Hoffnung vorwegnehmen, denn dann seit ihr nur wenig weiter als vorher. Aber dies gehört zum Lernvorgang dazu, sowohl bei der normalen Programmierung sowie bei der Entwicklung mit OpenGL. Ich selbst bin auch nicht der Beste.
Neben den Programmiertechnischen Fähigkeiten benötigt die OpenGL auch noch weitere Fähigkeiten. So kommt kein Grafisches Programm ohne Grafiken wie Texturen aus, und für 3D sind modellierungs-Fähigkeiten auch von Vorteil. Deshalb habe ich immer meinen Grafiker irgendwo greifbar.
Spiele Entwicklung benötigt auch, obwohl es viele wohl gerne nicht so hätten, Kenntnisse von Mathematik und Physik. So sollte Basis wissen über Vektoren vorhanden sein, wissen über Mechanische Energien und Kräfte etc.
Und auch noch könnte man ab und an ein paar Sounds gebrauchen, was wäre z.b. Age of War ohne das epische Lied Glorious Morning von Waterflame. Das ist aber Nebensache, und hat auch nichts direkt mit OpenGL zu tun (dafür bietet sich die OpenAL an, aber das hat hier nichts verloren).
Deshalb empfiehlt sich immer einen Designer und andere Leute, welche sich auf ein anderes Thema spezifizieren zur hand zu haben.
diesen Artikel verlassen.Wie bereits erwähnt gibt es Header für nahezu jede sprache, z.b. Pascal/Delphi, C/C++, Objective-C, Python, Autoit, Visual Basic und C#, Java, sogar fürs web als WebGL.
Welche Sprache ihr wählt ist relativ wurst, allerdings würde ich bei meiner Sprachwahl, gerade zur spiele Entwicklung auf folgende Faktoren achten:
OOP, objekt orientiertes programmieren ist grade bei so was sehr nützlich und erleichtert das leben ungemein
Kompiliert, kompilierte sprachen sind meist schneller
System unabhängig, falls man doch mal vor hat auf anderen Plattformen zu entwickeln (Mac OS ist ja im kommen)
Naja was da von meinen oben erwähnten sprachen über bleibt ist C/C++ und Pascal/Delphi.
Natürlich könnt ihr eure sprache frei wählen, und es gibt noch viel, viel, viel mehr sprachen, nur diese sind mir auf anhieb, innerhalb von 10 sekunden, eingefallen.
Theoretisch könntet ihr, nachdem ihr die absoluten Grundlagen gelernt habt, direkt am anfang eurer Programmierer Entwicklung, noch im ersten Jahr, direkt mit der Spieleentwickung, und generell mit OpenGL anfangen. Allerdings werdet ihr euch alles dabei selbst Steine in den Weg legen, euren Code unverständlich machen, und euch nur selbst peinigen.
Ich empfehle, dass man einiges über die Sprache wissen sollte, wissen sollte wie man Probleme am effektivsten und schnellsten löst, sowie (falls die Möglichkeit vorhanden) sich schon einigermaßen ordentlich mit OOP beschäftigt haben.
Als ein Beispiel aus Delphi: man sollte z.b. wissen was Sets sind, was Records sind, was Typisierung ist, was Enumerale sind, wie man eine TList verwendet, und mit Pointern umzugehen hat, denn das kann viel Arbeit und Zeit ersparen.
Die Entwicklung mit der OpenGL ist nicht schwer, ich würde es Lediglich als anders beschreiben. Man muss sich mit der Materie auseinander setzten, um die Funktionsweisen zu verstehen. Solltet ihr an dem Punkt angelangt sein, wo ihr das erste mal denkt ihr könnt es, dann darf ich euch die Hoffnung vorwegnehmen, denn dann seit ihr nur wenig weiter als vorher. Aber dies gehört zum Lernvorgang dazu, sowohl bei der normalen Programmierung sowie bei der Entwicklung mit OpenGL. Ich selbst bin auch nicht der Beste.
Neben den Programmiertechnischen Fähigkeiten benötigt die OpenGL auch noch weitere Fähigkeiten. So kommt kein Grafisches Programm ohne Grafiken wie Texturen aus, und für 3D sind modellierungs-Fähigkeiten auch von Vorteil. Deshalb habe ich immer meinen Grafiker irgendwo greifbar.
Spiele Entwicklung benötigt auch, obwohl es viele wohl gerne nicht so hätten, Kenntnisse von Mathematik und Physik. So sollte Basis wissen über Vektoren vorhanden sein, wissen über Mechanische Energien und Kräfte etc.
Und auch noch könnte man ab und an ein paar Sounds gebrauchen, was wäre z.b. Age of War ohne das epische Lied Glorious Morning von Waterflame. Das ist aber Nebensache, und hat auch nichts direkt mit OpenGL zu tun (dafür bietet sich die OpenAL an, aber das hat hier nichts verloren).
Deshalb empfiehlt sich immer einen Designer und andere Leute, welche sich auf ein anderes Thema spezifizieren zur hand zu haben.
[Das Spiele Projekt]
Nach dieser Hinführung, die eigentlich unnötig ist, und mehr Text in Anspruch genommen hat als erwartet, nun zum ersten mal richtiger Code.
Der aufmerksame Lektor sollte mitbekommen haben das ich von einem OpenGL Header gesprochen habe. Kaum Sprachen, oder besser gesagt Compiler, bringen standartmäßig einen OpenGL Header mit sich (Ausnahme macht C++). Einige Versionen von Delphi bringen schon standardmäßig einen OpenGL Header mit, allerdings sollte man den lieber in den Wind schießen, und stattdessen den Header von
verwenden. Mehr dazu, und der Downloadlink gibt es auf
zu finden.Wichtig: Dies gilt für Delphi, zu Lazarus komme ich Später noch.
Diesen ladet ihr euch runter und verschiebt ihn in das Lib Verzeichnis eurer Delphi Version. Dieses findet ihr bei Delphi 7 unter Programmordner\Borland\Delphi7\Lib oder unter Rad Studio Programmordner\Embarcadero\RAD Studio\7.0\lib.
Danach müsst ihr, Delphi/Rad Studio mit Administrator Rechten starten (damit die dcu erzeugt werden kann ist diese Berechtigung erforderlich).
Jetzt aber zum Eigentlichen Projekt. Ihr benötigt eine Formular Anwendung (eine mit Fenster), und speichert diese mal als OGL Template oder so ab. Im Editor müsst ihr soweit kaum etwas machen, nur im Objektinspektor unter der Registrierkarte Ereignisse das OnCreate, OnDestroy und OnResize Ereignis erzeugen. Dies bewerkstelligt ihr, für die die es nicht wissen, mit einem Doppelklick auf das Feld neben dem Event Namen.
Solltet ihr jetzt speichern oder Kompilieren, und die Prozeduren sollten leer sein, so wird Delphi diese automatisch löschen, und ihr müsst erneut durch Doppelklick diese erzeugen.
Bevor es ans fröhliche Programmieren geht, oder bei euch erst mal ums Copy-Pasten, erkläre ich euch kurz wie MEINE Templates immer aufgebaut sind, damit ICH den überblick behalte. Sollte jemand damit nicht zurecht kommen, so kann er gerne das so strukturieren wie er möchte, er ist was das angeht an Nichts und Niemanden gebunden.
Ein Spiel ist anders als das „gewöhnliche“ Event basierende Form Projekt in Delphi. Bei einem Spiel läuft es so ab, dass mehrere Male pro Sekunde eine schleife alle daten des Spiels neu Berechnet, und diese dann Zeichnet. Zu Deutsch, das gerammte auftreten wird mehrere male pro Sekunde komplett gelöscht und neu gezeichnet. Dank der Grafikkarte, und der Leistung moderner PC’s funktioniert das auch (zumeist) ohne sichtbare Lücken.
Also brauchen wir eine Schleife, die ungebremst immer und immer wieder durchläuft. Hierbei gibt es 2 Lösungsmöglichkeiten, die man ernsthaft in Betracht ziehen kann.
1. Ein Timer
Ein Timer läuft in einem gewissen Intervall regelmäßig durch. Dies geschieht in einem externen Thread, welcher den GUI Thread, den MainThread der Anwendung nicht ausbremst.
2. Idle
Jede VCL Form Anwendung hat einen interne Schleife, die sich um Events etc Kümmert. Diese ruft u.a. das OnIdle Event der TApplication Klasse auf. Wenn man seinen Code in diese Prozedur packt, so wird dieser Code solange die Anwendung läuft stetig wiederholt aufgerufen.
Die Vor und Nachteile dieser Möglichkeiten:
Timer Vorteile:
1. Ressource Schonend
2. Bestimmbarer Intervall
Nachteile:
1. Langsamer
2. Min Intervall von 25 (alles darunter ist nicht wirklich schneller)
3. Extra Thread
Idle Vorteile:
1. Maximale Framezahl kann erreicht werden
2. Flüssige große Animationen (z.b. größere Spiele)
Nachteile:
1. Akku Killer
2. FPS schwer Steuerbar
Für „richtige“ Spiele würde ich den Timer in den Wind schießen, und auf Idle Setzten.
Also brauchen wir eine Prozedur für das OnIdle Event, nennen wir sie mal Idle, kreativ wie wir sind.
Dann habe ich noch gerne 5 weitere Prozeduren, welche ein wenig übersicht in das Ganze bringen:
1. InitGame, z.b. für den Setup von OpenGL, und zum initialisieren andere Komponenten wie z.b. OpenAL.
2. LoadRes, in dieser Prozedur werden Ressourcen wie z.b. Texturen vor dem Spiel geladen, dies würde während dem Neuzeichnen Prozess zu viel zeit in Anspruch nehmen. (Bei größeren Projekten mit z.b. verschiedenen Level wird diese Prozedur nicht zu Start, sondern zu Beginn eines jeden Levels aufgerufen)
3. ReCalc, hier lasse ich die Position der Objekte, und abfragen von Tastatur und Kollisionen durchführen.
4. Render, hier wird alles Gezeichnet
5. Unload, hier wird alles was geladen wurde wieder gelöscht.
Ich komme mit dieser Aufteilung zurecht, aber jeder ist eigen, wenn euch diese aufteilung nicht gefällt, dann könnt ihr sie ohne Probleme anpassen.
Jetzt aber, endlich, an den Code.
Zu erst müsst ihr in der uses Klausel die Unit dglOpenGL hinzufügen (hinter den letzten Eintrag ein , und dahinter den Namen eintragen, am ende der Zeile ein ; „semikolon“). Es schadet auch nicht noch die Unit Math hinzuzufügen, ist aber, im Moment nicht allzu wichtig.
Seht auch nach ob da die unit Windows steht, denn ihr benötigt die WinAPI.
Nun fügt ihr eure Prozeduren in den Private teil eurer Form hinzu, als das es dann so aussieht:
PHP Code:
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormResize(Sender: TObject);
private
procedure Idle(Sender: TObject; var Done: Boolean);
procedure InitGame;
procedure LoadRes;
procedure ReCalc;
procedure Render;
procedure Unload;
public
{ Public-Deklarationen }
end;
Weiter unten in Implementation Teil müssen diese Prozeduren ja auch hinzugefügt werden, dafür fügt ihr unter die bereits zu Anfang erstellten Event Prozeduren folgendes ein
PHP Code:
procedure TForm1.InitGame;
begin
end;
procedure TForm1.LoadRes;
begin
end;
procedure TForm1.Idle(Sender: TObject; var Done: Boolean);
begin
end;
procedure TForm1.ReCalc;
begin
end;
procedure TForm1.Render;
begin
end;
procedure TForm1.Unload;
begin
end;
Die Prozeduren, die hier geschrieben werden, um den anfallenden Code in kleinere seperate stücke zu unterteilen, gehören zu der TForm1 Klasse, welche euer Fenster für das Programm darstellt. Deshalb wird auch Oben im Type Bereich eine Abbänderung des TForm1 = Class(TForm)… benötigt.
Bei
PHP Code:
procedure TForm1.InitGame;
begin
end;
Nun wollen wir unser Programm aber auch ein Wenig leben einhauchen, und das beginnen wir am besten mit dem Initialisieren von OpenGL. Hierfür benötigen wir 2 Field Variablen, die wir auch im private Teil unserer Form1 Klasse Definieren.
PHP Code:
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormResize(Sender: TObject);
private
DC: HDC; //Für die WinAPI benötigter Device Context
RC: HGLRC; //Für OpenGL benötigter Rendering Context
procedure Idle(Sender: TObject; var Done: Boolean);
procedure InitGame;
procedure LoadRes;
procedure ReCalc;
procedure Render;
procedure Unload;
public
{ Public-Deklarationen }
end;
) und den Rendering Context, über diese kann OpenGL auf die Form zeichnen.Nun beginnen wir damit OpenGL zu initialisieren. Dafür wechseln wir in die FormCreate Prozedur (direkt mit Doppelklick auf die Form im Designer) und Initialisieren dort erst mal die dglOpenGL unit
PHP Code:
procedure TForm1.FormCreate(Sender: TObject);
begin
ReportMemoryLeaksOnShutdown:=true; //Ab Späteren Delphi versionen verfügbar um Memory Leaks aufzuspüren
if InitOpenGL then //Initialisierung und abfrage ob es möglich war die Initialisierung durchzuführen
begin
InitGame; //Unsere Initialisierungs Methode
LoadRes; //Unsere Ressource lade Methode
end
else //wenn die Initialisierung fehl schlug
Application.Terminate; //Anwendung beenden
end;
In Zeile 4 wird OpenGL initialisiert, und dabei auch gleichzeitig abgefragt ob es Funktioniert hat. Sofern dies erfüllt, wird unsere Methode zum Initialisieren aufgerufen, und in Folge dessen auch die Methode zum Laden der Ressourcen wie Texturen. Bei einem Fehlschlagen der Initialisierung wird das Programm direkt beendet.
Schön und gut, OpenGL ist initialisiert, aber es weiß noch gar nichts, weder worauf gezeichnet werden soll, noch hat es irgendwelche anderen Informationen. Diese Informationen übergeben wir in unserer Prozedur InitGame (viele machen das was jetzt kommt direkt in FormCreate, aber das ist Apfel).
Also kommt in InitGame der Folgende Code
PHP Code:
procedure TForm1.InitGame;
begin
DC:=GetDC(Handle); //Den Device Kontext des Fensterns holen
RC:=CreateRenderingContext(DC, [opDoubleBuffered], 32, 24, 0, 0, 0, 0); //Den Rendering Context mit dem Device Context Erzeugen
ActivateRenderingContext(DC, RC); //Den Rendering Context in OpenGL “Registrieren”
glEnable(GL_DEPTH_TEST); //Tiefentest aktivieren
glClearColor(0.0, 0.0, 0.0, 0.0); //Die Clearcolor von OpenGL auf Schwarz setzten
Application.OnIdle := Idle; //Das OnIdle event unserer Prozedur zuweisen
end;
In der darauffolgenden zeile wird der Renderingcontext erstellt und in unserer Field Variable RC gesichert. Die hierfür benötigten Parameter sind
1. Der Device Kontext des Fensters oder Panels auf das gezeichnet werden soll
2. Die Optionen für den Rendering Context, z.b. opDoubleBuffered, das für einen Doppelten Puffer von nöten ist.
3. Die Farbtiefe in Bits, 32 für 8 bit rot grün und Blau und 8 bit Alpha, das erziehlt die höchstmögliche Anzahl von Farben+einen Alphakanal von 8 bit, das macht 2^32 Farben möglich, ne ganze menge
4. Tiefen bits, die geben an wie viel bit für den Tiefenpuffer reserviert werden sollen, für den Tiefentest (Vorwiegend für 3D)
5. Die Bits für den Stencil Test, vorerst unwichtig
6. Die Bitanzahl des Akkumulationspuffers, vorerst unwichtig
7. Die Anzahl der Ebenen (Layer), wüsste nicht wofür man die braucht bei OpenGL.
Diese Einstellungen oben, sollten vorerst als „Standart“ Reichen.
In der Darauffolgenden zeile, Zeile 5, wird der Rendering Context für OpenGL Aktiviert, dabei muss der Device Context und der Rendering Context, bzw das Handel dieser, als Parameter übergeben werden.
Danach wird in der Zeile drunter der Tiefentest Aktiviert, wird vorwiegend für 3D benötigt
Die Clearcolor die mit glClearColor(R, B, G, A) gesetzt wird, ist die Farbe, mit der OpenGL den Puffer automatisch füllt bei einem Löschen des bisherigen Puffers, zum zeichnen neuer Informationen.
Und in der Letzten Zeile vor dem end; wird das Oben erwähnte OnIdle Event unserer selbst erstellten Prozedur, welche noch nichts tut, zugewiesen.
Also wir haben nun endlich, durch das Erstellen des DC und RC OpenGL die Informationen zukommen lassen, die zum „Zeichnen“ benötigt werden.
Aber was erstellt wird muss auch wieder Zerstört werden, dafür gehen wir in die Event Prozedur FormDestroy, welches direkt durch den Destruktor der Form aufgerufen wird.
Dort kommt der Code wie folgt rein
PHP Code:
procedure TForm1.FormDestroy(Sender: TObject);
begin
Unload; //Unsere Unload Prozedur aufrufen
DeactivateRenderingContext; //Den Rendercontext Deaktiviern
DestroyRenderingContext(RC); //Den Rendercontext Schließen
ReleaseDC(Handle, DC); //Das DC Freigeben
end;
Unload entspricht unserer InitRes Methode, welche nichts tut (Genauso wie Unload).
DeactivateRenderingContext; Deaktiviert den RC, den wir in Init Aktiviert haben
DestroyRenderingContext; ist das Gegenstück des CreateRenderingContext Aufrufes, benötigt aber kaum Parameter.
Und mit ReleaseDC wird unser mit GetDC geholte Handle des Geräte Kontextes freigegeben.
Wer diesem haufen Bullshit-Text bis hier hin folgen konnte, dem sollte aufgefallen sein, das wir immer noch einige ungenutzte Prozeduren haben,
Als erstes einmal die Event-Prozedur FormResize, welche aufgerufen wird, wenn sich die Formgröße verändert. Natürlich muss, wenn sich die Form verändert auch OpenGL angepasst werden, das geht mit dem Folgenden Code
PHP Code:
procedure TForm1.FormResize(Sender: TObject);
var dummy: Boolean; //Variable zum aufrufen einer Funktion, ohne weitere verwendung
begin
glViewport(0, 0, ClientWidth, ClientHeight); //OpenGL AnzeigeFläche auf neue Formgröße anpassen
Idle(self, dummy); //Idle Methode aufrufen, um änderung zu zwichnen
end;
Desweiteren sind noch LoadRes und Unload jungfräulich. Dies bleibt auch jetzt so, da es sich um ein Template handelt, und wir in diesem Template im Moment keine Texturen oder andere Ressourcen verwenden.
ReCalc wird im moment auch noch genauso wenig benötigt, da keine Berechnungen unsererseits stattfinden
Also nur noch Idle und Render.
In der Prozedur Idle Müssen lediglich nur 3 Befehle ausgeführt werden
PHP Code:
procedure TForm1.Idle(Sender: TObject; var Done: Boolean);
begin
ReCalc;
Render;
Done:=False;
end;
Done ist eine als Parameter übergebene variable, die für die Idle Prozedur der TApplication Class wichtig ist. Ist Done auf true gesetzt, so wird diese Prozedur nur aufgerufen, sobald sich der Status der Application verändert (z.b. sich was an der Form ändert) und das Event wird nur sporadisch aufgerufen. Setzten wir es allerdings auf False, so wird diese Prozedur in einer Endlosschleife rausgehauen, genau das was wir, für viele FPS erreichen wollen.
Oft möchte man allerdings noch neben dem einfachen Anzeigen noch einen FPS (Frames Per Second, zu deutsch: Bilder pro Sekunde) zähler einbauen, und auch das geschieht hier in der Idle Methode.
Dafür werden 3 Neue Field Variablen Benötigt:
PHP Code:
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormResize(Sender: TObject);
private
DC: HDC;
RC: HGLRC;
Frames, FrameCount, TimeCount: Cardinal; //Für den FPS zähler
procedure Idle(Sender: TObject; var Done: Boolean);
procedure InitGame;
procedure LoadRes;
procedure ReCalc;
procedure Render;
procedure Unload;
public
{ Public-Deklarationen }
end;
Nun erweitern wir die Idle Prozedur wie folgt:
PHP Code:
procedure TForm1.Idle(Sender: TObject; var Done: Boolean);
var t1, t2: Cardinal; //Variablen zum messen des Zeit Abstandes
begin
t1:=GetTickCount; //Zeit vor Neurechnung und zeichnung
ReCalc;
render;
t2:=GetTickCount; //Zeit danach
inc(TimeCount, t2-t1); //TimeCount um den benötigten Intervall erhöhen
Inc(FrameCount); //Framcount erhöhen, da ein neues Bild angezeigt wurde
if TimeCount>=1000 then //Wenn mehr als 1 sekunde verstrichen ist
begin
Frames:=FrameCount; //Die FPS auf die angezeigte Anzahl Frames Setzten
dec(TimeCount, 1000); //Die Zeit um 1 Sekunde Erniedrigen
FrameCount:=0; //Die Anzahl angezeigter Frames wieder zurücksetzen
end;
Self.Caption:=IntToStr(Frames)+' FPS'; //Ausgabe der FPS in der Caption
Done:=False;
end;
Und zu guter letzt widmen wir uns der Prozedur Render, in welcher wir OpenGL erst wirklich „richtig“ verwenden.
PHP Code:
procedure TForm1.Render;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); // Puffer löschen
//Hier Geht’s ans Zeichnen
SwapBuffers(DC); //Puffer “Wechseln”
end;
Und SwapBuffer wird letztlich zum Anzeigen benötigt, doch um das gesammte System der Doppel Pufferung zu erklären fehlt mir letztlich der Nerf, und die Zeit, desshalb hier ein Link

Und somit wäre ein Allgemeines Template bereits fertig. Wenn ihr die Applikation nun Startet, so stahlt eich euch ein schwarzes (Die Farbe könnt ihr mit glClearColor in InitGame ändern) Fenster entgegen. Der erste Schritt ist getan, und euer Template vollendet.
[Schlusswort]
Das war jetzt doch ein ganzes Stück mehr als ich eigentlich vorhatte zu schreiben, und ich hoffe, das ist nicht so sehr verwirrender Bullshit, bei dem man nicht mehr durchblickt, das es tatsächlich ein paar Leute lesen.
Ich werde es natürlich nicht nur lediglich bei einem Template Beruhen lassen, sondern, sobald ich mal wieder ein Paar Stunden zeit finde, am nächsten Tutorial arbeiten.
Konstruktives Feedback ist gerne gesehen, sätze wie „Du bist scheisse und hast keine hobbys“ eher nicht.
Sollte sich jemand fragen, warum ich ein tutorial poste, wenn mich spiele Programmierung eigentlich nicht interresiert (habe ich schon mal gepostet), ich verwende OpenGL für andere visualisierungen, aber die meisten Tutorials sind nun mal auf Spiele ausgelegt, und so kam ich auch nicht drum rum
Das Template Projekt kann man hier downloaden:

Ich werde es natürlich nicht nur lediglich bei einem Template Beruhen lassen, sondern, sobald ich mal wieder ein Paar Stunden zeit finde, am nächsten Tutorial arbeiten.
Konstruktives Feedback ist gerne gesehen, sätze wie „Du bist scheisse und hast keine hobbys“ eher nicht.
Sollte sich jemand fragen, warum ich ein tutorial poste, wenn mich spiele Programmierung eigentlich nicht interresiert (habe ich schon mal gepostet), ich verwende OpenGL für andere visualisierungen, aber die meisten Tutorials sind nun mal auf Spiele ausgelegt, und so kam ich auch nicht drum rum
Das Template Projekt kann man hier downloaden:

Edit: in word sah die Formatierung irgendwie besser aus






