# Entwicklung einer 3D-Engine



## Sircoly (18. April 2008)

Halli Hallo,

ich habe grade angefangen, mich mit der DirectX-Programmierung auseinanderzusetzen.



Dazu habe ich mir zwei Bücher gekauft und ein weiteres habe ich vor einer Stunde bestellt:
Spieleprogrammierung mit DirectX und C++
3D-Spieleprogrammierung
Direct3D und 3D-Engine Programmierung (Bestellt)
Ich habe beide Bücher komplett durchgearbeitet. Letztenendes habe ich 5 Spiele auf meinem PC, die ich selbst Programmiert habe (natürlich unter Anleitung der Bücher). 

Ich möchte nicht behaupten, dass ich jetzt der ultra-profi in sachen DirectX-Programmierung bin, aber ich fühle mich soweit, dass ich es versuchen möchte, eine eigene (und wenn nur sehr billige) 3D-Engine zu programmieren.



Damit keine Missverständnisse aufkommen, möchte ich kurz erläutern, was ich (denke ich zumindest) schaffen könnte:
Automatische De/- und Initialisierung der Engine 
Die Engine soll sich, wenn das Spiel gestartet wird, soweit initialisieren, dass ich Sie direkt nutzen kann. (Objekte erstellen, Pointer initialisieren, etc...)
Das ganze Spielchen auch bei der Deinitialisierung.
OO Programmierung
DLL-Verwendung zur Erweiterungsmöglichkeit 
Am besten Modular aufgebaut. Ich stelle mir das so vor, dass ich Direct3D, DirectInput und DirectSound als einzelne Module (DLLs) implementiere.
Direct3D 
Dies soll beinhalten:
- Optionsverwaltung der Grafikkarte 
(Caps, Direct3D-Schnittstellen, Render-States, etc)
- Texturen inklusive Multi-Texturing
- Nebel
- Beleuchtung
- Alpha-Blending
Weiterhin soll *optional *implementiert werden:
- Stereo-3D-Unterstützung
DirectInput 
Dies soll beinhalten:
- Unterstützung vom Maus
- Unterstützung von Tastatur
- Dynamische Belegung von Tastaturknöpfen und Mausknöpfen
DirectSound 
Dies soll beinhalten:
- Abspielen von mehr als nur einem Sound gleichzeitig
- Unterstützung von WAV
- Unterstützung von MP3
Hier habe ich jetzt nur technische Möglichkeiten der Engine aufgeschrieben, die mir aber nichts nützen, wenn ich zum Beispiel eine Map in einer Datei habe. 

Ich weiß allerdings nicht, wie ich mir mein eigenes Konzept entwickeln kann, dass ich mir "so einer Art eigenen Dateityp" definiere, wo ich nachher sage: 
_"Da haste die Datei. Das ist deine MAP. Stell mir die da und lass den Charakter da drüber laufen."_

Da brauche ich eure Hilfe. Ich weiß nicht, wie ich meine Engine planen soll. 
Welche Klassen ich nachher haben will und was ich vielleicht beachten muss. 
Vielleicht könnt Ihr aus den gegebenen Informationen, die ich euch oben zusammengestellt habe, schon etwas erkennen und mir Tipps oder Anregungen geben. 
(Vielleicht habe ich auch eine elementare Entscheidung komplett vergessen.)

Hier wollte ich mich an euch wenden und euch Fragen, ob ihr Tipps und Anregungen habt oder ob ihr aus Erfahrung sagen könnt: 
_"Da wirst du ein Problem bekommen, achte >>da und da<< drauf."_

Aus Erfahrung möchte ich euch *freundlichst und ohne Vorwurf* noch etwas bitten:



