TLDR: Indem die Komponente zunächst aus mehreren Maschen besteht.
Ich stimme Asakeron / Byte56 / Laurent darin zu, dass eine andere Indirektionsebene zwischen den Maschen / Material-Paaren und der Entität selbst erforderlich ist. Anstatt die GraphicsComponent als Scheitelpunkte und Materialien zu betrachten, stellen Sie sie sich als einen Pixelklecks im endgültigen Raster vor - wie sie dort ankommt, ist ein Implementierungsdetail und nichts weiter.
Ich habe viel über mein Projekt nachgedacht und ich denke, die optimale Lösung besteht darin, die GraphicsComponent zu einer viel übergeordneten Komponente zu machen, die einen Großteil der Funktionalität des traditionellen 'Model'-Objekts umfasst - da diese Funktionalität nicht optional ist! Um diese Polygone zu rendern, werden viel mehr als nur die Pufferdaten und der Shader benötigt, wie zum Beispiel:
- Position, die Sie erwähnt haben
- Skinning- / Animationsdaten
- Der aktuelle Pass (z. B. bei Verwendung von Alpha mit zwei Passes)
- Informationen zum Schattenwerfen (wenn Sie dies tun)
- Informationen darüber, wie und wann das Material aktualisiert werden muss
- Culling-Funktionalität
Und das ist nur für 3D-Assets, ohne Partikelsysteme, Werbetafeln usw. zu berücksichtigen. Aber alles ist nur für den Grafik- / Rendering-Code relevant - es hat keinen Einfluss auf die Physik, den Sound oder das Scripting, daher ist es sinnvoll, darin zu sitzen die Grafik- / Rendering-Komponente.
Am Ende hatte ich:
Model : Entity, IHasGraphicsComponent, IHasSkeleton, IHasAnimationStore //This is the 'game object' - it is passed to the GraphicsController
ModelComponent : GraphicsComponent //This is the actual graphics component, used by the GraphicsController in the context of the game object.
ModelComponentPart : GraphicsComponent //This is also a graphics component
Mesh //These are implementation details
Material
ModelComponentPart : GraphicsComponent
Mesh
Material
Skeleton
Animations
In diesem:
Modell ist jedes Spielelement mit einer Grafikkomponente.
Die ModelComponent ist analog zum herkömmlichen Modell und gilt tatsächlich für 3D-Assets. Der GraphicsComponent-Controller (wenn Sie das Model-View-Controller-Muster verwenden) ist dafür verantwortlich, herauszufinden, um welche Art von Grafik-Asset es sich handelt, und es korrekt zu zeichnen (beachten Sie, dass ModelComponent eine Unterklasse von GraphicsComponent ist).
Aus Gründen der Einfachheit und Abwärtskompatibilität gab es bei mir auch einige Kompromisse, z. B. dass jede GraphicsComponent auch eine Entität ist und die Entität Positionsdaten direkt speichert, sodass sie nur an einer Stelle berechnet werden. Die Idee ist jedoch dieselbe: GraphicsComponent behandelt das, was ist benötigt, um den Gegenstand zu zeichnen - alles, was benötigt wird - nicht nur, was vom Modellbauer kommt.