Author Topic: Animation using OpenGL  (Read 18430 times)

Alhexx

  • *
  • Posts: 1894
    • View Profile
    • http://www.alhexx.com
Animation using OpenGL
« on: 2005-10-18 21:50:26 »
Okay, I'm currently writing a new model viewer. It already supports most basic functions for viewing a model. However, I have never programmed animation before :erm:

As far as I know, animation is rendered using a timer, which forces the engine to rerender the image a few times per second (let's say 24).

Moving objects is done using glRotate, glTranslate and glScale functions. However, I'm using these functions to move the camera.


Now let's say I wanted to make a sphere rolling along th x-axis. Using the 3 commands above would not really move the object, but it would move my camera...
And this gets more complicated when I have more than one object which is moving indepentently from the other objects (like a whole skeleton).

How do I do this?

 - Alhexx

alloy

  • *
  • Posts: 57
    • View Profile
Animation using OpenGL
« Reply #1 on: 2005-10-19 01:50:07 »
http://nehe.gamedev.net/ Best tutorial website for open gl...sorry i cant directly help you with the rpograming but this is the best i can do  :-?

Cyberman

  • *
  • Posts: 1572
    • View Profile
Animation using OpenGL
« Reply #2 on: 2005-10-19 06:06:23 »
Alhexx -- read the red book for OpenGL programing. Most people recomend NOT using Nehe's tutorials who do professional developement. The reason I've had difficulties for so long with my OpenGL code is because I used Nehe's tutorials originally. Just read the Red book for OpenGL is my suggestion.

Animation is very simple actually.

1) Update frame information (IE all your rotation translation and scale information)
2) Call your Paint method or invalidate the paint window and let the paint function be called.
3) goto 1

That's pretty much it. Your paint method should draw all the information for each frame when needed.

Also if you need help got to Efnet's #opengl and ask nicely there. YES they will ask you if you have read the redbook :D

Cyb

mirex

  • *
  • Posts: 1645
    • View Profile
    • http://mirex.mypage.sk
Animation using OpenGL
« Reply #3 on: 2005-10-19 09:23:23 »
Nehe's tutorials are quite good IMO.

Few things ... first if you draw on timer you should check if you have already ended drawing on last frame ... because sometimes drawing can take you more than 1/24 of second.

Then some animations are easy, because each frame is set of vertice positions. So you only render model with new vertex data.
Some animations are tougher, because they are done by bone rotations.
Some are even tougher because they are done by bone rotations and bone-vertex weight maps.

I don't remember the OpenGl code too much though, but maybe this will give you some idea, it is code from Leviathan to display bones from the model:

Code: [Select]
void CF7BwDlg::GlDisplayBoneChildren( int bone_parent )
{
   int    b;
   float   f;

   for( b=0; b<skelet.bones; b++ )
      if (( skelet.bone[ b ].parent == bone_parent ) &&
         ( skelet.bone[ b ].displayed == false )) {

         glPushMatrix();

         glRotatef( skelet.bone[ b ].roty, 0.0f, 1.0f, 0.0f );
         glRotatef( skelet.bone[ b ].rotx, 1.0f, 0.0f, 0.0f );
         glRotatef( skelet.bone[ b ].rotz, 0.0f, 0.0f, 1.0f );

           //displaying skeleton

            glBegin( GL_TRIANGLES );

            f = skelet.bone[ b ].length / 10;
            glColor3f( 1.0f, 0.8f, 0.8f );
            glVertex3f(  f, 0.0f, 0.0f );
            glColor3f( 0.8f, 1.0f, 0.8f );
            glVertex3f( -f, 0.0f, 0.0f );
            glColor3f( 1.0f, 1.0f, 1.0f );
            glVertex3f( 0.0f, 0.0f, skelet.bone[ b ].length );

            glColor3f( 0.8f, 1.0f, 0.8f );
            glVertex3f( -f, 0.0f, 0.0f );
            glColor3f( 0.8f, 0.8f, 1.0f );
            glVertex3f( 0.0f, f, 0.0f );
            glColor3f( 1.0f, 1.0f, 1.0f );
            glVertex3f( 0.0f, 0.0f, skelet.bone[ b ].length );

            glColor3f( 0.8f, 0.8f, 1.0f );
            glVertex3f( 0.0f, f, 0.0f );
            glColor3f( 1.0f, 0.8f, 0.8f );
            glVertex3f( f, 0.0f, 0.0f );
            glColor3f( 1.0f, 1.0f, 1.0f );
            glVertex3f( 0.0f, 0.0f, skelet.bone[ b ].length );

            glEnd();
 
         skelet.bone[ b ].displayed = true;

         glTranslatef( 0.0f, 0.0f, skelet.bone[ b ].length );

         GlDisplayBoneChildren( b );

         glPopMatrix();
      }

}

