[gelöst] std::bad_alloc trotz ausreichendem Speicher



  • Wenn ich das richtig verstehe, möchtest du also nur 2D-Grafiken rendern.

    So lange ich "nur" 1024 mal eine Textur zeichne, funktioniert alles, sobald ich aber mehr als 1024 Texturen zeichne

    Wie machst du das, wenn deine Vertexarrays nur Platz für jeweils 1024 Quads bieten?

    oder einen vector verwenden, aber dann müsste ich den VertexBuffer jedes mal neuerstellen, wenn mehr Vertices dazugekommen sind.

    Wie kommst du zu der Aussage? Es zwingt dich niemand, die Größe eines vectors zu verändern, aber im Gegensatz zu C-Arrays sind std::vector und std::array in der Lage out-of-bounds-Zugriffe im Debug-Modus zu erkennen, wie SeppJ ja schon gesagt hat.



  • Wenn die Arrays keinen Platz mehr haben, hab ich eben ein neues erstellt.
    Egal, ich habs jetzt so gemacht, dass ich alle Vertices in einen Vector speicher und dann ganz am Ende den Vector sozusagen in Arrays der Größe COUNT aufspalte um die Daten in den VertexBuffer zu kopieren und zu rendern. So funktioniert das nun auch, auch wenn bei 4096 mal eine Textur rendern das Bild blinkt und nur ca. 20FPS auf die Reihe bekommt, während so viele Texturen XNA keinesfalls aus dem Schritt bringen, auch wenn dieses auf C# basiert. Na ja, da werd ich mal noch ein bisschen nach Optimierungen suchen müssen.
    Auf jeden Fall mal ein Dankeschön an alle Helfenden hier 🙂

    Nur noch eine klitzekleine Frage:
    wenn ich per
    for each(pair<ID3D11ShaderResourceView*, vector<Vertex>> p in _textures)
    durch eine map<ID3D11ShaderResourceView*, vector<Vertex> durchiteriere, wirft IntelliSense einen Fehler, dass for each den Ausdruck nicht verarbeiten könnte, kompilieren tut es aber wunderbar. Sollte ich trotzdem lieber etwas (meiner Meinung nach unübersichtliches) wie
    for(map<ID3D11ShaderResourceView*, vector<Vertex>>::iterator i = _textures.begin(); i != _textures.end(); i++)
    verwenden, gibt es da noch eine viel bessere Variante, oder soll ich den Fehler einfach ignorieren?



  • Er hat also eine Größe von 36Bytes.

    Das kann man einfach so sagen? Ist das nicht total maschinenabhängig?



  • Kann sein, ich bin jetzt einfach mal von sizeof(float) = 4 Bytes ausgegangen, kann aber natürlich variieren, im Code verwende ich natürlich immer sizeof(Vertex), die 36 Bytes waren nur zum anschaulich machen.


  • Mod

    Xwin7userX schrieb:

    Nur noch eine klitzekleine Frage:
    wenn ich per
    for each(pair<ID3D11ShaderResourceView*, vector<Vertex>> p in _textures)
    durch eine map<ID3D11ShaderResourceView*, vector<Vertex> durchiteriere, wirft IntelliSense einen Fehler, dass for each den Ausdruck nicht verarbeiten könnte, kompilieren tut es aber wunderbar. Sollte ich trotzdem lieber etwas (meiner Meinung nach unübersichtliches) wie
    for(map<ID3D11ShaderResourceView*, vector<Vertex>>::iterator i = _textures.begin(); i != _textures.end(); i++)
    verwenden, gibt es da noch eine viel bessere Variante, oder soll ich den Fehler einfach ignorieren?

    for each ist eine nicht standardgemäße Compilererweiterung von MSVC++. Nutz lieber die standardkonforme zweite Variante, std::for_each oder am besten, falls MSVC++ dies inzwischen kann, ein range-based for.



  • Oder:
    map<ID3D11ShaderResourceView*, vector<Vertex>>::iterator ➡ auto

    <:xmas2:>



  • Vielen Dank, ein ranged based for war genau das, was ich gesucht hab (entspricht ja sozusagen dem MS for each). Jetzt wirft IntelliSense auch keinen Error mehr 🙂

    Edit: Also entweder hat MS bei der Implementierung von Ranged Based For ziemlich geschlampt, oder das ist, warum auch immer, immer so unperformant. Denn mit for(auto i : _textures) hab ich bei 4096 * mal eine Textur zeichnen 18FPS, wenn ich for(auto i = _textures.begin(); i != _textures.end(); i++) verwende, bekomme ich 23FPS. Oder kann es sein, dass dadurch, dass _textures im Moment nur eine Länge von 1 hat (ich zeichne ja bisher nur eine Textur) ranged base for noch einen sehr großen OverHead hat, der sich bei größeren Größen von _textures auszahlt?



  • die Textur wird jedes mal kopiert.



  • for(auto &i : _textures)
    

    ohne das & iteriert er by value, bzw erstellt eine Kopie und arbeitet damit.



  • Wunderbar, jetzt läuft das so auch mit 23FPS 😃
    Vielen Dank!


Anmelden zum Antworten