Flüssige Animation

Status
Nicht offen für weitere Antworten.

Wolfgang Lenhard

Bekanntes Mitglied
Hi,
ich habe für ein kleines Spiel eine kleine Animation mit Sound zu Beginn des Programmstarts. Der Einfachheit halber lade ich eine begrenzte Zahl an Bildern vorab in BufferedImages, und zeichne diese jeweils nach ca. 80 ms der Reihe nach auf ein JLabel. Die Bilder haben eine Größe von 700 * 500. Natürlich ruckelt es noch bei einem Intervall von 80 ms merklich. Das ist nicht so schlimm, da es nur ein kleines Intro sein soll. Was mich aber darüber hinaus wundert ist, dass die Prozessorlast relativ hoch ist. Sie liegt bei einem Core2 (Windows Vista) bei etwa 30 %.
Ist der Ansatz, den ich verfolge nicht gut gewählt? Wie macht man es besser?

Viele Grüße,
Wolfgang
 

0x7F800000

Top Contributor
ka... so rein theoretisch sollte man eine voxelige volumentextur mit den animationsschritten direkt in die grafikkarte laden und von der hardware dann durch die 2D-bildebene durchziehen lassen, das geht dann rasendschnell, ist beliebig fein interpolierbar, und belastet den prozessor zu 0 prozent, da alles ja dort stattfindet, wo es soll: in der grafikkarte.

praktisch kann ich dazu nicht viel empfehlen. Frage: wieso benutzst du JLabel? dieses objekt ist doch viel zu speziell und unnötig kompliziert, um drauf irgendwas rumzumalen...
 

muckelzwerg

Bekanntes Mitglied
Er meint, dass Du die Texturen in eine "3D-Textur" zusammenstapelst und dann von "hinten nach vorn" durchblätterst.

Aber wäre es nicht wesentlich einfacher die Animation in ein Videoformat zu schreiben und dann mit einem passenden Player abzuspielen? Da würde sich zum Bleistift das Java Media Framework anbieten.
Passende Tutorials findet Google.

-- -- muckelzwerg
 

0x7F800000

Top Contributor
Volumentexturen sind aber die_lösung für animierte Sprites. Ein Video lässt sich im gegenteil dazu nicht so leicht vom Frame zu Frame interpolieren. Aber wie gesagt: dafür bräuchte man ordentlichen zugriff auf die Grafikkarte, die sowas unterstützt, mit einer Ordentlichen API, da würde ich einfach anfangen das JOGL tutorial durchzulesen, wenn ich zeit hätte...
 

Fancy

Aktives Mitglied
Moin,

also wenn es JoGL sein darf und die Grafikkarte der Zielplattform das hergibt, sollte das relativ simpel sein:

Code:
package fancy.jf.texture;

import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.nio.FloatBuffer;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;

import com.sun.opengl.util.Animator;
import com.sun.opengl.util.BufferUtil;
import com.sun.opengl.util.FPSAnimator;
import com.sun.opengl.util.texture.TextureData;
import com.sun.opengl.util.texture.TextureIO;

public class Tex3D implements GLEventListener {
    
    // for full screen plane
    private static final float[] staticVertices = new float[] {
         1.0f,  1.0f, -1.0f, 
        -1.0f,  1.0f, -1.0f,   
        -1.0f, -1.0f, -1.0f,  
         1.0f,  1.0f, -1.0f, 
        -1.0f, -1.0f, -1.0f,  
         1.0f, -1.0f, -1.0f};
    
    // texture cords for full screen plane
    private static final float[] staticTexCord = new float[] {
         1.0f,  0.0f,  0.0f, 
         0.0f,  0.0f,  0.0f,  
         0.0f,  1.0f,  0.0f, 
         1.0f,  0.0f,  0.0f, 
         0.0f,  1.0f,  0.0f,   
         1.0f,  1.0f,  0.0f};

    
    private GL                   gl                  = null;

    private FloatBuffer          vertexArrayVertices = null;
    private FloatBuffer          vertexArrayTexture  = null;


    @Override
    public void init(GLAutoDrawable drawable) {

        gl = drawable.getGL();

        // setup vertex array
        vertexArrayVertices = BufferUtil.newFloatBuffer(staticVertices.length);
        vertexArrayVertices.put(staticVertices, 0, staticVertices.length);
        vertexArrayVertices.rewind();

        vertexArrayTexture = BufferUtil.newFloatBuffer(staticTexCord.length);
        vertexArrayTexture.put(staticTexCord, 0, staticTexCord.length);
        vertexArrayTexture.rewind();

        gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);

        // setup 3D texture
        final int[] handleTex3DBuffer = new int[1];
        gl.glGenTextures(1, handleTex3DBuffer, 0);
        final int handleTex3D = handleTex3DBuffer[0];