ficedula

  • *
  • Posts: 2178
    • View Profile
    • http://www.ficedula.co.uk
Re: Animation using OpenGL
« Reply #4 on: 2005-10-19 17:08:55 »
Quote from: Alhexx
Now let's say I wanted to make a sphere rolling along th x-axis. Using the 3 commands above would not really move the object, but it would move my camera...


Philosophical question: What is the difference between moving an object, or moving the rest of the world and leaving that object alone? :P

The way to position/rotate/scale multiple objects is to use glPushMatrix() and glPopMatrix(); they push/pop the current matrix onto a stack. Think of PushMatrix as 'saving' your current position and PopMatrix returning to the old version. Of course, you can (usually) nest calls successfully.

Eg:
//set up camera etc.
glPushMatrix(); //save current position
glTranslatef(...) //move object
glScalef(...) //scale object
DrawSomeObject; //draw the object
glPopMatrix(); //restore old position/scale now we've finished with object
glPushMatrix(); //save position again
glTranslatef(...); //move second object
DrawSomeOtherObject;
glPopMatrix(); //restore position again

Micky

  • *
  • Posts: 300
    • View Profile
Animation using OpenGL
« Reply #5 on: 2005-10-19 20:53:00 »
I don't bother with all the pushmatrix/popmatrix stuff. I render the world without any tranformation, and each object sets the transform that it needs relative to the world. That is of course only one of the million ways to do this...
Each object stores a vector for the position and a quaternion for the orientation, which I convert into a matrix to set with glLoadMatrix.
For animation I'm using using the same thing cyberman suggested. One thing you may have to decide is if you want your rendering synchronised to VBlank change. You'll have to look up how to set this up for your OpenGL version, I only know how to do that for MacOS/X.
Then you'll have to decide how you want the animation to work. You could keyframe your animation in a modelling application (like Maya, 3DS, Blender, Softimage, etc.), export the curves and play them back on your model. Or you could write a simple physics solution that updates the position from velocity and acceleration. So if you want to move your sphere alone the X axis with a constant speed you'd just add a vector to your position each frame. You could multiply this vector by the time it takes to render each frame, to get a constant speed independent from the framerate, etc, etc... We are getting more and more into engine territory.... :)

L. Spiro

  • *
  • Posts: 797
    • View Profile
    • http://www.memoryhacking.com/index.php
Animation using OpenGL
« Reply #6 on: 2005-10-20 02:47:56 »
Just a head’s up (to all of you).
Microsoft® is doing its best to deprecate OpenGL®.

http://www.theinquirer.net/?article=25215

You may want to drop OpenGL®.
But who knows how this war will end?

Call toll free: 1-800-888-8878


L. Spiro

Alhexx

  • *
  • Posts: 1894
    • View Profile
    • http://www.alhexx.com
Animation using OpenGL
« Reply #7 on: 2005-10-20 10:56:46 »
alloy: My basic code for OpenGL setup is a mixture of NeHe's code and code taken from other tutorials.

Cyberman: Yeah, that's the basic way. So far I understand that.

Quote from: mirex
Then some animations are easy, because each frame is set of vertice positions. So you only render model with new vertex data.

IIRC, that's the way Quake 3's MD3 models work - that's quite easy.

Quote from: mirex
Some animations are tougher, because they are done by bone rotations.

That's exactly what I wanted to know - bone animations.

