Xlib translucent OpenGL windows. - Xwindows

This is a discussion on Xlib translucent OpenGL windows. - Xwindows ; want to achieve a translucent effect in my OpenGL windows using Xlib. The easiest way to do this (but perhaps not the most efficient), is to copy the background underneath the OpenGL window, and render it to the OpenGL window ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: Xlib translucent OpenGL windows.

  1. Xlib translucent OpenGL windows.

    want to achieve a translucent effect in my OpenGL windows using Xlib.
    The easiest way to do this (but perhaps not the most efficient), is to
    copy the background underneath the OpenGL window, and render it to the
    OpenGL window before doing any other OpenGL calls.

    Then, i could simply draw any OpenGL geometry, possibly using blending,
    alpha testing, etc.. And get a cool translucent effect. I was thinking
    in the lines of an OpenGL accelerated version of gDesklets, and all
    sorts of eye candy for X users.

    The original idea is to capture somehow the background underneath the
    window, doing it only when the window is moved, resized or first
    created. The problem is, how can I capture it?, and after captured...
    how to blit it to the OpenGL window?

    First method:
    ------------
    Using XCopyArea, copy the background from the root window to the OpenGL
    window. This doesn't seem to work, I always end up with a black window
    (I AM NOT doing glClear, or issuing any opengl commands to clear the
    window). I think this may have something to do with the GL context, or
    maybe with the fact that i am using GLX_DOUBLEBUFFER. I have tried
    issuing the call glXGetCurrentDrawable() or glXGetCurrentReadDrawable()
    before doing the XCopyArea, this didn't work either. I tried to do it
    without double buffering, without any success, however it could be a
    code bug, beacause my single buffering code in Xlib is untested. (I
    know for a fact that double buffering does work correctly). Anyhow, I
    want it to be a double buffer application, and handling the double
    buffering my self using GLXPixmaps for offline rendering is just too
    much work and the performance hit is too high.

    Second method:
    -------------
    Capture the background of the root window to an XImage, and then
    issuing a glDrawPixels command with the correct parameters to blit this
    image onto the OpenGL window. I dont like this solution because it
    seems it would be even more inefficient. However, I would be willing to
    try it if nothing else works. The problem is, I dont know how to
    capture the background underneeth the OpenGL window to an XImage, being
    that XCopyArea only works on drawables.

    Please help!!!

    PS: I think this concept is being used in applications such as eterm,
    aterm, gterm, etc... Where they have a translucent looking effect. The
    difference is that I want to render using OpenGL, where these
    applications just render over using Xlib (possibly with GTK in the
    middle). I already posted this message in comp.graphics.api.opengl, but
    no one has given me a solution.


  2. Re: Xlib translucent OpenGL windows.

    acornejo@gmail.com wrote:
    > want to achieve a translucent effect in my OpenGL windows using Xlib.
    > The easiest way to do this (but perhaps not the most efficient), is to
    > copy the background underneath the OpenGL window, and render it to the
    > OpenGL window before doing any other OpenGL calls.
    >
    > Then, i could simply draw any OpenGL geometry, possibly using blending,
    > alpha testing, etc.. And get a cool translucent effect. I was thinking
    > in the lines of an OpenGL accelerated version of gDesklets, and all
    > sorts of eye candy for X users.
    >
    > The original idea is to capture somehow the background underneath the
    > window, doing it only when the window is moved, resized or first
    > created. The problem is, how can I capture it?, and after captured...
    > how to blit it to the OpenGL window?
    >
    > First method:
    > ------------
    > Using XCopyArea, copy the background from the root window to the OpenGL
    > window. This doesn't seem to work, I always end up with a black window
    > (I AM NOT doing glClear, or issuing any opengl commands to clear the
    > window). I think this may have something to do with the GL context, or
    > maybe with the fact that i am using GLX_DOUBLEBUFFER. I have tried
    > issuing the call glXGetCurrentDrawable() or glXGetCurrentReadDrawable()
    > before doing the XCopyArea, this didn't work either. I tried to do it
    > without double buffering, without any success, however it could be a
    > code bug, beacause my single buffering code in Xlib is untested. (I
    > know for a fact that double buffering does work correctly). Anyhow, I
    > want it to be a double buffer application, and handling the double
    > buffering my self using GLXPixmaps for offline rendering is just too
    > much work and the performance hit is too high.


    OpenGL has rgba and indexed color models, so you'll need to make
    sure the color model you're using matches the color model X is using
    such as directcolor or truecolor.

    > Second method:
    > -------------
    > Capture the background of the root window to an XImage, and then
    > issuing a glDrawPixels command with the correct parameters to blit this
    > image onto the OpenGL window. I dont like this solution because it
    > seems it would be even more inefficient. However, I would be willing to
    > try it if nothing else works. The problem is, I dont know how to
    > capture the background underneeth the OpenGL window to an XImage, being
    > that XCopyArea only works on drawables.
    >
    > Please help!!!
    >
    > PS: I think this concept is being used in applications such as eterm,
    > aterm, gterm, etc... Where they have a translucent looking effect. The
    > difference is that I want to render using OpenGL, where these
    > applications just render over using Xlib (possibly with GTK in the
    > middle). I already posted this message in comp.graphics.api.opengl, but
    > no one has given me a solution.


  3. Re: Xlib translucent OpenGL windows.

    I am using an RGBA color mode for OpenGL, and the color mode X is using
    should be RGBA also, although I am not very sure how to check this, I
    am not that of an Xlib experienced developer.

    A quick glance at my Xorg0.log tells us:

    (II) Setting vga for screen 0.
    (**) NVIDIA(0): Depth 24, (--) framebuffer bpp 32
    (==) NVIDIA(0): RGB weight 888
    (==) NVIDIA(0): Default visual is TrueColor

    So I guess I am using TrueColor, this should be correct right?

    I think the problem is with my call to XCopyArea, it returns error code
    1, which after looking in the include files is defined as:

    #define BadRequest 1 /* bad request code */

    What exactly does this happen, I am not sure. Attached to this post, I
    am sending the simplest source file I could come up with to open a
    window using Xlib and GLX, and render a simple scene demonstrating what
    happens. What does happen is a blended triangle is drawn in a black
    background, although I was hopping the background to be an image of
    what occures behind the window, thus making a cool translucent effect.

    // ATTACHMENT FOLLOWS ----
    // compile: gcc -o test test.cpp -lGL -lGLU
    #include
    #include
    #include
    #include

    void draw()
    {
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glBegin(GL_TRIANGLES);
    glColor4f(1.0f,0.0f,0.0f,0.5);
    glVertex3f( 0.0f, 1.0f, -3.0f);
    glColor4f(0.0f,1.0f,0.0f,0.5);
    glVertex3f(-1.0f,-1.0f, -3.0f);
    glColor4f(0.0f,0.0f,1.0f,0.5);
    glVertex3f( 1.0f,-1.0f, -3.0f);
    glEnd();
    }

    int main()
    {
    XEvent event;
    Display *display;
    int screen;
    XVisualInfo *visual;
    GLXContext context;
    Window window, root;
    XSetWindowAttributes winattr;
    int
    glxattr[]={GLX_RGBA,GLX_DOUBLEBUFFER,GLX_RED_SIZE,8,GLX_GRE EN_SIZE,8,GLX_BLUE_SIZE,8,GLX_ALPHA_SIZE,8,GLX_DEP TH_SIZE,24,GLX_STENCIL_SIZE,8,
    None};
    GC gc;

    display=XOpenDisplay(0);
    screen=DefaultScreen(display);
    visual=glXChooseVisual(display,screen,glxattr);
    context=glXCreateContext(display, visual, 0, True);
    root=RootWindow(display,screen);
    winattr.colormap=XCreateColormap(display,root,visu al->visual,
    AllocNone);
    winattr.event_mask=KeyPressMask;

    window=XCreateWindow(display,root,0,0,100,100,0,vi sual->depth,InputOutput,visual->visual,CWColormap|CWEventMask,
    &winattr);
    gc=XCreateGC(display,window,0,NULL);

    XMapWindow(display,window);
    glXMakeCurrent(display,window,context);
    glViewport(0,0,100,100);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60, 1.0, 0.1, 100);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    do
    {
    if (XPending(display) > 0)
    {
    XNextEvent(display, &event);
    if (event.type == KeyPress)
    break;
    }
    else
    {
    printf("%d\n",
    XCopyArea(display,root,glXGetCurrentDrawable(),gc, 0,0,100,100,0,0));
    draw();
    glXSwapBuffers(display, window);
    }
    } while(true);

    XFreeGC(display,gc);
    glXMakeCurrent(display, None, NULL);
    glXDestroyContext(display, context);
    XDestroyWindow(display,window);
    XCloseDisplay(display);

    return 0;
    }


  4. Re: Xlib translucent OpenGL windows.

    alex wrote:
    > I am using an RGBA color mode for OpenGL, and the color mode X is using
    > should be RGBA also, although I am not very sure how to check this, I
    > am not that of an Xlib experienced developer.
    >
    > A quick glance at my Xorg0.log tells us:
    >
    > (II) Setting vga for screen 0.
    > (**) NVIDIA(0): Depth 24, (--) framebuffer bpp 32
    > (==) NVIDIA(0): RGB weight 888
    > (==) NVIDIA(0): Default visual is TrueColor
    >
    > So I guess I am using TrueColor, this should be correct right?
    >
    > I think the problem is with my call to XCopyArea, it returns error code
    > 1, which after looking in the include files is defined as:
    >
    > #define BadRequest 1 /* bad request code */
    >
    > What exactly does this happen, I am not sure. Attached to this post, I
    > am sending the simplest source file I could come up with to open a
    > window using Xlib and GLX, and render a simple scene demonstrating what
    > happens. What does happen is a blended triangle is drawn in a black
    > background, although I was hopping the background to be an image of
    > what occures behind the window, thus making a cool translucent effect.
    >
    > // ATTACHMENT FOLLOWS ----

    ....

    I'd look at the values at each step with ddd/gdb, and use XSync() to
    make the asynchronous errors synchronous and easier to debug.
    http://tronche.com/gui/x/xlib/event-handling/XSync.html

+ Reply to Thread