void DrawingGlobal::render_frame()
{
    initialize();
    glEnable(GL_DEPTH_TEST);
    glShadeModel(shading);
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS,shininess);
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    
    gluLookAt(
        // eye positioning
        eye.x,eye.y,eye.z,
        eye.x + eye_direction_delta.x, eye.y + eye_direction_delta.y,
        eye.z + eye_direction_delta.z,
        // camera is oriented so that it's top is in the y direction
        0.f,1.f,0.f);

    // draw the spline path
    gl_draw_spline_path();
    
    // ground plane to follow interpolation itinerary
    draw_global_coords();

    
    if (spline != NULL)
    {
        // draw control points if we're supposed to
        if (draw_ctrl_pts)
        {
            glColor3f(.5f,.5f,.5f);
            const ControlVec& cv = spline->control_points();
            for (ControlVecCIter citer = cv.begin(); citer != cv.end();
                 ++citer)
            {
                draw_control_point(*citer);
            }
        }

        // translate model view before drawing
        Point3 translate_point;
        Quaternion rot_quat;
        spline->get_pos(
            ticks_since_start*CALLBACK_TIME_MS/1000.,translate_point,rot_quat);

        glTranslatef(
            translate_point.x,
            translate_point.y,
            translate_point.z);

        glMultMatrixf(rot_quat.gl_mult_matrix());
    }

    if (bm != NULL)
    {
        glEnable(GL_TEXTURE_2D);
        glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
        glBindTexture(GL_TEXTURE_2D, texture_id);
    }


    glColor3f(0.f,0.f,.7f);
    for (Face::FaceMapCIter face_citer = fmap->begin();
         face_citer != fmap->end(); ++face_citer)
    {
        Face* f = face_citer->second;
        glBegin(gl_begin_type);

        if (shading == GL_FLAT)
        {
            VertexNormal* fnormal = f->face_normal();
            const Point3& norm_pt = fnormal->pt();
            glNormal3f(norm_pt.x,norm_pt.y,norm_pt.z);
        }
        
        for (FaceVertDataVecCIter vert_data_iter = f->vert_iter_begin();
             vert_data_iter != f->vert_iter_end(); ++vert_data_iter)
        {
            Vertex* vert = (*vert_data_iter)->vert;
            if (shading == GL_SMOOTH)
            {
                VertexNormal* vert_normal = vert->avg_normal(*vnmap);
                const Point3& norm_pt = vert_normal->pt();
                glNormal3f(norm_pt.x,norm_pt.y,norm_pt.z);
            }
            
            Vertex* single_vert = (*vert_data_iter)->vert;
            const Point3& vert_pt = single_vert->pt();
            glVertex3f(vert_pt.x,vert_pt.y,vert_pt.z);
        }
        glEnd();
    }

    
    glPopMatrix(); // matches push from glulookat
    glutSwapBuffers();
    glFlush();
}