Quote from: ficedula
Philosophical question: What is the difference between moving an object, or moving the rest of the world and leaving that object alone?

Okay, that was a bad example.
But if I have two independent object, which are moving differently in the world? I cannot move the world around the two objects then - I have to move the two objects independently.

Quote from: ficedula
The way to position/rotate/scale multiple objects is to use glPushMatrix() and glPopMatrix(); they push/pop the current matrix onto a stack. Think of PushMatrix as 'saving' your current position and PopMatrix returning to the old version. Of course, you can (usually) nest calls successfully.


That's what I wanted to know. In that case, if I understand that correctly, I first save the world's current position etc., then I move the world around  object a, then I restore the world and move it around object b then. Okay.

So if I have a model animated using a skeleton, then I simply move, rotate and scale the root bone, save its pos etc., then I draw all vertices which belong to the root bone. After that, I calculate the new pos etc for the first child bone, then draw its vertices, then I restore the root (or parent) bone's stats again, and continue with the second child...
Is that right?

 - Alhexx

Cyberman

  • *
  • Posts: 1572
    • View Profile
Animation using OpenGL
« Reply #8 on: 2005-10-20 15:58:43 »
Quote from: L. Spiro
Just a head’s up (to all of you).
Microsoft® is doing its best to deprecate OpenGL®.

http://www.theinquirer.net/?article=25215

You may want to drop OpenGL®.
But who knows how this war will end?

Call toll free: 1-800-888-8878


L. Spiro

Yes What MS is doing is bordering on what they got sued for by the US government. They are rolling DX into the OS <--- gee is this something new? Someone was saying 'this is great' yada yada on the opengl forum. I guess some people will believe anything they are told.

back to the subject though. I forgot about the issue of long draw times.  You may want to use a static semaphor in the paint function that is set in case the paint method gets invoked while it's still painting. I am assuming you are going to be using a seperate thread for OpenGL command issuing though :D. You may consider droping updates (skip) if your paint times bump into each other.

Sadly I have to redo my OpenGL code again for FF7's models for the playstation.  This time I think I'll start from scratch and use the RedBooks advice.

Cyb

L. Spiro

  • *
  • Posts: 797
    • View Profile
    • http://www.memoryhacking.com/index.php
Animation using OpenGL
« Reply #9 on: 2005-10-20 15:59:30 »
Quote
So if I have a model animated using a skeleton, then I simply move, rotate and scale the root bone, save its pos etc., then I draw all vertices which belong to the root bone. After that, I calculate the new pos etc for the first child bone, then draw its vertices, then I restore the root (or parent) bone's stats again, and continue with the second child...
Is that right?

Almost.
You are right about how to traverse the skeleton.  Recursive calls to walk down each bone.
And along the way, you push/pop the rotation stack and rotate by the correct amount.
And yes, you want to save its position at this point—that is, save all the matrix data for this bone at this point.
The thing you would want to reconsider is your drawing.
It is not convention to mix drawing with bone attachment or animation applications.
Aside from convention, there are other reasons you want to separate your drawing and bone attaching.
Firstly, collision detection.
In a normal game engine, you would handle input, run some physics to determine the current status of the player, based on the status you would attach the correct animation to the models, then you would handle model interactions.  This involves determining if a bullet is hitting your player, and other things along that line.
You have to do this after you attach the skeleton for obvious reasons.

Drawing always comes last and it should always be its own routine, completely secluded from everything else.
The data needed to draw the scene should already be created and ready to use.
This not only gives you a more organized game flow (organization is always important), but also allows you to combine more complicated render states without having to worry about when the drawing of certain objects will take place.

For example, when an enemy in Final Fantasy® VII dies, we all know it becomes red and see-through.  There are also other render states that could be applied to enemies at various times during your game.
If you check for all these states while attaching bones, your code will become cluttered and unmanageable.
Furthermore, you would literally be forcing yourself to draw each object at what would be random points throughout a frame and placing specific limitations on the capabilities of your engine.



For each bone, save the final “world” rotation.
At the end of your frame, make a single pass through each model and use that saved world rotation to draw.
The rendering routine should not do anything but what it says: Render.


