home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
-
- /*
- * renderboth
- *
- * Demonstrates how to render both Open GL and X to the same window. Based
- * on Mark Kilgard's glxmotif example.
- *
- * Instructions: The arrow keys rotate the model manually. The ESC key quits.
- *
- * $Revision: 1.4 $
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <Xm/Form.h>
- #include <Xm/Frame.h>
- #include <Xm/DrawingA.h>
- #include <X11/keysym.h>
- #include <X11/extensions/sgiXnmbx.h>
- #include <GL/gl.h>
- #include <GL/glu.h>
- #include <GL/glx.h>
-
- static int snglBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, None};
- static int doubleBuf[] = {GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, None};
-
- static String fallbackResources[] =
- {
- "*glxarea*width: 300",
- "*glxarea*height: 300",
- "*frame*shadowType: SHADOW_IN",
- NULL
- };
-
- Display *dpy;
- Bool viewportUpdateNeeded = GL_TRUE;
- XtAppContext app;
- Widget toplevel, form, frame, glxarea;
- GC gc;
-
- void
- updateViewport(Widget w)
- {
- Arg args[2];
- int num;
-
- num = 0;
- XtSetArg(args[num], XtNwidth, 0); num++;
- XtSetArg(args[num], XtNheight, 0); num++;
- XtGetValues(w, args, num);
- glViewport(0, 0, (GLint) args[0].value - 1, (GLint) args[1].value - 1);
- viewportUpdateNeeded = GL_FALSE;
- }
-
-
- static void
- makeGC (Colormap cmap)
- {
- Display * display = XtDisplay(glxarea);
- Window win = XtWindow(glxarea);
- unsigned long ply_mask;
- Font font1 = XLoadFont (display,"9x15");
- XGCValues ply_vals;
- XColor color_def;
- Pixel black_pixel = 0, white_pixel = 0;
-
- XParseColor(display, cmap, "Black", &color_def);
- XAllocColor(display, cmap, &color_def);
- black_pixel = color_def.pixel;
- XParseColor(display, cmap, "White", &color_def);
- XAllocColor(display, cmap, &color_def);
- white_pixel = color_def.pixel;
-
- ply_vals.function = GXcopy;
- ply_vals.foreground = white_pixel;
- ply_vals.background = black_pixel;
- ply_vals.line_width = 5;
- ply_vals.line_style = LineSolid;
- ply_vals.cap_style = CapRound;
- ply_vals.join_style = JoinRound;
- ply_vals.fill_style = FillSolid;
- ply_vals.font = font1;
- ply_vals.graphics_exposures = 0;
- ply_vals.clip_x_origin = 0;
- ply_vals.clip_y_origin = 0;
- ply_vals.clip_mask = None;
- ply_mask = GCFunction | GCForeground | GCBackground |
- GCLineWidth | GCLineStyle | GCCapStyle |
- GCGraphicsExposures | GCClipXOrigin |
- GCClipYOrigin | GCClipMask;
- gc = XCreateGC(display,win,ply_mask,&ply_vals);
- }
-
- static void
- initXRendering (Colormap cmap, Boolean double_b)
- {
- makeGC(cmap);
- if (double_b) {
- XBuffer buffers[2];
- sgiXnmbxCreateBuffers(dpy, XtWindow(glxarea), 2,
- sgiNMBX_Frequent, sgiNMBX_Background,
- 0L, buffers);
- sgiXnmbxSetDestinationOfGC(dpy, gc, sgiNMBX_Back);
- }
- }
-
- static void
- renderX (Widget w, Boolean double_b)
- {
- XPoint pts[13];
- Display * display = XtDisplay(w);
- Window win = XtWindow(w);
-
- pts[0].x = 150; pts[0].y = 30;
- pts[1].x = 30; pts[1].y = 270;
- pts[2].x = 270; pts[2].y = 100;
- pts[3].x = 30; pts[3].y = 100;
- pts[4].x = 270; pts[4].y = 270;
- pts[5].x = 150; pts[5].y = 30;
-
- XDrawLines(display,win,gc,pts,6,CoordModeOrigin);
-
- if (double_b) {
- sgiXnmbxSwapWindow(display, win);
- }
- }
-
- void
- draw(Widget w, Boolean double_b)
- {
- if (viewportUpdateNeeded)
- updateViewport(w);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- glBegin(GL_POLYGON);
- glColor3f(0.0, 0.0, 0.0);
- glVertex3f(-10.0, -10.0, 0.0);
- glColor3f(0.7, 0.7, 0.7);
- glVertex3f(10.0, -10.0, 0.0);
- glColor3f(1.0, 1.0, 1.0);
- glVertex3f(-10.0, 10.0, 0.0);
- glEnd();
- glBegin(GL_POLYGON);
- glColor3f(1.0, 1.0, 0.0);
- glVertex3f(0.0, -10.0, -10.0);
- glColor3f(0.0, 1.0, 0.7);
- glVertex3f(0.0, -10.0, 10.0);
- glColor3f(0.0, 0.0, 1.0);
- glVertex3f(0.0, 5.0, -10.0);
- glEnd();
- glBegin(GL_POLYGON);
- glColor3f(1.0, 1.0, 0.0);
- glVertex3f(-10.0, 6.0, 4.0);
- glColor3f(1.0, 0.0, 1.0);
- glVertex3f(-10.0, 3.0, 4.0);
- glColor3f(0.0, 0.0, 1.0);
- glVertex3f(4.0, -9.0, -10.0);
- glColor3f(1.0, 0.0, 1.0);
- glVertex3f(4.0, -6.0, -10.0);
- glEnd();
-
- renderX(w, double_b);
- glXSwapBuffers(XtDisplay(w), XtWindow(w));
- XSync(XtDisplay(w), False);
- }
-
- void
- expose(Widget w, XtPointer clientData, XtPointer callData)
- {
- Boolean double_b = (Boolean)clientData;
- draw(w, double_b);
- }
-
- void
- resize(Widget w, XtPointer clientData, XtPointer callData)
- {
- XmDrawingAreaCallbackStruct *cd = (XmDrawingAreaCallbackStruct *) callData;
-
- /* don't try OpenGL until window is realized! */
- if (XtIsRealized(w)) {
- updateViewport(w);
- } else {
- viewportUpdateNeeded = GL_TRUE;
- }
- }
-
- void
- input(Widget w, XtPointer clientData, XtPointer callData)
- {
- Boolean double_b = (Boolean)clientData;
- XmDrawingAreaCallbackStruct *cd = (XmDrawingAreaCallbackStruct *) callData;
- char buffer[1];
- KeySym keysym;
- int rc;
-
- switch (cd->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
- */
- rc = XLookupString((XKeyEvent *) cd->event, buffer, 1, &keysym, NULL);
- switch (keysym) {
- case XK_Up:
- glRotatef(10.0, 0.0, 0.0, 1.0);
- draw(w, double_b);
- break;
- case XK_Down:
- glRotatef(-10.0, 0.0, 0.0, 1.0);
- draw(w, double_b);
- break;
- case XK_Left:
- glRotatef(-10.0, 0.0, 1.0, 0.0);
- draw(w, double_b);
- break;
- case XK_Right:
- glRotatef(10.0, 0.0, 1.0, 0.0);
- draw(w, double_b);
- break;
- case XK_Escape:
- exit(0);
- }
- break;
- }
- }
-
- static void
- initGraphics (GLXContext cx, Colormap cmap, Boolean double_b)
- {
- unsigned int height = 0, width = 0;
- /*
- * Once widget is realized (ie, associated with a created X window), we
- * can bind the OpenGL rendering context to the window.
- */
- glXMakeCurrent(dpy, XtWindow(glxarea), cx);
-
- /* setup OpenGL state */
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LEQUAL);
- glClearDepth(1.0);
- glClearColor(0.0, 0.0, 0.0, 0.0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glLoadIdentity();
- gluPerspective(40.0, 1.0, 10.0, 200.0);
- glTranslatef(0.0, 0.0, -50.0);
- glRotatef(-58.0, 0.0, 1.0, 0.0);
- initXRendering(cmap, double_b);
- }
-
- static Boolean
- isValidXnmbxVisual(Display * dpy, XVisualInfo * vi)
- {
- Boolean ret_value = False;
- int error_base, event_base;
- XVisualInfo * list = NULL;
- int num_visuals = 0;
- int num_v_caps = 0;
- sgiXnmbxCapability * v_caps = NULL;
-
- XVisualInfo template;
-
- if (sgiXnmbxQueryExtension(dpy, &event_base, &error_base)) {
-
- v_caps = sgiXnmbxGetVisualCapabilities(dpy, vi->visual, &num_v_caps);;
-
- template.visualid = vi->visualid;
- list = sgiXnmbxGetExtendedVisualInfo(dpy, VisualIDMask,
- &template, &num_visuals,
- num_v_caps, v_caps);
- if (list != NULL) {
- ret_value = True;
- }
- else {
- fprintf(stderr, "No x double-buffering capability in visual\n");
- }
- }
- else {
- fprintf(stderr, "X multi-buffered extension not available\n");
- }
- return ret_value;
- }
-
- static XVisualInfo *
- setupVisual (Display * display, Boolean * double_b)
- {
- /* find an OpenGL-capable RGB visual with depth buffer */
-
- /* First try to find a double buffered visual. */
- XVisualInfo * vi = glXChooseVisual(dpy, DefaultScreen(dpy), doubleBuf);
-
- /* Now make sure that we can use the Xnmbx extension with it. */
- if ((vi == NULL) || (!isValidXnmbxVisual(dpy, vi))) {
- vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf);
- *double_b = False;
- }
- else {
- *double_b = True;
- }
- return vi;
- }
-
- main(int argc, char *argv[])
- {
- Arg args[20];
- int num;
- XVisualInfo *vi;
- Colormap cmap;
- GLXContext cx;
- Boolean double_b = False;
-
- /*
- * XtVaAppInitialize is too automatic; we do step-by-step initialization
- * of Xt so we can get Display* before the toplevel widget is created.
- */
- XtToolkitInitialize();
- app = XtCreateApplicationContext();
- XtAppSetFallbackResources(app, fallbackResources);
- dpy = XtOpenDisplay(app, NULL, "glxmotif", "Glxmotif",
- NULL, 0, &argc, argv);
- if (dpy == NULL) {
- XtAppError(app, "could not open display");
- }
-
- vi = setupVisual(dpy, &double_b);
- if (vi == NULL) {
- XtAppError(app, "no RGB visual with depth buffer");
- }
- else if (double_b) {
- fprintf(stderr, "Double buffering on\n");
- }
- else {
- fprintf(stderr, "Single buffering on\n");
- }
-
- /* create an OpenGL rendering context */
- cx = glXCreateContext(dpy, vi, /* no sharing of display lists */ None,
- /* direct rendering if possible */ GL_TRUE);
- if (cx == NULL) {
- XtAppError(app, "could not create rendering context");
- }
- /* create an X colormap since probably not using default visual */
- cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),
- vi->visual, AllocNone);
-
- num = 0;
- XtSetArg(args[num], XtNscreen, DefaultScreenOfDisplay(dpy)); num++;
- XtSetArg(args[num], XtNargc, argc); num++;
- XtSetArg(args[num], XtNargv, argv); num++;
- XtSetArg(args[num], XtNvisual, vi->visual); num++;
- XtSetArg(args[num], XtNdepth, vi->depth); num++;
- XtSetArg(args[num], XtNcolormap, cmap); num++;
- toplevel = XtAppCreateShell(NULL, "Glxmotif", applicationShellWidgetClass,
- dpy, args, num);
-
- form = XmCreateForm(toplevel, "form", NULL, 0);
- XtManageChild(form);
-
- num = 0;
- XtSetArg(args[num], XtNx, 20); num++;
- XtSetArg(args[num], XtNy, 20); num++;
- XtSetArg(args[num], XmNbottomAttachment, XmATTACH_FORM); num++;
- XtSetArg(args[num], XmNtopAttachment, XmATTACH_FORM); num++;
- XtSetArg(args[num], XmNleftAttachment, XmATTACH_FORM); num++;
- XtSetArg(args[num], XmNrightAttachment, XmATTACH_FORM); num++;
- XtSetArg(args[num], XmNleftOffset, 20); num++;
- XtSetArg(args[num], XmNtopOffset, 20); num++;
- XtSetArg(args[num], XmNbottomOffset, 20); num++;
- XtSetArg(args[num], XmNrightOffset, 20); num++;
- frame = XmCreateFrame(form, "frame", args, num);
- XtManageChild(frame);
-
- glxarea = XtCreateManagedWidget("glxarea", xmDrawingAreaWidgetClass, frame,
- NULL, 0);
- XtAddCallback(glxarea, XmNexposeCallback, expose, (XtPointer)double_b);
- XtAddCallback(glxarea, XmNresizeCallback, resize, NULL);
- XtAddCallback(glxarea, XmNinputCallback, input, (XtPointer)double_b);
-
- XtRealizeWidget(toplevel);
- initGraphics(cx, cmap, double_b);
-
- XtAppMainLoop(app);
- }
-