        gl.glBindTexture(GL.GL_TEXTURE_3D, handleTex3D);
        gl.glTexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
        gl.glTexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
        gl.glTexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
        gl.glTexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
        gl.glTexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_WRAP_R, GL.GL_REPEAT);

        try {
            final TextureData data = TextureIO.newTextureData(getClass().getResource("/3d.jpg"), false, null);
            gl.glTexImage3D(GL.GL_TEXTURE_3D, 0, GL.GL_RGB8, 500, 500, 10, 0, GL.GL_BGR, GL.GL_UNSIGNED_BYTE, data.getBuffer());
        } catch (final IOException e) {
            e.printStackTrace();
        }

        gl.glEnable(GL.GL_TEXTURE_3D);

    }


    @Override
    public void display(GLAutoDrawable drawable) {

        gl.glClear(GL.GL_COLOR_BUFFER_BIT);
        gl.glLoadIdentity();

        // walk through texture
        for (int i = 0; i < 6; i++)
            vertexArrayTexture.put(i * 3 + 2, vertexArrayTexture.get(i * 3 + 2) + 0.001f);

        // draw vertex array with current texture part
        gl.glTexCoordPointer(3, GL.GL_FLOAT, 0, vertexArrayTexture);
        gl.glVertexPointer(3, GL.GL_FLOAT, 0, vertexArrayVertices);
        gl.glDrawArrays(GL.GL_TRIANGLES, 0, staticVertices.length);

    }


    @Override
    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {

        if (height <= 0) height = 1;

        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();
    }


    @Override
    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {}


    public static void main(String[] args) {

        final Frame frame = new Frame();
        final GLCanvas canvas = new GLCanvas();
        final Animator animator = new FPSAnimator(canvas, 60, true);
        canvas.addGLEventListener(new Tex3D());
        frame.add(canvas);
        frame.setSize(500, 500);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                new Thread(new Runnable() {
                    public void run() {
                        animator.stop();
                        System.exit(0);
                    }
                }).start();
            }
        });
        frame.setVisible(true);
        animator.start();
    }

}

Für das Eingangsformat ist Zeile 77 – 78 maßgeblich. Alle Frames werden als eine große Bilddatei geladen, dazu müssen die einzelnen Frames untereinander angeordnet werden. Das Beispiel oben erwartet eine Auflösung von 500 x 500 Pixel pro Frame bei 10 Frames, dementsprechend muss in diesem Fall die geladene Bilddatei 500 x 5000 Pixel groß sein.

Die 0.001f in Zeile 96 gibt an wie schnell durch den Bildstapel geblendet werden soll.

Der Rest ist JoGL Standart.

Gruß,
Michael
 

Wolfgang Lenhard

Bekanntes Mitglied
Vielen Dank für die Postings. Das hilft mir sehr weiter.

Ok, noch eine Frage in Bezug auf das Code-Beispiel: Wie bekomme ich die 10 Bilder in das TextureData-Object?
 

muckelzwerg

Bekanntes Mitglied
Bei glTexImage3d gibst Du das Bild als einfache DataBuffer an.
"data.getBuffer()".
Den Buffer kannst Du mit seinen eigenen Methoden auch selbst füllen, anstatt ihn direkt aus einem einzelnen Bild zu erzeugen.
Du kannst also die Bilder einzeln laden, und dann in einen Buffer zusammenkopieren, wenn Du sie nicht in einem Bild speichern willst.
Ist dann auch etwas angenehmer und flexibler.

-- -- muckelzwerg
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Flüssige Bewegung Spiele- und Multimedia-Programmierung 7
G Flüssige Bewegungen Spiele- und Multimedia-Programmierung 7
H Minecraft Casino EinarmigerBandit Animation Spiele- und Multimedia-Programmierung 5
B Animation Spiele- und Multimedia-Programmierung 4
Meeresgott Morph Targets und Skeleton Animation Spiele- und Multimedia-Programmierung 2
J (Libgdx) animation nur einmal in einem Event aufrufen Spiele- und Multimedia-Programmierung 1
N Animation funktioniert icht wie sie soll Spiele- und Multimedia-Programmierung 10
K Animation fliegendes JLabel Spiele- und Multimedia-Programmierung 1
R [LWJGL] Skeletal Animation Spiele- und Multimedia-Programmierung 5
F [LWJGL] Skeletal Animation 3D Spiele- und Multimedia-Programmierung 1
R Animation mit Interpolator starten wenn Key pressed Spiele- und Multimedia-Programmierung 0
kaoZ Animation in eigenen Thread auslagern..... Spiele- und Multimedia-Programmierung 1
S Animation zieht "Spur" hinter sich her Spiele- und Multimedia-Programmierung 2
H [ANIMATION] Hintergrundbild nur einmal zeichnen Spiele- und Multimedia-Programmierung 3
A LwJGL - Animation Stockt Spiele- und Multimedia-Programmierung 5
0 Sprung Animation Spiele- und Multimedia-Programmierung 10
M [Java3D] Animation von mehreren Objekten Spiele- und Multimedia-Programmierung 7
C Java3D Interaktion während Animation Spiele- und Multimedia-Programmierung 3
StrikeTom .gif animation als image abspielen Spiele- und Multimedia-Programmierung 2
G [Java3D] Probleme bei Animation Spiele- und Multimedia-Programmierung 4
baddestpoet Animation startet bei gedrückter Taste immer wieder von vorn Spiele- und Multimedia-Programmierung 12
M Animation Spiele- und Multimedia-Programmierung 5
aze Animation an TransformGroup anpassen Spiele- und Multimedia-Programmierung 5
S Animation mit repaint Spiele- und Multimedia-Programmierung 2
K "Animation" funktioniert nur bedingt. Spiele- und Multimedia-Programmierung 8
B Animation durch Button auslösen Spiele- und Multimedia-Programmierung 2
J Animation hinter transparentem Bild auf der GlassPane Spiele- und Multimedia-Programmierung 6
D Problem mit Animation bei Little Fighter Spiele- und Multimedia-Programmierung 5
R Double Buffering in Animation ich bekomms einfach nicht hin? Spiele- und Multimedia-Programmierung 3
G GL4Java Animation erstellen Spiele- und Multimedia-Programmierung 2
T Geschwindigkeit einer Animation aendern Spiele- und Multimedia-Programmierung 6
S 3ds animation einbinden Spiele- und Multimedia-Programmierung 3
A Animation mit jmonkeyengine Spiele- und Multimedia-Programmierung 10
S Gif Animation aus Prog heraus erstellen Spiele- und Multimedia-Programmierung 11

Ähnliche Java Themen


Oben