Ich könnte ein paar Ratschläge und ein wenig Hilfe gebrauchen. Ich bastel im Moment an einer Outdoor-Engine, welche schon ganz passabel die Landschaft und statische Modelle ohne Ladepausen nachläd. Die Landschaft und die Objekte werden in Blöcken nachgeladen.
Da passt Multithreading ja ganz gut, glaub ich. Ein Thread rendert und der andere läd die neuen Blöcke nach, z.B. .
Erbe ich mir eine neue Klasse von TThread so wie im Tutorial von Lossy, wie erstelle ich dann einen Thread, der Befehle ausführt, ohne diese in Execute hineinzuschreiben? Ich würde einem Objekt meiner Klasse am Liebsten nur die Anweisungen geben, wie "Führe diese Funktion/Prozedur mit der Priorität X aus", ganz allgemein, und nicht nur beschränkt auf Prozeduren oder Funktionen mit vorgegebenen Parametern. Funktioniert das irgendwie mit Methodenzeigern o.Ä.?
Wenn ich dann unmittelbar nach dem Starten des einen Threads einen anderen starten würde, dann würden die Befehle in beiden Threads doch abwechselnd zur selben Zeit bearbeitet werden, oder? Hab ich das Prinzip da richtig verstanden?
Im Moment überlege ich mir auch gerade Methoden, wie ich eine Kollisionskontrolle am Besten implementieren könnte. Dazu wollte ich eine Klasse schreiben, die bei jedem Rendervorgang prüft, ob die Bounding-Box des Spielers eine Bounding-Box eines Objektes berührt und dann entsprechend reagiert. Das traue ich mir auch noch zu, schwieriger finde ich da die "Kollisionskontrolle" mit dem Boden. Ich generiere das Terrain aus Heightmaps in einem Editor, speichere jedoch die Vertexdaten, um evtl. noch Höhlen und Felsvorsprünge zu realisieren. Darstellbar ist das, aber ich habe keine Ahnung, wie in so einem Fall die Kollisionskontrolle aussieht. Würde ich Höhlen weglassen, könnte ich den Spieler einfach immer auf die Höhe des Terrains an einer Stelle (X,Y) setzen, wenn es nicht zu steil ist. Doch wenn an der gleichen Position (X,Y) mehrere Höhenwerte möglich sind, weil z.B. unter der Erde eine Höhle ist, so klappt das nicht mehr so einfach und sauber.
Habt ihr vielleicht ein paar Tipps, wie ich die Kollisionskontrolle für das Terrain am Besten implementieren kann? Wie läuft das in kommerziellen Programmen wie z.B. Gothic 1,2,3?
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Öhm, wäre vielleicht ganz gut, wenn das mal in zwei Themen aufgespalten wird, ich gebe jetzt aber trotzdem mal meinen Senf zu beidem hinzu.
1. Multithreading Du bist bei einem Thread an die Execute gebunden. Was man aber ohne weiteres und wunderbar elegant machen kann ist, dem Thread eine Liste zu verpassen mit auszuführenden Anweisungen. Das könnte so aussehen:
Code:
TActionThread =class(TThread)
private
FQueue: TList;
FQueueMutex: <Ein Typ für einen Mutex, beispielsweise TCriticalSection>
end;
(Der Mutex ist nötig, damit sich beim Hinzufügen von Aufträgen nachher nicht die methoden in die Haare bekommen. )
Die Liste ist wie oben gezeigt vom Typ TList und hat als Einträge Instanzen einer von dir erstellten Klasse, die z.B. so aussehen könnte:
Was in der Run-Methode passiert, wäre dann egal. Die würde von dem Thread aufgerufen und dann könnte man FFinishNotifier (welcher vorher von der Klasse festgelegt wurde) aufrufen und der Klasse so mitteilen, dass die Aufgabe ausgeführt wurde. Dies muss dann natürlich in einem Synchronize passieren. Wenn dann FAutoFree auf True steht, wird die Klasse freigegeben.
Die Queue vom Thread sollte nach dem FIFO-Prinzip arbeiten, also First In First Out, was zuerst reinkommt, wird zuerst bearbeitet. Außerdem sollten die benutzenden Klassen die möglichkeit haben, eine Aufgabe mit priorität sofort nach ganz oben in die liste zu schieben, zum Beispiel das sofortige Nachladen eines Gegners, der gerade spontan in der Luft auftauchen soll oder solche späße.
Nun zu deinen Fragen:
Rüdiger hat geschrieben:
Wenn ich dann unmittelbar nach dem Starten des einen Threads einen anderen starten würde, dann würden die Befehle in beiden Threads doch abwechselnd zur selben Zeit bearbeitet werden, oder?
Das ist zwangsläufig so, da es eigentlich kein echtes Multithreading/-tasking gibt. Dies wird vom Betriebssystem simuliert, indem es die Anwendungen schnell hintereinander abwechselt, sodass der Benutzer es letztenendes garnicht merkt. Ausnahme sind Mehrprozessor bzw. Mehrkern-Systeme, bei denen die Anwendungen auf mehreren Prozessor(kern)en verteilt sind und wirklich nebeneinander ablaufen.
2. Kollisionserkennung Lösen kannst du das mit per-face-collision, also indem du wirklich jede Fläche einzeln auf Kollision prüfst. Da das aber massiv an der Performance zieht, solltest du dir zusätzlich eine Optimierung anschaffen, zum beispiel einen Octtree, um nur das Gebiet zu prüfen, dass für eine Kollision in frage kommt.
Wie das Gothic X macht, weiss ich nicht. Ich habe aber bei einem Rollenspiel mal im Editor sehen können, dass sich die Welt aus einzelnen "Nodes" zusammensetzte, die man mehr oder weniger beliebig zusammensetzen kann. Da man dem Spieler dann eindeutig einer aktuell aktiven Node zuordnen kann, schränkt das das gebiet der potentiellen Kollisionserkennung schonmal deutlich ein.
Ich habe mich noch nicht eingehend mit der Kollision befasst und wie ich schon an diversen Stellen erwähnte graust es mir davor. Was du als Optimierung versuchen könntest wäre zum Beispiel, das Terrain schon im Editor in "Heightmap" und "Non-Heightmap"-Gebiete zu teilen. Wenn du es hinbekommst, dass man keinen Unterschied in der Behandlung merkt, könnte das die Performance deutlich heben, wenn dein Programm Gebiete, die als Heightmap definierbar sind von solchen die eine Per-Face-Kollision benötigen, unterscheiden kann.
So ich hoffe das war jetzt nicht zu wirr alle.
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Danke für die Antworten! Ich werde das nächste mal aufteilen.
Zur Kollisionserkennung: Der Spieler befindet bei mir immer nur in einem Patch/Block, den man im Editor beliebig klein einstellen kann. Vielleicht könnte ich dann nur per-face-culling anwenden, wenn es um den Boden/das Terrain geht. Das Terrain ist bei mir in einem dieser Blöcke kein sehr polygonreiches Objekt. Die statischen Modelle könnte ich dann mit Bounding Boxes machen. Ich kann ersteres ja mal versuchen...
Mitglieder in diesem Forum: 0 Mitglieder und 8 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.