Author Topic: Animation using OpenGL  (Read 20189 times)

Alhexx

  • *
  • Posts: 1894
    • View Profile
    • http://www.alhexx.com
Animation using OpenGL
« Reply #25 on: 2005-10-23 17:30:04 »
No, I was told not to use timers since they're inaccurate.

Finally, I have found a solution. I had to override CWinApp's OnIdle() function to achieve instant redrawing without letting the rest of the window die:

Code: [Select]
BOOL COpenGLApp::OnIdle(LONG lCount)
{
CMainFrame* pFrame = (CMainFrame*)GetMainWnd();
if(pFrame)
{
COpenGLView* pView = (COpenGLView*)pFrame->GetActiveView();
if(pView)
//pView->Invalidate();
//pView->PostMessage(WM_PAINT);
pView->OnDraw(pView->GetDC());
}

return TRUE;
//return CWinApp::OnIdle(lCount);
}


Okay, problem solved.

 - Alhexx

Alhexx

  • *
  • Posts: 1894
    • View Profile
    • http://www.alhexx.com
Animation using OpenGL
« Reply #26 on: 2005-10-24 19:51:19 »
Sorry, for double-posting, but I want to give it another try:


I've been trying around to programm a test tool to practice with Key frames.
The tool is very simple, it simply draws a line, the only animation is a rotation of the line around (0,0,0).

There is a total of 100 Frames in the loop. There are 4 Keyframes:

KeyFrame #0 (Frame #0): Rotation value: 0°
KeyFrame #1 (Frame #10): Rotation value: -45°
KeyFrame #2 (Frame #20): Rotation value: 0°
KeyFrame #3 (Frame #60): Rotation value: 45°

Member explanation:
m_iKeyFramesIndex tells the frame offset of a keyframe (e.g. m_iKeyFramesIndex[1] = 10 )
m_fKeyFrames is the rotation of the keyframe.

Here's the code I used:
Code: [Select]
void COpenGLView::Render(void)
{
glColor3f(1, 1, 1);

if(m_bAnimate)
{
// Get elapsed time
long lTime = clock() - m_StartTime;

// Convert to frame offset
double dFrameOff = double(lTime) / 1000 * double(m_iFramesPerSec);

// Simulate modulo: dFrameOff % m_iTotalFrames
dFrameOff -= double(int(dFrameOff / m_iTotalFrames) * m_iTotalFrames);

// Find the 2 neighbours
int iKey1 = 0;
int iKey2 = 0;

// Find left neighbour
for(int i = 0; i < m_iNumKeyFrames; i++)
{
if(double(m_iKeyFramesIndex[i]) <= dFrameOff)
iKey1 = i;
if(double(m_iKeyFramesIndex[i]) > dFrameOff)
break;
}

// Find right neighbour
if((iKey1+1) >= m_iNumKeyFrames)
iKey2 = 0;
else
iKey2 = iKey1 + 1;

// Calculate frame position
double dFramePos = dFrameOff - double(m_iKeyFramesIndex[iKey1]);

if(iKey2 > 0)
dFramePos /= double(m_iKeyFramesIndex[iKey2] - m_iKeyFramesIndex[iKey1]);
else
dFramePos /= double(m_iTotalFrames - m_iKeyFramesIndex[iKey1]);

// Calculate current frame
float fCurFrame =
(m_fKeyFrames[iKey1] * (1.0 - dFramePos)) +
(m_fKeyFrames[iKey2] * dFramePos);


// Rotate
glRotatef(fCurFrame, 0, 0, 1.0f);
}

// Render our line
glBegin(GL_LINES);
glVertex3f(0, 0, 0);
glVertex3f(0, -3, 0);
glEnd();
}


Surprisingly, the code does what it should do :P
However, I have problem:
When I start the app, the frame rate is ~120 FPS. After a minute of running it goes down to ~50 FPS...

Does anyone know why? And does anyone have suggestions to improve the code?

 - Alhexx

 - edit -
I have uploaded the compiled tool incl. source code here:
http://www.alhexx.com/stuff/OpenGL_Anim.rar