> 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