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:
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();
}
}