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
Zitat von »[Anonymer Benutzer«
]Aber es könnte auch am Zeichnen liegen. SFML macht ja kein Spritebatching, das bedeutet dass jeder Partikel einzeln gezeichnet wird, anstatt in einem Rutsch. Dadurch gibt es halt Abertausende von einzelnen Zeichnenaufrufen.
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Ich habe Dir schon mehrfach gesagt, dass das nicht stimmt. SFML kennt sehr wohl VertexArrays und die wurden hier auch verwendet. Da wird eben nicht jeder Partikel einzeln gezeichnet, sondern alles auf einmal. Genau wie andere Frameworks das mit SpriteBatching auch machen. Ich wäre Dir also sehr dankbar, wenn Du endlich aufhören würdest solchen Unfug zu verbreiten.SFML macht ja kein Spritebatching, das bedeutet dass jeder Partikel einzeln gezeichnet wird, anstatt in einem Rutsch.
C-/C++-Quelltext |
|
1 2 3 4 |
struct Particles { v2* positions; float* timers; }; |
Administrator
C-/C++-Quelltext |
|
1 2 3 4 |
for (int i = 0; i < 10000; i++) { if (v[i]); } |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
#include <SFML\Graphics.hpp> #include "Resources.hpp" #define particleNumber 100000 struct particles { enum Type { energy, airSplit, smoke, fire, typeCount }; particles() { for (int i = 0; i < particleNumber; i++) isActive[i] = false; } bool isActive[particleNumber]; float leftLifeTime[particleNumber]; float xVelocity[particleNumber]; float yVelocity[particleNumber]; }; class particleSystem : public sf::Drawable { public: explicit particleSystem(particles::Type type); void update(sf::Time timePerFrame); void addParticle(float xPos, float yPos, float xDirectionVelocity, float yDirectionVelocity); unsigned int getParticleCount() const; private: void draw(sf::RenderTarget& target, sf::RenderStates states) const override; private: particles::Type mType; float particleLifetime; const sf::Texture* mTexture; float xHalfTextureSize; float yHalfTextureSize; unsigned int nextFreeParticle; particles mParticles; sf::Vertex vertices[4 * particleNumber]; }; |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
#include "particleSystem.hpp" particleSystem::particleSystem(particles::Type type) : mType(type), mTexture(nullptr), nextFreeParticle(0) { switch (type) { case particles::energy: { particleLifetime = 15.f; mTexture = &Resources::get()->getResource(Holder::particles, Texture::energy); break; } case particles::fire: { particleLifetime = 0.3f; mTexture = &Resources::get()->getResource(Holder::particles, Texture::fire); break; } case particles::smoke: { particleLifetime = 1.6f; mTexture = &Resources::get()->getResource(Holder::particles, Texture::smoke); break; } case particles::airSplit: { particleLifetime = 0.8f; mTexture = &Resources::get()->getResource(Holder::particles, Texture::airSplit); break; } default: { assert(false); } } xHalfTextureSize = (sf::Vector2f(mTexture->getSize()) / 2.f).x; yHalfTextureSize = (sf::Vector2f(mTexture->getSize()) / 2.f).y; for (int i = 0; i < 4 * particleNumber; i += 4) { vertices[i].texCoords = sf::Vector2f(0, 0); vertices[i + 1].texCoords = sf::Vector2f(mTexture->getSize().x, 0); vertices[i + 2].texCoords = sf::Vector2f(mTexture->getSize().x, mTexture->getSize().y); vertices[i + 3].texCoords = sf::Vector2f(0, mTexture->getSize().y); } } void particleSystem::update(sf::Time timePerFrame) { float dt = timePerFrame.asSeconds(); float xPos = 0; float yPos = 0; float alpha = 0; for (int i = 0; i < particleNumber; i++) { if (mParticles.isActive[i]) { mParticles.leftLifeTime[i] -= dt; if (mParticles.leftLifeTime[i] <= 0) { mParticles.isActive[i] = false; vertices[4 * i].color.a = 0; vertices[4 * i + 1].color.a = 0; vertices[4 * i + 2].color.a = 0; vertices[4 * i + 3].color.a = 0; } else { xPos = vertices[4 * i].position.x + xHalfTextureSize; yPos = vertices[4 * i].position.y + yHalfTextureSize; xPos += mParticles.xVelocity[i] * dt; yPos += mParticles.yVelocity[i] * dt; vertices[4 * i].position.x = xPos - xHalfTextureSize; vertices[4 * i].position.y = yPos - yHalfTextureSize; vertices[4 * i + 1].position.x = xPos + xHalfTextureSize; vertices[4 * i + 1].position.y = yPos - yHalfTextureSize; vertices[4 * i + 2].position.x = xPos + xHalfTextureSize; vertices[4 * i + 2].position.y = yPos + yHalfTextureSize; vertices[4 * i + 3].position.x = xPos - xHalfTextureSize; vertices[4 * i + 3].position.y = yPos + yHalfTextureSize; alpha = mParticles.leftLifeTime[i] / particleLifetime * 255.f; vertices[4 * i].color.a = alpha; vertices[4 * i + 1].color.a = alpha; vertices[4 * i + 2].color.a = alpha; vertices[4 * i + 3].color.a = alpha; } } } } void particleSystem::addParticle(float xPos, float yPos, float xDirectionVelocity, float yDirectionVelocity) { mParticles.isActive[nextFreeParticle] = true; mParticles.leftLifeTime[nextFreeParticle] = particleLifetime; mParticles.xVelocity[nextFreeParticle] = xDirectionVelocity; mParticles.yVelocity[nextFreeParticle] = yDirectionVelocity; vertices[4 * nextFreeParticle].position.x = xPos - xHalfTextureSize; vertices[4 * nextFreeParticle].position.y = yPos - yHalfTextureSize; vertices[4 * nextFreeParticle + 1].position.x = xPos + xHalfTextureSize; vertices[4 * nextFreeParticle + 1].position.y = yPos - yHalfTextureSize; vertices[4 * nextFreeParticle + 2].position.x = xPos + xHalfTextureSize; vertices[4 * nextFreeParticle + 2].position.y = yPos + yHalfTextureSize; vertices[4 * nextFreeParticle + 3].position.x = xPos - xHalfTextureSize; vertices[4 * nextFreeParticle + 3].position.y = yPos + yHalfTextureSize; vertices[4 * nextFreeParticle].color.a = 255; vertices[4 * nextFreeParticle + 1].color.a = 255; vertices[4 * nextFreeParticle + 2].color.a = 255; vertices[4 * nextFreeParticle + 3].color.a = 255; nextFreeParticle++; if (nextFreeParticle >= particleNumber) nextFreeParticle = 0; } unsigned int particleSystem::getParticleCount() const { unsigned int count = 0; for (int i = 0; i < particleNumber; i++) if (mParticles.isActive[i]) count++; return count; } void particleSystem::draw(sf::RenderTarget& target, sf::RenderStates states) const { states.texture = mTexture; target.draw(&vertices[0], 4 * particleNumber, sf::PrimitiveType::Quads, states); } |
Zitat
So wie ich das sehe, haben...
...die Liste dann so aus: [150, 100, 500]
Hoffe ich konnte helfen
Zitat
@sw1
Hast du mal versucht, die Partikel in-place zu aktualisieren (wie z.B. in diesem offiziellen Tutorial) anstatt das Array vor jedem Rendern zu leeren und neu zu befüllen? Ich könnte mir vorstellen, dass das eine Verbesserung bewirkt.
Zitat
@Thread-Ersteller:
Hast du denn mal einen Profiler benutzt und geschaut, was genau wie viel Zeit benötigt?
Nicht dass du an der falschen Stelle optimierst.
Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »sw1« (17.04.2016, 12:16)
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Spiele Programmierer« (17.04.2016, 14:12)
Anstatt 4 Vertices zu updaten und an die Grafikkarte zu schicken, könntest du auch die Partikeldaten einfach direkt übermitteln und die Vertexdaten auf der Grafikkarte zum Beispiel mit einem Geometry Shader erzeugen. (Ich befürchte allerdings, dass SFML da wiedermal nix bietet.)
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Werbeanzeige