Ich bitte euch, auf Antworten wie...
"Das ist unmöglich, weil..."
"Das schaffst du sowieso nicht, weil ..."
"Dazu brauchst du viel mehr Leute als nur dich allein. Das kannst du nicht schaffen."
...
... zu verzeichten. Ich weiß, dass dieses Projekt ein bisschen heavy ist und auch ganz schnell in die Hose gehen kann, weil ich keine Lust mehr habe oder aus sonst irgendeinem Grund. Freuen tue ich mich, wenn ihr mich dabei Unterstützt und mir konstruktive Kritik gebt, die mir nicht suggeriert, dass ich das Projekt "in die Tonne kloppen" soll, sondern äquivalente Kompromisse oder Ideen vorschlägt. 
Ich weiß, dass diese Art der Kritik etwas schwieriger ist als die normale Kritik. Und grade in den Dingen (im Sinne des Projekts) ist es sehr schwer, etwas äquivalentes zu finden.
_(Das kennt jeder, der schon einmal ein Projekt aufgehört hat, [von dem er so begeistert war] weil er doch nur gehört hat, dass es beschissen oder viel zu schwer sei.)_

Ich freue mich sehr über eure Hilfe und dafür schonmal ein fettes *DANKESCHÖN* im vorraus.


----------



## Enumerator (18. April 2008)

Abend!

Das Problem mit der Map/ den Levels hast du im Moment noch nicht. Es fehlen noch zu viele Grundlagen um sich auf ein Format für solche Daten festzulegen. Aber es gibt freie Formate, mitunter auch als ISO-Standard. Vor allem die, die für CAD entwickelt wurden (gibt's z.B. auch XML-Derivate), könnten dich interessieren - aber darüber würde ich mir Gedanken machen, wenn es soweit ist.

Mal ehrlich: ich glaube dass es möglich ist, eine Engine mit einem sehr kleinen Team - zur not auch allein - zu entwickeln. Aber: bis man damit fertig ist, ist sie sowas von veraltet, dass man das Ganze fast ausschließlich als Referenz nutzen kann.

Wenn Du das allerdings 'nur' als Hobby machen möchtest sage ich nur: Mach! Ich war sebst fast zwei Jahre mit einer eigenen Engine - in OpenGL und OpenAL - am basteln, und es hat sich echt gelohnt: Massenweise Erfahrungen und jede Menge Spass.
Das beste war eigendlich der Audio-Part. Mit dem Source kann ich sogar hin und wieder was Vernünftiges anfangen.

Allerdings solltest Du Dir im Klaren darüber sein, dass eine Engine nicht nur Talent und Erfahrung vorraussetzt, sondern auch jede Menge Know-how in Sachen Physik.
Also erwarte nicht zuviel von Dir selbst! *billig* - wie Du es nennst - ist vielleicht der falsche Ausdruck: 'einfach' passt wohl eher.

Gruß - und viel Erfolg
Enum


----------



## Sircoly (18. April 2008)

Halli Hallo,

erst einmal *Danke *für deine Verbesserung.

Mich würde es interessieren, welches Know-How in Sachen Physik und Mathematik dir am meisten geholfen haben. 


Als ich das Buch 3D-Spieleprogrammierung gelesen habe, gab es auch ein Kapitel über die mathematischen Grundvorraussetzungen. Da wurden als Themen nachher behandelt:
Vektoren
Matrizen
Ebenen
Das Thema Vektoren habe ich auch komplett durchgearbeitet, mir Notizen drüber gemacht und mir nachher ein kleines Handbuch zum Thema Vektoren zusammengestellt.
(Das hat mir in der Schule auch sehr gute Dienste geleistet.)

Die beiden anderen Themen habe ich allerdings nicht so wirklich gecheckt. 
Besonders das Thema Ebenen habe ich absolut garnicht kapiert. 
Zum Thema Matrizen habe ich mir auch ein kleines Handbuch angelegt, aber die Materie selbst habe ich nicht verstanden.

Ohne mich nocheinmal Wiederholen zu wollen, interessiert es mich, welches weitere Know-How ich haben muss, damit ich meine Engine programmieren kann. 



> Ich war sebst fast zwei Jahre mit einer eigenen Engine ... am basteln, ...


Insofern ich das richtig verstanden habe, hast du eine Engine programmiert? 
Dann würde ich dich bitten, mir das Know-How aus dem Bereich Physik und Mathematik zu nennen, dass ich brauche.
_(In dem Hintergrund meiner Engine, da ich nicht weiß, welche Art von Engine du programmiert hast.)_

An dich jetzt schonmal ein großes Danke!


----------



## Enumerator (18. April 2008)

Hi!

Also ich schrieb - zusammen mit einem guten Freund - eine 3D Engine in OpenGL und OpenAl. Das war mal so etwas wie das freie Equivalent zu Microsofts DirectX, allerdings steckt hinter DirectX eine Menge Geld, daher sind die Möglichkeiten inzwischen einfach gigantisch. Leider bedeutet DirectX auch, dass man unter Linux/Mac OS immer einen Emulator braucht, um die Anwendungen zu starten - eine Portierung via Compiler ist damit (fast) unmöglich. Ich weiss nicht wie es heutzutage mit .NET, C# etc. aussieht, aber ich glaube daran hat sich nicht viel geändert.

Die mathematischen Vorraussetzungen für eine 3D Engine sind schon enorm, allerdings ist Coden nun mal zu mindestens 70% Mathematik. Aber lass Dich nicht davon entmutigen, einige der Bücher die du aufführst durfte ich auch schon lesen. Wenn du einfach loslegst, diese Werke und das Netz permanent befragst, kommt das Verständniss zwangsweise von allein - oder Du gibst eh auf. Wenn du allerdings z.B. schon mit den diversen Arten von Algebra nichts anfangen kannst - z.b. der Booleschen, ist es eh hoffnungslos. Das Vertändniss von Matritzen wiederum können dir Bücher zur 3D Programmierung garantiert besser vermitteln als ein Mathe-Schinken - bei den Details der Engine ist der Schinken dann wieder besser.

Die physikalischen Vorraussetzungen beschränken sich vorerst auf ein verdammt gutes bildliches Vorstellungsvermögen. Später entscheidet dein Ehrgeiz darüber, wie weit du in die Physik einsteigen musst. Spiegelungen auf glatten Flächen sind z.B. Physik 7. oder 8. Klasse und recht einfach umzusetzten. Auf gewölbten, teiltransparenten Köpern (z.B. Wasser...) ist das ganze schon wieder etwas komplizierter... ;-)

