user717572
user717572

Reputation: 3652

Implementing Animations in OpenGL

I'm having a hard time thinking out a way to implement tween-like animations, like for example move to currentX+3, where you only put in deltaX, and the rest gets interpolated. What i've got for now:

drawing/opengl thread, which keeps track of the drawing time and handles framerate:

public void onDrawFrame(GL10 gl) {

    endingTime = System.currentTimeMillis();
    int timeElapsed = (int) (endingTime - startingTime);

    if (timeElapsed < FRAMEDURATION_MILISEC) {
        try {
            Thread.sleep(FRAMEDURATION_MILISEC - timeElapsed);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    startingTime = System.currentTimeMillis();
    Game.renderGame(gl);
}

And a logic thread, which animate by changing GameObjects' x and y values:

static long RATE = 30l; // times
static long duration = 1000l / RATE;

public void run() {
    lastUpdate = System.currentTimeMillis();

    long dur = duration; // copy

    while (Game.running) {

        long tElapsed = System.currentTimeMillis() - lastUpdate;

        if (tElapsed >= dur) {
            lastUpdate = System.currentTimeMillis();
            Game.updateGame(tElapsed);
        } else {
            try {
                GameLogicThread.sleep(dur - tElapsed);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

I wanted to implement an Animation class where I could for example set a difference in x for an GameObject, and apply this Animation object to the GameObject, so that the position gets updated, in either the drawing, or the logic loop.

I don't know where I should do this, or how to keep a kinda clean structure in all. Could anyone help me?


EDIT:

Thanks, I now made an GLAnimation class, to which you can pass dX, dY, dRotation, dScale etc. It then calculates the speed, which the object has to be changed PER milisecond. This Animation object call by applied TO an GameObject, so the update and render calls can pass timeElapsed to move the object. Thanks zmccord!

Upvotes: 0

Views: 676

Answers (1)

zmccord
zmccord

Reputation: 2612

So, essentially the situation you're talking about right now is one where you have a physics thread ("logic thread") and a graphics thread. I think the first question you want to ask yourself is whether it's worth splitting those into separate threads; is your logic/physics actually computationally intensive enough to have a negative effect on your framerate? For a simple game you will save bugs and effort keeping them together in one loop. The code should definitely be factored apart with different files for each category of functionality, but they can both run on the same thread (step logic once, draw, repeat).

One reason to go to a single-threaded approach is looks right now like your physics is running at as high a rate as possible, which isn't actually a good idea; you'll burn lots of power for small precision increases --- possibly precision decreases, depending on what your game code looks like. There's not a whole lot of point to your physics framerate being way higher than your graphics framerate unless your physics is really complicated and needs high precision.

I like your Animation object idea; how you do that is going to depend a lot on what GameObjects can contain or what your Animation object is likely to want to change. I would suggest writing your GameObject to conform to a protocol that the Animation object can use to mutate it; if you're in C++ the easiest way to achieve that is to have all GameObjects inherit from a root GameObject class. Then your Animation objects can contain information on how to modify the GameObject.

If we're in C++, I would suggest:

root GameObject class methods:

  • set/get position
  • set/get orientation
  • set/get whatever other state game objects have; size? color? velocity?

root Animation class is a virtual with one (virtual) method:

  • apply animation to object

Then subclass the Animation root class to do individual animations e.g. AnimationTranslate could add an offset to the position and angle of the object, or AnimationScale could change the size, or AnimationGravity could accelerate the object toward the bottom of the screen.

Similar designs could be done in any object-oriented language. You could also pull it off in straight C with a bit of leg-work; if you did that you'd probably want to go for the trick of putting function pointer members into your structures. If you're using a language with sum types, you can use sum types instead of an inheritance hierarchy for Animation; same idea applies.

Upvotes: 2

Related Questions