L. Spiro

ficedula

  • *
  • Posts: 2178
    • View Profile
    • http://www.ficedula.co.uk
Animation using OpenGL
« Reply #10 on: 2005-10-20 17:11:41 »
Speaking of people believing anything they're told, it should be pointed out that the Inquirer link is not what I'd call unbiased; the actual situation at the moment is that;

-Microsoft are providing a default OpenGL implementation with Vista which works by emulating OpenGL via DirectX. It emulates GL v1.4 which is currently far better than the default implementation you get with any other version of Windows (v1.1 software only).

-You can still use a normal OpenGL ICD (driver module, if you like) on Vista, it'll just temporarily disable the shiny Vista effects. Which aren't visible in full screen mode, anyway.

-If the driver vendors develop Vista-specific OpenGL drivers then they could work normal OpenGL without disabling the Shiny Vista Effects. This hasn't happened yet because Vista's driver models aren't, as I understand it, finalised anyway. It is, after all, still in beta.

Summary: OpenGL doesn't work flawlessly on the beta version of Vista. Shock result. Hundreds of news sites take this as a cue to say "OMG Microsoft is teh sux!".

Microsoft's hardly rolling DX into the OS; how many years has it been since DirectX came with Windows anyway? I'm pretty sure Win98 came with it. The only difference is now they're going to use DX to accelerate the normal shell as well as games & 3D applications, and you'll need new drivers to use OpenGL at the same time as the new special effects.


On the subject of animation: I would agree that rendering shouldn't be done at the same time as physics, but not because it makes your code disorganised; that depends on, er, how you organise your code. It's quite possible to write a well-structured object based approach that does the two things at the same time. The real issue is that when you have hardware T&L (like always nowadays), the hardware (should be) doing the matrix multiplications for you, and it's hideously expensive to try and get the finished data back off the video card. So you don't gain anything by transforming the data 'once' rather than twice, it gets transformed twice anyway: once by you for your purposes, and once by the hardware for its purposes.

Alhexx

  • *
  • Posts: 1894
    • View Profile
    • http://www.alhexx.com
Animation using OpenGL
« Reply #11 on: 2005-10-20 17:49:43 »
L. Spiro & fice:

Thanx, now I have the chance give it another try.

Btw, I'm not trying to write a game engine (yet), so fortunately I do not have to care about physics or a "world" in that meaning, since the world will be empty except for the model(s) that have to be rendered.

So if I under stand correctly:

0. I go recursively through the whole skeleton
1. At each bone I compute the current rotation(, scalation) and translation and push them onto the stack.
2. After all bones have been processed, I start drawing:
3. I go through the whole skeleton again
4. At each bone, I pop the translation and rotation from the stack
5. I draw all vertices (or polygons) which belong to the bone I currently am at...

...is that (more or less) correct now?

 - Alhexx

Cyberman

  • *
  • Posts: 1572
    • View Profile
Animation using OpenGL
« Reply #12 on: 2005-10-20 18:31:11 »
Quote from: ficedula
Speaking of people believing anything they're told, it should be pointed out that the Inquirer link is not what I'd call unbiased; the actual situation at the moment is that;
LOL :D

Quote from: ficedula
-Microsoft are providing a default OpenGL implementation with Vista which works by emulating OpenGL via DirectX. It emulates GL v1.4 which is currently far better than the default implementation you get with any other version of Windows (v1.1 software only).

Hmmm I heard this, Eweek was discussing this a bit.

Quote from: ficedula
-You can still use a normal OpenGL ICD (driver module, if you like) on Vista, it'll just temporarily disable the shiny Vista effects. Which aren't visible in full screen mode, anyway.
This seems to be a sticky issue for most new games.  It's because many people playing games no longer wish to exclusively play the game on the machine (IE have other things going on while playing the game).  Translation, people want the game in a window these days.  A few of the people I've spoken with are waiting to see how it affects things as a developer.