Aber ich bin auch nicht der größte Fachhmann dafür - zumal wir aufgehört haben, nachdem wir ein paar mal durch eine recht statische Landschaft geflitzt sind - als Geister, ohne Körper...
Aber wie bereits erwähnt, der 3D-Audio-Part unserer Engine war komplett fertig. Das Schöne im Vergleich zum Visuellen war, dass ein Geräusch nur eine 'Koordinate' hatte, keine Polygone...

Dein Hauptaugenmerk sollte jetzt nicht auf den Details der Mathematik oder Physik beruhen, sondern auf der Umsetzung eines 'Frameworks' das es dir ermöglicht, Funktionen, Modifikationen und Erweiterungen modular aufzubauen. Mit ooP und dlls bist Du da schon gut beraten.
Und such Dir jemanden, mit dem Du dieses Projekt teilen kannst - nicht nur, weil Du sonst vereinsamst... ;-)

Gruß
Enum


----------



## Sircoly (18. April 2008)

Halli Hallo,

*vielen Dank für deine viele Hilfe!*

ich habe vergessen zu sagen, dass ich bereits viel Erfahrung im Umgang mit C++ und mit Allgorythmen habe. 
Ich Programmiere seid knapp 2 Jahren in C++ und lerne es immernoch in der Ausbildung. 
Allerdings beschränkt sich das schulische Lernen auf Architekturentwiclung (z.B. Document-View-Controler).

