# Übereinander blenden?



## LoN_Nemesis (30. Sep 2007)

Hallo,

leider kenne ich mich mit Grafik Fachbegriffen nicht so aus, darum bräuchte ich mal Hilfe.

Ich habe mir im Rahmen eines Spieles eine kleine Partikelengine geschrieben. Diese funktioniert auch recht gut, nur leider kostet sie relativ viel Prozessorpower. Ich habe mir nun mal andere Partikelengines angesehen und bin dabei auf einen Partikeleditor gestoßen. Hier ist der Link: http://slick.cokeandcode.com/demos/pedigree.jnlp
Dieser Editor hat rechts oben im GUI die Option 'Use Points'. Wenn man das einschaltet, dann sieht das Ganze genau so aus wie bei meiner Partikelengine. Und genau wie mir bricht dann die Framerate ein (sieht man bei dem Standardeffekt eventuell nicht so, aber wenn man was komplexeres wie z.B. http://bcardoso.planetaclix.pt/pedigree/system.xml in den Editor lädt wird es sehr deutlich).

So wie ich das sehe, wird ohne die Option 'Use Points' wirklich jeder Partikel einzeln komplett gezeichnet. Bei 100+ kostet das natürlich sehr viel Zeit, und ist vor allem auch unnötig, da es meist viele Überschneidungen gibt und sich die Partikel die ganze Zeit übermalen. Wie aber erreiche ich nun diese Überblendung, bei der anscheinend sehr viel Rechenzeit bei der Darstellung gespart werden kann?


Vielen Dank im Voraus!


----------



## Gast (1. Okt 2007)

Leg doch zwei bilder Ã¼bereinander


----------



## Evil-Devil (1. Okt 2007)

Ich weiß zwar nicht was du für eine Hardware Basis hast, aber hier auf der Arbeit mit ner alten GF4 Ti 4200 läuft dein komplexes Beispiel mit konstanten 75fps.

Beim testen ist erst bei 400+ Partikeln eingebrochen.

Dabei war es egal ob ich "Use Points" aktiviert hatte oder nicht. Bei beidem hatte ich die selbe Anzahl an FPS in den meisten fällen. Beim 400+ Test war ein Unterschied von ~10fps.

Getest auf P4 2,4GHz, GF4 Ti 4200, 1GB RAM

//Edit: @blending: Alpha Blending. Was nutzt du denn zur Darstellung? J3D, J2D oder OpenGL?


----------



## LoN_Nemesis (1. Okt 2007)

Ich nutze Java2D, der Partikeleditor hingegen nutzt zur Darstellung OpenGL. Es kann sein, dass es dann gar nicht so geht wie ich mir wünsche.

Nochmal bezüglich der Framerate: Ich habe einen Core 2 Duo Prozessor und eine relativ neue ATI Grafikkarte. Bei mir läuft das geladene system.xml mit ~1500 Frames pro Sekunde, wenn ich jedoch die Option 'use points' aktiviere, dann bricht das auf 3 fps ein.

In meinem eigentlichen Spiel kommen Partikeleffekte nicht so exessiv zum Einsatz, es ist auf jeden Fall noch spielbar. Nur ich dachte halt bei einem Faktor von 500mal schneller lohnt es sich mal darüber nachzudenken - vor allem sieht dieses Ineinanderüberblenden noch besser aus.

Falls das aber mit Java2D nicht geht (wovon ich ausgehe), dann habe ich nur die Wahl auf irgendeine OpenGL Basis umzusteigen oder es so zu lassen.


----------



## Evil-Devil (1. Okt 2007)

Hast du deine Texturen die du darstellst bereits hardware beschleunigt?

Von ~1500 auf ~3? Das nenn ich krass....AA und AF hochgedreht?

//Edit: Hab VSync mal deaktiviert. Dann komm ich auf ~195 ohne "usePoints" und auf ~205 mit aktivierten UsePoints.

TripleBuffering ist deaktiviert, AF und AA sind anwendungsgesteuert und Textures auf Qualitity. Werd das zuhause nachher mal testen. Da hab ich auch eine Radeon.


----------



## LoN_Nemesis (1. Okt 2007)

Ich arbeite mit Double-Buffering, dabei ist der Backbuffer auf den ich male ein VolatileImage. Dadurch sollte er eigentlich hardware beschleunigt sein, wenn ich das recht verstehe.

AF und AA sind bei mir auch anwendungsgesteuert, VSync deaktiviert. Habs gerade nochmal mit einem anderen Partikeleffekt getestet, kommt ein ähnliches Ergebnis. Nach dem Laden 1700 Frames, mit Use Points auf 14 runter.

Bei dir hingegen ist das ja ganz anders, da wird es sogar noch schneller wenn du Use Points aktivierst? Hm sehr seltsam, vielleicht tatsächlich irgendwas Grafikkarten spezifisches.


----------



## Evil-Devil (1. Okt 2007)

Joar, PointSprites sollten eigentlich auch schneller sein, so wie ich die bisher immer verstanden hab.

Das mit der Hardwarebeschleunigung der Bilder geschieht schon bei der Erzeugung selbiger.

Hab mal nen Schnipsel aus nem bekannten Tutorial geliehen 

```
sourceImage = ImageIO.read(url);
// create an accelerated image of the right size to store our sprite in
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
Image image = gc.createCompatibleImage(sourceImage.getWidth(),sourceImage.getHeight(),Transparency.BITMASK);
```


----------



## LoN_Nemesis (1. Okt 2007)

Was sind denn PointSprites genau?

Also bei mir sind die einzelnen Partikel einfach geometrische Formen, die ich mit AWT auf den Bildschirm male.

Hier mal meine Partikel Klasse, wie man sieht hat ein Partikel einfach eine Farbe, Form und Größe und wird dann gezeichnet. Texturen habe ich momentan noch nicht zugelassen.


```
public class Particle {
	public final static int RECTANGLE = 1,
							ELLIPSE = 2,
							FULL_RECTANGLE = 3,
							FULL_ROUND_RECTANGLE = 4,
							FULL_ELLIPSE = 5;
	
	public boolean active, gradient;
	public int shape, lineThickness;
	public float posX, posY, horSpeed, verSpeed, sizeX, sizeY;
	public Color color, color2;
	public int alphaDecay;
	
	public void draw(Graphics2D g) {
		if (!active || sizeX<=0 || sizeY<=0) return;
		Stroke oldStroke = g.getStroke();
		g.setStroke(new BasicStroke(lineThickness));
		g.setColor(color);
		//g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
		if (gradient)
			g.setPaint(new RoundGradientPaint(posX+sizeX/2, posY+sizeY/2, color, new Point((int)sizeX/3+1,(int)sizeY/3+1), color2));
		if (shape==Particle.ELLIPSE)
			g.drawOval((int)posX, (int)posY, (int)sizeX, (int)sizeY);
		else if (shape==Particle.RECTANGLE)
			g.drawRect((int)posX, (int)posY, (int)sizeX, (int)sizeY);
		else if (shape==Particle.FULL_RECTANGLE)
			g.fillRect((int)posX, (int)posY, (int)sizeX, (int)sizeY);
		else if (shape==Particle.FULL_ROUND_RECTANGLE)
			g.fillRoundRect((int)posX, (int)posY, (int)sizeX, (int)sizeY, 10, 10);
		else if (shape==Particle.FULL_ELLIPSE)
			g.fillOval((int)posX, (int)posY, (int)sizeX, (int)sizeY);
		g.setStroke(oldStroke);
	}
	
	public Particle() {
		gradient = false;
		lineThickness = 1;
	}
	
}
```


----------



## Evil-Devil (1. Okt 2007)

PointSprites wirst du in J2D auch nicht finden. Die hast du nur unter DirectX und OpenGL. Und das funktioniert dann so, das du anstatt einen Quads (4 vertecies) nur einen Vertex übertragen musst um einen Partikel darstellen zu können. Textur kann man weiterhin benutzen, aber man muss nur einen Vertex übertragen. Den Rest macht die Grafikkarte ^^


----------

