| /* Code example to illustrate the use of OpenGL rendering into */
/* Motif DrawingArea widgets with overlay planes */
#include <math.h>
#include <stdio.h>
#include <X11/Intrinsic.h>
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <Xm/Xm.h>
#include <Xm/BulletinB.h>
#include <Xm/DrawingA.h>
#include <X11/GLw/GLwMDrawA.h>
#include <GL/gl.h>
#define WIDTH 300
#define HEIGHT 300
static void init_window();
static void window_expose();
Display *display;
Widget draw, overlay;
GLXContext cx, cx_overlay;
/******************************************************************************/
int main (int argc, char* argv[])
/******************************************************************************/
{
XtAppContext application_context;
int screen_number;
XSizeHints size_hints;
Widget toplevel_application_shell;
Widget toplevel_shell;
Arg args[10];
int n;
/******************************************** create Application Shell ****/
printf("Motif version %d\n", XmVersion);
XtToolkitInitialize();
application_context = XtCreateApplicationContext();
display = XtOpenDisplay(application_context,
NULL, NULL, "Display",
NULL, 0, &argc, argv);
XSynchronize(display, True);
if (!display)
{
XtWarning("Test program: The XtOpenDisplay won't open the display. \n");
exit(0);
}
screen_number = DefaultScreen(display);
toplevel_application_shell = XtAppCreateShell("main",
"Freddy",
applicationShellWidgetClass,
display,
args,
0);
/******************************************** create Toplevel Shell *******/
n=0;
XtSetArg(args[n], XmNx, (Position)500);
n++;
XtSetArg(args[n], XmNy, (Position)50);
n++;
toplevel_shell = XtCreatePopupShell("Test program",
topLevelShellWidgetClass,
toplevel_application_shell ,
args,
n);
/************ create GL Overlay planes ********/
n=0;
XtSetArg(args[n], XmNwidth, (Dimension) WIDTH );
n++;
XtSetArg(args[n], XmNheight, (Dimension) HEIGHT );
n++;
XtSetArg(args[n], XmNmarginWidth, (Dimension)0);
n++;
XtSetArg(args[n], XmNmarginHeight, (Dimension)0);
n++;
XtSetArg(args[n], XmNwidth, (Dimension) WIDTH );
n++;
XtSetArg(args[n], XmNheight, (Dimension) HEIGHT );
n++;
XtSetArg(args[n], GLwNrgba, FALSE );
n++;
XtSetArg(args[n], GLwNlevel, 1 );
n++;
overlay = GLwCreateMDrawingArea(toplevel_shell, "overlay", args, n);
XtManageChild(overlay);
XtAddCallback(overlay, GLwNexposeCallback, window_expose, 0);
XtAddCallback(overlay, GLwNginitCallback, init_window, 0);
/************ create GL Drawing Area ********/
n=0;
XtSetArg(args[n], XmNwidth, (Dimension) WIDTH );
n++;
XtSetArg(args[n], XmNheight, (Dimension) HEIGHT );
n++;
XtSetArg(args[n], XmNmarginWidth, (Dimension)0);
n++;
XtSetArg(args[n], XmNmarginHeight, (Dimension)0);
n++;
XtSetArg(args[n], XmNwidth, (Dimension) WIDTH );
n++;
XtSetArg(args[n], XmNheight, (Dimension) HEIGHT );
n++;
XtSetArg(args[n], GLwNrgba, TRUE );
n++;
XtSetArg(args[n], GLwNallocateBackground, TRUE );
n++;
XtSetArg(args[n], GLwNlevel, 0 );
n++;
draw = GLwCreateMDrawingArea(toplevel_shell, "draw", args, n);
XtManageChild(draw);
XtAddCallback(draw, GLwNexposeCallback, window_expose, 0);
/* if XtRealizeWidget and XtAddCallback are switched around all is well */
/* the GLwNginitCallback must be registered before the widget tree is realised
*/
/* as the callback appears to happen at realisation */
XtAddCallback(draw, GLwNginitCallback, init_window, 0);
XtRealizeWidget(toplevel_shell);
XtPopup(toplevel_shell, XtGrabNone);
XtAppMainLoop(application_context);
}
static void init_window(Widget widget, XtPointer client_data, XtPointer
call_data)
{
Arg args[1];
XVisualInfo *vi;
XColor c;
XSetWindowAttributes win_attr;
Colormap colormap;
unsigned long backpixel = 0;
int i;
GLenum error;
printf("GLwNginitCallback\n");
XtSetArg(args[0], GLwNvisualInfo, &vi);
XtGetValues(widget, args, 1);
printf("visual ID = %d\n", vi->visualid);
printf("depth = %d\n", vi->depth);
/* if (vi->depth > 4) { */
if (widget != overlay) {
cx = glXCreateContext(XtDisplay(widget), vi, 0, GL_TRUE);
GLwDrawingAreaMakeCurrent(widget, cx);
glClearColor(1.0, 1.0, 0.0, 1.0);
} else {
colormap = XCreateColormap(XtDisplay(widget), XtWindow(widget),
vi->visual, AllocAll);
for (i=0; i<16; i++){
if (i != backpixel){
c.pixel = i;
c.red = (65535/16)*i;
c.green = (65535/16)*i;
c.blue = (65535/16)*i;
c.flags = DoRed | DoGreen | DoBlue;
XStoreColor(XtDisplay(widget), colormap, &c);
}
}
/* set up window attributes */
win_attr.background_pixel = backpixel;
win_attr.border_pixel = backpixel;
win_attr.colormap = colormap;
XChangeWindowAttributes(XtDisplay(widget), XtWindow(widget),
CWBackPixel | CWBorderPixel | CWColormap ,
&win_attr);
XInstallColormap(XtDisplay(widget), colormap);
cx_overlay = glXCreateContext(XtDisplay(widget), vi, 0, GL_TRUE);
GLwDrawingAreaMakeCurrent(widget, cx_overlay);
glClearIndex(0.0);
}
while (error = glGetError())
printf("glGetError returns %s\n",gluErrorString(error));
}
static void window_expose( widget, tag, callback_data )
Widget widget;
char *tag;
XmAnyCallbackStruct *callback_data;
{
float x;
int i;
GLenum error;
printf("Expose event on ");
if (widget == draw) {
printf("main window\n");
GLwDrawingAreaMakeCurrent(draw, cx);
/* clear the buffer */
glClear(GL_COLOR_BUFFER_BIT);
/* draw a blue polygon (square) in main window */
glColor3f(0.0, 0.0, 1.0);
glBegin(GL_POLYGON);
glVertex2f(-0.5, -0.5);
glVertex2f(-0.5, 0.5);
glVertex2f(0.5, 0.5);
glVertex2f(0.5, -0.5);
glEnd();
} else {
printf("overlay window\n");
/* draw lines in the overlay planes */
GLwDrawingAreaMakeCurrent(overlay, cx_overlay);
glClear(GL_COLOR_BUFFER_BIT);
for (i = 1; i < 16; i++) {
glIndexi(i);
x = ((float) i) / 17.0;
glBegin(GL_LINES);
glIndexi(i);
glVertex2f(x, 0.1);
glVertex2f(x, 0.9);
glEnd();
}
}
glFlush();
while (error = glGetError())
printf("glGetError returns %s\n",gluErrorString(error));
}
|