Quote from: ficedula
-If the driver vendors develop Vista-specific OpenGL drivers then they could work normal OpenGL without disabling the Shiny Vista Effects. This hasn't happened yet because Vista's driver models aren't, as I understand it, finalised anyway. It is, after all, still in beta.
That seems to be the real problem, vendors are frustrated with having to redo there drivers for Vista. IE they don't want to have to change things. (NVidia in particular has voiced issues with this). Likely because they invested so much into developing there universal drivers for win9x winXp and without any solid specs MS is making things in there view anoyingly difficult.  They have times of 3 months to get something working, which is short order for a potential complete rewrite for a driver.

Quote from: ficedula
Summary: OpenGL doesn't work flawlessly on the beta version of Vista. Shock result. Hundreds of news sites take this as a cue to say "OMG Microsoft is teh sux!".
No shock really, however I personally seldom use News Sites for useful information. I just listen to developers gripes LOL.

Quote from: ficedula
Microsoft's hardly rolling DX into the OS; how many years has it been since DirectX came with Windows anyway? I'm pretty sure Win98 came with it. The only difference is now they're going to use DX to accelerate the normal shell as well as games & 3D applications, and you'll need new drivers to use OpenGL at the same time as the new special effects.
It's an Internet Explorer type issue I suppose.  A particular person was excited about having acelerated desktop drawing which I thought was already supported by windows since 95.. I could be wrong.   It's a fairly convoluted situation I admit.  Microsoft seems to be pretty confused themselves at times.

Thanks for a bit of perspective Fice. :D

Back to the subject (coughs)
So the OpenGL functions supporting the transformation etc. issues tokens for the cards dynamic rec compilor and this makes the data flow one directional for anything that utilizes the T & L. Thus it has to do it twice (IE once on the processor and once on the card when it processes the actual list of codes generated by the driver).
I'll have to spend more time reading the function 'liturgy' for OpenGL it looks like.

I would like to set up my FF7 battle model viewing code to work with the internal animations myself.

The only way I can think of to update the models though at FF7's frame rate (15FPS for battle) is to have a seperate 'Timer' that changes the 'frame of reference' the paint function uses at 15FPS (or 2 67 ms waits with 1 66 ms wait every third frame).  Unfortunately the acuracy of using such timers I've found tends to be REALLY bad.  I suppose it doesn't matter since it's not 'in game'.

Cyb

Alhexx

  • *
  • Posts: 1894
    • View Profile
    • http://www.alhexx.com
Animation using OpenGL
« Reply #13 on: 2005-10-20 19:21:55 »
Okay, I took a look at the OpenGL redbook, and it seems that I exchange the glRotate etc. command for the camera to gluLookAt...

Anyway, there's a problem:

When I first calculate the bone positions and rotations, and I push them onto the stack, aftwards, when I draw the polygons, I have to go through the bones in reversed order?!?

 - Alhexx

ficedula

  • *
  • Posts: 2178
    • View Profile
    • http://www.ficedula.co.uk
Animation using OpenGL
« Reply #14 on: 2005-10-20 19:36:12 »
Um ... my rendering loops for skeletal models (both on the PC, eg. Ifalna, and on the DS, which is pretty much OpenGL compliant ;) would look rather like this (WARNING: pseudocode follows);

Code: [Select]

procedure RenderBone(Bone: TBone);
begin
  glPushMatrix();
  glTranslatef(Bone.Length, 0, 0);
  for i := 0 to Bone.ChildCount-1 do
    RenderBone(Bone.Children[i]); //recurse through children

  Bone.RenderPolygons();
  glPopMatrix();
end;


I guess you could see that as rendering in reverse order ... but there's no real reason you have to, of course. Thinking about it, you could easily move the rendering up above the loop; same behaviour. Anyway, recursion seems a fairly obvious way to implement walking the skeleton (and most skeletons aren't more than 7-8 bones 'deep', which isn't a problem. I think GL guarantees your modelview matrix stack is at least 32 entries long).

Alhexx

  • *
  • Posts: 1894
    • View Profile
    • http://www.alhexx.com
Animation using OpenGL
« Reply #15 on: 2005-10-20 21:46:59 »
I do not have a problem with that "reverse order" rendering - that's the way I usually handle recursive function - first the children, then the parent.

