#include #include #include #include #include #include #include #include #include /* Demonstration OpenGL application Create a model of a pulsar */ typedef struct { double x,y,z; } XYZ; typedef struct { double r,g,b; } COLOUR; typedef struct { unsigned char r,g,b,a; } PIXELA; typedef struct { XYZ vp; /* View position */ XYZ vd; /* View direction vector */ XYZ vu; /* View up direction */ XYZ pr; /* Point to rotate about */ double focallength; /* Focal Length along vd */ double aperture; /* Camera aperture */ double eyesep; /* Eye separation */ int screenwidth,screenheight; } CAMERA; void DrawBlueLine(void); void Display(void); void CreateEnvironment(void); void MakeGeometry(void); void MakeLighting(void); void HandleKeyboard(unsigned char key,int x, int y); void HandleSpecialKeyboard(int key,int x, int y); void HandleMouse(int,int,int,int); void HandleMainMenu(int); void HandleSpeedMenu(int); void HandleSpinMenu(int); void HandleVisibility(int vis); void HandleReshape(int,int); void HandleMouseMotion(int,int); void HandlePassiveMotion(int,int); void HandleIdle(void); void GiveUsage(char *); void RotateCamera(int,int,int); void TranslateCamera(int,int); void CameraHome(int); void Normalise(XYZ *); XYZ CalcNormal(XYZ,XYZ,XYZ); int WindowDump(int,int,int); #define ABS(x) (x < 0 ? -(x) : (x)) #define MIN(x,y) (x < y ? x : y) #define MAX(x,y) (x > y ? x : y) #define TRUE 1 #define FALSE 0 #define ESC 27 #define PI 3.141592653589793238462643 #define DTOR 0.0174532925 #define RTOD 57.2957795 #define CROSSPROD(p1,p2,p3) \ p3.x = p1.y*p2.z - p1.z*p2.y; \ p3.y = p1.z*p2.x - p1.x*p2.z; \ p3.z = p1.x*p2.y - p1.y*p2.x /* Flags */ int fullscreen = FALSE; int stereo = FALSE; int showconstruct = FALSE; int windowdump = FALSE; int record = FALSE; int debug = FALSE; int currentbutton = -1; double rotatespeed = 1; double dtheta = 1; CAMERA camera; XYZ origin = {0.0,0.0,0.0}; double rotateangle = 0.0; /* Pulsar Rotation angle */ int main(int argc,char **argv) { int i; int mainmenu,speedmenu,spinmenu; camera.screenwidth = 400; camera.screenheight = 300; /* Parse the command line arguments */ for (i=1;ix * p->x + p->y * p->y + p->z * p->z); if (length != 0) { p->x /= length; p->y /= length; p->z /= length; } else { p->x = 0; p->y = 0; p->z = 0; } } XYZ CalcNormal(XYZ p,XYZ p1,XYZ p2) { XYZ n,pa,pb; pa.x = p1.x - p.x; pa.y = p1.y - p.y; pa.z = p1.z - p.z; pb.x = p2.x - p.x; pb.y = p2.y - p.y; pb.z = p2.z - p.z; Normalise(&pa); Normalise(&pb); n.x = pa.y * pb.z - pa.z * pb.y; n.y = pa.z * pb.x - pa.x * pb.z; n.z = pa.x * pb.y - pa.y * pb.x; Normalise(&n); return(n); } /* Move the camera to the home position */ void CameraHome(int mode) { camera.aperture = 50; camera.focallength = 70; camera.eyesep = camera.focallength / 20; camera.pr = origin; /* camera.vp.x = camera.focallength; camera.vp.y = 0; camera.vp.z = 0; camera.vd.x = -1; camera.vd.y = 0; camera.vd.z = 0; */ /* Special camera position so the beam crosses the view */ camera.vp.x = 39; camera.vp.y = 53; camera.vp.z = 22; camera.vd.x = -camera.vp.x; camera.vd.y = -camera.vp.y; camera.vd.z = -camera.vp.z; camera.vu.x = 0; camera.vu.y = 1; camera.vu.z = 0; } /* Handle mouse motion */ void HandleMouseMotion(int x,int y) { static int xlast=-1,ylast=-1; int dx,dy; dx = x - xlast; dy = y - ylast; if (dx < 0) dx = -1; else if (dx > 0) dx = 1; if (dy < 0) dy = -1; else if (dy > 0) dy = 1; if (currentbutton == GLUT_LEFT_BUTTON) RotateCamera(-dx,dy,0); else if (currentbutton == GLUT_MIDDLE_BUTTON) RotateCamera(0,0,dx); xlast = x; ylast = y; } /* Write the current view to a PPM file Do the right thing for stereo, ie: two images */ int WindowDump(int width,int height,int stereo) { int i,j; FILE *fptr; static int counter = 0; char fname[32]; unsigned char *image; /* Allocate our buffer for the image */ if ((image = malloc(3*width*height*sizeof(char))) == NULL) { fprintf(stderr,"WindowDump - Failed to allocate memory for image\n"); return(FALSE); } /* Open the file */ sprintf(fname,"L_%04d.ppm",counter); if ((fptr = fopen(fname,"w")) == NULL) { fprintf(stderr,"WindowDump - Failed to open file for window dump\n"); return(FALSE); } /* Copy the image into our buffer */ glReadBuffer(GL_BACK_LEFT); glReadPixels(0,0,width,height,GL_RGB,GL_UNSIGNED_BYTE,image); /* Write the PPM file */ fprintf(fptr,"P3\n%d %d\n255\n",width,height); for (j=height-1;j>=0;j--) { for (i=0;i=0;j--) { for (i=0;i