> OK, I found my hacked-up gl_gears example - actually it's the glut one,
> but anyway... converted to be fltk-ish.
>
> It was originally meant to run on the idle loop, and with this WIN32 box
> that runs about 3,000 FPS.
>
> I've added an fl_timer aiming for 100 FPS, and on this box I get a
> rock-solid 64 FPS... Hmm, 64 !=3D 100, so that's odd.
>
> I wonder if I'm hitting some issue with the resolution of the WIN32
> timers or something, as the FPS I get is *exactly* 64, even though the
> idle-loop version runs much, much faster...
>
> Anyway, it is longer and messier than I'd like, sorry.
> The conversion to/from using the idle or timer option should be
> obvious...
>
> ----------------------------
>
>
> /*
>  * 3-D gear wheels.  This program is in the public domain.
>  *
>  * Command line options:
>  *    -info      print GL implementation information
>  *    -exit      automatically exit after 30 seconds
>  *
>  *
>  * Brian Paul
>  */
>
> /* Conversion to GLUT by Mark J. Kilgard */
> /*
>  * Conversion to FLTK by IMM
>  * Compile as:  fltk-config --use-gl --compile fl_gears.cxx
>  */
>
> #include <math.h>
> #include <stdlib.h>
> #include <stdio.h>
> #include <string.h>
> #include <time.h>
>
> //#include <GL/glut.h>
> #include <FL/glut.H>
> #ifdef __APPLE__
> #  include <OpenGL/glu.h>
> #else
> #  include <GL/glu.h> // added for FLTK
> #endif
>
> #include <FL/Fl_Window.H>
> #include <FL/Fl_Value_Output.H>
>
> static GLint T0 =3D 0;
> static GLint Frames =3D 0;
> static GLint autoexit =3D 0;
>
> static Fl_Value_Output *fps_out =3D NULL;
> static Fl_Value_Output *fps_max =3D NULL;
> static Fl_Value_Output *fps_avg =3D NULL;
>
> static float f_max =3D 0.0;
> static float f_avg =3D 0.0;
>
> static float desired_frame_rate =3D 100.0;
> static float per_frame_time =3D 1.0 / desired_frame_rate;
>
> /**
>
>   Draw a gear wheel.  You'll probably want to call this function when
>   building a display list since we do a lot of trig here.
>
>   Input:  inner_radius - radius of hole at center
>           outer_radius - radius at center of teeth
>           width - width of gear
>           teeth - number of teeth
>           tooth_depth - depth of tooth
>
>  **/
>
> static void
> gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
>   GLint teeth, GLfloat tooth_depth)
> {
>   GLint i;
>   GLfloat r0, r1, r2;
>   GLfloat angle, da;
>   GLfloat u, v, len;
>
>   r0 =3D inner_radius;
>   r1 =3D outer_radius - tooth_depth / 2.0;
>   r2 =3D outer_radius + tooth_depth / 2.0;
>
>   da =3D 2.0 * M_PI / teeth / 4.0;
>
>   glShadeModel(GL_FLAT);
>
>   glNormal3f(0.0, 0.0, 1.0);
>
>   /* draw front face */
>   glBegin(GL_QUAD_STRIP);
>   for (i =3D 0; i <=3D teeth; i++) {
>     angle =3D i * 2.0 * M_PI / teeth;
>     glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
>     glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
>     if (i < teeth) {
>       glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
>       glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
> width * 0.5);
>     }
>   }
>   glEnd();
>
>   /* draw front sides of teeth */
>   glBegin(GL_QUADS);
>   da =3D 2.0 * M_PI / teeth / 4.0;
>   for (i =3D 0; i < teeth; i++) {
>     angle =3D i * 2.0 * M_PI / teeth;
>
>     glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
>     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
>     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width
> * 0.5);
>     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width
> * 0.5);
>   }
>   glEnd();
>
>   glNormal3f(0.0, 0.0, -1.0);
>
>   /* draw back face */
>   glBegin(GL_QUAD_STRIP);
>   for (i =3D 0; i <=3D teeth; i++) {
>     angle =3D i * 2.0 * M_PI / teeth;
>     glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
>     glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
>     if (i < teeth) {
>       glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
> -width * 0.5);
>       glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
>     }
>   }
>   glEnd();
>
>   /* draw back sides of teeth */
>   glBegin(GL_QUADS);
>   da =3D 2.0 * M_PI / teeth / 4.0;
>   for (i =3D 0; i < teeth; i++) {
>     angle =3D i * 2.0 * M_PI / teeth;
>
>     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
> -width * 0.5);
>     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
> -width * 0.5);
>     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width *
> 0.5);
>     glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
>   }
>   glEnd();
>
>   /* draw outward faces of teeth */
>   glBegin(GL_QUAD_STRIP);
>   for (i =3D 0; i < teeth; i++) {
>     angle =3D i * 2.0 * M_PI / teeth;
>
>     glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
>     glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
>     u =3D r2 * cos(angle + da) - r1 * cos(angle);
>     v =3D r2 * sin(angle + da) - r1 * sin(angle);
>     len =3D sqrt(u * u + v * v);
>     u /=3D len;
>     v /=3D len;
>     glNormal3f(v, -u, 0.0);
>     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
>     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width *
> 0.5);
>     glNormal3f(cos(angle), sin(angle), 0.0);
>     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width
> * 0.5);
>     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
> -width * 0.5);
>     u =3D r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
>     v =3D r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
>     glNormal3f(v, -u, 0.0);
>     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width
> * 0.5);
>     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
> -width * 0.5);
>     glNormal3f(cos(angle), sin(angle), 0.0);
>   }
>
>   glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
>   glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
>
>   glEnd();
>
>   glShadeModel(GL_SMOOTH);
>
>   /* draw inside radius cylinder */
>   glBegin(GL_QUAD_STRIP);
>   for (i =3D 0; i <=3D teeth; i++) {
>     angle =3D i * 2.0 * M_PI / teeth;
>     glNormal3f(-cos(angle), -sin(angle), 0.0);
>     glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
>     glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
>   }
>   glEnd();
>
> }
>
> static GLfloat view_rotx =3D 20.0, view_roty =3D 30.0, view_rotz =3D 0.0;
> static GLint gear1, gear2, gear3;
> static GLfloat angle =3D 0.0;
>
> static void
> draw(void)
> {
>   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
>
>   glPushMatrix();
>     glRotatef(view_rotx, 1.0, 0.0, 0.0);
>     glRotatef(view_roty, 0.0, 1.0, 0.0);
>     glRotatef(view_rotz, 0.0, 0.0, 1.0);
>
>     glPushMatrix();
>       glTranslatef(-3.0, -2.0, 0.0);
>       glRotatef(angle, 0.0, 0.0, 1.0);
>       glCallList(gear1);
>     glPopMatrix();
>
>     glPushMatrix();
>       glTranslatef(3.1, -2.0, 0.0);
>       glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
>       glCallList(gear2);
>     glPopMatrix();
>
>     glPushMatrix();
>       glTranslatef(-3.1, 4.2, 0.0);
>       glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
>       glCallList(gear3);
>     glPopMatrix();
>
>   glPopMatrix();
>
>   glutSwapBuffers();
>
>   Frames++;
> }
>
> static void idle_fl(void *)
> {
>   static short fixed_angle =3D 0;
>   fixed_angle +=3D 500;
>   angle =3D (double)(fixed_angle) * 180.0 / 32768.0;
>   glutPostRedisplay();
> }
>
> void fixed_fps(void *v)
> {
>     Fl::repeat_timeout(per_frame_time, fixed_fps);
>     idle_fl(v);
> }
>
> void check_fps(void *)
> {
>     static int first =3D 1;
>     float fps;
>
>     static time_t old_tod;
>     time_t delta_tod, new_tod =3D time(NULL);
>     if(first)
>     {
>         delta_tod =3D 5;
>     }
>     else
>     {
>         delta_tod =3D new_tod - old_tod;
>     }
>     fps =3D Frames / (float)delta_tod;
>
>     printf("%d frames in %d seconds =3D %6.3f FPS\n", Frames, delta_tod,
> fps);
>     fflush(stdout);
>
>     Frames =3D 0;
>
>     if (fps > f_max)
>     {
>         f_max =3D fps;
>         fps_max->value(floor(f_max));
>     }
>     if (first)
>     {
>         f_avg =3D fps;
>         first =3D 0;
>     }
>     else
>     {
>         f_avg =3D (f_avg * 0.7) + (fps * 0.3);
>     }
>     old_tod =3D new_tod;
>
>     fps_avg->value(floor(f_avg));
>     fps_out->value(floor(fps));
>
>     if (autoexit)
>     {
>       autoexit =3D autoexit - (int)delta_tod;
>       if (autoexit <=3D 0) exit(0);
>     }
>     Fl::repeat_timeout(10.0, check_fps);
> }
>
> /* change view angle, exit upon ESC */
> /* ARGSUSED1 */
> static void
> key(unsigned char k, int x, int y)
> {
>   switch (k) {
>   case 'z':
>     view_rotz +=3D 5.0;
>     break;
>   case 'Z':
>     view_rotz -=3D 5.0;
>     break;
>   case 27:  /* Escape */
>     exit(0);
>     break;
>   default:
>     return;
>   }
>   glutPostRedisplay();
> }
>
> /* change view angle */
> /* ARGSUSED1 */
> static void
> special(int k, int x, int y)
> {
>   switch (k) {
>   case GLUT_KEY_UP:
>     view_rotx +=3D 5.0;
>     break;
>   case GLUT_KEY_DOWN:
>     view_rotx -=3D 5.0;
>     break;
>   case GLUT_KEY_LEFT:
>     view_roty +=3D 5.0;
>     break;
>   case GLUT_KEY_RIGHT:
>     view_roty -=3D 5.0;
>     break;
>   default:
>     return;
>   }
>   glutPostRedisplay();
> }
>
> /* new window size or exposure */
> static void
> reshape(int width, int height)
> {
>   GLfloat h =3D (GLfloat) height / (GLfloat) width;
>
>   glViewport(0, 0, (GLint) width, (GLint) height);
>   glMatrixMode(GL_PROJECTION);
>   glLoadIdentity();
>   glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
>   glMatrixMode(GL_MODELVIEW);
>   glLoadIdentity();
>   glTranslatef(0.0, 0.0, -40.0);
> }
>
> static void
> init(int argc, char *argv[])
> {
>   static GLfloat pos[4] =3D {5.0, 5.0, 10.0, 0.0};
>   static GLfloat red[4] =3D {0.8, 0.1, 0.0, 1.0};
>   static GLfloat green[4] =3D {0.0, 0.8, 0.2, 1.0};
>   static GLfloat blue[4] =3D {0.2, 0.2, 1.0, 1.0};
>   GLint i;
>
>   glLightfv(GL_LIGHT0, GL_POSITION, pos);
>   glEnable(GL_CULL_FACE);
>   glEnable(GL_LIGHTING);
>   glEnable(GL_LIGHT0);
>   glEnable(GL_DEPTH_TEST);
>
>   /* make the gears */
>   gear1 =3D glGenLists(1);
>   glNewList(gear1, GL_COMPILE);
>   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
>   gear(1.0, 4.0, 1.0, 20, 0.7);
>   glEndList();
>
>   gear2 =3D glGenLists(1);
>   glNewList(gear2, GL_COMPILE);
>   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
>   gear(0.5, 2.0, 2.0, 10, 0.7);
>   glEndList();
>
>   gear3 =3D glGenLists(1);
>   glNewList(gear3, GL_COMPILE);
>   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
>   gear(1.3, 2.0, 0.5, 10, 0.7);
>   glEndList();
>
>   glEnable(GL_NORMALIZE);
>
>   for ( i=3D1; i<argc; i++ ) {
>     if (strcmp(argv[i], "-info")=3D=3D0) {
>       printf("GL_RENDERER   =3D %s\n", (char *) glGetString(GL_RENDERER));
>       printf("GL_VERSION    =3D %s\n", (char *) glGetString(GL_VERSION));
>       printf("GL_VENDOR     =3D %s\n", (char *) glGetString(GL_VENDOR));
>       printf("GL_EXTENSIONS =3D %s\n", (char *)
> glGetString(GL_EXTENSIONS));
>       fflush(stdout);
>     }
>     else if ( strcmp(argv[i], "-exit")=3D=3D0) {
>       autoexit =3D 35;
>       printf("Auto Exit after approx. %i seconds.\n", autoexit );
>       fflush(stdout);
>     }
>   }
> }
>
> static void
> visible(int vis)
> {
>   if (vis =3D=3D GLUT_VISIBLE)
>     //Fl::add_idle(idle_fl); // Takes the place of the glut idle loop
>     Fl::add_timeout(per_frame_time, fixed_fps);
>   else
>     //Fl::remove_idle(idle_fl); // Takes the place of the glut idle loop
>     Fl::remove_timeout(fixed_fps);
> }
>
> int main(int argc, char *argv[])
> {
> //  glutInit(&argc, argv); // not needed by fltk
> // create FLTK window instead
>     Fl::get_system_colors();
>     Fl_Window window(320, 350);
>     window.resizable(window);
>     window.label("FL Gears");
>
>     fps_out =3D new Fl_Value_Output(260, 318, 50, 25, "FPS:");
>     fps_max =3D new Fl_Value_Output(152, 318, 50, 25, "MAX:");
>     fps_avg =3D new Fl_Value_Output( 45, 318, 50, 25, "AVG:");
>
>     window.show();  // glut will die unless parent window visible
>     window.begin(); // this will cause Glut window to be a child
>
>     glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
>
>     glutInitWindowPosition(10, 10);
>     glutInitWindowSize(300, 300);
>     glutCreateWindow("flGears");
>
>     window.end();
>
>     init(argc, argv);
>
>     glutDisplayFunc(draw);
>     glutReshapeFunc(reshape);
>     glutKeyboardFunc(key);
>     glutSpecialFunc(special);
>     glutVisibilityFunc(visible);
>
>     Fl::add_timeout(5.0, check_fps); // compute FPS without
> GLUT_ELAPSED_TIME
>
> //    Fl::add_idle(idle_fl); // Takes the place of the glut idle loop
>     Fl::add_timeout(per_frame_time, fixed_fps); // draw at desired FPS
>
>     glutMainLoop();
>     return 0;             /* ANSI C requires main to return int. */
> }
>
> /* End of File */
>
>
>
>
> SELEX Galileo Ltd
> Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS=
> 14 3EL
> A company registered in England & Wales.  Company no. 02426132
> ********************************************************************
> This email and any attachments are confidential to the intended
> recipient and may also be privileged. If you are not the intended
> recipient please delete it from your system and notify the sender.
> You should not copy it or use it for any purpose nor disclose or
> distribute its contents to any other person.
> ********************************************************************
>


You all are beautiful!  I'll take this example and go through it line by line.
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to