Implementation von Vertex-Klassen



  • TGGC schrieb:

    Allokier doch einfach soviel Byte, wie du brauchst und schreib dann die Daten "von Hand" an die passenden Stellen. Die kann man ja aus dem Format einfach berechnen.

    Worauf bezieht sich diese Antwort??

    Auf die illuminator-Lösung?



  • hi,

    nützlich ist es schon eine eigene Vertexklasse zu schreiben die angibt welche informationen verwendet werden sollen. in gängingen lösungen (bspw. ogre3d, nebula2) findet man in einer solchen struktur alle benötigten datenelemente (xyz, normal, tangent, binormal, diffuse, blend, specular, tex0..3). nur so viele Kombinationen wird man meist nicht nutzen. da man die daten fast immer parallel im system ram rumliegen hat, würde ich es darauf beziehen. aus den vorhandenen daten dann nen vertexbuffer zu erstellen und zu füllen, der dann nur die elemente aufnimmt die auch wirklich benötigt werden, ist dann auch nicht das problem. mit geringem aufwand lässt sich für den vertexarray ein iterator basteln, mit dem man noch handlicher und effektiver arbeiten kann (oder vertices gleich in einen std::vector packen). den operator new dafür zu überladen, halte ich für unnötigen overkill.

    @illuminator
    deine lösung finde ich teilweise unschön. wieso zeigt zB jeder vertex auf das nächste element?

    gruss,
    Sebastian



  • zebel schrieb:

    deine lösung finde ich teilweise unschön. wieso zeigt zB jeder vertex auf das nächste element?

    Weil ich dann eine verkette Liste hab wo ich einfach mit z.B. Vertex->InsertAfter(new Vertex[10],10) zehn vertices mittendrin einfügen kann.
    fragt sich natürlich wie sinnvoll das ist und ob man das braucht... 😃
    Aber meine Überlegung war halt, dass wenn man eh schon nur eine Klasse für jeden Vertex-Typ hat und deswegen sowieso nicht mit einem memcpy-befehl alles in eine Vertexbuffer schieben kann und jeden Vertex einzeln anfassen muss, auch gleich eine verkette liste Liste draus machen könnte.

    TGGC schrieb:

    Allokier doch einfach soviel Byte, wie du brauchst und schreib dann die Daten "von Hand" an die passenden Stellen. Die kann man ja aus dem Format einfach berechnen.

    Hm, wie meinst du das?

    Soll der Konstruktur der Vertexklasse anhand des FVF genügend Byte allokieren ?
    Dann musst du dir doch aber auch offsets für normale, tex1, farbe etc. merken, damit du die nicht bei jedem Aufruf von z.B. Vertex->SetNormal(nx,ny,nz) neu ermitteln musst.
    womit du dann wieder unnötigen Speicherverbrauch hättest (wenn auch möglichweise weniger) und du trotzdem wieder für jeden Vertex einen memcpy beim erstellen des Vertexbuffer bräuchtest.

    Oder meintest du es anders? 😕



  • @EnERgYzEr:
    Auf deine Frage.

    @Optimizer:
    Und an ein paar Offsets pro VB wirst du nicht sterben. Als Offset reicht ein Byte, ein Eintrag (normal ja float oder DWORD) braucht vier. Ab 25 Vertizen pro VB brauchen die Offsets also nur noch 1%...

    Denk ausserdem mal drüber nach, ob das wirklich unnötig ist. Die Offsets brauchst du bei _jeder_ Methode.

    Was du für'n Problem mit memcpy meinst, weiss ich nicht. Ich seh keines.

    Bye, TGGC \-/



  • TGGC schrieb:

    @Optimizer:

    Du meinst mich nicht Optimizer 😃

    TGGC schrieb:

    Und an ein paar Offsets pro VB wirst du nicht sterben. Als Offset reicht ein Byte, ein Eintrag (normal ja float oder DWORD) braucht vier. Ab 25 Vertizen pro VB brauchen die Offsets also nur noch 1%...

    Du willst dir die Offsets also außerhalb der Vertexklasse merken? Find ich nicht gut.
    Oder willst du sie in der Klasse static machen? Ist doch auch gar nicht gut wenn du veschiedene Vertextypen brauchst, oder?

    TGGC schrieb:

    Denk ausserdem mal drüber nach, ob das wirklich unnötig ist. Die Offsets brauchst du bei _jeder_ Methode.

    Nichts anderes hab ich gesagt. Ich meinte lediglich "unnötig" im dem Sinne, dass man ja eigentlich nur den Speicher für Vertexdaten an einem Stück haben möchte und nicht mittendrin noch die Offsets.



  • Finde das alles ziemlich interessant, und würde gern mal wissen, was von folgender Idee zu halten ist (Einfachheit geht mal vor Effizienz):
    Man übergibt dem Konstruktor der Vertexklasse (ich nenn sie lieber Meshklasse) einen Enum, der den Typ spezifiziert.
    Die Klasse initialisiert damit ihren std::vector<std::vector<>> mit entsprechend vielen Vectoren des entsprechenden Typs, also wenn man POS_NORM_TEX als Typ des Meshes angibt, bekommt der obere std::vector der Klasse 3 std::vectoren, von denen wieder 2 vom Typ vec3 sind und einer vom Typ vec2 ist.

    Fragen sind also: Wäre das eine gute, einfache Möglichkeit? Ist das überhaupt möglich, muss man denn nicht schon in der Klassendefinition den Typ des std::vectors der in dem oberen std::vector enthalten ist, angeben?
    Also z.b. so: std::vector<std::vector<vec3>>
    Das wär aber nicht möglich, weil man ja nicht weiß obs ein vec3, vec4 oder doch nur ein vec2 sein soll, bzw. weil sich das ja dann auch unterscheidet.

    Und noch was:
    Wäre es schlechtes Design, schon dieser Meshklasse API-spezifische Funktionen zu geben?
    Wenn nicht, würde dann (für OGL) eine Funktion "GLuint compileDisplayList()" oder irgendwas mit VertexArrays / VBOs Sinn machen?

    EDIT: "std::" hinzugefügt und andere Unklarheiten beseitigt.



  • das geht nur mit templates, und die habenw ir schon ausgeschlossen.
    in der richtung mit enum gings nur über polymorphie, und ich glaub nich, dass wir 1000 verschiedene vertexklassen wollen^^

    aber nur mal so ne frage am rande: wozu brauch man 8 paar vertexkoordinaten?
    1.schicht relief
    2. schicht standardtextur
    3.schicht detailtextur
    4.schicht lightmap

    vielelicht noch ne 5. schicht für ne weitere textur mit details...
    darüber hinaus wirds doch schon sehr ungewöhnlich oder irr ich mich jetzt?



  • otze schrieb:

    aber nur mal so ne frage am rande: wozu brauch man 8 paar vertexkoordinaten?
    1.schicht relief
    2. schicht standardtextur
    3.schicht detailtextur
    4.schicht lightmap

    z.B. noch Alpha für Detailtextur oder noch weitere Standardtexturen



  • alpha für detail?



  • Also ich meinte mit Detailtextur eine Normalmap (vielleicht bezeichnest du
    das als Relief??). Und die macht durchaus Sinn mit einer Alphamap zu
    kombinieren. Z.B., wenn man will, dass nur die Steine im Terrain Risse haben
    und nicht das Gras 😉



  • relief ist dafür da um einer textur durch grautöne eine plastizität zu geben.
    ansonsten mein ich mit detailmap das, was du auch meinst^^



  • @Opti: Sorry.

    @illumintaor:
    Von ausserhalb oder innerhalb habe ich nichts gesagt, möglich wäre alles. Es könnte z.b. einen OffsetManager geben, der Offset alle bisher nötigen Vertextypen cached...
    Und Die Offsets sind doch nicht mittendrin!

    Bye, TGGC \-/



  • Das Problem bei der Implemation einer Vertex-Klasse ist aus meiner Sicht
    folgendes: Da jedes Objekt unterschiedlich viele Textur-Schichten hat, muss
    ein Vertex auch dynamisch viele Textur-Koordinaten bieten (bis zu 8).

    nach längerem überlegen kam ich auf folgenden gedanken:
    pack in die vertices das, was jedes objekt minimal braucht, und pack das, was objektspeziell ist, in eine andre streamsource und benutz shader.
    (5 unbenutze texturschichts koordinaten pro vertex 😮 ).



  • Das ist die andere einfache Lösung. 😎

    Bye, TGGC \-/



  • otze schrieb:

    nach längerem überlegen kam ich auf folgenden gedanken:
    pack in die vertices das, was jedes objekt minimal braucht, und pack das, was objektspeziell ist, in eine andre streamsource und benutz shader.
    (5 unbenutze texturschichts koordinaten pro vertex 😮 ).

    Ich verstehe nicht, was extra-streamsources mit Shadern zu tun haben, kannste das bitte nochmal erklären 🙂



  • ganz einfache erklärung: du hast 2 vertexbuffer a und b
    buffer a enthält positionsangaben und normale der vertices.
    b enthält die Texturkoordinaten.
    jetzt wird ein vertexbuffern mit den angaben von a und b erstellt

    das gibt aber ein problem,da man ja die angaben in einem bestimmten schema anordnen muss, dh wenn es zum kopiervorgang kommt, wird für jedes vertex ein kopiervorgang von a und b gestartet,bei 2000 vertices sind das 4000 vorgänge.
    nun kann man aber einfach 2 buffer mit verschiedenen FVF werten benutzen, aber die standard T&L weis nicht, wie sie die daten verknüpfen soll,deshalb muss man einen shader kreieren, der definiert von welcher quelle er welche daten bekommt.

    vorallem kann dies sehr viele resourcen sparen:
    beispiel an einem strategiespiel:
    4 spieler, 4 verschiedene farben, gleiche rassen, also gleiche einheiten:
    jetzt brauch man rein theoretisch nur einen vertexbuffer mit den modeldaten, und 4 buffer mit den farben, das war alles. eder modelbuffer wird nur einmal geschrieben,kann also statisch sein, und die farbbuffer zu wechseln geht auch relativ schnell. Ohne shader müsste man den modelbuffer jedes mal komplett neu beschreiben,das würde keinen spaß machen,und die performance "leicht" in den Keller treiben



  • Hmm, so richtig genau weiß ich immer noch nicht wie du das meinst, aber das könnte glaub ich daran liegen dass ich von DX keine Ahnung habe 😉
    In OGL gibts ja solche Vertexarrays, da isses sogar üblich, dass in einem Array die Positionen und in nem anderen die Texturkoordinaten stehen.
    Und ich hab so dass Gefühl, dass auch die Pipline etwas anderes aussieht...



  • tja, bei dx muss man da sofort mit shadern ran^^

    //edit
    hier der thread


Anmelden zum Antworten