Was du sagst stimmt voll und ganz, dass C++ mehr auf Mathematik als auf sonstirgendwas aufbaut.
Durch meine Erfahrung habe ich keine Probleme mit den Algorythmen, die in meiner Engine verwendet werden.



> ... auf der Umsetzung eines 'Frameworks' das es dir ermöglicht, Funktionen, Modifikationen und Erweiterungen modular aufzubauen. ...


Vorrausgesetzt, dass ich dich richtig verstehe, muss ich mich jetzt auf eine einheitliche und gut überlegte Entwicklung meiner Klassen und Funktionen sowie Attribute konzentrieren?

Ich würde dich bitten, mir hier ein paar tipps zu geben, die aus deiner Erfahrung resultieren.
Vielleicht gab es in eurem Projekt so einer Art "FU**-Erlebnis", über das du nicht informiert warst und es lieber am Anfang gewusst hättest. 
_(Vielleicht kennst du das: Funktion ist fertig, aber das Resultat hat den falschen Datentyp.)_


----------



## Enumerator (18. April 2008)

Abend!



> muss ich mich jetzt auf eine einheitliche und gut überlegte Entwicklung meiner Klassen und Funktionen sowie Attribute konzentrieren?


Genau das. Du solltest eine Grundstruktur für Klassen definieren (nicht unbedingt im Source) die u.U. auch Deine persönlichen Koventionen mit einschliesst und dennoch flexibel genug ist - und Dich daran halten.
Das ist kein Projekt das man - allein oder nicht - mal eben in ein paar Wochen abschließt.
Du musst also sicherstellen, dass Du deinen Source von vor Monaten noch verstehst und er Änderungen zulässt. ooP ist da die Grundlage, Abstraktion der Schlüssel - auch wenn er nicht zwingend im Quellcode auftauchen muss.



> Vielleicht gab es in eurem Projekt so einer Art "FU**-Erlebnis", über das du nicht informiert warst und es lieber am Anfang gewusst hättest.


Mehrmals pro Tag, aber nach ein paar Stunden - OK, manchmal Tage oder Wochen - liess sich eigentlich alles lösen. Allerdings hatten wir ca. einen Monat in die Entwicklung des Frameworks gesteckt und einiges verworfen...
Mir fällt nur eine Sache ein, die man von vornherein hätte Beachten sollen: Template Induced Code Bloat. Eine Engine ist nicht unbedingt etwas, dass mal eben so vom Rechner verarbeitet wird. Wir hatten aufgrund der Flexibilität einfach zu viel mit Templates gearbeitet - mit dem Resultat, dass das Kompilierte Programm selbst im unfertigen Zustand einfach zu groß war...



> Vielleicht kennst du das: Funktion ist fertig, aber das Resultat hat den falschen Datentyp.


 Klar - mittlerweile aber eher selten. Viel mehr Sorgen bereitet mir das Verteilen von Aufgaben an Klassen/Objekte. Quasi: Wann lohnt sich eine neue Klasse, welchen Job erledige ich eine Ebene höher, welche erst ein paar Ebenen tiefer... Wenn man die Anforderung an sich selbst stellt, Klassen als Problemlöser zu betrachten und jederzeit woanders zu nutzen, ist das manchmal echt knifflig... ;-)

Gruß
Enum


----------



## Sircoly (18. April 2008)

Halli Hallo,

*danke für deine weitere Hilfe.*



> Du solltest eine Grundstruktur für Klassen definieren ...


Ich verstehe nicht, was du genau mit Grundstruktur meinst?
Falls du eine Grundstruktur im Source meinst, habe ich mir eine vorbereitet.
Dazu gehört die Kommentierung jedes nennenswerten Funktionsaufrufs bis hin zur Dokumentation von Makros und Klassen sowie Variablen mit Autor, Beschreibung, VersionHistory und Parametern. 
Dazu kommt meine eigene Notation für Variablen, Klassen, Funktionen, etc...



