PDA

View Full Version : Visual C++ (MFC) OpenGL Animation



04-04-2002, 10:39 AM
Hello.

I am trying to animate an OpenGL scene in Visual C++ using the MFC. I can do it succesfully using the OnTimer function, but I wish to perform an animation outside the timer loop so that i can perform an animation based on input in a dialogue box from the user. I have tried using Invalidate() and setting/getting RCs and DCs but nothing seems to work. Can anyone help?

Many thanks,
Chris.

nexusone
04-04-2002, 11:08 AM
After the user does a input are you updating the window?
You could also keep your ontimer event loop, just add a statment only update screen if a input has been made.

onTimer()
{

if (Input_event)
{
process event
}
else do nothing
}



Originally posted by nodemons:
Hello.

I am trying to animate an OpenGL scene in Visual C++ using the MFC. I can do it succesfully using the OnTimer function, but I wish to perform an animation outside the timer loop so that i can perform an animation based on input in a dialogue box from the user. I have tried using Invalidate() and setting/getting RCs and DCs but nothing seems to work. Can anyone help?

Many thanks,
Chris.

04-04-2002, 11:49 AM
I think then my problem is how you update the window. For example currently I am trying:

[user enters that s/he wants to move object 10 units in x direction]
...
MoveObject 1 unit in x direction
Invalidate();
Sleep(500)
MoveObject 1 unit in x direction
Invalidate();
Sleep(500)
MoveObject 1 unit in x direction
Invalidate();
Sleep(500)
...

But this doesn't work, the screen pauses then the object is drawn having been moved 10 units in the x direction, but there is no animation.

Chris.

nexusone
04-04-2002, 12:20 PM
What do you mean by no animation, if the object moves it is animated vs. not moving.
What do you expect your object to do?

I am not sure what you do when you invalidate(), do you redraw the screen?

I like to do animation in a frame type setup.

Let's say you have a timer routine.
every x seconds you timer is called.

Object 'A' is only update every X seconds.
Object 'B' is only update if the user gives a signal, via keyboard or menu.

Event()
{
// ticks is number of times the routine has been called.
if (ticks_A == 5) Update 'A' every 5 ticks.
{
Update_A();
ticks_A = 0;
}else ticks++;

if ( Input_B == TRUE) // You also could have a ticks for b, on user input animate for x ticks.
{
Update_B();
Input_B = FALSE;
}
Update_display();
}


Originally posted by nodemons:
I think then my problem is how you update the window. For example currently I am trying:

[user enters that s/he wants to move object 10 units in x direction]
...
MoveObject 1 unit in x direction
Invalidate();
Sleep(500)
MoveObject 1 unit in x direction
Invalidate();
Sleep(500)
MoveObject 1 unit in x direction
Invalidate();
Sleep(500)
...

But this doesn't work, the screen pauses then the object is drawn having been moved 10 units in the x direction, but there is no animation.

Chris.



[This message has been edited by nexusone (edited 04-04-2002).]

J P
04-04-2002, 01:11 PM
Here is an example of menu control of the rotation of a cube. This should give you an idea of how to hookup a MFC control, in a dialog or what ever, to animate an object.
http://www.mfcogl.com/Menu%20RPC%20MFC%20&%20OpenGL.htm

Furrage
04-05-2002, 07:02 AM
I use InvalidateRect(NULL, FALSE) and it works fine. Its a member of the CWnd Class (and thus any derived class). NULL means you want to redraw the whole screen, FALSE means you don't want windows to clear the screen (OpenGL will do that for you with the glClear() command). If you leave out the FALSE you get screen flicker.

Just a suggestion. Place the InvalidateRect() call in your CWinApp::OnIdle function. This will give you better refresh rates than the Windows timer (which gets called a minimum of 55 ms). Note the state of your input via the KeyDown, KeyUp an mouse events (eg LButtonDown, LButtomUp, MouseMove), and in your OnPaint() function update the location of your object before drawing. You can make it smooth by noting the elapsed time since the last move and factoring that into your move equation. You can use QueryPerformanceCounter() or timeGetTime() to work out the current time.