开发者

OpenGL key frame animation - the best approach

开发者 https://www.devze.com 2022-12-14 21:20 出处:网络
I\'m trying to animate object. I use keyframe animation: I have two vertex buffers (two frames) with vertices of my object - first buffer is for object start state and second for end state. To transfo

I'm trying to animate object. I use keyframe animation: I have two vertex buffers (two frames) with vertices of my object - first buffer is for object start state and second for end state. To transform the object I simply use linear interpolation.

To make it more clear, please take a look at the code snippet:



FloatBuffer vertexBuffer_motion;
FloatBuffer  vertexBuffer_source, vertexBuffer_destination;
...
int indicesCount = mSphereFrame1.getVertexBuffer().capacity()
...
public void onDrawFrame(GL10 gl) {

   float percentDone = (float)timeSinceStartKeyFrame / (float)animationDuration;   
   //Calculate the new position of each vertex - this is done for each frame
   for (int i = 0; i < indicesCount; i++) {
      float diffIndice = vertexBuffer开发者_开发知识库_destination.get(i) - vertexBuffer_source.get(i);          
      vertexBuffer_motion.put( vertexBuffer_source.get(i) + (percentDone * diffIndice) );           
   }
   ...
   //draw the object
   gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer_motion);
   gl.glDrawElements(GL10.GL_TRIANGLES, mSphereFrame1.getElementsCount(),
                     GL10.GL_UNSIGNED_SHORT, mSphereFrame1.getIndexBuffer());
}

As you can see I actually use one more buffer. vertexBuffer_motion is the one I use to draw my object in intermediate state.

Time for my question.

What is the best approach for such keyframe animation on android? Can I somehow avoid (quite time consuming) operations of calculating and copying new state of all vertices to vertexBuffer_motion?

I know I could use VBO but still, I would have to prepare this vertexBuffer_motion and use glBufferData to set data to this VBO (or not?). Could someone provide me with some code example showing the best approach for keyframe animation on android?

Thanks for reading.


I'm assuming you're making a game, if you aren't ignore the bits about velocity and position, everything else applies.

You're going to have to calculate where to draw everything, there isn't really a shortcut around that.

However, as far as copying state goes, you need to approach the problem a little differently.

Each visible game object (Actor, Doodad, etc.) must maintain it's own state of where it is, where it is going, what frame of animation to show. The way I'm showing you here will also prevent temporal aliasing

As part of your game loop, you should first update each object by looping through them, passing them the delta time since the last update, and then each object should maintain a previous and current state. When asked to draw with a dt, that the time to do the linear interpolation between the two states, to create a drawable state.

When calculating the proper time, you should follow the guideline here. Yes, the article is about a integrating engine but the approach used will work with games without them, and will allow a game to downscale gracefully in environments where there isn't enough power to keep up as well as never to run too fast if the hardware changes under your feet.

Pseudo code:

Abstract Class GameObject {
     private State previous_state;
     private State current_state;
     private State draw_state;

     void Update(float dt) {
          previous_state = current_state.copy();
          current_state = current_state + dt;
     }
     void Draw(float dt) {
          draw_state = interpolate(previous_state, current_state, dt);
          //Do opengl commands to draw draw_state
     }
}

Then your game loop should look like:

void GameLoop() {
     while(1) {
          //Calculate dt here
          process_inputs();
          for {game_object in object_list} {
               game_object.Update(dt)
          }
          //...
          for {game_object in object_list} {
               game_object.Draw(dt)
          }
 }

Each State contains all the information needed to describe the object's position, velocity and animation frame. A simple State class might look like:

Class State {
     public float position_x;
     public float position_y;
     public float velocity_x;
     public float velocity_y;
     public int frame_number;
     public int max_frame;
     public float animation_duration;  //milliseconds
}

Subtracting two states should produce an intermediate state. Adding a time to a State should calculate the next position based on the velocity, as well as determine the next frame of animation.

0

精彩评论

暂无评论...
验证码 换一张
取 消