glXCreateGLXPixmap XCopyArea troubles

Hello,

I have an application written in Xt/Motif. I want to incorporate OpenGL for rendering - dynamic rotation, pan, and zoom. The application without OpenGL basically has a main widget (toplevel), a menu bar on top, and an xmDrawingAreaWidget (canvas) for drawing into. It also has an XPixmap copied over the canvas, I believe to better handle expose events.

So, I understand that with OpenGL, I need a GLXPixmap also. I’m having trouble setting it up though. I think I know what the problem is, but I’m not sure how to fix it.

To incorporate the OpenGL, I’ve done the following (I’ve left out much of the code, just these are the important things):

– snip –
dpy = XtDisplay(toplevel);
vi = glXChooseVisual(
dpy,
DefaultScreen(dpy),
dblBuf);
cx = glXCreateContext(dpy,
vi,
/* no display list sharing / None,
/
favor direct */ GL_TRUE);
cmap = XCreateColormap(
dpy,
RootWindow(dpy, vi->screen),
vi->visual,
AllocNone);
XtVaSetValues(toplevel,
XtNvisual, vi->visual,
XtNdepth, vi->depth,
XtNcolormap, cmap,
NULL);
–snip–
canvas = XtVaCreateManagedWidget(“canvas”,
xmDrawingAreaWidgetClass, form,
XmNleftAttachment, XmATTACH_WIDGET,
XmNleftWidget, icons,
XmNrightAttachment, XmATTACH_FORM,
XmNtopAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_WIDGET,
XmNbottomWidget, xyz_label,
XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
XmNresizeWidth, False,
XmNresizeHeight, False,
XmNbackground, WhitePixel(XtDisplay(main_frame),
DefaultScreen(XtDisplay(main_frame))),
NULL);
–snip–
XtRealizeWidget(toplevel);
canvas_dpy = XtDisplay(canvas);
gcv.foreground = background;
gcv.background = WhitePixel(canvas_dpy, curr_screen);
xgc.clear = XtGetGC(canvas, GCForeground | GCBackground, &gcv);
pix = XCreatePixmap(canvas_dpy, RootWindowOfScreen(XtScreen(toplevel)), width, height, depth);
XFillRectangle(canvas_dpy, pix, xgc.clear, 0, 0, width, height);
GLXpix = glXCreateGLXPixmap(canvas_dpy, vi, pix);
glXMakeCurrent(dpy, XtWindow(canvas), cx);
XtAppMainLoop(app);

Then, to draw the scene, I do:

–snip–
(draw vertices and lines)
if (doubleBuffer) glXSwapBuffers(dpy, XtWindow(canvas));
glFlush();
glXWaitGL();
window = XtWindow(canvas);
XCopyArea(canvas_dpy, pix, window, xgc.clear, 0, 0, width, height, 0, 0);

The code compiles and runs, but when I try to render, the screen flickers once then returns to the default white screen. If I remove the XCopyArea command, the scene is drawn correctly, but the background goes to black. If I use GLXPix instead of pix in the XCopyArea command, it crashes with a BadDrawable X error. So, I know my GLXPixmap is not being created correctly, and I assume it is because I created it with XVisualInfo vi, which was created from the toplevel widget instead of the canvas, and Display canvas_dpy, which was created from the canvas.

So, my question is: How can I get an XVisualInfo for the canvas to use with glXCreateGLXPixmap?

Thank you
KS

Why not just skip the pixmap and use OpenGL for the drawing?
You do first draws the scene with OpenGL and then blits the pixmap over it so the result is no surprise.

Skipping the pixmap sounds good to me, but then how do I handle expose events? Early on in my transitioning to opengl, I did not have any pixmaps, but the scene would be redrawn for every expose event that X passed to it. So sometimes it would redraw 5 or more times, which is obvioiusly annoying. Do you know how to prevent that?

Thank you,
KS

X reports each dirty rectangle and I do not know of any way to avoid that. If you have hardware supported OpenGL should it not be a problem to redraw 5 or more times. Use double buffer to avoid flickering. Perhaps do you need to try something else but this will not be so clean and easy as the brute force method.

Update -

I did go back to not using the GLXPixmap, and it turned out my problem was more how the multiple expose events affected my motif menu bars and icons surrounding my drawing area. The drawing area would redraw quickly, but the icons would redraw verrrrrrry slowly.

So, I looked around a little and found this tidbit to use as my XmNexposeCallback for the drawing area widget:

XtCallbackProc expose(Widget w, XtPointer clientData, XtPointer callData)
{
XEvent event;

/* Consume any extra expose events. */
while (XCheckTypedWindowEvent(XtDisplay(w), XtWindow(w),
    Expose, &event)) {}   

draw();

}

I found this on an archived posting to comp.sys.sgi.misc by Mike Stroyan - to give credit to those deserving it.

Simple enough - too bad I couldn’t come up with it on my own!

Thanks,
Ken

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.