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