diff options
| author | Michael R Sweet <michael.r.sweet@gmail.com> | 2002-01-03 14:08:08 +0000 |
|---|---|---|
| committer | Michael R Sweet <michael.r.sweet@gmail.com> | 2002-01-03 14:08:08 +0000 |
| commit | 81be28e2dd5c7609ba9a07f20646b05bcb53e727 (patch) | |
| tree | 113678c885d4f1ef191a67b9c6daa74b708628b1 /test/fracviewer.c | |
| parent | 1775984dbea2b186a9cd7b5a8b697558028e7da9 (diff) | |
Fixup fractals demo so it doesn't get way ahead of display - some Linux
OpenGL implementations can queue dozens of frames...
Also fix controls in "flying" mode - the Y axis was reversed.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@1907 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'test/fracviewer.c')
| -rw-r--r-- | test/fracviewer.c | 496 |
1 files changed, 0 insertions, 496 deletions
diff --git a/test/fracviewer.c b/test/fracviewer.c deleted file mode 100644 index 9d926c175..000000000 --- a/test/fracviewer.c +++ /dev/null @@ -1,496 +0,0 @@ -/* - * fractviewer.c [from agviewer.c (version 1.0)] - * - * AGV: a glut viewer. Routines for viewing a 3d scene w/ glut - * - * See agv_example.c and agviewer.h comments within for more info. - * - * I welcome any feedback or improved versions! - * - * Philip Winston - 4/11/95 - * pwinston@hmc.edu - * http://www.cs.hmc.edu/people/pwinston - */ - -#include <GL/glut.h> -#include <stdio.h> -#include <stdlib.h> -#include <math.h> - -#include "fracviewer.h" - -/* Some <math.h> files do not define M_PI... */ -#ifndef M_PI -#define M_PI 3.14159265 -#endif - -/***************************************************************/ -/************************** SETTINGS ***************************/ -/***************************************************************/ - - /* Initial polar movement settings */ -#define INIT_POLAR_AZ 0.0 -#define INIT_POLAR_EL 30.0 -#define INIT_DIST 4.0 -#define INIT_AZ_SPIN 0.5 -#define INIT_EL_SPIN 0.0 - - /* Initial flying movement settings */ -#define INIT_EX 0.0 -#define INIT_EY -2.0 -#define INIT_EZ -2.0 -#define INIT_MOVE 0.01 -#define MINMOVE 0.001 - - /* Start in this mode */ -#define INIT_MODE POLAR - - /* Controls: */ - - /* map 0-9 to an EyeMove value when number key is hit in FLYING mode */ -#define SPEEDFUNCTION(x) ((x)*(x)*0.001) - - /* Multiply EyeMove by (1+-MOVEFRACTION) when +/- hit in FLYING mode */ -#define MOVEFRACTION 0.25 - - /* What to multiply number of pixels mouse moved by to get rotation amount */ -#define EL_SENS 0.5 -#define AZ_SENS 0.5 - - /* What to multiply number of pixels mouse moved by for movement amounts */ -#define DIST_SENS 0.01 -#define E_SENS 0.01 - - /* Minimum spin to allow in polar (lower forced to zero) */ -#define MIN_AZSPIN 0.1 -#define MIN_ELSPIN 0.1 - - /* Factors used in computing dAz and dEl (which determine AzSpin, ElSpin) */ -#define SLOW_DAZ 0.90 -#define SLOW_DEL 0.90 -#define PREV_DAZ 0.80 -#define PREV_DEL 0.80 -#define CUR_DAZ 0.20 -#define CUR_DEL 0.20 - -/***************************************************************/ -/************************** GLOBALS ****************************/ -/***************************************************************/ - -int MoveMode = INIT_MODE; /* FLYING or POLAR mode? */ - -GLfloat Ex = INIT_EX, /* flying parameters */ - Ey = INIT_EY, - Ez = INIT_EZ, - EyeMove = INIT_MOVE, - - EyeDist = INIT_DIST, /* polar params */ - AzSpin = INIT_AZ_SPIN, - ElSpin = INIT_EL_SPIN, - - EyeAz = INIT_POLAR_AZ, /* used by both */ - EyeEl = INIT_POLAR_EL; - -int agvMoving; /* Currently moving? */ - -int downx, downy, /* for tracking mouse position */ - lastx, lasty, - downb = -1; /* and button status */ - -GLfloat downDist, downEl, downAz, /* for saving state of things */ - downEx, downEy, downEz, /* when button is pressed */ - downEyeMove; - -GLfloat dAz, dEl, lastAz, lastEl; /* to calculate spinning w/ polar motion */ -int AdjustingAzEl = 0; - -int AllowIdle, RedisplayWindow; - /* If AllowIdle is 1 it means AGV will install its own idle which - * will update the viewpoint as needed and send glutPostRedisplay() to the - * window RedisplayWindow which was set in agvInit(). AllowIdle of 0 - * means AGV won't install an idle funciton, and something like - * "if (agvMoving) agvMove()" should exist at the end of the running - * idle function. - */ - -#define MAX(x,y) (((x) > (y)) ? (x) : (y)) -#define TORAD(x) ((M_PI/180.0)*(x)) -#define TODEG(x) ((180.0/M_PI)*(x)) - -/***************************************************************/ -/************************ PROTOTYPES ***************************/ -/***************************************************************/ - - /* - * these are functions meant for internal use only - * the other prototypes are in agviewer.h - */ - -void PolarLookFrom(GLfloat dist, GLfloat elevation, GLfloat azimuth); -void FlyLookFrom(GLfloat x, GLfloat y, GLfloat z, - GLfloat az, GLfloat el); -int ConstrainEl(void); -void MoveOn(int v); -void SetMove(float newmove); -static void normalize(GLfloat v[3]); -static void ncrossprod(float v1[3], float v2[3], float cp[3]); - - -/***************************************************************/ -/************************ agvInit ******************************/ -/***************************************************************/ - -void agvInit(int window) -{ - glutMouseFunc(agvHandleButton); - glutMotionFunc(agvHandleMotion); - glutKeyboardFunc(agvHandleKeys); - RedisplayWindow = glutGetWindow(); - agvSetAllowIdle(window); -} - -/***************************************************************/ -/************************ VIEWPOINT STUFF **********************/ -/***************************************************************/ - - /* - * viewing transformation modified from page 90 of red book - */ -void PolarLookFrom(GLfloat dist, GLfloat elevation, GLfloat azimuth) -{ - glTranslatef(0, 0, -dist); - glRotatef(elevation, 1, 0, 0); - glRotatef(azimuth, 0, 1, 0); - -} - - /* - * I took the idea of tracking eye position in absolute - * coords and direction looking in Polar form from denis - */ -void FlyLookFrom(GLfloat x, GLfloat y, GLfloat z, GLfloat az, GLfloat el) -{ - float lookat[3], perp[3], up[3]; - - lookat[0] = sin(TORAD(az))*cos(TORAD(el)); - lookat[1] = sin(TORAD(el)); - lookat[2] = -cos(TORAD(az))*cos(TORAD(el)); - normalize(lookat); - perp[0] = lookat[2]; - perp[1] = 0; - perp[2] = -lookat[0]; - normalize(perp); - ncrossprod(lookat, perp, up); - gluLookAt(x, y, z, - x+lookat[0], y+lookat[1], z+lookat[2], - up[0], up[1], up[2]); -} - - /* - * Call viewing transformation based on movement mode - */ -void agvViewTransform(void) -{ - switch (MoveMode) { - case FLYING: - FlyLookFrom(Ex, Ey, Ez, EyeAz, EyeEl); - break; - case POLAR: - PolarLookFrom(EyeDist, EyeEl, EyeAz); - break; - } -} - - /* - * keep them vertical; I think this makes a lot of things easier, - * but maybe it wouldn't be too hard to adapt things to let you go - * upside down - */ -int ConstrainEl(void) -{ - if (EyeEl <= -90) { - EyeEl = -89.99; - return 1; - } else if (EyeEl >= 90) { - EyeEl = 89.99; - return 1; - } - return 0; -} - - /* - * Idle Function - moves eyeposition - */ -void agvMove(void) -{ - - switch (MoveMode) { - case FLYING: - Ex += EyeMove*sin(TORAD(EyeAz))*cos(TORAD(EyeEl)); - Ey += EyeMove*sin(TORAD(EyeEl)); - Ez -= EyeMove*cos(TORAD(EyeAz))*cos(TORAD(EyeEl)); - break; - - case POLAR: - EyeEl += ElSpin; - EyeAz += AzSpin; - if (ConstrainEl()) { /* weird spin thing to make things look */ - ElSpin = -ElSpin; /* look better when you are kept from going */ - /* upside down while spinning - Isn't great */ - if (fabs(ElSpin) > fabs(AzSpin)) - AzSpin = fabs(ElSpin) * ((AzSpin > 0) ? 1 : -1); - } - break; - } - - if (AdjustingAzEl) { - dAz *= SLOW_DAZ; - dEl *= SLOW_DEL; - } - - if (AllowIdle) { - glutSetWindow(RedisplayWindow); - glutPostRedisplay(); - } -} - - - /* - * Don't install agvMove as idle unless we will be updating the view - * and we've been given a RedisplayWindow - */ -void MoveOn(int v) -{ - if (v && ((MoveMode == FLYING && EyeMove != 0) || - (MoveMode == POLAR && - (AzSpin != 0 || ElSpin != 0 || AdjustingAzEl)))) { - agvMoving = 1; - if (AllowIdle) - glutIdleFunc(agvMove); - } else { - agvMoving = 0; - if (AllowIdle) - glutIdleFunc(NULL); - } -} - - /* - * set new redisplay window. If <= 0 it means we are not to install - * an idle function and will rely on whoever does install one to - * put statement like "if (agvMoving) agvMove();" at end of it - */ -void agvSetAllowIdle(int allowidle) -{ - if ((AllowIdle = allowidle)) - MoveOn(1); -} - - - /* - * when moving to flying we stay in the same spot, moving to polar we - * reset since we have to be looking at the origin (though a pivot from - * current position to look at origin might be cooler) - */ -void agvSwitchMoveMode(int move) -{ - switch (move) { - case FLYING: - if (MoveMode == FLYING) return; - Ex = -EyeDist*sin(TORAD(EyeAz))*cos(TORAD(EyeEl)); - Ey = EyeDist*sin(TORAD(EyeEl)); - Ez = EyeDist*(cos(TORAD(EyeAz))*cos(TORAD(EyeEl))); - EyeAz = EyeAz; - EyeEl = -EyeEl; - EyeMove = INIT_MOVE; - break; - case POLAR: - EyeDist = INIT_DIST; - EyeAz = INIT_POLAR_AZ; - EyeEl = INIT_POLAR_EL; - AzSpin = INIT_AZ_SPIN; - ElSpin = INIT_EL_SPIN; - break; - } - MoveMode = move; - MoveOn(1); - glutPostRedisplay(); -} - -/***************************************************************/ -/******************* MOUSE HANDLING ***********************/ -/***************************************************************/ - -void agvHandleButton(int button, int state, int x, int y) -{ - if (state == GLUT_DOWN && downb == -1) { - lastx = downx = x; - lasty = downy = y; - downb = button; - - switch (button) { - case GLUT_LEFT_BUTTON: - lastEl = downEl = EyeEl; - lastAz = downAz = EyeAz; - AzSpin = ElSpin = dAz = dEl = 0; - AdjustingAzEl = 1; - MoveOn(1); - break; - - case GLUT_MIDDLE_BUTTON: - downDist = EyeDist; - downEx = Ex; - downEy = Ey; - downEz = Ez; - downEyeMove = EyeMove; - EyeMove = 0; - } - - } else if (state == GLUT_UP && button == downb) { - - downb = -1; - - switch (button) { - case GLUT_LEFT_BUTTON: - if (MoveMode != FLYING) { - AzSpin = -dAz; - if (AzSpin < MIN_AZSPIN && AzSpin > -MIN_AZSPIN) - AzSpin = 0; - ElSpin = -dEl; - if (ElSpin < MIN_ELSPIN && ElSpin > -MIN_ELSPIN) - ElSpin = 0; - } - AdjustingAzEl = 0; - MoveOn(1); - break; - - case GLUT_MIDDLE_BUTTON: - EyeMove = downEyeMove; - } - } -} - - /* - * change EyeEl and EyeAz and position when mouse is moved w/ button down - */ -void agvHandleMotion(int x, int y) -{ - int deltax = x - downx, deltay = y - downy; - - switch (downb) { - case GLUT_LEFT_BUTTON: - EyeEl = downEl + EL_SENS * ((MoveMode == FLYING) ? -deltay : deltay); - ConstrainEl(); - EyeAz = downAz + AZ_SENS * deltax; - dAz = PREV_DAZ*dAz + CUR_DAZ*(lastAz - EyeAz); - dEl = PREV_DEL*dEl + CUR_DEL*(lastEl - EyeEl); - lastAz = EyeAz; - lastEl = EyeEl; - break; - case GLUT_MIDDLE_BUTTON: - EyeDist = downDist + DIST_SENS*deltay; - Ex = downEx - E_SENS*deltay*sin(TORAD(EyeAz))*cos(TORAD(EyeEl)); - Ey = downEy - E_SENS*deltay*sin(TORAD(EyeEl)); - Ez = downEz + E_SENS*deltay*cos(TORAD(EyeAz))*cos(TORAD(EyeEl)); - break; - } - glutPostRedisplay(); -} - -/***************************************************************/ -/********************* KEYBOARD HANDLING ***********************/ -/***************************************************************/ - - /* - * set EyeMove (current speed) for FLYING mode - */ -void SetMove(float newmove) -{ - if (newmove > MINMOVE) { - EyeMove = newmove; - MoveOn(1); - } else { - EyeMove = 0; - MoveOn(0); - } -} - - /* - * 0->9 set speed, +/- adjust current speed -- in FLYING mode - */ -void agvHandleKeys(unsigned char key, int, int) { - if (MoveMode != FLYING) - return; - - if (key >= '0' && key <= '9') - SetMove(SPEEDFUNCTION((key-'0'))); - else - switch(key) { - case '+': - if (EyeMove == 0) - SetMove(MINMOVE); - else - SetMove(EyeMove *= (1 + MOVEFRACTION)); - break; - case '-': - SetMove(EyeMove *= (1 - MOVEFRACTION)); - break; - } -} - -/***************************************************************/ -/*********************** VECTOR STUFF **************************/ -/***************************************************************/ - - /* normalizes v */ -static 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 */ -static 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); -} - -/***************************************************************/ -/**************************** AXES *****************************/ -/***************************************************************/ - - - /* draw axes -- was helpful to debug/design things */ -void agvMakeAxesList(int displaylistnum) -{ - int i,j; - GLfloat axes_ambuse[] = { 0.5, 0.0, 0.0, 1.0 }; - glNewList(displaylistnum, GL_COMPILE); - glPushAttrib(GL_LIGHTING_BIT); - glMatrixMode(GL_MODELVIEW); - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, axes_ambuse); - glBegin(GL_LINES); - glVertex3f(15, 0, 0); glVertex3f(-15, 0, 0); - glVertex3f(0, 15, 0); glVertex3f(0, -15, 0); - glVertex3f(0, 0, 15); glVertex3f(0, 0, -15); - glEnd(); - for (i = 0; i < 3; i++) { - glPushMatrix(); - glTranslatef(-10*(i==0), -10*(i==1), -10*(i==2)); - for (j = 0; j < 21; j++) { -// glutSolidCube(0.1); - glTranslatef(i==0, i==1, i==2); - } - glPopMatrix(); - } - glPopAttrib(); - glEndList(); -} - - |
