Da auf meine Anfrage nach dem geplanten Spiele-Typ für das Spielprojekt auf der Mailingliste leider kein Reply kam - starte ich diese Frage hier nun mal im Wiki (obwohl das ja eigentlich nicht der richtige Platz dafür ist)
Sorry - die Mailingliste vergammelt bei mir in einem extra-Ordner, in den ich aus Spam-Gründen nicht reinsehe. Ein Grund mehr, der Diskussion auf LugMailingListe zu folgen, und das zu ändern (siehe dort). -- ThomasBayen
Was für Spiele hattet ihr euch überlegt in Java und mit OpenGL zu realisieren?
- Puzzle (z.B. Tetris)
- First-Person Shooter (z.B. wie Quake oder Unreal Tournament)
- Rollenspiel (z.B. wie Neverwinter Nights)
- Action-Adventure (z.B. wie Tomb Raider)
- Jump'nRun (z.B. Spyro the dragon, Rayman)
Eine Beschreibung unseres Projektes steht inzwischen auf JEmpire. Ich hoffe, was dort steht, beantwortet Deine Fragen. Deine Hilfe nehmen wir natürlich sehr gerne an. :-) -- ThomasBayen
Was mich persönlich angeht, möchte ich erstmal alle zugrundeliegenden Technologien stückweise lösen und dann erst das echte Spiel anfangen, wenn ich weiß, das ich alle Fertigkeiten dazu beherrsche. Leider ist aber ein wichtiger Punkt, den man nur durch die echte Applikation herausfinden kann, die Performance. Unsere Welt besteht ja aus recht vielen Polygonen mit Textur. Eine erste Version ohne Texturen kam auf meinem (zugegeben rechenschwachen) Thin Client auf 3-4 fps, die ich mit Drawlists und einigen Optimierungen auf Kosten der Klassen-Eleganz auf über 5 gepusht habe... Auf der Grundlage brauche ich über Texturen gar nicht nachzudenken. :-( Wie würdest Du da rangehen? -- ThomasBayen
Um wieviele Polygone handelt es sich denn? Sind es wirklich Polygone? Am besten wäre es Polyone aus Dreiecken aufzubauen, denn darauf sind die Grafikroutinen optimiert. Es gibt mehrere Optimierungsstrategien - leider fallen bei Java die meisten weg :( Darum ist dein Ansatz mit den DisplayLists schon sehr gut - du könntest nun noch dafür sorgen dass die Vertices möglichst oft im Vertexbuffer der Grafikkarte liegen wenn sie gebraucht werden. Jeder Vertex das zur Grafikkarte geschickt wird, wird dort in einen Puffer eingetragen. Dieser fasst irgendwas zwischen 8 und 64 Vertices. Wenn nun Dreiecke gezeichnet werden deren Eckpunkte bereits im Puffer liegen kann die Grafikkarte sich die Matrixmultiplikation sparen und das Dreieck sehr schnell zeichnen. Dies ist aber schon eine fortgeschrittenere Optimierung - eine die viel mehr Performance bringt ist es die Dreiecke nach Renderer-Zustand zu sortieren. Also möglichst viele Dreiecke an einem Stück zeichnen ohne dass man Methoden wie glBindTexture, glEnable oder glDisable aufrufen muss. Dies sind aber wirklich Optimierungen die man erst dann macht, wenn man sicher ist auch nur dass zu zeichnen was wirklich sichtbar ist.
Um die Anzahl an sichtbaren Dreiecken zu reduzieren gibt es mehrere Ansätze:
- Spatial data structures (BSP-Bäume, Octrees) - mit diesen Strukturen kann man sehr schnell ermitteln welche Geometrieelemente sich in einem bestimmten räumlichen Bereich befinden. Lässt man diese Strukturen auf den View-Frustum (die Sichtpyramide) los, dann nennt man das View frustum culling - es werden dann nur die Dreiecke an die Grafikkarte geschickt die auch sichtbar sind. Diese Strukturen sind auch unentbehrlich wenn es um Kollisionsabfragen geht.
- Terrain-culling - dies ist eine Technik die davon ausgeht, dass es ein Gelände ohne Höhlen gibt - d.h. alles was sich hinter einer Bergkette befindet ist unsichtbar. Ich habe dies bisher nicht implementiert, aber davon im Buch "Real Time Rendering" gelesen. Die Technik liest sich sehr rechenintensiv.
- Level-of-detail (LOD) - hierbei werden Objekte die weiter entfernt sind auch durch weniger Dreiecke dargestellt. Da Objekte die weit weg sind klein sind, tragen sie auch wenig zum Detailgrad des Gesamtbildes bei. Aus diesem Grund genügt es für diese Objekte reduziertere Modelle zu verwenden. Man kann diese reduzierten Objekte gut automatisch berechnen, muss sie also nicht per Hand erstellen.
- Backface culling - dies ist die einfachste und einzige von OpenGL nativ unterstützte Technik. Sie besagt einfach, dass alle Dreiecke deren Rückseite nach vorne zeigt nicht gezeichnet werden. OpenGL ermittelt die Seite eines Dreiecks über deren Windung: Im Uhrzeigersinn=vorne, gegen den Uhrzeigersinn=hinten (oder umgekehrt *g*).
- 4*1600 = 6400 Dreiecken hin, ascii art: < |\ \| >
- 1600 Triangle Strips mit je 6 Punkten (übergeben nur 6 anstelle von 16 (oder 24) punkten an opengl, brauchen aber ein glBegin und glEnd)
- 1600 Triangle Fans mit je 8 Punkten