> Allerdings hatten wir ca. einen Monat in die Entwicklung des Frameworks gesteckt ...


Kannst du mir bitte genauer erklären, was du mit Framework meinst?
Und wie so ein Framework aussehen könnte?
Denn beides kann ich mir im Sinne meiner Engine nicht vorstellen.


----------



## Enumerator (18. April 2008)

> Kommentierung jedes nennenswerten Funktionsaufrufs bis hin zur Dokumentation von Makros und Klassen sowie Variablen mit Autor, Beschreibung, VersionHistory und Parametern.
> Dazu kommt meine eigene Notation für Variablen, Klassen, Funktionen, etc...


Klingt schon ganz gut - was will man mehr?

Und 'Framework' war wohl nicht ganz der richtige Begriff.. ;-)
Ist Dir schon mal aufgefallen das viele Programme nur wenige KB groß sind, aber offensichtlich auch nicht einfach nur auf ein anderes Programm verweisen? Das Prinzip kennst Du selbst: Bibliotheken. Mit 'Framework' war eine Programm gemeint, das in der Lage ist einen Ablauf nachzuvollziehen, Konfigurationsdateien einzulesen, Dlls/Module/Bibliotheken etc. dynamisch - on demand - zu laden und ein Interface für Logs bietet usw.
Im Endeffekt was 'Framework' wohl doch der richtige Begriff - oder?


----------



## Sircoly (20. April 2008)

Halli Hallo,

ich selbst habe mir für meine Engine eine modulare Aufteilung überlegt.



> ... Mit 'Framework' war eine Programm gemeint, das in der Lage ist einen Ablauf nachzuvollziehen, Konfigurationsdateien einzulesen, Dlls/Module/Bibliotheken etc. dynamisch - on demand - zu laden ...


