Du bist nicht angemeldet.

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

1

07.08.2013, 10:59

[OpenGL] Keyframes

Hi, ich bin recht neu im 3D-Bereich und habe erste Erfahrungen mit Umgamg mit OpenGL - eingebettet in eine SDL-Anwendung - gesammelt. Aktuell überlege ich, wie ich Keyframes intern speichern will. Das Prinzip ist mir klar: zu jeder Vertex jeder Face des Meshs gibt es neue Koordinaten, die quasi Zwischenschritte der Animation darstellen - zwischen diesen kann ich dann mittels Interpolation Zwischenpunkte ermitteln, damit die Animation kontinuierlich wirkt. Allerdings bin ich mir über die Speicherung der Keyframe-Daten in internen Datenstrukturen noch nicht ganz sicher.

Meine bisherige Idee: Ich erfasse jeden Mesh mit einer Instanz einer Mesh-Klasse. Diese Klasse enthält dann die Faces und zugehörigen Vertices (Ausgangspunkt der Animation). Diese kann ich mittels OpenGL im VBO speichern, so dass ich das Objekt schnell zeichnen kann. Für die Animation bräuchte ich nun für jeden Keyframe wieder einen solche Mesh, da sich ja (i.d.R.) alle (oder fast alle) Vertices verändert haben.

Speichere ich da pro Mesh mehrere Meshs in VBOs? Wenn ja, muss ich die interpolierten Vertices ebenfalls dort speichern. Das erscheint mir irgendwie überzogen.
Die andere Idee (die bisher nur geometrisch überlegt ist) wäre, für jeden Keyframe die Verschiebung, Skalierung und Rotationen zu berechnen. Den "Grund"-Mesh würde ich dann beim Zeichnen entsprechend bewegen. Jedoch klingt das (gerade die Berechnung der Bewegungen) nach ziemlich viel Arbeit.

Was würdet ihr mir empfehlen? Eine fertige Engine möchte ich (noch) nicht verwenden.

LG Glocke

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

2

07.08.2013, 11:57

Soweit ich weiß verfolgt MD2 aus Quake einen ähnlichen Ansatz. Vielleicht gibt dir das ein paar hilfreiche Tipps.

P.S.: In welcher Band spielst du denn? ;)

LukasBanana

Alter Hase

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

3

07.08.2013, 13:11

Also alleine das Speichern aller Keyframes in VBOs wird nicht langen. Denn da fehlt ja noch die Interpolation zwischen den Frames.
Ich nehme mal an, dass du das interpolieren willst, weil nur die einzelnen Frames zu rendern sähe ziemlich abgehackt aus. Andernfalls bräuchtest du mehrere tausend solcher Frames
um eine flüssige Animation zu erzielen.

Diese Animation nennt sich übrigens MorphTarget-Animation und wurd u.A. in Quake 1 bis Quake III Arena verwendet.
Heutzutage verwendet man sowas eher für Facial-Animation. Alles andere wird wohl eher mit Skeletal-Animation gemacht.

Zu deinem Problem: Da gibt's natürlich wieder viele Möglichkeiten.
Eine wäre folgende: Du speichert alle Instanzen der Frames nur als eine Liste von Vertices (bzw. nur deren Koordinaten und Normalen).
z.B. so:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
sturct FrameInstance
{
    float coord[3];
    float normal[3];
};
struct AnimatedMesh
{
    std::vector<FrameInstance> Frames;
};

Du könntest dann, immer wenn ein frame zu ende interpoliert wurde, den aktuellen VBO aktuallisieren in dem du für jeden Vertex die Koordinate und Normale für den neuen Start und End-Frame speicherst (z.B. speichert man sowas in den Texture Koordinaten).
Im Shader (falls du das schon nutzen kannst) kannst du die finale Vertex Koordinate dann zwischen diesen beiden Frames interpolieren.

Falls du noch nichts mit Shadern zu tun hast, kannst du das interpolieren auch auf der CPU machen und in jedem Bild das zu renderst, den VBO aktuallisieren.
Ist natürlich deutlich langsamer, aber das wäre eine weitere Möglichkeit.

Ansonsten wäre das eine gute Gelegenheit gleich mal mit Shadern anzufnagen :-D

Hier mal ein Beispiel zu einer solchen Animation (Normalen Vektor zur Vereinfachung weggelassen):

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// GLSL Vertex Shader:

#version 410

layout (std140) uniform MainUniforms
{
    mat4 WVPMatrix;
    float Interpolation; // Sollte im Bereich [0 .. 1) sein
};

in vec3 CoordA; // Koordinate des ersten Frames
in vec3 CoordB; // Koordinate des zweiten Frames

void main()
{
    vec3 Coord = mix(CoordA, CoordB, Interpolation);
    
    gl_Position = WVPMatrix * Coord;
}


Oder mit etwas älterem OpenGL:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
#version 120

uniform float Interpolation;

void main()
{
    vec3 Coord = mix(gl_TexCoord[0].xyz, gl_TexCoord[1].xyz, Interpolation);
    
    gl_Position = gl_ModelViewProjectionMatrix * Coord;
}


Gruß,
Lukas

4

08.08.2013, 11:25

P.S.: In welcher Band spielst du denn? ;)


Siehe Signatur xD

Also alleine das Speichern aller Keyframes in VBOs wird nicht langen. Denn da fehlt ja noch die Interpolation zwischen den Frames.
Ich nehme mal an, dass du das interpolieren willst, weil nur die einzelnen Frames zu rendern sähe ziemlich abgehackt aus. Andernfalls bräuchtest du mehrere tausend solcher Frames
um eine flüssige Animation zu erzielen.


Ja genau :)

Zu deinem Problem: Da gibt's natürlich wieder viele Möglichkeiten.
Eine wäre folgende: Du speichert alle Instanzen der Frames nur als eine Liste von Vertices (bzw. nur deren Koordinaten und Normalen).
z.B. so:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
sturct FrameInstance
{
    float coord[3];
    float normal[3];
};
struct AnimatedMesh
{
    std::vector<FrameInstance> Frames;
};

Du könntest dann, immer wenn ein frame zu ende interpoliert wurde, den aktuellen VBO aktuallisieren in dem du für jeden Vertex die Koordinate und Normale für den neuen Start und End-Frame speicherst (z.B. speichert man sowas in den Texture Koordinaten).


Hmm okay - klingt gut :)


Im Shader (falls du das schon nutzen kannst) kannst du die finale Vertex Koordinate dann zwischen diesen beiden Frames interpolieren.


Mit Shadern habe ich noch nicht gearbeitet --> denk ich mir erstmal weg ^^

LG Glocke

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

5

08.08.2013, 11:45

.... Wer lesen kann ist klar im Vorteil... :D

Werbeanzeige