home *** CD-ROM | disk | FTP | other *** search
- /*
- * overlay.c
- * Test routine for working with glxDraw widgets.
- */
-
- #include <stdio.h>
- #include <errno.h>
-
- #include <X11/Xlib.h>
- #include <X11/StringDefs.h>
- #include <X11/Intrinsic.h>
- #include <X11/keysym.h>
-
- #include <Xm/Xm.h>
- #include <Xm/Frame.h>
-
- #include "GlxMDraw.h"
- #ifndef USE_GL
- #include <GL/glu.h>
- #endif
-
- #define USE_OVERLAY
-
- int oldx, oldy, curx, cury, dx, dy;
-
- enum { SINGLE, DOUBLE } bufferMode;
- enum { MONO, STEREO } stereoMode;
-
- /* The GLX configuration parameter:
- * Double buffering
- * color index (default so unspecified)
- * overlay
- * nothing else special
- */
-
- #define OV_TYPE 2
-
- #ifdef USE_GL
- static GLXconfig glxConfig [] = {
- { GLX_NORMAL, GLX_DOUBLE, FALSE },
- { GLX_NORMAL, GLX_BUFSIZE, GLX_NOCONFIG },
- { GLX_OVERLAY, GLX_BUFSIZE, 2 },
- { 0, 0, 0 }
- };
- #else
- static int glxConfig[] = {
- #ifdef USE_STEREO
- GLX_DOUBLEBUFFER,
- #endif
- GLX_RGBA,
- GLX_RED_SIZE,3,
- GLX_BLUE_SIZE,3,
- GLX_GREEN_SIZE,3,
- GLX_DEPTH_SIZE,12,
- None,
- };
- static int glxConfigOverlay[] = {
- GLX_LEVEL, 1,
- GLX_BUFFER_SIZE, 4,
- None
- };
- #endif
-
- String fallback_resources[] = {
- "*geometry: =750x600",
- "*frame*shadowType: SHADOW_IN",
- NULL
- };
-
- struct
- {
- int width, height;
- }view;
-
- Boolean use_pups=FALSE; /* if TRUE, must use popup planes */
-
- static XtAppContext app_context;
-
- /* forward declarations of callbacks */
- static void exposeCB();
- static void overlayExposeCB();
- static void resizeCB();
- static void initCB();
- static void inputCB();
-
- main (int argc, char *argv[])
- {
- Arg args[20];
- int n = 0;
- Widget toplevel, frame, glw;
- Window windows[3];
-
- /*----
- * First, initialize the display.
- *----*/
-
- toplevel = XtAppInitialize(&app_context, "4DgiftsGlx",
- (XrmOptionDescList)NULL , 0,
- #if XtSpecificationRelease == 4
- (Cardinal*)&argc,
- #else
- &argc,
- #endif
- (String*)argv,
- fallback_resources,
- (ArgList)NULL, 0);
-
- /*----
- * Find out if we can use overlay planes (they exist),
- * otherwise, use popup planes. While we're at it,
- * fix the glxConfig parameter to request popup planes
- * instead of the default overlay planes (default because
- * we defined it above).
- *----*/
-
- #ifdef USE_GL
- if (getgdesc(GD_BITS_OVER_SNG_CMODE) < 2)
- {
- use_pups = TRUE;
- glxConfig[OV_TYPE].buffer = GLX_POPUP;
- }
- #endif
-
- /*----
- * Create a frame widget to put the GLX widget into.
- *----*/
-
- n = 0;
- frame = XtCreateManagedWidget("frame",
- xmFrameWidgetClass,
- toplevel, args, n);
-
- /*----
- * Set up the resources/arguments for the GLX widget and
- * then create the widget.
- *----*/
-
- n = 0;
- XtSetArg(args[n], GlxNglxConfig, glxConfig); n++;
- #ifdef USE_OVERLAY
- #ifdef USE_GL
- XtSetArg(args[n], use_pups?GlxNusePopup:GlxNuseOverlay, TRUE); n++;
- #else
- XtSetArg(args[n], GlxNoverlayGlxConfig, glxConfigOverlay); n++;
- #endif
- #endif
- #ifdef USE_STEREO
- XtSetArg(args[n], GlxNprovideStereoBuffer, TRUE); n++;
- #else
- XtSetArg(args[n], GlxNprovideSingleBuffer, TRUE); n++;
- #endif
- glw = XtCreateManagedWidget("glwidget",
- glxMDrawWidgetClass,
- frame, args, n);
-
- /*----
- * This is just a flag to help me keep track of which window
- * is up now.
- *----*/
-
- bufferMode = SINGLE;
- stereoMode = MONO;
-
- /*----
- * Add required callbacks.
- *----*/
-
- XtAddCallback(glw, GlxNexposeCallback, exposeCB, 0);
- XtAddCallback(glw,
- use_pups?GlxNpopupExposeCallback:GlxNoverlayExposeCallback,
- overlayExposeCB, 0);
- XtAddCallback(glw, GlxNresizeCallback, resizeCB, 0);
- XtAddCallback(glw, GlxNginitCallback, initCB, 0);
- XtAddCallback(glw, GlxNinputCallback, inputCB, 0);
-
- /*----
- * Ok, now we can realize our widgets.
- *----*/
-
- XtRealizeWidget(toplevel);
-
- /*----
- * Notify the window manager of colormaps that we are using
- * so it will switch them in for us automatically.
- *----*/
-
- XtVaGetValues (glw,
- use_pups ? GlxNpopupWindow : GlxNoverlayWindow,
- &windows[0], NULL);
- windows[1] = XtWindow (glw);
- windows[2] = XtWindow (toplevel);
- XSetWMColormapWindows (XtDisplay (toplevel), XtWindow (toplevel),
- windows, 3);
-
- XtAppMainLoop(app_context);
-
- }
-
- /* Return the overlay window of the widget */
- Window overlayWindow(w)
- Widget w;
- {
- Arg args[1];
- Window overlayWindow;
-
- XtSetArg(args[0], use_pups?GlxNpopupWindow:GlxNoverlayWindow,
- &overlayWindow);
- XtGetValues(w, args, 1);
- return (overlayWindow);
- }
- #ifndef USE_GL
- /* Return the overlay window of the widget */
- GLXContext overlayContext(w)
- Widget w;
- {
- Arg args[1];
- GLXContext overlayContext;
-
- XtSetArg(args[0], GlxNoverlayGlxContext, &overlayContext);
- XtGetValues(w, args, 1);
- return (overlayContext);
- }
- #endif
-
- /* Callbacks */
- static void
- exposeCB(w, client_data, call_data)
- Widget w;
- caddr_t client_data;
- GlxDrawCallbackStruct *call_data;
- {
- view.width = call_data->width-1;
- view.height = call_data->height-1;
- #ifdef USE_GL
- GLXwinset(XtDisplay(w), call_data->window);
- #else
- glXMakeCurrent(XtDisplay(w), call_data->window, call_data->context);
- #endif
- drawscene (XtDisplay(w), call_data->window, dx, dy);
- }
-
- static void
- overlayExposeCB(w, client_data, call_data)
- Widget w;
- caddr_t client_data;
- GlxDrawCallbackStruct *call_data;
- {
- #ifdef USE_GL
- GLXwinset(XtDisplay(w), call_data->window);
- #else
- glXMakeCurrent(XtDisplay(w), call_data->window, call_data->context);
- #endif
- drawhouse();
- }
-
- static void
- resizeCB(w, client_data, call_data)
- Widget w;
- caddr_t client_data;
- GlxDrawCallbackStruct *call_data;
- {
- view.width = call_data->width-1;
- view.height = call_data->height-1;
- #ifdef USE_GL
- GLXwinset(XtDisplay(w), call_data->window);
- viewport(0, (Screencoord) call_data->width-1,
- 0, (Screencoord) call_data->height-1);
- drawscene (XtDisplay(w), call_data->window, dx, dy);
- GLXwinset(XtDisplay(w), overlayWindow(w));
- viewport(0, (Screencoord) call_data->width-1,
- 0, (Screencoord) call_data->height-1);
- drawhouse();
- #else
- glXMakeCurrent(XtDisplay(w), call_data->window, call_data->context);
- glViewport(0, call_data->width-1, 0, call_data->height-1);
- drawscene (XtDisplay(w), call_data->window, dx, dy);
- glXMakeCurrent(XtDisplay(w), overlayWindow(w), overlayContext(w));
- glViewport(0, call_data->width-1, 0, call_data->height-1);
- drawhouse();
- #endif
- }
-
- static void
- initCB(w, client_data, call_data)
- Widget w;
- caddr_t client_data;
- GlxDrawCallbackStruct *call_data;
- {
- #ifdef USE_GL
- GLXwinset(XtDisplay(w), call_data->window);
- #else
- GLenum error;
-
- glXMakeCurrent(XtDisplay(w), call_data->window, call_data->context);
- #endif
- view.width = call_data->width-1;
- view.height = call_data->height-1;
- initialize_gl();
- dx = call_data->width / 2;
- dy = call_data->height / 2;
- #ifdef USE_OVERLAY
- #ifdef USE_GL
- GLXwinset(XtDisplay(w), overlayWindow(w));
- initialize_overlay(w);
- #else
- glXMakeCurrent(XtDisplay(w), overlayWindow(w), overlayContext(w));
- initialize_overlay(w);
- error = glGetError();
- if(error != GL_NO_ERROR)
- printf("OpenGL error: %s\n",gluErrorString(error));
- #endif
- #endif
- }
-
- static void
- inputCB(w, client_data, call_data)
- Widget w;
- caddr_t client_data;
- GlxDrawCallbackStruct *call_data;
- {
- char buffer[1];
- KeySym keysym;
- static Position oldx, oldy, newx, newy;
- static Boolean buttonDown = FALSE;
-
- #ifdef USE_GL
- GLXwinset(XtDisplay(w), call_data->window);
- #else
- GLboolean isStereoSupported;
-
- glXMakeCurrent(XtDisplay(w), call_data->window, call_data->context);
- #endif
- switch(call_data->event->type)
- {
- case KeyRelease:
- /* It is necessary to convert the keycode to a keysym before
- * it is possible to check if it is an escape
- */
- if (XLookupString((XKeyEvent *)call_data->event,
- buffer,1,&keysym,NULL) == 1 &&
- keysym == (KeySym)XK_Escape)
- exit(0);
- break;
- case ButtonPress:
- switch(call_data->event->xbutton.button)
- {
- case Button1:
- buttonDown = TRUE;
- oldx = newx = call_data->event->xbutton.x;
- oldy = newy = call_data->event->xbutton.y;
- break;
- case Button2:
- XtVaSetValues (w, GlxNsingleBuffer, TRUE, NULL);
- #ifdef USE_STEREO
- stereoMode = MONO;
- glDrawBuffer(GL_BACK);
- glGetBooleanv(GL_STEREO, &isStereoSupported);
- printf("isStereoSupported = %d\n",isStereoSupported);
- drawscene (XtDisplay(w), call_data->window, dx, dy);
- #else
- bufferMode = SINGLE;
- drawscene (XtDisplay(w), call_data->window, dx, dy);
- #endif
- break;
-
- case Button3:
- XtVaSetValues (w, GlxNsingleBuffer, FALSE, NULL);
- #ifdef USE_STEREO
- stereoMode = STEREO;
- glGetBooleanv(GL_STEREO, &isStereoSupported);
- printf("isStereoSupported = %d\n",isStereoSupported);
- #else
- bufferMode = DOUBLE;
- #endif
- drawscene (XtDisplay(w), call_data->window, dx, dy);
- break;
- }
- break;
- case ButtonRelease:
- switch(call_data->event->xbutton.button)
- {
- case Button1:
- buttonDown = FALSE;;
- break;
- }
- break;
- case MotionNotify:
- if (buttonDown && call_data->event->xmotion.state & Button1Mask)
- {
- oldx = newx;
- oldy = newy;
- newx = call_data->event->xbutton.x;
- newy = call_data->event->xbutton.y;
- dx += newx-oldx;
- /* GL and X have opposite y coordinates so subtract from dy */
- dy -= newy-oldy;
- drawscene (XtDisplay(w), call_data->window, dx, dy);
- }
- break;
- }
- }
-
- initialize_gl () {
- #ifdef USE_GL
- long xmaxscrn, ymaxscrn; /* maximum size of screen in x and y */
- long xscrnsize; /* size of screen in x used to set globals */
-
- xscrnsize = getgdesc(GD_XPMAX); /* get/set screen size[/aspect] */
- if (xscrnsize == 1280) {
- xmaxscrn = 1279;
- ymaxscrn = 1023;
- keepaspect(5, 4);
- } else if (xscrnsize == 1024) {
- xmaxscrn = 1023;
- ymaxscrn = 767;
- keepaspect(4, 3);
- } else {
- fprintf(stderr, "Something's EXTREMELY wrong: ");
- fprintf(stderr, "xscrnsize=%d\n", xscrnsize);
- exit(-1) ;
- }
- shademodel (FLAT);
- #else
- /* Define the initial projection */
- glViewport(0, 0, view.width, view.height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, (double)view.width, 0, (double)view.height, -1.0, 1.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- #endif
- }
-
- initialize_overlay(Widget w)
- {
- int stat;
- Arg args[2];
- Colormap overlayColormap;
- XColor color;
-
- #ifdef USE_GL
- mapcolor (1, 255, 0, 255);
- mapcolor (2, 0, 255, 255);
- #else
- XtSetArg(args[0], GlxNoverlayColormap, &overlayColormap);
- XtGetValues(w, args, 1);
-
- color.pixel = 1;
- color.red = 65535;
- color.green = 0;
- color.blue = 65535;
- stat = XAllocColor(XtDisplay(w), overlayColormap, &color);
- if(!stat)
- printf("Overlay XAllocColor failed\n");
-
- color.pixel = 2;
- color.red = 0;
- color.green = 65535;
- color.blue = 65535;
- stat = XAllocColor(XtDisplay(w), overlayColormap, &color);
- if(!stat)
- printf("Overlay XAllocColor failed\n");
-
- glViewport(0, 0, view.width, view.height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, (double)view.width, 0, (double)view.height, -1.0, 1.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- #endif
- }
-
- /* Everytime through the loop, draw only the car, not the house. */
- drawscene (display, window, x, y)
- Display *display;
- Window window;
- int x, y;
- {
- #ifdef USE_GL
- color (BLACK);
- clear ();
- drawcar (x, y);
- gflush();
- if (bufferMode == DOUBLE)
- swapbuffers ();
- #else
- GLenum error;
-
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT);
- #ifdef USE_STEREO
- if(stereoMode == STEREO)
- {
- int eye;
-
- for(eye = 0 ; eye < 1 ; eye++)
- {
- if(eye == 0)
- glDrawBuffer(GL_BACK_LEFT);
- else
- glDrawBuffer(GL_BACK_RIGHT);
- drawcar (x, y);
- }
- }else
- drawcar (x, y);
- #else
- drawcar (x, y);
- #endif
- if (bufferMode == DOUBLE)
- glXSwapBuffers(display, window);
- error = glGetError();
- if(error != GL_NO_ERROR)
- printf("OpenGL error: %s\n",gluErrorString(error));
-
- #endif
- }
-
- /* draw a car with several colors.
- * The car itself is drawn with the front window first. Then the front
- * window is flipped over (scaled) for the rear window. The translate
- * routine moves the car to an (x,y) position.
- */
- drawcar (x, y)
- int x, y;
- {
- float fx, fy;
- #ifndef USE_GL
- static int first=1;
- static GLUquadricObj *quadric;
- #endif
-
-
- fx = (float) x;
- fy = (float) y;
- #ifdef USE_GL
- pushmatrix ();
- translate (fx, fy, 0.0); /* move to mouse location */
- color (BLUE); /* wheels */
- circfi (-75, -75, 20);
- circfi (75, -75, 20);
- color (RED); /* car body */
- pmv2i (-150, -50);
- pdr2i (-125, 0);
- pdr2i (125, 0);
- pdr2i (150, -50);
- pclos ();
- color (YELLOW); /* front window */
- drawwindow ();
- color (GREEN); /* rear window */
- scale (-1.0, 1.0, 1.0);
- drawwindow ();
- popmatrix ();
- #else
- if(first)
- {
- first = 0;
- quadric = gluNewQuadric();
- }
- glPushMatrix();
- glTranslatef (fx, fy, 0.0);
- glColor3f(0.0, 0.0, 1.0);
- glPushMatrix();
- glTranslatef (-75.0, -75.0, 0.0);
- gluDisk(quadric, 0.0, 20, 36, 1);
- glTranslatef (150.0, 0.0, 0.0);
- gluDisk(quadric, 0.0, 20, 36, 1);
- glPopMatrix();
- glColor3f(1.0, 0.0, 0.0);
- glBegin(GL_QUADS);
- glVertex2i(-150, -50);
- glVertex2i(-125, 0);
- glVertex2i(125, 0);
- glVertex2i(150, -50);
- glEnd();
- drawwindow ();
- glColor3f(1.0, 1.0, 0.0);
- drawwindow ();
- glColor3f(0.0, 1.0, 0.0);
- glScalef(-1.0, 1.0, 1.0);
- drawwindow();
- glPopMatrix();
- #endif
- }
-
- /* draw a window for the car */
- drawwindow () {
- #ifdef USE_GL
- pmv2i (0, 0);
- pdr2i (0, 50);
- pdr2i (50, 50);
- pdr2i (75, 0);
- pclos ();
- #else
- glBegin(GL_QUADS);
- glVertex2i(0, 0);
- glVertex2i(0, 50);
- glVertex2i(50, 50);
- glVertex2i(75, 0);
- glEnd();
- #endif
- }
-
- /* draw a house in two colors at a fixed position, specified by the trans-
- * late routine. The house is drawn with colors in the 4D overlay bitplanes.
- */
- drawhouse () {
- #ifdef USE_GL
- color (0);
- clear ();
- pushmatrix ();
- translate (200.0, 100.0, 0.0); /* move house into position */
- color (1); /* roof */
- pmv2i (0, 0);
- pdr2i (0, 250);
- pdr2i (350, 250);
- pdr2i (350, 0);
- pclos ();
- color (2); /* 1st floor */
- pmv2i (175, 400);
- pdr2i (0, 250);
- pdr2i (350, 250);
- pclos ();
- popmatrix ();
- gflush();
- #else
- glClear(GL_COLOR_BUFFER_BIT);
- glPushMatrix();
- glTranslatef(200.0, 100.0, 0.0);
- glIndexi(1);
- glBegin(GL_QUADS);
- glVertex2i(0, 0);
- glVertex2i(0, 250);
- glVertex2i(350, 250);
- glVertex2i(350, 0);
- glEnd();
- glIndexi(2);
- glBegin(GL_TRIANGLES);
- glVertex2i(175, 400);
- glVertex2i(0, 250);
- glVertex2i(350, 250);
- glEnd();
-
- /* ..... */
- glPushMatrix();
- #endif
- }
-