home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / tutorials / custEducation / opengl2 / examples / porting / xsolar_opengl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  10.5 KB  |  401 lines

  1. /*                xsolar_opengl.c
  2.  *    Displays a planet with a moon, orbiting a sun.
  3.  *     Uses X and Open GL widget.
  4.  *
  5.  *    Exit with the ESCape key or through the window manager menu.
  6.  */
  7. #include <Xm/Xm.h>
  8. #include <Xm/Frame.h>
  9. #include <Xm/Form.h>
  10. #include <X11/StringDefs.h>
  11. #include <X11/keysym.h>
  12.  
  13. #include <GL/GLwMDrawA.h>
  14. #include <GL/gl.h>
  15. #include <GL/glu.h>
  16. #include <GL/glx.h>
  17. #include <stdio.h>
  18. #include <math.h>
  19.  
  20. typedef struct _spin {
  21.     GLfloat year;
  22. } SPINDATA, *SPINPTR;
  23.  
  24. /* function prototypes */
  25.  
  26. void main(int argc, char **argv);
  27.  
  28. void initCB (Widget w, XtPointer client_data, XtPointer call_data);
  29. void exposeCB (Widget w, XtPointer spin, XtPointer call_data);
  30. void resizeCB (Widget w, XtPointer spin, XtPointer call_data);
  31. void inputCB (Widget w, XtPointer client_data, XtPointer call_data);
  32.  
  33. GLboolean drawWP (XtPointer spin);
  34.  
  35. void drawscene(SPINPTR spin);
  36. void setbeachball(int stripes);
  37. void beachball(unsigned long color1, unsigned long color2);
  38.  
  39. SPINPTR spin;
  40.  
  41. static XtAppContext app_context;
  42. static XtWorkProcId workprocid = NULL;
  43.  
  44. GLXContext    glx_context;
  45. Display     *global_display;
  46. Window         global_window;
  47.  
  48. /* Create application context, and a form widget to contain
  49.  * the Open GL widget.  Set up the Open GL widget callbacks
  50.  */
  51. void main(int argc, char **argv)
  52. {
  53.     Arg wargs[15];
  54.     int n;
  55.     Widget glw, toplevel, frame, form;
  56.  
  57.     static String fallback_resources[] = {
  58.         "*frame*shadowType: SHADOW_IN",
  59.         "*glwidget*width: 750",
  60.         "*glwidget*height: 600",
  61.         "*glwidget*rgba: TRUE",
  62.         "*glwidget*doublebuffer: TRUE",
  63.         "*glwidget*allocateBackground: TRUE",
  64.         NULL
  65.     };
  66.  
  67.     /*    create main data structure, spin pointer    */
  68.     spin = (SPINPTR) malloc (sizeof (SPINDATA));
  69.     spin->year = 0.0;
  70.  
  71.     toplevel = XtAppInitialize(
  72.             &app_context,    /* Application context */
  73.             "XSolar",    /* Application class */
  74.             NULL, 0,     /* command line option list */
  75.             &argc, argv,    /* command line args */
  76.             fallback_resources,
  77.             NULL,        /*  argument list  */
  78.             0);        /* number of arguments */
  79.  
  80.     n = 0;
  81.     form = XmCreateForm(toplevel, "form", wargs, n);
  82.     XtManageChild(form);
  83.  
  84.     n = 0;
  85.     XtSetArg(wargs[n], XtNx, 30); n++;
  86.     XtSetArg(wargs[n], XtNy, 30); n++;
  87.     XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  88.     XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_FORM); n++;
  89.     XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
  90.     XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_FORM); n++;
  91.  
  92.     XtSetArg(wargs[n], XmNleftOffset, 30); n++;
  93.     XtSetArg(wargs[n], XmNbottomOffset, 30); n++;
  94.     XtSetArg(wargs[n], XmNrightOffset, 30); n++;
  95.     XtSetArg(wargs[n], XmNtopOffset, 30); n++;
  96.     frame = XmCreateFrame (form, "frame", wargs, n);
  97.     XtManageChild (frame);
  98.  
  99.     n = 0;
  100.     glw = GLwCreateMDrawingArea(frame, "glwidget", wargs, n);
  101.     XtManageChild (glw);
  102.     XtAddCallback(glw, GLwNginitCallback, initCB, 
  103.         (XtPointer) NULL);
  104.     XtAddCallback(glw, GLwNexposeCallback, exposeCB, 
  105.         (XtPointer) spin);
  106.     XtAddCallback(glw, GLwNresizeCallback, resizeCB, 
  107.         (XtPointer) spin);
  108.     XtAddCallback(glw, GLwNinputCallback, inputCB, 
  109.         (XtPointer) NULL);
  110.  
  111.     XtRealizeWidget(toplevel);    /* instantiate it now */
  112.     XtAppMainLoop(app_context);    /* loop for events */
  113. }    /*   end main()   */
  114.  
  115. /*        initCB     
  116.  *    The initCB subroutine initializes graphics modes and
  117.  *    transformation matrices.
  118.  */
  119.  
  120. void initCB (Widget w, XtPointer client_data, XtPointer call_data)
  121. {
  122.     Arg args[1];
  123.     XVisualInfo *vi;
  124.  
  125.     XtSetArg(args[0], GLwNvisualInfo, &vi);
  126.     XtGetValues(w, args, 1);
  127.  
  128.     global_display = XtDisplay(w);
  129.     global_window = XtWindow(w);
  130.     glx_context = glXCreateContext(global_display, vi, 0, GL_FALSE);
  131. }    /*   end initCB()   */
  132.  
  133. /*    exposeCB() and resizeCB() are called when the window
  134.  *    is uncovered, moved, or resized.
  135.  */
  136.  
  137. void exposeCB (Widget w, XtPointer ptr, XtPointer call_data)
  138. {
  139.     SPINPTR spin = (SPINPTR) ptr;
  140.     static int first_time = 1;
  141.     GLwDrawingAreaCallbackStruct *call_ptr = 
  142.         (GLwDrawingAreaCallbackStruct *) call_data;
  143.  
  144.     GLwDrawingAreaMakeCurrent(w, glx_context);
  145.  
  146.     if (first_time) {
  147.         glClearColor(0.0, 0.0, 0.0, 0.0);   
  148.  
  149.         glShadeModel(GL_FLAT);
  150.         glEnable(GL_DEPTH_TEST);
  151.  
  152.         glMatrixMode(GL_PROJECTION);
  153.         glLoadIdentity();
  154.         gluPerspective(45.0, (GLfloat)(call_ptr->width)
  155.                 /(GLfloat)(call_ptr->height), 1.0, 25.0);
  156.         glMatrixMode(GL_MODELVIEW);
  157.         glLoadIdentity();
  158.         glTranslatef(0.0, 0.0, -12.0);
  159.  
  160.         workprocid = XtAppAddWorkProc 
  161.             (app_context, drawWP, spin);    /*  ptr is spin  */
  162.         first_time = 0;
  163.     }
  164.     drawscene(spin);
  165. }
  166.  
  167. void resizeCB (Widget w, XtPointer ptr, XtPointer call_data)
  168. {
  169.     SPINPTR spin = (SPINPTR) ptr;
  170.     GLwDrawingAreaCallbackStruct *call_ptr = 
  171.         (GLwDrawingAreaCallbackStruct *) call_data;
  172.  
  173.     GLwDrawingAreaMakeCurrent(w, glx_context);
  174.  
  175.     glViewport(0, 0, (GLsizei) (call_ptr->width-1),
  176.             (GLsizei) (call_ptr->height-1));
  177.  
  178.     glMatrixMode(GL_PROJECTION);
  179.     glLoadIdentity();
  180.     gluPerspective(45.0, (GLfloat)(call_ptr->width)
  181.             /(GLfloat)(call_ptr->height), 1.0, 25.0);
  182.     glMatrixMode(GL_MODELVIEW);
  183.     glLoadIdentity ();
  184.     glTranslatef(0.0, 0.0, -12.0);
  185.  
  186.     drawscene(spin);
  187. }
  188.  
  189. /*    inputCB() handles all types of input from the GL widget.
  190.  *    The KeyRelease handles the ESCape key, so that it exits
  191.  *    the program.  
  192.  */
  193. void inputCB (Widget w, XtPointer client_data, 
  194.     XtPointer call_data)
  195. {
  196.     char buffer[1];
  197.     KeySym keysym;
  198.     GLwDrawingAreaCallbackStruct *call_ptr = 
  199.         (GLwDrawingAreaCallbackStruct *) call_data;
  200.     XKeyEvent *kevent = (XKeyEvent *) (call_ptr->event);
  201.  
  202.     GLwDrawingAreaMakeCurrent(w, glx_context);
  203.  
  204.     switch(call_ptr->event->type) {
  205.     case KeyRelease:
  206.         /* It is necessary to convert the keycode to a 
  207.          * keysym before checking if it is an escape */
  208.         if (XLookupString(kevent,buffer,1,&keysym,NULL) == 1 
  209.             && keysym == (KeySym)XK_Escape)
  210.             exit(0);
  211.         break;
  212.     default:
  213.         break;
  214.     }
  215. }
  216.  
  217. /*    drawWP() is called by the WorkProc.  When the scene
  218.  *    is in automatic motion, the WorkProc calls this routine,
  219.  *    which adds 1 degree (10 tenths) to the cumulative amount
  220.  *    of rotation.  drawscene() is called, so the image is
  221.  *    redrawn.  It returns(FALSE) so the WorkProc does not
  222.  *    discontinue operation.
  223.  */
  224. GLboolean drawWP (XtPointer ptr)
  225. {
  226.     SPINPTR spin;
  227.  
  228.     spin = (SPINPTR) ptr;
  229.     spin->year = fmodf((spin->year + 1.0), 360.0);
  230.     drawscene (spin);
  231.     return (FALSE);
  232. }
  233.  
  234.  
  235. /*    drawscene calculates angles relative to the spin->year
  236.  *    and then draws sun, planet, and moon.
  237.  */
  238.  
  239. void drawscene(SPINPTR spin)
  240. {
  241.     static GLfloat bluecol[] = { 0, 0, 1.0 };
  242.     static GLfloat whitecol[] = { 1.0, 1.0, 1.0 };
  243.     GLfloat sunangle, dayangle, monthangle;
  244.     /* actual 1.5e8 kM * 3.0e-9 fudgefactor */
  245.     GLfloat earthdist = 4.5, earthscale = 0.5;
  246.     GLfloat moondist = 0.9, moonscale = 0.2;
  247.  
  248.     glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
  249.  
  250.     glPushMatrix();
  251.         glRotatef(10.0, 1.0, 0.0, 0.0); /*  tilt scene slightly    */
  252.         glPushMatrix(); 
  253.             sunangle = fmodf((spin->year*365.0/25.0), 360.0);
  254.             /* sun rotates on axis every 25 days */
  255.                 glRotatef(sunangle, 0.0, 1.0, 0.0);
  256.                 /* cpack format color1, color2 swapped by hand */
  257.             /* was beachball(0x20C0FF, 0x200FFFF);  */
  258.             beachball(0xFFC02000, 0xFFFF0020);
  259.         glPopMatrix();
  260.         glPushMatrix();
  261.             glRotatef(spin->year, 0.0, 1.0, 0.0);
  262.             glTranslatef(earthdist,  0.0,  0.0);
  263.             glPushMatrix();
  264.                 dayangle = fmodf((spin->year*5.0), 360.0);    
  265.                 /* dayangle fudged so earth rotation shows  */
  266.                 glRotatef(dayangle, 0.0, 1.0, 0.0);
  267.                 glScalef(earthscale,  earthscale,  earthscale);
  268.                 glColor3fv(bluecol);
  269.                 /* swapped; was beachball(0xFF0000, 0xC02000);*/
  270.                 beachball(0x0000FF00, 0x0020C000); /* earth */
  271.             glPopMatrix();
  272.             monthangle = fmodf((spin->year*365.0/28.0), 360.0);
  273.             glRotatef(monthangle, 0.0, 1.0, 0.0);
  274.             glTranslatef(moondist,  0.0,  0.0);
  275.             glScalef(moonscale,  moonscale,  moonscale);
  276.             glColor3fv(whitecol);
  277.             /* hand swapped; was beachball(0xFFFFFF, 0xC0C0C0); */
  278.             beachball(0xFFFFFF00, 0xC0C0C000); /* moon */
  279.         glPopMatrix();
  280.     glPopMatrix();
  281.  
  282.     glXSwapBuffers(global_display, global_window);
  283. }   /*  end drawscene()  */
  284.  
  285. /* BEACHBALL */
  286.  
  287. /* three dimensional vector */
  288. typedef float vector[3];
  289.  
  290. static vector front  = { 0.0,  0.0,  1.0 };
  291. static vector back   = { 0.0,  0.0, -1.0 };
  292. static vector top    = { 0.0,  1.0,  0.0 };
  293. static vector bottom = { 0.0, -1.0,  0.0 };
  294. static vector right  = { 1.0,  0.0,  0.0 };
  295. static vector left   = { -1.0,  0.0,  0.0 };
  296. static vector center = { 0.0,  0.0,  0.0 };
  297.  
  298. /* Number of colored stripes. Should be even to look right */
  299. #define BEACHBALL_STRIPES 12
  300.  
  301. /* Default number of polygons  making up a stripe. Should be even */
  302. #define BEACHBALL_POLYS 16
  303.  
  304. /* array of vertices making up a stripe */
  305. static vector stripe_point[BEACHBALL_POLYS + 3];
  306.  
  307. /* has the beachball been initialized */
  308. static GLboolean beachball_initialized = FALSE;
  309.  
  310. /* Number of polygons making up a stripe */
  311. static int beachball_stripes;
  312.  
  313. /* Number of vertices making up a stripe */
  314. static int stripe_vertices;
  315.  
  316. /* Initialize beachball_point array to be a stripe 
  317.  * of unit radius.
  318.  */
  319. void setbeachball(int stripes)
  320. {
  321.     int i,j;
  322.     float x,y,z;             /* vertex points */
  323.     float theta,delta_theta;    /* angle from top pole to bottom pole */
  324.     float offset;         /* offset from center of stripe to vertex */
  325.     float cross_radius; /* radius of cross section at current latitude */
  326.     float cross_theta;  /* angle occupied by a stripe  */
  327.  
  328.     beachball_stripes = stripes;
  329.  
  330.     /* polys distributed by even angles from top to bottom */
  331.     delta_theta = M_PI/((float)BEACHBALL_POLYS/2.0);
  332.     theta = delta_theta;
  333.  
  334.     cross_theta = 2.0*M_PI/(float)beachball_stripes;
  335.  
  336.     j = 0;
  337.  
  338.     stripe_point[j][0] = top[0];
  339.     stripe_point[j][1] = top[1];
  340.     stripe_point[j][2] = top[2];
  341.     j++;
  342.  
  343.     for (i = 0; i < BEACHBALL_POLYS; i += 2) {
  344.         cross_radius = fsin(theta);
  345.         offset = cross_radius * ftan(cross_theta/2.0);
  346.  
  347.         stripe_point[j][0] = - offset;
  348.         stripe_point[j][1] = fcos(theta);
  349.         stripe_point[j][2] = cross_radius;
  350.         j++;
  351.  
  352.         stripe_point[j][0] = offset;
  353.         stripe_point[j][1] = stripe_point[j-1][1];
  354.         stripe_point[j][2] = stripe_point[j-1][2];
  355.         j++;
  356.  
  357.         theta += delta_theta;
  358.     }
  359.  
  360.     stripe_point[j][0] = bottom[0];
  361.     stripe_point[j][1] = bottom[1];
  362.     stripe_point[j][2] = bottom[2];
  363.  
  364.     stripe_vertices = j + 1;
  365.  
  366.     beachball_initialized = TRUE;
  367. }
  368.  
  369. /*
  370.  *    Draws a canonical beachball.  The colors are cpack values.
  371.  */
  372. void beachball(unsigned long c1, unsigned long c2)
  373. {
  374.     GLfloat angle, delta_angle;
  375.     int i,j;
  376.  
  377.     if (! beachball_initialized)
  378.         setbeachball(BEACHBALL_STRIPES);
  379.  
  380.     angle = 0.0;
  381.     delta_angle = 360.0/(float)beachball_stripes;
  382.  
  383.     for (i = 0; i < beachball_stripes; i++) {
  384.         if ( i%2 == 0)
  385.             glColor4ubv((GLubyte *)(&c1));
  386.         else glColor4ubv((GLubyte *)(&c2));
  387.  
  388.         glPushMatrix();
  389.             glRotatef(angle, 0.0, 1.0, 0.0);
  390.  
  391.             angle += delta_angle;
  392.  
  393.             glBegin(GL_TRIANGLE_STRIP);
  394.                 for (j = 0; j < stripe_vertices; j++)
  395.                     glVertex3fv(stripe_point[j]);
  396.             glEnd();
  397.         glPopMatrix();
  398.     }
  399. }
  400.  
  401.