2017-05-29 34 views
0

Entwickeln ein Spiel von Teris Ich kam zu der Schlussfolgerung, dass die Verwendung der üblichen MVC-Muster würde möglicherweise meinen Code überfluten, sowie, weil OpenGL unter GLEW arbeitet, machen es wesentlich schwieriger, darauf aufzubauen. Stattdessen kam ich mit dieser ordentlichen Änderung, auch abhängig von Beobachter-Muster auf, das wäre etwas mehr Sinn machen, zumindest kurzfristig (Bild nicht vollständig Klassenbaum reflektiert):
makeshift architectureWie löst man diesen Designfehler?

zu erklären:
-Jeder Box ist eine Klasse, Engine enthält Instanz von Entities, Game enthält Instanzen von Figure.
- Figure erbt Entity.
- Engine beobachtet Game und Game gekoppelt ist, die von Beobachtern mit Figures.

Wie sollte es funktionieren:
Im Idealfall sollte ich Engine instanziiert die GLEW und GLFW zusammen mit allen anderen, die das Fenster bilden, dann erstellen Sie ein Game Objekt, das im neuen Thread gesetzt wird, eine Figur schaffen, und benachrichtigen Sie die Engine, um die Zeichnungsschleife zu starten, und wenn diese Zahl festgelegt ist, übergeben Sie sie mit einem Objektzeiger an Engine über Observer.
Dies würde wunderbar funktionieren, ich wäre in der Lage, alle Arten von Zahlen durch Erben Entity, Zahlen würden nicht vom Bildschirm fallen, wie jedes Koordinatenupdate würde gehen durch Game, und ich könnte wahrscheinlich geben jede Figur ein einzigartiges Shader, wenn das nötig wäre.

Wie es funktioniert tatsächlich:
Motor initialisiert wird, Spiel initialisiert, Abbildung für in einem anderen Thread aufgerufen wird, und

atioglxx.dll: 0xC0000005: Access violation reading location 0x00000728. 

wirft, wenn jede OpenGL-Funktion für den Zugriff gefragt.
Ich vermute, dies passiert, weil die Figure nicht weiß, dass alle unterstützende Funktionalität in Engine gestartet ist. Und ich kann es nicht noch einmal in Figure tun. Ich könnte alles, was mit View zu tun hat, auf die Engine verschieben, aber dann wäre ich nicht in der Lage, separate Shader zu setzen, und ich müsste VAOs (Vertex Array Objects) für jede Figur innerhalb von Engine erstellen.
Also, wie mache ich den Fehler weg, während so wenig Änderungen wie möglich einzuführen?

+0

kann dies ein interessantes Problem sein, kann aber auch sein Wegthema . – Walter

+0

@Walter, ich überlegte, es auf gamedev.stack zu platzieren, aber es scheint sich nicht so sehr um architektonische Probleme zu kümmern –

Antwort

0

Die kurze Antwort ist, dass alle OpenGL-Aufrufe für einen gegebenen Kontext im selben Thread sein müssen. Eine längere Antwort ist auf dem Weg ...


Zuerst Entities Bedarf, sich mit GL Anrufe ziehen. Sie können Zeichnungscode nicht aus einem Thread mit einem anderen mischen, der OpenGL-Client-Status wäre nicht korrekt. (Stellen Sie sich OpenGL als eine C-Zustandsmaschine vor).

Zweitens müssen Sie die Entity-Status nach Frame puffern. Die Engine möglicherweise nicht beendet werden, Zeichnungsaufrufe zu senden, wenn Sie Ihren nächsten Rahmen im Game Thread starten. Sie benötigen also einen synchronisierten Weg, um alle Entity Zustände für einen Rahmen zu übermitteln. Dies wird ein wenig schwierig, weil Sie Synchronisationsgrundelemente (z. B. Mutexe) vermeiden möchten, die Ihre Pipeline blockieren oder blockieren könnten.

Sie können die Doom III source code lesen, die eine doppelt gepufferte Pipeline zum Senden von Zeichnungsaufrufen an das Engine Backend verwendet.Der Trick ist, dass Doom am Hauptthread alles erledigt, sich dann zum Ausführen von Draw Calls im Backend-Thread (Engine) aufteilt und Zeichnungszustände (Entities) für den nächsten Frame auf dem Game Hauptthread übergibt. Dann wartet es auf den Thread Engine, um zu beenden, und tauscht die Puffer aus.

Lesen Sie auf Metal und Vulkan Multithreading. Diese sind sehr ähnlich.

Ressourcen müssen auf der Engine und zurück Griffe für Ihre Einheiten geladen werden, hier zu referenzieren (Shaders, Texturen, Static Geomety, etc ..)