Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

27.01.2015, 10:45

[C++] Const-Access für einen Einzelfall aufgeben?

Hi, ich baue im Moment am RenderSystem meines 2D-Spiels (Tile-based) und habe folgende Situation:

Ich habe Physik- und Render-System voneinander getrennt und beide weitestgehend nach Data-oriented Design aufgebaut. Nun will ich das Render-System etwas modifizieren und jeder Render-Komponente (nahezu POD) eine Hand voll RenderNodes geben, wobei ein RenderNode aus einem VertexArray und einer Reihe von Transformationen besteht. Beim Rendern erzeuge ich mir einen einfachen SceneGraph der die zu zeichnenden Nodes kennt.

Nun verändern (bewegen, drehen etc.) sich nicht alle Objekte gleichzeitig aber viele über die Zeit gesehen schon, so dass ich die Transformationen aktualisieren muss. Dazu habe ich überlegt, da die Physik auch weiterhin vom Render-System nichts wissen soll, dass jede Physics-Komponente (komplett POD) noch ein Dirty-Flag bekommt, wenn sich das Objekt z.B. bewegt hat. Dann kann das Render-System das Flag prüfen und ggf. die Transformationen neu berechnen.

Nun würde ich das ganze in der render()-Methode des Render-Systems ansiedeln: Dort erzeuge ich den SceneGraph, kann mir dabei die zugehörige Physik-Komponente holen, mir das Dirty-Flag dort anschauen und aus der Position etc. (die ich in der Physik-Komponente habe) die neuen Transformationen berechnen. Anschließend setze ich das Dirty-Flag zurück. Auf diese Weise berechne ich Transformationen nur für zu zeichnende Objekte. Nebeneffekt: Prinzipiell funktioniert das Zeichnen mehrerer Szenen in einem Fenster (Splitscreen Camera ^^ ) bisher ganz gut und sollte es auch weiterhin tun, da für nicht disjunkte Bereiche die Transformationen auch nur einmal berechnet werden, da das Flag anschließend zurückgesetzt wird.

So, nun kommen wir zum eigentlichen Problem :D Da das Render-System (bisher) nichts von den Physik-Komponenten geändert hat (wie gesagt: das Dirty-Flag ist noch nicht implementiert), hat das Render-System auf Physik-Komponenten nur Zugriff via PhysicsData const &, so dass ich das Dirty-Flag so nicht zurücksetzen kann. Allerdings kann ich mich im Moment noch nicht dazu durchringen dem Render-System nicht-const-Access auf das Physik-System zu geben .. nur für den einen Fall die Garantie aufzugeben, dass das Render-System nicht versehentlich das Physik-System beeinflussen kann, gefällt mir noch nicht so :S

Ich habe mir in diesem Kontext mal angesehen was das volatile-Schlüsselwort macht und festgestellt, dass ich es hier besser nicht verwenden sollte :D (Irgendwie hatte ich das mal irgendwo gesehen, wo jmd. eine const Variable trotzdem ändern wollte :dash: ). Afaik kann der Wert dann nicht mehr gecachet werden und muss immer aus dem RAM geladen werden :nono: Also genau das falsche für mich ^^

Habt ihr eine Idee was ich machen kann um meine nicht-const-Ängste für diesen Fall abzubauen? :D Oder kennt jmd. eine Alternative? Die einzige Alternative die mir einfällt wäre schon Ketzerei:

C-/C++-Quelltext

1
2
3
4
5
6
struct PhysicsData {
    // ...
    bool dirty_flag;

    void clearDirtyFlag() const { dirty_flag = false; } // <-- müsste gehen aber ist alles andere als elegant
}


LG Glocke

Hello_Kitty!

unregistriert

2

27.01.2015, 10:56

Suchst du nach mutable?

3

27.01.2015, 11:05

Für deine "Ketzerei" wird dich dein Compiler bestrafen, dass müssen wir nicht mehr tun ;)

Du meintest allerdings wohl eher mutable anstatt volatile. Sehr empfehlenswert: Herb Sutter: You don't know const and mutable

Dies weicht dein const allerdings schon sehr stark auf. Da wäre ein anderes System eventuell sinnvoller. Muss dein Renderer das Flag zurücksetzen? Kann das nicht dein Physiksystem im nächsten Update machen?
"Theory is when you know something, but it doesn’t work. Practice is when something works, but you don’t know why. Programmers combine theory and practice: Nothing works and they don’t know why." - Anon

4

27.01.2015, 11:13


Danke, schau ihc mir mal an!

Muss dein Renderer das Flag zurücksetzen? Kann das nicht dein Physiksystem im nächsten Update machen?

Naja wenn ich das Flag beim Rendern auswerte ja. Ich rufe meine Render-Methode für jede Kamera einzeln auf, so dass anhand der Kamera alle sichtbaren Objekte ermittelt werden. Setze ich das Flag nicht zurück und mehrere Kameras zeigen das gleiche Objekt an, wird dafür die Transformation mehrfach berechnet, obwohl 1x ausreichend wäre.

Alternativ könnte ich auch - bevor es zum Rendern geht - einen update()-Loop über das Render-System laufen lassen um alle Objekte anzupacken, das Flag zu prüfen und ggf. die Transformation zu verändern. Dann würde ich aber für viele Objekte die gar nicht gezeichnet werden unnötige Transformationen ausführen. Im Grunde reicht es die Trafo für so ein Objekt dann zu berechnen, wenn es gerade sichtbar wird - weil alle vorherigen Trafos dann eh keine Rolle mehr spielen.

LG

/EDIT: Ja ich habe nach mutable gesucht :search: Danke :D

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Glocke« (27.01.2015, 11:50)


dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

27.01.2015, 12:47

Ein Scenegraph ist für Rendering meiner Erfahrung nach keine besonders tolle Datenstruktur. Wofür genau brauchst du den Scenegraph denn?

6

27.01.2015, 13:22

Ein Scenegraph ist für Rendering meiner Erfahrung nach keine besonders tolle Datenstruktur. Wofür genau brauchst du den Scenegraph denn?

Ok, SceneGraph ist glaube etwas zu hoch gegriffen xD Im Endeffekt merke ich mir die Zeiger auf die zu zeichnenden Render-Komponenten... vllt. hätte ich das besser formulieren sollen :D

Werbeanzeige