I had another problem - but you solved it by calling your drawing routine "Bone.RenderPolygons()" before calling glPopMatrix.

The problem I had is, when I first calculate the bone's positions without drawing them, then I need all alPopMatrix commands to calculate the child's bones, that means ... ah, forget it...

Thanx

 - Alhexx

L. Spiro

  • *
  • Posts: 797
    • View Profile
    • http://www.memoryhacking.com/index.php
Animation using OpenGL
« Reply #16 on: 2005-10-21 03:18:43 »
Each bone should have a member (in its class) that stores its final rotation, so when you go back to draw, the order doesn’t matter (of course you need to go in an order that allows you to get to all of the bones).
Likewise, once you have saved this information, you don’t need to push/pop a stack or translate anything.
You just store the bone’s matrix into the world and draw.





Quote
The only way I can think of to update the models though at FF7's frame rate (15FPS for battle) is to have a seperate 'Timer' that changes the 'frame of reference' the paint function uses at 15FPS (or 2 67 ms waits with 1 66 ms wait every third frame). Unfortunately the acuracy of using such timers I've found tends to be REALLY bad. I suppose it doesn't matter since it's not 'in game'.

The best way is to simply save a DWORD value indicating the time when your scene begins and use that to calculate your camera/whatever positions based off how much time has passed since then.  Of course doing this allows you more flexibility than a timer (variable speeds, smooth interpolation, etc.), and there is no method more accurate.
Not only that, it helps maintain a single-threaded nature—if you wish to avoid threading issues.

And you are absolutely right that timers are terribly inaccurate.
They use Sleep() for the length of time you specify and then either send the WM_TIMER message or they call the function you specify, and then Sleep() again after it is done.
There are two problems with this.
The first is that Sleep() goes into a low-priority mode which it can only leave when the system runs its standard pass over the thread, which isn’t as often as other threads, and it easily leads to delays of several milliseconds which compound for every time the timer is supposed to trigger an event.
The second problem is that when it triggers an event, it awaits for the event to finish before starting its next Sleep() cycle.
If your event takes more than 0 milliseconds, you’ve already thrown your timer off.
(Note that some timer systems may not use Sleep() directly but still use a method exactly like it.)


L. Spiro

Cyberman

  • *
  • Posts: 1572
    • View Profile
Animation using OpenGL
« Reply #17 on: 2005-10-21 06:13:48 »
L. Spiro - in summary I have to interpolate intermediate frames as an approximation through the fixed rotation time point in the timeline for the animations in other words.  IE check time elapsed and then estimate the rotation using the fixed time rotations in the frames to compute the intermediate frame. Might make the animation look smoother :D

Cyb

L. Spiro

  • *
  • Posts: 797
    • View Profile
    • http://www.memoryhacking.com/index.php
Animation using OpenGL
« Reply #18 on: 2005-10-21 07:18:01 »
My engine interpolates already and I have found problems when playing animations where Squaresoft took shortcuts.

Some models have spinning spikes (or cards) and the animations for them are incomplete.
In other words, they spin a short ways and then start back at 0 and spin again, etc.
This makes one spike/card rotate, then transform into the next spike/card, and so on, making the illusion that the spikes/cards spin the entire circle.
With interpolation, you can clearly see the point where the spikes go back to their original positions, and the illusion created is just a bunch of spikes that wiggle back and forth.

You would definitely want to be able to toggle interpolation off on certain or all) models.
Or even just on specific bones of certain models, if you really want to do all that work.


L. Spiro

mirex

  • *
  • Posts: 1645
    • View Profile
    • http://mirex.mypage.sk
Animation using OpenGL
« Reply #19 on: 2005-10-21 12:14:29 »
Quote
My engine interpolates already and I have found problems when playing animations where Squaresoft took shortcuts.
Yup mine interpolates too and I saw some problems aswell.

But this shortcut you're talking about is no bad thing. why to have 24 frames to do the cycle when 6 is enough. If you want to interpolate thing that was not meant for it either redo the animation or find another way.

Cyberman

  • *
  • Posts: 1572
    • View Profile