Ich habe zwei Module geplant und auch schon Beta-Weise implementiert. Es geht einmal um eine Konfigurationsklasse, die eine Datei ausließt und die Werte aus der Datei dann speichert/zurückgibt. Das zweite Modul ist eine Log-File, die mir DEBUG-Informationen über die Engine ausgibt. 
_(Bei Vollbildmodi ist die "PopUp-Methode bestimmt nicht sehr Effektiv.)_

Ich hätte eine Frage an dich:
*Hättest du Lust, mich bei meiner Engine weiter zu unterstützen?*
_(Ich möchte damit nicht sagen, dass du mich bis jetzt nicht schon sehr stark unterstützt hast.)_
Ich sehe nämlich die Realität, dass du schon eigene Erfahrung mit deiner Engine gemacht hast.
Ich würde dir dazu auf meinem Home-Server einen FTP-Zugang einrichten, über den du dir dann den Source-Code von meiner Engine herunterladen und anschauen kannst.
Du solltest dabei nicht selbst programmieren, sondern nur eine Art beratende Position einnehmen.

Ich warte gespannt auf deine Antwort und freue mich über deine Unterstützung.


----------



## Enumerator (21. April 2008)

Abend!

Ich bin mir nicht sicher, ob Dir meine Unterstützung allzuviel nützen wird. Immerhin gibt es doch gravierende Unterschiede zwischen OpenGL/AL und DirectX. Zwar verfogen beide Systeme so etwa den gleichen Ansatz, allerdings ist letzteres inzwischen doch immens leistungsfähiger - mal davon abgesehen, dass ich mich schon seit fast zwei Jahren nicht mehr mit 3D-Programmierung beschäftigt hab.
Allerdings kannst Du mich gern per PM kontaktieren, und wir werden weitersehen...

Gruß
Enum


----------



## Sircoly (21. April 2008)

Halli Hallo,

*ich bin dir dankbar, dass du wenigstens nicht abgeneigt bist, mir zu helfen.*

Falls du dich dazu entschließen würdest mir bei meinem Projekt zur Seite zu stehen, wäre es als einzigstes Hilfreich, wenn du meinen Quellcode auf Sourceoptimierung hin prüfen würdest. (Weniger Source = mehr Performance)


Ich habe jetzt in den letzten Tagen in meine Engine ein paar Module eingebaut:
*Modul 1: CAFile*
Das ist eine virtuelle Datei. Also liegt irgendwo auf meiner Festplatte eine Datei, die ich in die Klasse einlese und damit habe ich eine Kopie des Originals in meinem Speicher. Verwenden kann ich das zum Beispiel bei Bitmaps oder bei Musikstücken.
*Modul 2: CAInput*
Ich denke mal, dass das klar ist: Alle Eingaben und Ausgaben laufen über dieses Modul. Hier müsste ich mir allerdings noch etwas überlegen, wie ich die individuell belegbaren Tasten realisiere. 
(Aufgeteilt in CAMouse und CAKeyboard)
*Modul 3: CAMemory*
Hiermit will ich eine effiziente Lösung für SpaceLeeks verwenden. Alle allokierten Speicher trage ich in eine Liste ein und zum Schluss, wenn die Engine heruntergefahren wird, werden alle Speicher in der Liste wieder freigegeben.
*Modul 4: CAMath*
Hier habe ich bis jetzt alle benötigten Rechenoperationen implementiert. Leider kann ich Aufgrund meines Wissensstandes nur die Vektor-Rechenoperationen und die entsprechenden 2D und 3D Vektorstrukturen implementieren.
Hier wäre eine Auffrischung in Themen "Ebenen" und "Matrizen" hilfreich.
*Modul 5: CASound*
Ich denke mal, dass dies hier auch klar ist. Hierdrüber laufen alle Soundausgaben. Aufgeteilt in CASound und CASoundFile. Über CASound werden die Ausgaben über die Lautsprecher konfiguriert und über CASoundFile werden die Daten an CASound zum Ausgeben weitergeleitet.
Das waren bis jetzt meine implementierten Module. Falls du noch eine sinnvolle Ergänzung hast, die dir einfällt, dann bitte ich dich, sie mir und den vielen Themenbesuchern nicht vorzuenthalten.


Damit wir nicht auf Missverständnisse stoßen, hier eine Liste der Module, die ich noch geplant habe:
*CALogFile*
Mit diesem Modul werden Ausgaben in eine Datei gemacht. Implementieren möchte ich Funktionen, die mir ermöglichen, zum Beispiel eine Variable als NULL-Pointer zu prüfen und dementsprechend Fehlermeldungen in diese Log-File schreiben. Das hat den Vorteil, dass ich bei Vollbildmodi keine PopUp-Fenster brauche.
*CAConfigFile*
Mit diesem Modul kann ich eine Datei einlesen. Es liegt auf meiner Festplatte eine Datei, die einen bestimmten Syntax folgt und die Klasse kann diese Datei analysieren und zum Beispiel Werte aus der Datei speichern (um nachher von mir abgerufen zu werden).
*CAGraphic*
Mit diesem Modul werden dann die ganzen grafischen Ausgaben getätigt. Wie ich diese Klasse allerdings implementiere, steht noch in den Sternen. Dieses Modul werde ich warscheinlich zu allerletzt implementieren.
Auf deine Meinung und hilfe freue ich mich sehr!


----------



## Enumerator (22. April 2008)

Abend!

Klar, mach ich gern. Ich schick' Dir meine eMail Adresse als PM. Antworte am besten gleich mit dem bisherigen Source als Anhang - damit ich mir ein genaueres Bild von dem ganzen Kram machen kann, denn du oben so schön beschrieben hast ;-)
Bei der Optimierung kann ich Dir bestimmt behilflich sein, ebenso in Sachen Theorie und Mathematik. Allerdings habe ich selbst - wie gesagt - kaum Erfahrung mit DirectX.

Gruß
Enum


----------

