SFML - Partikeldarstellung beschleunigen



  • Hallo,

    ich programmiere eine Ameisensimulation mit SFML.
    Derzeit nutze ich SF::RectangleShape (antShape) für die Darstellung der Ameisen - Pheromonspuren.
    Die könnte man auch als Partikel auffassen.

    Leider ist das ziemlich lahm. Kann ich das irgendwie beschleunigen?

    void Drawer::drawAnts (openCLinit * init, Helper * helper){
    	for (int antid = 0; antid < ARRAY_SIZE; antid++){
    		sf::RectangleShape antShape(sf::Vector2f(SIZEOFANANT,SIZEOFANANT));
    		// Do this only for Living Ants
    		if (init->lifeStadium[antid] != 0){
    			// Selection Mode
    
    			////////////////////////////////////////////////////////Drawer::selectAnts(antid, targetMode);
    			Drawer::selectAnts( antid, init, shapeSelection, helper->selectedAnts, helper->selectionMode);
    
    			if (init->color[antid] == 0){
    				antShape.setFillColor(sf::Color(255,255,255,255));
    			}
    			if (init->color[antid] == 1){
    				antShape.setFillColor(sf::Color::Yellow);
    			}
    			if (init->color[antid] == 3){
    				antShape.setFillColor(sf::Color::Green);
    			}
    			if (init->color[antid] == 33){
    				antShape.setFillColor(sf::Color::Magenta);
    			}
    			if (helper->viewRadiusMode){
    				sf::CircleShape radius;
    				int transparency;
    				BOOST ? transparency =255 : transparency = 25;
    				init->isCarryingFood[antid] ? radius.setFillColor(sf::Color(0,255,0,transparency)) : radius.setFillColor(sf::Color(255,0,0,transparency));
    
    				radius.setRadius(ANT_VIEWRADIUS);
    				radius.setPosition(init->antX[antid]-ANT_VIEWRADIUS+2,init->antY[antid]-ANT_VIEWRADIUS+2);
    				window->draw(radius);
    			}
    
    			antShape.setPosition(init->antX[antid],init->antY[antid]);
    
    			window->draw(antShape);
    
    			if (helper->targetMode){
    				Drawer::drawTargets(init, antid);
    
    				sf::Vertex line[] =
    				{
    					sf::Vertex(sf::Vector2f(init->antX[antid], init->antY[antid])),
    					sf::Vertex(sf::Vector2f(init->targetX[antid], init->targetY[antid]))
    				};
    
    				window->draw(line, 2, sf::Lines);
    
    			}
    
    			// Check 
    
    		}
    
    	}
    
    }
    


  • Das muss ich einfach korrigieren, ich finde das so deutlich einfacher zu lesen:

    void Drawer::drawAnts (openCLinit * init, Helper * helper){
        for (int antid = 0; antid < ARRAY_SIZE; antid++){
            sf::RectangleShape antShape(sf::Vector2f(SIZEOFANANT,SIZEOFANANT));
            // Do this only for Living Ants
            if (init->lifeStadium[antid] != 0){
                // Selection Mode
    
                ////////////////////////////////////////////////////////Drawer::selectAnts(antid, targetMode);
                Drawer::selectAnts( antid, init, shapeSelection, helper->selectedAnts, helper->selectionMode);
    			switch(init->color[antid])
    			{
    			case 0:
    				antShape.setFillColor(sf::Color(255,255,255,255));
    				break;
    			case 1:
    				antShape.setFillColor(sf::Color::Yellow);
    				break;
    			case 3:
    				antShape.setFillColor(sf::Color::Green);
    				break;
    			case 33:
    				antShape.setFillColor(sf::Color::Magenta);
    				break;
    			}
    
                if (helper->viewRadiusMode){
                    sf::CircleShape radius;
                    int transparency = BOOST ? 255 : 25;
                    if(init->isCarryingFood[antid])
    					radius.setFillColor(sf::Color(0,255,0,transparency))
    				else
    					radius.setFillColor(sf::Color(255,0,0,transparency));
    
                    radius.setRadius(ANT_VIEWRADIUS);
                    radius.setPosition(init->antX[antid]-ANT_VIEWRADIUS+2, init->antY[antid]-ANT_VIEWRADIUS+2);
                    window->draw(radius);
                }
    
                antShape.setPosition(init->antX[antid],init->antY[antid]);
                window->draw(antShape);
    
                if (helper->targetMode){
                    Drawer::drawTargets(init, antid);
    
                    sf::Vertex line[] =
                    {
                        sf::Vertex(sf::Vector2f(init->antX[antid], init->antY[antid])),
                        sf::Vertex(sf::Vector2f(init->targetX[antid], init->targetY[antid]))
                    };
    
                    window->draw(line, 2, sf::Lines);
                }
                // Check  
            }
        } 
    }
    

    So, nun zu deinem Problem:
    Um ehrlich zu sein kenne ich mich mit SFML nicht so gut aus, ich weiß nicht ob das intern vielleicht sogar 3D nutzt.
    Aber SFML understüzt auch 3D. Wie wärs wenn du alle Sprites für die Ameisen, Spure, etc. in großes Vertexarray packst und dieses dann mit einem Aufruf an die Grafikkarte sendest ? Das sollte ein der schnellsten Möglichkeiten sein. Jedes Rechteck einzeln zu zeichen ist einfach langsam. 😃


Anmelden zum Antworten