Ein Objekt beliebig oft rendern / Spriteanimation

Started by Thunderfox, July 21, 2011, 09:15:25 PM

Previous topic - Next topic

Thunderfox

Hallo,

mein Anliegen hier einmal auf Deutsch, da ich dies auf Englisch nur schwer erklären könnte:

Für das Android Game, an welches ich arbeite, benötige ich verschiedene Effekte, die allerdings nur auf einer 2D-Ebene im Game gezeigt werden sollen, bsp. Feuerkugeln, Lichter etc..
Pro Effekt wollte ich dafür eine halbtransparente PNG benutzen, die um die 16-64 verschiedene Bildsequenzen enthält. Beispielsweise eine 512x512 PNG, die 64 Animationsabschnitte in der Größe von 64x64 Pixel enthält und diese auf ein Viereck in einer Schleife abspielt.
Das erste Problem hieran ist, dass diese Animationen nach wenigen Sekunden wieder verschwinden sollen und viele parallel ablaufen können müssen. Es wäre hier also etwas unschön, für jede Animation ein neues Objekt zu erstellen bzw. es zu kopieren und dann nach wenigen Sekunden wieder zu löschen. Kann man ein Objekt in der Form, wie man es bei OpenGL kann, mehrfach rendern oder gibt es eine Möglichkeit, in der onDrawFrame vielleicht selbst mit OpenGL kommunizieren zu können und das Ergebnis in den Framebuffer schreiben zu können (ähnlich wie die blit-Funktionen bei GLFont)(ohne Probleme mit dem Z-Buffer zu bekommen)? Das zweite Problem: Wie kann ich auf diesen Vierecken eine Animation aus dieser PNG abspielen?

Als ich die Render-Klasse noch auf OpenGL-Basis programmiert habe, habe ich hierfür ein Objekt erstellt, welches aus so vielen Rechtecken (also jeweils 2 Dreiecke) bestand, wie die Animation lang ist. Alle Rechtecke lagen hier übereinander, auf jedem Rechteck wurde ein anderer Teil der Textur gemappt und je nach Fortschritt der Animation habe ich über die glDrawArrays(GL10.GL_TRIANGLES, offset, vertices); nur ein bestimmtes Rechteck gezeichnet, indem ich "offset" und "vertices" des aktuellen Animationsbildes bestimmte.
Außerdem konnte ich das Objekt bei der gleichen Anzahl an Animationen mit einer anderen Textur ohne Probleme ein zweites mal rendern, ohne gleich ein neues Objekt erstellen zu müssen.

Gibt es in dieser Engine eventuell eine ähnliche Funktion, die dies macht, welche ich noch nicht entdeckt habe?

Viele Grüße,

Thunderfox.

EgonOlsen

Also du könntest im Prinzip mit OpenGL direkt arbeiten...aber dann brauchst du die Engine eigentlich ja nicht. Du könntest auch so ein Zwischending machen, d.h. ein Objekt erstellen und es über eine Implementierung von IRenderHook mehrfach zeichnen lassen...dabei müsstest du aber die Transformationen wieder über OpenGL leisten...klingt für mich hakelig.

Ich persönlich würde ruhig mit Einzelobjekten arbeiten. Die muss man ja nicht immer neu erzeugen, sondern kann sie aus einem einfachen Pool holen (also quasi 100 Objekte vorgenerieren und immer dann eines aus dem Pool holen, wenn es Not tut...danach wieder zurück in den Pool). Das ist nicht ganz so performant, aber sollte kein Problem sein. Selbst meine Partikelsystem habe ich immer so realisiert...war nie ein Problem. jPCT (und auch -AE) ist optimiert dafür, den Overhead im Rahmen zu halten. Die Animation würde ich nicht über Einzelobjekte abbilden, sondern entweder über den PolygonManager die uv-Koordinaten "animieren" und damit immer den aktuellen Stand auswählen oder mit einer Matrix arbeiten, die die Translation über die Textur erledigt (http://www.jpct.net/jpct-ae/doc/com/threed/jpct/Object3D.html#setTextureMatrix(com.threed.jpct.Matrix)). Das ist schneller, funktioniert aber auf ganz ollen Telefonen nicht so gut (jedenfalls nicht auf dem ersten Samsung Galaxy). Ein Beispiel für die erste Lösung (allerdings für Desktop-jPCT) findest du in den Quellen von Robombs (http://jpct.de/download/robombs_src.zip) in der Datei Explosion.java in setTexture(...).

Thunderfox

Die Rechtecke (jeweils zwei Dreiecke) der Animation habe ich auch in nur einem Floatbuffer definiert und über diese Rechtecke (Dreiecke) dann die Textur. Wenn man diesen Floatbuffer als ein Objekt bezeichnen kann, war dieses also auch nur eins.
Anstatt die Textur zu verschieben habe ich also immer nur ein paar Vertices aus dem Floatbuffer gezeichnet und das funktionierte problemlos auf mein Samsung Galaxy S3 I5800 und war trotz allem performant, da ja schließlich immer nur 2 Dreiecke des Objekts gezeichnet wurden und nur zwei Floatbuffer (für Vertices und Texturekoordinaten) existierte.

Die Engine finde ich sonst aber vor allem im Bereich der Objekt-Animationen und der Performance besser.

Ich werde mal mehrere Möglichkeiten, unter anderem die vorgeschlagenen Möglichkeiten, durchprobieren und dann einmach kurz ergänzen, wie ich das Problem für mich gelöst habe ;)

EgonOlsen

Wenn das alles auf eine einzigen Ebene abläuft, könntest du auch einfach die blit-Methoden in FrameBuffer dafür nehmen.