Animation using OpenGL
« Reply #20 on: 2005-10-21 15:38:14 »
I suppose animations with frames missing beyond the end of the animation can be assumed to be repeating and the frames be 'extended' as a loop?

That does make things more interesting to decode though doesn't it :D

Cyb

Alhexx

  • *
  • Posts: 1894
    • View Profile
    • http://www.alhexx.com
Animation using OpenGL
« Reply #21 on: 2005-10-23 01:33:45 »
Well, this might sound newbish, but how do I do that animation when not using a timer? Using that DWORD value L.Spiro said is no problem - I did this using the "clock" command, which returns the current process' lifetime in milliseconds.

Once I have drawn Frame 1, I have to make the engine redraw. Redrawing calling CWnd's UpdateWindow() function does not work - I have to invalidate the client area by moving the mouse for example...
Invalidating the client area using "Invalidate()" or "RedrawWindow()" mess up the window's other childs as the toolbar. Calling "PostMessage(WM_PAINT)" maks my app run in some sort of endless-loop - so I can't even close the window without killing it using the task manager... -_-

Here's the code of a test program I wrote - it simply simutes a "second pointer" of an analog clock:
Code: [Select]
void COpenGLView::Render(void)
{
// Get current time
clock_t CurTime = clock();

// Calculate difference between last click and now
double dDiff = double(CurTime - m_LastTime);
m_LastTime = CurTime;

m_Angle += dDiff * CLK_TO_RAD;

if(m_Angle >= 360)
m_Angle -= 360;

glColor3f(1, 1, 1);
glRotatef(m_Angle, 0, 0, -1.0f);

glBegin(GL_LINES);

glVertex3f(0, 0, 0);
glVertex3f(0, 2, 0);

glEnd();

//Invalidate();
//RedrawWindow();
UpdateWindow();
//PostMessage(WM_PAINT);

}


 - Alhexx

L. Spiro

  • *
  • Posts: 797
    • View Profile
    • http://www.memoryhacking.com/index.php
Animation using OpenGL
« Reply #22 on: 2005-10-23 07:36:46 »
Handle this in your window message loop.

As you know, you will already have a loop created to catch all incoming messages and dispatch them.

Use this loop to draw the scene as well.
Usually the loop checks for messages, and if there are any in the queue, it dispatches them and continues.
Then, if there are no message, it calls the game engine function (usually Tick()) which will handle an entire single frame of the game engine, from physics to rendering.

Depending on how you have set up your engine, you would handle input either at the beginning of your Tick() function or use the WM_* messages dispatched by your message handler.
For your project, you would definitely want to use the WM_* messages, which means your Tick() will only need to calculate the current frame of the object being displayed, attach its bones, and then render it.
Your current method of accepting input will remain in tact and you don’t need to change it at all.



There is one last thing.
Be careful how you use my DWORD method with clock().
You are probably already doing it correctly, but the only thing about which you have to be careful is using a very high DWORD and converting it to a FLOAT.
As you know, FLOAT’s lose accuracy when they reach higher numbers, which may cause your animation to be jerky, especially when using interpolation.
So you must always calculate the time that has passed since the start of the animation rather than using the time the computer has been on (timeGetTime()) or the time since all existance as we know it began (clock()).
Of course, to calculate the time since the animation began, you can use any method you want, be it clock() or timeGetTime() or another.


L. Spiro

Alhexx

  • *
  • Posts: 1894
    • View Profile
    • http://www.alhexx.com
Animation using OpenGL
« Reply #23 on: 2005-10-23 13:51:45 »
Well, there's a problem with the message loop - I do not handle it.
I'm using MFC for the application, including document-view-architecture...

The function "Render()" is called in "OnDraw()", CView's handler for the WM_PAINT message...


I have tried overriding CWinApp's OnIdle() and Run() methods, but it didn't help...

 - Alhexx

Micky

  • *
  • Posts: 300
    • View Profile
Animation using OpenGL
« Reply #24 on: 2005-10-23 14:20:30 »
Quote from: Alhexx
The function "Render()" is called in "OnDraw()", CView's handler for the WM_PAINT message...

It has been a while... but can you send a repaint message from a timer?