home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / tutorials / custEducation / opengl1 / demos / glxmotif.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  6.6 KB  |  217 lines

  1. /* Copyright (c) Silcon Graphics, Inc. 1995 */
  2.  
  3.  
  4. /* Copyright (c) Mark J. Kilgard, 1994. */
  5.  
  6. /* compile: cc -o glxmotif glxmotif.c -lGLU -lGL -lXm -lXt -lX11 */
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <Xm/Form.h>
  10. #include <Xm/Frame.h>
  11. #include <Xm/DrawingA.h>
  12. #include <X11/keysym.h>
  13. #include <GL/gl.h>
  14. #include <GL/glu.h>
  15. #include <GL/glx.h>
  16.  
  17. static int snglBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, None};
  18. static int dblBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None};
  19. static String   fallbackResources[] = {
  20.     "*glxarea*width: 300", "*glxarea*height: 300",
  21.     "*frame*x: 20", "*frame*y: 20",
  22.     "*frame*topOffset: 20", "*frame*bottomOffset: 20",
  23.     "*frame*rightOffset: 20", "*frame*leftOffset: 20",
  24.     "*frame*shadowType: SHADOW_IN",
  25.     NULL
  26. };
  27.  
  28. Display        *dpy;
  29. GLboolean       doubleBuffer = GL_TRUE, viewportUpdateNeeded = GL_TRUE, spinning = GL_FALSE;
  30. XtAppContext    app;
  31. XtWorkProcId    workId = 0;
  32. Widget          toplevel, form, frame, glxarea;
  33.  
  34. void
  35. updateViewport(Widget w)
  36. {
  37.     Dimension width, height;
  38.  
  39.     XtVaGetValues(w, XmNwidth, &width, XmNheight, &height, NULL);
  40.     glViewport(0, 0, (GLint) width, (GLint) height);
  41.     viewportUpdateNeeded = GL_FALSE;
  42. }
  43.  
  44. void
  45. draw(Widget w)
  46. {
  47.     if (viewportUpdateNeeded) updateViewport(w);
  48.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  49.     glBegin(GL_POLYGON);
  50.     glColor3f(0.0, 0.0, 0.0); glVertex3f(-10.0, -10.0, 0.0);
  51.     glColor3f(0.7, 0.7, 0.7); glVertex3f(10.0, -10.0, 0.0);
  52.     glColor3f(1.0, 1.0, 1.0); glVertex3f(-10.0, 10.0, 0.0);
  53.     glEnd();
  54.     glBegin(GL_POLYGON);
  55.     glColor3f(1.0, 1.0, 0.0); glVertex3f(0.0, -10.0, -10.0);
  56.     glColor3f(0.0, 1.0, 0.7); glVertex3f(0.0, -10.0, 10.0);
  57.     glColor3f(0.0, 0.0, 1.0); glVertex3f(0.0, 5.0, -10.0);
  58.     glEnd();
  59.     glBegin(GL_POLYGON);
  60.     glColor3f(1.0, 1.0, 0.0); glVertex3f(-10.0, 6.0, 4.0);
  61.     glColor3f(1.0, 0.0, 1.0); glVertex3f(-10.0, 3.0, 4.0);
  62.     glColor3f(0.0, 0.0, 1.0); glVertex3f(4.0, -9.0, -10.0);
  63.     glColor3f(1.0, 0.0, 1.0); glVertex3f(4.0, -6.0, -10.0);
  64.     glEnd();
  65.     if (doubleBuffer) glXSwapBuffers(dpy, XtWindow(w));
  66.     glFlush();
  67. }
  68.  
  69. void
  70. expose(Widget w, XtPointer clientData, XtPointer callData)
  71. {
  72.     draw(w);
  73. }
  74.  
  75. void
  76. resize(Widget w, XtPointer clientData, XtPointer callData)
  77. {
  78.     XmDrawingAreaCallbackStruct *cd = (XmDrawingAreaCallbackStruct *) callData;
  79.  
  80.     /* don't try OpenGL until window is realized! */
  81.     if (XtIsRealized(w)) updateViewport(w);
  82.         else viewportUpdateNeeded = GL_TRUE;
  83. }
  84.  
  85. Boolean
  86. spin(XtPointer clientData)
  87. {
  88.     glRotatef(2.5, 1.0, 0.0, 0.0);
  89.     draw(glxarea);
  90.     return False; /* leave work proc active */
  91. }
  92.  
  93. void
  94. input(Widget w, XtPointer clientData, XtPointer callData)
  95. {
  96.     XmDrawingAreaCallbackStruct *cd = (XmDrawingAreaCallbackStruct *) callData;
  97.     char            buffer[1];
  98.     KeySym          keysym;
  99.     int             rc;
  100.  
  101.     switch (cd->event->type) {
  102.     case KeyRelease:
  103.         /*
  104.          * It is necessary to convert the keycode to a keysym before it is
  105.          * possible to check if it is an escape
  106.          */
  107.         rc = XLookupString((XKeyEvent *) cd->event, buffer, 1, &keysym, NULL);
  108.         switch (keysym) {
  109.         case XK_Up:
  110.             glRotatef(10.0, 0.0, 0.0, 1.0);
  111.             if (!spinning) draw(w);
  112.             break;
  113.         case XK_Down:
  114.             glRotatef(-10.0, 0.0, 0.0, 1.0);
  115.             if (!spinning) draw(w);
  116.             break;
  117.         case XK_Left:
  118.             glRotatef(-10.0, 0.0, 1.0, 0.0);
  119.             if (!spinning) draw(w);
  120.             break;
  121.         case XK_Right:
  122.             glRotatef(10.0, 0.0, 1.0, 0.0);
  123.             if (!spinning) draw(w);
  124.             break;
  125.         case XK_S: case XK_s: /* the S key */
  126.             if (spinning) {
  127.                 XtRemoveWorkProc(workId);
  128.                 spinning = GL_FALSE;
  129.             } else {
  130.                 workId = XtAppAddWorkProc(app, spin, NULL);
  131.                 spinning = GL_TRUE;
  132.             }
  133.             break;
  134.         case XK_Escape:
  135.             exit(0);
  136.         }
  137.         break;
  138.     }
  139. }
  140.  
  141. void
  142. map_state_changed(Widget w, XtPointer clientData, XEvent * event, Boolean * cont)
  143. {
  144.     switch (event->type) {
  145.     case MapNotify:
  146.         if (spinning && workId != 0) workId = XtAppAddWorkProc(app, spin, NULL);
  147.         break;
  148.     case UnmapNotify:
  149.         if (spinning) XtRemoveWorkProc(workId);
  150.         break;
  151.     }
  152. }
  153.  
  154. main(int argc, char *argv[])
  155. {
  156.     Arg             args[20];
  157.     int             num;
  158.     XVisualInfo    *vi;
  159.     Colormap        cmap;
  160.     GLXContext      cx;
  161.     int             saved_argc;
  162.     String         *saved_argv;
  163.  
  164.     toplevel = XtAppInitialize(&app, "Glxmotif", NULL, 0, &argc, argv,
  165.                                fallbackResources, NULL, 0);
  166.     dpy = XtDisplay(toplevel);
  167.  
  168.     /* find an OpenGL-capable RGB visual with depth buffer */
  169.     vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf);
  170.     if (vi == NULL) {
  171.         vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf);
  172.         if (vi == NULL) XtAppError(app, "no RGB visual with depth buffer");
  173.         doubleBuffer = GL_FALSE;
  174.     }
  175.     /* create an OpenGL rendering context */
  176.     cx = glXCreateContext(dpy, vi, /* no display list sharing */ None, /* favor direct */ GL_TRUE);
  177.     if (cx == NULL) XtAppError(app, "could not create rendering context");
  178.     /* create an X colormap since probably not using default visual */
  179.     cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
  180.  
  181.     XtVaSetValues(toplevel, XtNvisual, vi->visual, XtNdepth, vi->depth,
  182.        XtNcolormap, cmap, NULL);
  183.     XtAddEventHandler(toplevel, StructureNotifyMask, False, map_state_changed, NULL);
  184.  
  185.     form = XmCreateForm(toplevel, "form", NULL, 0);
  186.     XtManageChild(form);
  187.  
  188.     frame = XmCreateFrame(form, "frame", NULL, 0);
  189.     XtVaSetValues(frame, XmNbottomAttachment, XmATTACH_FORM,
  190.         XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM,
  191.         XmNrightAttachment, XmATTACH_FORM, NULL);
  192.     XtManageChild(frame);
  193.  
  194.     glxarea = XtCreateManagedWidget("glxarea", xmDrawingAreaWidgetClass, frame, NULL, 0);
  195.     XtAddCallback(glxarea, XmNexposeCallback, expose, NULL);
  196.     XtAddCallback(glxarea, XmNresizeCallback, resize, NULL);
  197.     XtAddCallback(glxarea, XmNinputCallback, input, NULL);
  198.  
  199.     XtRealizeWidget(toplevel);
  200.  
  201.     /* Once widget is realized (ie, associated with a created X window), we
  202.      * can bind the OpenGL rendering context to the window.
  203.      */
  204.     glXMakeCurrent(dpy, XtWindow(glxarea), cx);
  205.  
  206.     /* setup OpenGL state */
  207.     glEnable(GL_DEPTH_TEST);
  208.     glDepthFunc(GL_LEQUAL);
  209.     glClearDepth(1.0);
  210.     glClearColor(0.0, 0.0, 0.0, 0.0);
  211.     glLoadIdentity();
  212.     gluPerspective(40.0, 1.0, 10.0, 200.0);
  213.     glTranslatef(0.0, 0.0, -50.0); glRotatef(-58.0, 0.0, 1.0, 0.0);
  214.  
  215.     XtAppMainLoop(app);
  216. }
  217.