source: rtems-graphics-toolkit/fltk-1.1.10/test/fractals.cxx @ 513eea1

Last change on this file since 513eea1 was 513eea1, checked in by Joel Sherrill <joel.sherrill@…>, on 01/09/10 at 22:43:24

2010-01-08 Joel Sherrill <joel.sherrill@…>

fltk 1.1.10. imported

  • ORIGIN: Updated.
  • Property mode set to 100644
File size: 22.3 KB
Line 
1//
2// "$Id$"
3//
4// Fractal drawing demo for the Fast Light Tool Kit (FLTK).
5//
6// This is a GLUT demo program, with modifications to
7// demonstrate how to add FLTK controls to a GLUT program.   The GLUT
8// code is unchanged except for the end (search for FLTK to find changes).
9//
10// Copyright 1998-2005 by Bill Spitzak and others.
11//
12// This library is free software; you can redistribute it and/or
13// modify it under the terms of the GNU Library General Public
14// License as published by the Free Software Foundation; either
15// version 2 of the License, or (at your option) any later version.
16//
17// This library is distributed in the hope that it will be useful,
18// but WITHOUT ANY WARRANTY; without even the implied warranty of
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20// Library General Public License for more details.
21//
22// You should have received a copy of the GNU Library General Public
23// License along with this library; if not, write to the Free Software
24// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
25// USA.
26//
27// Please report all bugs and problems on the following page:
28//
29//     http://www.fltk.org/str.php
30//
31
32#include "config.h"
33#if !HAVE_GL || !HAVE_GL_GLU_H
34#include <FL/Fl.H>
35#include <FL/fl_message.H>
36int main(int, char**) {
37  fl_alert("This demo does not work without GL and GLU (%d)");
38  return 1;
39}
40#else
41/*
42 * To compile: cc -o fractals fractals.c -lGL -lGLU -lX11 -lglut -lXmu -lm
43 *
44 * Usage: fractals
45 *
46 * Homework 6, Part 2: fractal mountains and fractal trees
47 * (Pretty Late)
48 *
49 * Draws fractal mountains and trees -- and an island of mountains in water
50 * (I tried having trees on the island but it didn't work too well.)
51 *
52 * Two viewer modes: polar and flying (both restrained to y>0 for up vector).
53 * Keyboard 0->9 and +/- control speed when flying.
54 *
55 * Only keyboard commands are 0-9 and +/- for speed in flying mode.
56 *
57 * Fog would make the island look much better, but I couldn't get it to work
58 * correctly.  Would line up on -z axis not from eye.
59 *
60 * Philip Winston - 3/4/95
61 * pwinston@hmc.edu
62 * http://www.cs.hmc.edu/people/pwinston
63 *
64 */
65
66#include <FL/glut.H>
67#include <FL/glu.h>
68
69#include <stdio.h>
70#include <stdlib.h>
71#include <math.h>
72#include <limits.h>           /* ULONG_MAX is defined here */
73#include <float.h>            /* FLT_MAX is atleast defined here */
74
75#include <time.h>  /* for random seed */
76
77#include "fracviewer.h"
78
79#if defined(WIN32) || defined(__EMX__)
80#  define drand48() (((float) rand())/((float) RAND_MAX))
81#  define srand48(x) (srand((x)))
82#elif defined __APPLE__
83#  define drand48() (((float) rand())/((float) RAND_MAX))
84#  define srand48(x) (srand((x)))
85#endif
86
87typedef enum { NOTALLOWED, MOUNTAIN, TREE, ISLAND, BIGMTN, STEM, LEAF,
88               MOUNTAIN_MAT, WATER_MAT, LEAF_MAT, TREE_MAT, STEMANDLEAVES,
89               AXES } DisplayLists;
90
91#define MAXLEVEL 8
92
93int Rebuild = 1,        /* Rebuild display list in next display? */
94    fractal = TREE,     /* What fractal are we building */
95    Level   = 4;        /* levels of recursion for fractals */     
96
97int DrawAxes = 0;       
98
99/***************************************************************/
100/************************* VECTOR JUNK *************************/
101/***************************************************************/
102
103  /* print vertex to stderr */
104void printvert(float v[3])
105{
106  fprintf(stderr, "(%f, %f, %f)\n", v[0], v[1], v[2]);
107}
108
109#if 0   // removed for FL, it is in fracviewer.c
110  /* normalizes v */
111void normalize(GLfloat v[3])
112{
113  GLfloat d = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
114
115  if (d == 0)
116    fprintf(stderr, "Zero length vector in normalize\n");
117  else
118    v[0] /= d; v[1] /= d; v[2] /= d;
119}
120
121  /* calculates a normalized crossproduct to v1, v2 */
122void ncrossprod(float v1[3], float v2[3], float cp[3])
123{
124  cp[0] = v1[1]*v2[2] - v1[2]*v2[1];
125  cp[1] = v1[2]*v2[0] - v1[0]*v2[2];
126  cp[2] = v1[0]*v2[1] - v1[1]*v2[0];
127  normalize(cp);
128}
129#endif
130
131  /* calculates normal to the triangle designated by v1, v2, v3 */
132void triagnormal(float v1[3], float v2[3], float v3[3], float norm[3])
133{
134  float vec1[3], vec2[3];
135
136  vec1[0] = v3[0] - v1[0];  vec2[0] = v2[0] - v1[0];
137  vec1[1] = v3[1] - v1[1];  vec2[1] = v2[1] - v1[1];
138  vec1[2] = v3[2] - v1[2];  vec2[2] = v2[2] - v1[2];
139
140  ncrossprod(vec2, vec1, norm);
141}
142
143float xzlength(float v1[3], float v2[3])
144{
145  return sqrt((v1[0] - v2[0])*(v1[0] - v2[0]) +
146              (v1[2] - v2[2])*(v1[2] - v2[2]));
147}
148
149float xzslope(float v1[3], float v2[3])
150{
151  return ((v1[0] != v2[0]) ? ((v1[2] - v2[2]) / (v1[0] - v2[0]))
152                           : FLT_MAX);
153}
154
155
156/***************************************************************/
157/************************ MOUNTAIN STUFF ***********************/
158/***************************************************************/
159
160GLfloat DispFactor[MAXLEVEL];  /* Array of what to multiply random number
161                                  by for a given level to get midpoint
162                                  displacement  */
163GLfloat DispBias[MAXLEVEL];  /* Array of what to add to random number
164                                before multiplying it by DispFactor */
165
166#define NUMRANDS 191
167float RandTable[NUMRANDS];  /* hash table of random numbers so we can
168                               raise the same midpoints by the same amount */
169
170         /* The following are for permitting an edge of a moutain to be   */
171         /* pegged so it won't be displaced up or down.  This makes it    */
172         /* easier to setup scenes and makes a single moutain look better */
173
174GLfloat Verts[3][3],    /* Vertices of outside edges of mountain */
175        Slopes[3];      /* Slopes between these outside edges */
176int     Pegged[3];      /* Is this edge pegged or not */           
177
178 /*
179  * Comes up with a new table of random numbers [0,1)
180  */
181void InitRandTable(unsigned int seed)
182{
183  int i;
184
185  srand48((long) seed);
186  for (i = 0; i < NUMRANDS; i++)
187    RandTable[i] = drand48() - 0.5;
188}
189
190  /* calculate midpoint and displace it if required */
191void Midpoint(GLfloat mid[3], GLfloat v1[3], GLfloat v2[3],
192              int edge, int level)
193{
194  unsigned hash;
195
196  mid[0] = (v1[0] + v2[0]) / 2;
197  mid[1] = (v1[1] + v2[1]) / 2;
198  mid[2] = (v1[2] + v2[2]) / 2;
199  if (!Pegged[edge] || (fabs(xzslope(Verts[edge], mid)
200                        - Slopes[edge]) > 0.00001)) {
201    srand48((int)((v1[0]+v2[0])*23344));
202    hash = unsigned(drand48() * 7334334);
203    srand48((int)((v2[2]+v1[2])*43433));
204    hash = (unsigned)(drand48() * 634344 + hash) % NUMRANDS;
205    mid[1] += ((RandTable[hash] + DispBias[level]) * DispFactor[level]);
206  }
207}
208
209  /*
210   * Recursive moutain drawing routine -- from lecture with addition of
211   * allowing an edge to be pegged.  This function requires the above
212   * globals to be set, as well as the Level global for fractal level
213   */
214static float cutoff = -1;
215
216void FMR(GLfloat v1[3], GLfloat v2[3], GLfloat v3[3], int level)
217{
218  if (level == Level) {
219    GLfloat norm[3];
220    if (v1[1] <= cutoff && v2[1]<=cutoff && v3[1]<=cutoff) return;
221    triagnormal(v1, v2, v3, norm);
222    glNormal3fv(norm);
223    glVertex3fv(v1);
224    glVertex3fv(v2);
225    glVertex3fv(v3);
226
227  } else {
228    GLfloat m1[3], m2[3], m3[3];
229
230    Midpoint(m1, v1, v2, 0, level);
231    Midpoint(m2, v2, v3, 1, level);
232    Midpoint(m3, v3, v1, 2, level);
233
234    FMR(v1, m1, m3, level + 1);
235    FMR(m1, v2, m2, level + 1);
236    FMR(m3, m2, v3, level + 1);
237    FMR(m1, m2, m3, level + 1);
238  }
239}
240
241 /*
242  * sets up lookup tables and calls recursive mountain function
243  */
244void FractalMountain(GLfloat v1[3], GLfloat v2[3], GLfloat v3[3],
245                     int pegged[3])
246{
247  GLfloat lengths[MAXLEVEL];
248  GLfloat fraction[8] = { 0.3, 0.3, 0.4, 0.2, 0.3, 0.2, 0.4, 0.4  };
249  GLfloat bias[8]     = { 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1  };
250  int i;
251  float avglen = (xzlength(v1, v2) +
252                  xzlength(v2, v3) +
253                  xzlength(v3, v1) / 3);
254
255  for (i = 0; i < 3; i++) {
256    Verts[0][i] = v1[i];      /* set mountain vertex globals */
257    Verts[1][i] = v2[i];
258    Verts[2][i] = v3[i];
259    Pegged[i] = pegged[i];
260  }
261
262  Slopes[0] = xzslope(Verts[0], Verts[1]);   /* set edge slope globals */
263  Slopes[1] = xzslope(Verts[1], Verts[2]);
264  Slopes[2] = xzslope(Verts[2], Verts[0]);
265
266  lengths[0] = avglen;         
267  for (i = 1; i < Level; i++) {   
268    lengths[i] = lengths[i-1]/2;     /* compute edge length for each level */
269  }
270
271  for (i = 0; i < Level; i++) {     /* DispFactor and DispBias arrays */     
272    DispFactor[i] = (lengths[i] * ((i <= 7) ? fraction[i] : fraction[7]));
273    DispBias[i]   = ((i <= 7) ? bias[i] : bias[7]);
274  }
275
276  glBegin(GL_TRIANGLES);
277    FMR(v1, v2, v3, 0);    /* issues no GL but vertex calls */
278  glEnd();
279}
280
281 /*
282  * draw a mountain and build the display list
283  */
284void CreateMountain(void)
285{
286  GLfloat v1[3] = { 0, 0, -1 }, v2[3] = { -1, 0, 1 }, v3[3] = { 1, 0, 1 };
287  int pegged[3] = { 1, 1, 1 };
288
289  glNewList(MOUNTAIN, GL_COMPILE);
290  glPushAttrib(GL_LIGHTING_BIT);
291    glCallList(MOUNTAIN_MAT);
292    FractalMountain(v1, v2, v3, pegged);
293  glPopAttrib();
294  glEndList();
295}
296
297  /*
298   * new random numbers to make a different moutain
299   */
300void NewMountain(void)
301{
302  InitRandTable(time(NULL));
303}
304
305/***************************************************************/
306/***************************** TREE ****************************/
307/***************************************************************/
308
309long TreeSeed;   /* for srand48 - remember so we can build "same tree"
310                     at a different level */
311
312 /*
313  * recursive tree drawing thing, fleshed out from class notes pseudocode
314  */
315void FractalTree(int level)
316{
317  long savedseed;  /* need to save seeds while building tree too */
318
319  if (level == Level) {
320      glPushMatrix();
321        glRotatef(drand48()*180, 0, 1, 0);
322        glCallList(STEMANDLEAVES);
323      glPopMatrix();
324  } else {
325    glCallList(STEM);
326    glPushMatrix();
327    glRotatef(drand48()*180, 0, 1, 0);
328    glTranslatef(0, 1, 0);
329    glScalef(0.7, 0.7, 0.7);
330
331      savedseed = (long)((ulong)drand48()*ULONG_MAX);
332      glPushMatrix();   
333        glRotatef(110 + drand48()*40, 0, 1, 0);
334        glRotatef(30 + drand48()*20, 0, 0, 1);
335        FractalTree(level + 1);
336      glPopMatrix();
337
338      srand48(savedseed);
339      savedseed = (long)((ulong)drand48()*ULONG_MAX);
340      glPushMatrix();
341        glRotatef(-130 + drand48()*40, 0, 1, 0);
342        glRotatef(30 + drand48()*20, 0, 0, 1);
343        FractalTree(level + 1);
344      glPopMatrix();
345
346      srand48(savedseed);
347      glPushMatrix();
348        glRotatef(-20 + drand48()*40, 0, 1, 0);
349        glRotatef(30 + drand48()*20, 0, 0, 1);
350        FractalTree(level + 1);
351      glPopMatrix();
352
353    glPopMatrix();
354  }
355}
356
357  /*
358   * Create display lists for a leaf, a set of leaves, and a stem
359   */
360void CreateTreeLists(void)
361{
362  GLUquadricObj *cylquad = gluNewQuadric();
363  int i;
364
365  glNewList(STEM, GL_COMPILE);
366  glPushMatrix();
367    glRotatef(-90, 1, 0, 0);
368    gluCylinder(cylquad, 0.1, 0.08, 1, 10, 2 );
369  glPopMatrix();
370  glEndList();
371
372  glNewList(LEAF, GL_COMPILE);  /* I think this was jeff allen's leaf idea */
373    glBegin(GL_TRIANGLES);
374      glNormal3f(-0.1, 0, 0.25);  /* not normalized */
375      glVertex3f(0, 0, 0);
376      glVertex3f(0.25, 0.25, 0.1);
377      glVertex3f(0, 0.5, 0);
378
379      glNormal3f(0.1, 0, 0.25);
380      glVertex3f(0, 0, 0);
381      glVertex3f(0, 0.5, 0);
382      glVertex3f(-0.25, 0.25, 0.1);
383    glEnd();
384  glEndList();
385
386  glNewList(STEMANDLEAVES, GL_COMPILE);
387  glPushMatrix();
388  glPushAttrib(GL_LIGHTING_BIT);
389    glCallList(STEM);
390    glCallList(LEAF_MAT);
391    for(i = 0; i < 3; i++) {
392      glTranslatef(0, 0.333, 0);
393      glRotatef(90, 0, 1, 0);
394      glPushMatrix();
395        glRotatef(0, 0, 1, 0);
396        glRotatef(50, 1, 0, 0);
397        glCallList(LEAF);
398      glPopMatrix();
399      glPushMatrix();
400        glRotatef(180, 0, 1, 0);
401        glRotatef(60, 1, 0, 0);
402        glCallList(LEAF);
403      glPopMatrix();
404    }
405  glPopAttrib();
406  glPopMatrix();
407  glEndList();
408
409  gluDeleteQuadric(cylquad);
410}
411
412 /*
413  * draw and build display list for tree
414  */
415void CreateTree(void)
416{
417  srand48(TreeSeed);
418
419  glNewList(TREE, GL_COMPILE);
420    glPushMatrix();
421    glPushAttrib(GL_LIGHTING_BIT);
422    glCallList(TREE_MAT);
423    glTranslatef(0, -1, 0);
424    FractalTree(0);
425    glPopAttrib();
426    glPopMatrix();
427  glEndList(); 
428}
429
430 /*
431  * new seed for a new tree (groan)
432  */
433void NewTree(void)
434{
435  TreeSeed = time(NULL);
436}
437
438/***************************************************************/
439/*********************** FRACTAL PLANET ************************/
440/***************************************************************/
441
442void CreateIsland(void)
443{
444  cutoff = .06;
445  CreateMountain();
446  cutoff = -1;
447  glNewList(ISLAND, GL_COMPILE);
448  glPushAttrib(GL_LIGHTING_BIT);
449  glMatrixMode(GL_MODELVIEW);
450  glPushMatrix();
451    glCallList(WATER_MAT);
452
453    glBegin(GL_QUADS);
454      glNormal3f(0, 1, 0);
455      glVertex3f(10, 0.01, 10);
456      glVertex3f(10, 0.01, -10);
457      glVertex3f(-10, 0.01, -10);
458      glVertex3f(-10, 0.01, 10);
459    glEnd();
460
461    glPushMatrix();
462    glTranslatef(0, -0.1, 0);
463    glCallList(MOUNTAIN);
464    glPopMatrix();
465
466    glPushMatrix();
467    glRotatef(135, 0, 1, 0);
468    glTranslatef(0.2, -0.15, -0.4);
469    glCallList(MOUNTAIN);
470    glPopMatrix();
471
472    glPushMatrix();
473    glRotatef(-60, 0, 1, 0);
474    glTranslatef(0.7, -0.07, 0.5);
475    glCallList(MOUNTAIN);
476    glPopMatrix();
477
478    glPushMatrix();
479    glRotatef(-175, 0, 1, 0);
480    glTranslatef(-0.7, -0.05, -0.5);
481    glCallList(MOUNTAIN);
482    glPopMatrix();
483
484    glPushMatrix();
485    glRotatef(165, 0, 1, 0);
486    glTranslatef(-0.9, -0.12, 0.0);
487    glCallList(MOUNTAIN);
488    glPopMatrix();
489
490  glPopMatrix();
491  glPopAttrib();
492  glEndList(); 
493}
494
495
496void NewFractals(void)
497{
498  NewMountain();
499  NewTree();
500}
501
502void Create(int fract)
503{
504  switch(fract) {
505    case MOUNTAIN:
506      CreateMountain();
507      break;
508    case TREE:
509      CreateTree();
510      break;
511    case ISLAND:
512      CreateIsland();
513      break;
514  }
515}
516
517
518
519/***************************************************************/
520/**************************** OPENGL ***************************/
521/***************************************************************/
522
523
524void SetupMaterials(void)
525{
526  GLfloat mtn_ambuse[] =   { 0.426, 0.256, 0.108, 1.0 };
527  GLfloat mtn_specular[] = { 0.394, 0.272, 0.167, 1.0 };
528  GLfloat mtn_shininess[] = { 10 };
529
530  GLfloat water_ambuse[] =   { 0.0, 0.1, 0.5, 1.0 };
531  GLfloat water_specular[] = { 0.0, 0.1, 0.5, 1.0 };
532  GLfloat water_shininess[] = { 10 };
533
534  GLfloat tree_ambuse[] =   { 0.4, 0.25, 0.1, 1.0 };
535  GLfloat tree_specular[] = { 0.0, 0.0, 0.0, 1.0 };
536  GLfloat tree_shininess[] = { 0 };
537
538  GLfloat leaf_ambuse[] =   { 0.0, 0.8, 0.0, 1.0 };
539  GLfloat leaf_specular[] = { 0.0, 0.8, 0.0, 1.0 };
540  GLfloat leaf_shininess[] = { 10 };
541
542  glNewList(MOUNTAIN_MAT, GL_COMPILE);
543    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mtn_ambuse);
544    glMaterialfv(GL_FRONT, GL_SPECULAR, mtn_specular);
545    glMaterialfv(GL_FRONT, GL_SHININESS, mtn_shininess);
546  glEndList();
547
548  glNewList(WATER_MAT, GL_COMPILE);
549    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, water_ambuse);
550    glMaterialfv(GL_FRONT, GL_SPECULAR, water_specular);
551    glMaterialfv(GL_FRONT, GL_SHININESS, water_shininess);
552  glEndList();
553
554  glNewList(TREE_MAT, GL_COMPILE);
555    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, tree_ambuse);
556    glMaterialfv(GL_FRONT, GL_SPECULAR, tree_specular);
557    glMaterialfv(GL_FRONT, GL_SHININESS, tree_shininess);
558  glEndList();
559
560  glNewList(LEAF_MAT, GL_COMPILE);
561    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, leaf_ambuse);
562    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, leaf_specular);
563    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, leaf_shininess);
564  glEndList();
565}
566
567void myGLInit(void)
568{
569  GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
570  GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
571  GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
572  GLfloat light_position[] = { 0.0, 0.3, 0.3, 0.0 };
573
574  GLfloat lmodel_ambient[] = { 0.4, 0.4, 0.4, 1.0 };
575
576  glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
577  glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
578  glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
579  glLightfv(GL_LIGHT0, GL_POSITION, light_position);
580   
581  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
582
583  glEnable(GL_LIGHTING);
584  glEnable(GL_LIGHT0);
585
586  glDepthFunc(GL_LEQUAL);
587  glEnable(GL_DEPTH_TEST);
588
589  glEnable(GL_NORMALIZE);
590#if 0
591  glEnable(GL_CULL_FACE);
592  glCullFace(GL_BACK);
593#endif
594
595  glShadeModel(GL_SMOOTH);
596#if 0
597  glEnable(GL_BLEND);
598  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
599#endif
600
601  SetupMaterials();
602  CreateTreeLists();
603
604  glFlush();
605}
606
607/***************************************************************/
608/************************ GLUT STUFF ***************************/
609/***************************************************************/
610
611int winwidth = 1;
612int winheight = 1;
613
614void reshape(int w, int h)
615{
616  glViewport(0,0,w,h);
617
618  winwidth  = w;
619  winheight = h;
620}
621
622void display(void)
623{
624  time_t curtime;
625  char buf[255];
626  static time_t fpstime = 0;
627  static int fpscount = 0;
628  static int fps = 0;
629
630  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
631
632  glMatrixMode(GL_PROJECTION);
633  glLoadIdentity();
634  gluPerspective(60.0, (GLdouble)winwidth/winheight, 0.01, 100);
635  agvViewTransform();
636
637  glMatrixMode(GL_MODELVIEW);
638  glLoadIdentity();
639
640  if (Rebuild) {
641    Create(fractal);
642    Rebuild = 0;
643  }
644
645  glCallList(fractal);
646
647  if (DrawAxes)
648    glCallList(AXES);
649
650  glMatrixMode(GL_PROJECTION);
651  glLoadIdentity();
652  gluOrtho2D(0.0, winwidth, 0.0, winheight);
653
654  sprintf(buf, "FPS=%d", fps);
655  glColor3f(1.0f, 1.0f, 1.0f);
656  gl_font(FL_HELVETICA, 12);
657  gl_draw(buf, 10, 10);
658
659  //
660  // Use glFinish() instead of glFlush() to avoid getting many frames
661  // ahead of the display (problem with some Linux OpenGL implementations...)
662  //
663
664  glFinish();
665
666  // Update frames-per-second
667  fpscount ++;
668  curtime = time(NULL);
669  if ((curtime - fpstime) >= 2)
670  {
671    fps      = (fps + fpscount / (curtime - fpstime)) / 2;
672    fpstime  = curtime;
673    fpscount = 0;
674  }
675}
676
677void visible(int v)
678{
679  if (v == GLUT_VISIBLE)
680    agvSetAllowIdle(1);
681  else {
682    glutIdleFunc(NULL);
683    agvSetAllowIdle(0);
684  }
685}
686
687void menuuse(int v)
688{
689  if (v == GLUT_MENU_NOT_IN_USE)
690    agvSetAllowIdle(1);
691  else {
692    glutIdleFunc(NULL);
693    agvSetAllowIdle(0);
694  }
695}
696
697/***************************************************************/
698/******************* MENU SETUP & HANDLING *********************/
699/***************************************************************/
700
701typedef enum { MENU_QUIT, MENU_RAND, MENU_MOVE, MENU_AXES } MenuChoices;
702
703void setlevel(int value)
704{
705  Level = value;
706  Rebuild = 1;
707  glutPostRedisplay();
708}
709
710void choosefract(int value)
711{
712  fractal = value;
713  Rebuild = 1;
714  glutPostRedisplay();
715}
716
717void handlemenu(int value)
718{
719  switch (value) {
720    case MENU_QUIT:
721      exit(0);
722      break;
723    case MENU_RAND:
724      NewFractals();
725      Rebuild = 1;
726      glutPostRedisplay();
727      break;
728    case MENU_AXES:
729      DrawAxes = !DrawAxes;
730      glutPostRedisplay();
731      break;
732    }
733}
734
735void MenuInit(void)
736{
737  int submenu3, submenu2, submenu1;
738
739  submenu1 = glutCreateMenu(setlevel);
740  glutAddMenuEntry((char *)"0", 0);  glutAddMenuEntry((char *)"1", 1);
741  glutAddMenuEntry((char *)"2", 2);  glutAddMenuEntry((char *)"3", 3);
742  glutAddMenuEntry((char *)"4", 4);  glutAddMenuEntry((char *)"5", 5);
743  glutAddMenuEntry((char *)"6", 6);  glutAddMenuEntry((char *)"7", 7);
744  glutAddMenuEntry((char *)"8", 8);
745
746  submenu2 = glutCreateMenu(choosefract);
747  glutAddMenuEntry((char *)"Moutain", MOUNTAIN);
748  glutAddMenuEntry((char *)"Tree", TREE);
749  glutAddMenuEntry((char *)"Island", ISLAND);
750
751  submenu3 = glutCreateMenu(agvSwitchMoveMode);
752  glutAddMenuEntry((char *)"Flying", FLYING);
753  glutAddMenuEntry((char *)"Polar", POLAR);
754
755  glutCreateMenu(handlemenu);
756  glutAddSubMenu((char *)"Level", submenu1);
757  glutAddSubMenu((char *)"Fractal", submenu2);
758  glutAddSubMenu((char *)"Movement", submenu3);
759  glutAddMenuEntry((char *)"New Fractal",      MENU_RAND);
760  glutAddMenuEntry((char *)"Toggle Axes", MENU_AXES);
761  glutAddMenuEntry((char *)"Quit",             MENU_QUIT);
762  glutAttachMenu(GLUT_RIGHT_BUTTON);
763}
764
765
766/***************************************************************/
767/**************************** MAIN *****************************/
768/***************************************************************/
769
770// FLTK-style callbacks to Glut menu callback translators:
771void setlevel(Fl_Widget*, void *value) {setlevel(long(value));}
772
773void choosefract(Fl_Widget*, void *value) {choosefract(long(value));}
774
775void handlemenu(Fl_Widget*, void *value) {handlemenu(long(value));}
776
777#include <FL/Fl_Button.H>
778#include <FL/Fl_Group.H>
779#include <FL/Fl_Window.H>
780
781int main(int argc, char** argv)
782{
783//  glutInit(&argc, argv); // this line removed for FLTK
784
785  // create FLTK window:
786  Fl_Window window(512+20, 512+100);
787  window.resizable(window);
788
789  // create a bunch of buttons:
790  Fl_Group *g = new Fl_Group(110,50,400-110,30,"Level:");
791  g->align(FL_ALIGN_LEFT);
792  g->begin();
793  Fl_Button *b;
794  b = new Fl_Button(110,50,30,30,"0"); b->callback(setlevel,(void*)0);
795  b = new Fl_Button(140,50,30,30,"1"); b->callback(setlevel,(void*)1);
796  b = new Fl_Button(170,50,30,30,"2"); b->callback(setlevel,(void*)2);
797  b = new Fl_Button(200,50,30,30,"3"); b->callback(setlevel,(void*)3);
798  b = new Fl_Button(230,50,30,30,"4"); b->callback(setlevel,(void*)4);
799  b = new Fl_Button(260,50,30,30,"5"); b->callback(setlevel,(void*)5);
800  b = new Fl_Button(290,50,30,30,"6"); b->callback(setlevel,(void*)6);
801  b = new Fl_Button(320,50,30,30,"7"); b->callback(setlevel,(void*)7);
802  b = new Fl_Button(350,50,30,30,"8"); b->callback(setlevel,(void*)8);
803  g->end();
804
805  b = new Fl_Button(400,50,100,30,"New Fractal"); b->callback(handlemenu,(void*)MENU_RAND);
806 
807  b = new Fl_Button( 10,10,100,30,"Mountain"); b->callback(choosefract,(void*)MOUNTAIN);
808  b = new Fl_Button(110,10,100,30,"Tree"); b->callback(choosefract,(void*)TREE);
809  b = new Fl_Button(210,10,100,30,"Island"); b->callback(choosefract,(void*)ISLAND);
810  b = new Fl_Button(400,10,100,30,"Quit"); b->callback(handlemenu,(void*)MENU_QUIT);
811
812
813  window.show(argc,argv); // glut will die unless parent window visible
814  window.begin(); // this will cause Glut window to be a child
815  glutInitWindowSize(512, 512);
816  glutInitWindowPosition(10,90); // place it inside parent window
817  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE);
818  glutCreateWindow("Fractal Planet?");
819  window.end();
820  window.resizable(glut_window);
821
822  agvInit(1); /* 1 cause we don't have our own idle */
823
824  glutReshapeFunc(reshape);
825  glutDisplayFunc(display);
826  glutVisibilityFunc(visible);
827  glutMenuStateFunc(menuuse);
828
829  NewFractals();
830  agvMakeAxesList(AXES);
831  myGLInit();
832  MenuInit();
833
834  glutMainLoop(); // you could use Fl::run() instead
835
836  return 0;
837}
838#endif
839
840//
841// End of "$Id$".
842//
Note: See TracBrowser for help on using the repository browser.