?? fractals.cxx
字號:
//// "$Id: fractals.cxx,v 1.1.1.1 2003/08/07 21:18:42 jasonk Exp $"//// Fractal drawing demo for the Fast Light Tool Kit (FLTK).//// This is a GLUT demo program, with modifications to// demonstrate how to add fltk controls to a glut program. The glut// code is unchanged except for the end (search for fltk to find changes).//// Copyright 1998-1999 by Bill Spitzak and others.//// This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Library General Public// License as published by the Free Software Foundation; either// version 2 of the License, or (at your option) any later version.//// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Library General Public License for more details.//// You should have received a copy of the GNU Library General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307// USA.//// Please report all bugs and problems to "fltk-bugs@easysw.com".//#include <config.h>#if !HAVE_GL#include <FL/Fl.H>#include <FL/fl_message.H>int main(int, char**) { fl_alert("This demo does not work without GL"); return 1;}#else/* * To compile: cc -o fractals fractals.c -lGL -lGLU -lX11 -lglut -lXmu -lm * * Usage: fractals * * Homework 6, Part 2: fractal mountains and fractal trees * (Pretty Late) * * Draws fractal mountains and trees -- and an island of mountains in water * (I tried having trees on the island but it didn't work too well.) * * Two viewer modes: polar and flying (both restrained to y>0 for up vector). * Keyboard 0->9 and +/- control speed when flying. * * Only keyboard commands are 0-9 and +/- for speed in flying mode. * * Fog would make the island look much better, but I couldn't get it to work * correctly. Would line up on -z axis not from eye. * * Philip Winston - 3/4/95 * pwinston@hmc.edu * http://www.cs.hmc.edu/people/pwinston * */#include <FL/glut.H>#include <stdio.h>#include <stdlib.h>#include <math.h>#include <limits.h> /* ULONG_MAX is defined here */#include <float.h> /* FLT_MAX is atleast defined here */#include <time.h> /* for random seed */#include "fracviewer.c" // changed from .h for fltk#if defined(WIN32) || defined(__EMX__)#define drand48() (((float) rand())/((float) RAND_MAX))#define srand48(x) (srand((x)))#endiftypedef enum { NOTALLOWED, MOUNTAIN, TREE, ISLAND, BIGMTN, STEM, LEAF, MOUNTAIN_MAT, WATER_MAT, LEAF_MAT, TREE_MAT, STEMANDLEAVES, AXES } DisplayLists;#define MAXLEVEL 8int Rebuild = 1, /* Rebuild display list in next display? */ Fract = TREE, /* What fractal are we building */ Level = 4; /* levels of recursion for fractals */ int DrawAxes = 0; /***************************************************************//************************* VECTOR JUNK *************************//***************************************************************/ /* print vertex to stderr */void printvert(float v[3]){ fprintf(stderr, "(%f, %f, %f)\n", v[0], v[1], v[2]);}#if 0 // removed for FL, it is in fracviewer.c /* normalizes v */void normalize(GLfloat v[3]){ GLfloat d = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); if (d == 0) fprintf(stderr, "Zero length vector in normalize\n"); else v[0] /= d; v[1] /= d; v[2] /= d;} /* calculates a normalized crossproduct to v1, v2 */void ncrossprod(float v1[3], float v2[3], float cp[3]){ cp[0] = v1[1]*v2[2] - v1[2]*v2[1]; cp[1] = v1[2]*v2[0] - v1[0]*v2[2]; cp[2] = v1[0]*v2[1] - v1[1]*v2[0]; normalize(cp);}#endif /* calculates normal to the triangle designated by v1, v2, v3 */void triagnormal(float v1[3], float v2[3], float v3[3], float norm[3]){ float vec1[3], vec2[3]; vec1[0] = v3[0] - v1[0]; vec2[0] = v2[0] - v1[0]; vec1[1] = v3[1] - v1[1]; vec2[1] = v2[1] - v1[1]; vec1[2] = v3[2] - v1[2]; vec2[2] = v2[2] - v1[2]; ncrossprod(vec2, vec1, norm);}float xzlength(float v1[3], float v2[3]){ return sqrt((v1[0] - v2[0])*(v1[0] - v2[0]) + (v1[2] - v2[2])*(v1[2] - v2[2]));}float xzslope(float v1[3], float v2[3]){ return ((v1[0] != v2[0]) ? ((v1[2] - v2[2]) / (v1[0] - v2[0])) : FLT_MAX);}/***************************************************************//************************ MOUNTAIN STUFF ***********************//***************************************************************/GLfloat DispFactor[MAXLEVEL]; /* Array of what to multiply random number by for a given level to get midpoint displacement */GLfloat DispBias[MAXLEVEL]; /* Array of what to add to random number before multiplying it by DispFactor */#define NUMRANDS 191float RandTable[NUMRANDS]; /* hash table of random numbers so we can raise the same midpoints by the same amount */ /* The following are for permitting an edge of a moutain to be */ /* pegged so it won't be displaced up or down. This makes it */ /* easier to setup scenes and makes a single moutain look better */GLfloat Verts[3][3], /* Vertices of outside edges of mountain */ Slopes[3]; /* Slopes between these outside edges */int Pegged[3]; /* Is this edge pegged or not */ /* * Comes up with a new table of random numbers [0,1) */void InitRandTable(unsigned int seed){ int i; srand48((long) seed); for (i = 0; i < NUMRANDS; i++) RandTable[i] = drand48() - 0.5;} /* calculate midpoint and displace it if required */void Midpoint(GLfloat mid[3], GLfloat v1[3], GLfloat v2[3], int edge, int level){ unsigned hash; mid[0] = (v1[0] + v2[0]) / 2; mid[1] = (v1[1] + v2[1]) / 2; mid[2] = (v1[2] + v2[2]) / 2; if (!Pegged[edge] || (fabs(xzslope(Verts[edge], mid) - Slopes[edge]) > 0.00001)) { srand48((int)((v1[0]+v2[0])*23344)); hash = unsigned(drand48() * 7334334); srand48((int)((v2[2]+v1[2])*43433)); hash = (unsigned)(drand48() * 634344 + hash) % NUMRANDS; mid[1] += ((RandTable[hash] + DispBias[level]) * DispFactor[level]); }} /* * Recursive moutain drawing routine -- from lecture with addition of * allowing an edge to be pegged. This function requires the above * globals to be set, as well as the Level global for fractal level */static float cutoff = -1;void FMR(GLfloat v1[3], GLfloat v2[3], GLfloat v3[3], int level){ if (level == Level) { GLfloat norm[3]; if (v1[1] <= cutoff && v2[1]<=cutoff && v3[1]<=cutoff) return; triagnormal(v1, v2, v3, norm); glNormal3fv(norm); glVertex3fv(v1); glVertex3fv(v2); glVertex3fv(v3); } else { GLfloat m1[3], m2[3], m3[3]; Midpoint(m1, v1, v2, 0, level); Midpoint(m2, v2, v3, 1, level); Midpoint(m3, v3, v1, 2, level); FMR(v1, m1, m3, level + 1); FMR(m1, v2, m2, level + 1); FMR(m3, m2, v3, level + 1); FMR(m1, m2, m3, level + 1); }} /* * sets up lookup tables and calls recursive mountain function */void FractalMountain(GLfloat v1[3], GLfloat v2[3], GLfloat v3[3], int pegged[3]){ GLfloat lengths[MAXLEVEL]; GLfloat fraction[8] = { 0.3, 0.3, 0.4, 0.2, 0.3, 0.2, 0.4, 0.4 }; GLfloat bias[8] = { 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 }; int i; float avglen = (xzlength(v1, v2) + xzlength(v2, v3) + xzlength(v3, v1) / 3); for (i = 0; i < 3; i++) { Verts[0][i] = v1[i]; /* set mountain vertex globals */ Verts[1][i] = v2[i]; Verts[2][i] = v3[i]; Pegged[i] = pegged[i]; } Slopes[0] = xzslope(Verts[0], Verts[1]); /* set edge slope globals */ Slopes[1] = xzslope(Verts[1], Verts[2]); Slopes[2] = xzslope(Verts[2], Verts[0]); lengths[0] = avglen; for (i = 1; i < Level; i++) { lengths[i] = lengths[i-1]/2; /* compute edge length for each level */ } for (i = 0; i < Level; i++) { /* DispFactor and DispBias arrays */ DispFactor[i] = (lengths[i] * ((i <= 7) ? fraction[i] : fraction[7])); DispBias[i] = ((i <= 7) ? bias[i] : bias[7]); } glBegin(GL_TRIANGLES); FMR(v1, v2, v3, 0); /* issues no GL but vertex calls */ glEnd();} /* * draw a mountain and build the display list */void CreateMountain(void){ GLfloat v1[3] = { 0, 0, -1 }, v2[3] = { -1, 0, 1 }, v3[3] = { 1, 0, 1 }; int pegged[3] = { 1, 1, 1 }; glNewList(MOUNTAIN, GL_COMPILE); glPushAttrib(GL_LIGHTING_BIT); glCallList(MOUNTAIN_MAT); FractalMountain(v1, v2, v3, pegged); glPopAttrib(); glEndList();} /* * new random numbers to make a different moutain */void NewMountain(void){ InitRandTable(time(NULL));}/***************************************************************//***************************** TREE ****************************//***************************************************************/long TreeSeed; /* for srand48 - remember so we can build "same tree" at a different level */ /* * recursive tree drawing thing, fleshed out from class notes pseudocode */void FractalTree(int level){ long savedseed; /* need to save seeds while building tree too */ if (level == Level) { glPushMatrix(); glRotatef(drand48()*180, 0, 1, 0); glCallList(STEMANDLEAVES); glPopMatrix(); } else { glCallList(STEM); glPushMatrix(); glRotatef(drand48()*180, 0, 1, 0); glTranslatef(0, 1, 0); glScalef(0.7, 0.7, 0.7); savedseed = (long)((ulong)drand48()*ULONG_MAX); glPushMatrix(); glRotatef(110 + drand48()*40, 0, 1, 0); glRotatef(30 + drand48()*20, 0, 0, 1); FractalTree(level + 1); glPopMatrix(); srand48(savedseed); savedseed = (long)((ulong)drand48()*ULONG_MAX); glPushMatrix(); glRotatef(-130 + drand48()*40, 0, 1, 0); glRotatef(30 + drand48()*20, 0, 0, 1); FractalTree(level + 1); glPopMatrix(); srand48(savedseed); glPushMatrix(); glRotatef(-20 + drand48()*40, 0, 1, 0); glRotatef(30 + drand48()*20, 0, 0, 1); FractalTree(level + 1); glPopMatrix(); glPopMatrix(); }} /* * Create display lists for a leaf, a set of leaves, and a stem */void CreateTreeLists(void){ GLUquadricObj *cylquad = gluNewQuadric(); int i; glNewList(STEM, GL_COMPILE); glPushMatrix(); glRotatef(-90, 1, 0, 0); gluCylinder(cylquad, 0.1, 0.08, 1, 10, 2 ); glPopMatrix(); glEndList(); glNewList(LEAF, GL_COMPILE); /* I think this was jeff allen's leaf idea */ glBegin(GL_TRIANGLES); glNormal3f(-0.1, 0, 0.25); /* not normalized */ glVertex3f(0, 0, 0); glVertex3f(0.25, 0.25, 0.1); glVertex3f(0, 0.5, 0); glNormal3f(0.1, 0, 0.25); glVertex3f(0, 0, 0); glVertex3f(0, 0.5, 0); glVertex3f(-0.25, 0.25, 0.1); glEnd(); glEndList(); glNewList(STEMANDLEAVES, GL_COMPILE); glPushMatrix(); glPushAttrib(GL_LIGHTING_BIT); glCallList(STEM); glCallList(LEAF_MAT); for(i = 0; i < 3; i++) { glTranslatef(0, 0.333, 0); glRotatef(90, 0, 1, 0); glPushMatrix(); glRotatef(0, 0, 1, 0); glRotatef(50, 1, 0, 0); glCallList(LEAF); glPopMatrix(); glPushMatrix(); glRotatef(180, 0, 1, 0); glRotatef(60, 1, 0, 0); glCallList(LEAF); glPopMatrix(); } glPopAttrib(); glPopMatrix(); glEndList(); gluDeleteQuadric(cylquad);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -