dx11 2d recreate buffers



  • Ich hab einen ziemlich simplen renderer geschrieben, der es ermöglicht farbige rechtecke und sprites zu zeichnen.
    zum testen (bzw. damit ich den überhaupt mal ans laufen bekomme) hab ich das erstmal so gemacht, dass jedes dieser objekte mit einem eigenen draw-call gezeichnet wird. Das ist natürlicht irre langsam 😕

    Wie mache ich das am besten anders? ist es eine gute idee bei jedem bild neue buffer (index und vertex) zu erstellen, in welche alle sprites auf einmal reinpassen, sodass ich sie alle auf einmal zeichnen kann.

    Mir ist keine möglichkeit bekannt wie ich die größe von einem buffer ändern kann, deshalb müsste man das doch eigendlich so machen wie beschrieben.

    Wäre cool wenn ihr mir ein paar anregungen geben könntet 😉



  • Wenn deine Sprites alle dieselben Dimensionen haben brauchst du nur ein Rechteck in den Buffer speichern und für jedes Sprite eine eigene Textur nehmen. Damit du nicht 200 Texturen hast kannst du dann alle Sprites (oder soviele wie möglich) in eine Textur zusammenfassen. Beim Rendern passt du dann die Texturkoordinaten an damit du dir nur ein Sprite aus der Textur holst. Letzteres kannst du entweder die CPU erledigen lassen oder den Vertexshader - zB die linke obere Ecke des zweiten Sprite in der dritten Zeile der Textur hätte Texturkoordinaten (Spritebreite/Texturbreite, 2*Spritehöhe/Texturhöhe).
    Gibt auch noch die Möglichkeit pro Sprite nur einen Punkt zu zeichnen und im Geometry Shader daraus ein Rechteck zu machen.

    Beim Texturatlas musst du nur drauf aufpassen, dass du das Filtering und die Koordinaten richtig setzt, sonst kriegst du hässliche Ränder.



  • Erzeug einen dynamischen Buffer der groß genug ist, um z.B. 1000 Sprites zu halten. Am Anfang mappest du den Buffer mit D3D11_MAP_DISCARD. Beim Rendern packst du jetzt ein Sprite nach dem anderen in diesen Buffer. Sobald der Buffer voll ist, oder ein Statewechsel nötig wird, unmappest du den Buffer und zeichnest alles, was im Moment im Buffer drin ist. Falls der Buffer nicht voll war, mappest du den Buffer mit D3D11_MAP_NOOVERWRITE und füllst ihn weiter, ansonsten mappest du ihn mit D3D11_MAP_DISCARD und füllst wieder am Anfang.



  • dot schrieb:

    Falls der Buffer nicht voll war, mappest du den Buffer mit D3D11_MAP_NOOVERWRITE und füllst ihn weiter, ansonsten mappest du ihn mit D3D11_MAP_DISCARD und füllst wieder am Anfang.

    Wieso nicht immer D3D11_MAP_DISCARD?
    Ist es wirklich schneller mit D3D11_MAP_NOOVERWRITE anzuhängen, wenn man den vorderen Teil der nicht verändert wird gar nicht mehr braucht?



  • okay 👍 hat mir schon sehr weitergeholfen 😉


Log in to reply