GdkGLPixmap troubles

View: New views
9 Messages — Rating Filter:   Alert me  

GdkGLPixmap troubles

by Lindley :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I'm trying to allow an offscreen render to a pixmap to occur now, instead of trying to force an expose event while a window is offscreen like I was before.

I've looked over the example code in pixmap.c that comes with GtkGLExt, but my adaptation of it isn't working.

My configure-event handler:

gboolean reshapeGL(GtkWidget *widget, GdkEventConfigure *evnt, gpointer data)
{
    GUIWindow* me = (GUIWindow*)data;
    GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
    GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);

    assert(pthread_equal(me->mainthread, pthread_self()));
    fprintf(stderr,"reshaping window %d, %d %d %d %d\n",me->window_id,evnt->x,evnt->y,evnt->width,evnt->height);

    if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
        return FALSE;

    me->lock();
    me->xviewport = evnt->x;
    me->widthvp = evnt->width;
    me->yviewport = evnt->y;
    me->heightvp = evnt->height;
    glViewport(me->xviewport,me->yviewport,me->widthvp,me->heightvp);
    me->unlock();

    gdk_gl_drawable_gl_end (gldrawable);

    if (me->osPixmap)
        g_object_unref(me->osPixmap);
    if (me->osContext)
        gdk_gl_context_destroy(me->osContext);
    me->osPixmap = gdk_pixmap_new (widget->window,
                                   widget->allocation.width,
                                   widget->allocation.height,
                                   -1);
    GdkGLConfig *glconfig = gdk_gl_config_new_by_mode (
        GdkGLConfigMode(GDK_GL_MODE_RGB    |
                        GDK_GL_MODE_SINGLE));
    GdkGLDrawable *osDrawable = GDK_GL_DRAWABLE (
        gdk_pixmap_set_gl_capability (me->osPixmap,
                                      glconfig,
                                      NULL));
    me->osContext = gdk_gl_context_new (osDrawable,
                                        glcontext,
                                        FALSE,
                                        GDK_GL_RGBA_TYPE);
   
    return FALSE;
}

That all works fine so far as I can tell. There may be some issues with when exactly I'm supposed to unref something; the whole reference counting scheme is less than well-documented. However, I'm not concerned about that for now.

I also have this function, which is not linked to any particular event:

gboolean doTakeScreenshot(gpointer data)
{
    GUIWindow *me = (GUIWindow *)data;

    assert(pthread_equal(me->mainthread, pthread_self()));

    me->lock();

    GdkGLDrawable *osDrawable = GDK_GL_DRAWABLE(me->osPixmap);
    if (!osDrawable || !me->osContext)
    {
        fprintf(stderr, "Warning, no offscreen pixbuf configured in aeGraphWindow::doTakeScreenshot.\n");
        me->signal(&me->screenshot_complete);
        me->unlock();
        return FALSE;
    }

    if (!gdk_gl_drawable_gl_begin (osDrawable, me->osContext))
    {
        me->signal(&me->screenshot_complete);
        me->unlock();
        return FALSE;
    }
   
    // OPENGL DRAWING HERE
   
    gdk_gl_drawable_wait_gl(osDrawable);
    glReadBuffer(GL_FRONT);
    glReadPixels(me->xviewport,me->yviewport,me->widthvp,me->heightvp,
                 GL_RGBA,GL_UNSIGNED_BYTE,me->screenshot_dest->data[0]);

    me->signal(&me->screenshot_complete);

    me->unlock();

    gdk_gl_drawable_gl_end (osDrawable);

    return FALSE;
}

It appears that gdk_gl_drawable_gl_begin() is failing here. What could cause that? Both the context and drawable being passed are valid pointers. However, I did notice that gdk_gl_context_get_gl_drawable(me->osContext) returned NULL, which I thought was odd.

I'm not positive that my glReadPixels() is valid either, but I want to get past this hurdle before worrying about that one.

Any ideas?
_______________________________________________
gtkglext-list mailing list
gtkglext-list@...
http://mail.gnome.org/mailman/listinfo/gtkglext-list

Re: GdkGLPixmap troubles

by Lindley :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Well, I've solve the initial issue---I was trying to cast a GdkPixmap when I should have been trying to cast a GdkGLPixmap. The bad cast warning was hidden because I'd forgotten I'd closed stderr on that program.

However, the images aren't coming out right when the "host window" isn't on-screen. This is odd, since the pixmap is supposed to be sharing lists, textures, etc with the window's context, but not otherwise related to anything on-screen.

It *looks* to me like what's getting drawn when the window is off-screen is a small part of the image, almost as if the orthographic projection were messed up; but I've checked that, it's fine. So is the viewport. So it must be something else?

----- Original Message -----
From: Lindley M French <lfrench1@...>
Date: Wednesday, August 26, 2009 2:46 pm
Subject: [GtkGLExt] GdkGLPixmap troubles

> I'm trying to allow an offscreen render to a pixmap to occur now,
> instead of trying to force an expose event while a window is
> offscreen like I was before.
>
> I've looked over the example code in pixmap.c that comes with
> GtkGLExt, but my adaptation of it isn't working.
>
> My configure-event handler:
>
> gboolean reshapeGL(GtkWidget *widget, GdkEventConfigure *evnt,
> gpointer data)
> {
>    GUIWindow* me = (GUIWindow*)data;
>    GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
>    GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
>
>    assert(pthread_equal(me->mainthread, pthread_self()));
>    fprintf(stderr,"reshaping window %d, %d %d %d %d\n",me-
> >window_id,evnt->x,evnt->y,evnt->width,evnt->height);
>
>    if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
>        return FALSE;
>
>    me->lock();
>    me->xviewport = evnt->x;
>    me->widthvp = evnt->width;
>    me->yviewport = evnt->y;
>    me->heightvp = evnt->height;
>    glViewport(me->xviewport,me->yviewport,me->widthvp,me->heightvp);
>    me->unlock();
>
>    gdk_gl_drawable_gl_end (gldrawable);
>
>    if (me->osPixmap)
>        g_object_unref(me->osPixmap);
>    if (me->osContext)
>        gdk_gl_context_destroy(me->osContext);
>    me->osPixmap = gdk_pixmap_new (widget->window,
>                                   widget->allocation.width,
>                                   widget->allocation.height,
>                                   -1);
>    GdkGLConfig *glconfig = gdk_gl_config_new_by_mode (
>        GdkGLConfigMode(GDK_GL_MODE_RGB    |
>                        GDK_GL_MODE_SINGLE));
>    GdkGLDrawable *osDrawable = GDK_GL_DRAWABLE (
>        gdk_pixmap_set_gl_capability (me->osPixmap,
>                                      glconfig,
>                                      NULL));
>    me->osContext = gdk_gl_context_new (osDrawable,
>                                        glcontext,
>                                        FALSE,
>                                        GDK_GL_RGBA_TYPE);
>    
>    return FALSE;
> }
>
> That all works fine so far as I can tell. There may be some issues
> with when exactly I'm supposed to unref something; the whole
> reference counting scheme is less than well-documented. However,
> I'm not concerned about that for now.
>
> I also have this function, which is not linked to any particular
> event:
> gboolean doTakeScreenshot(gpointer data)
> {
>    GUIWindow *me = (GUIWindow *)data;
>
>    assert(pthread_equal(me->mainthread, pthread_self()));
>
>    me->lock();
>
>    GdkGLDrawable *osDrawable = GDK_GL_DRAWABLE(me->osPixmap);
>    if (!osDrawable || !me->osContext)
>    {
>        fprintf(stderr, "Warning, no offscreen pixbuf configured
> in aeGraphWindow::doTakeScreenshot.\n");
>        me->signal(&me->screenshot_complete);
>        me->unlock();
>        return FALSE;
>    }
>
>    if (!gdk_gl_drawable_gl_begin (osDrawable, me->osContext))
>    {
>        me->signal(&me->screenshot_complete);
>        me->unlock();
>        return FALSE;
>    }
>    
>    // OPENGL DRAWING HERE
>    
>    gdk_gl_drawable_wait_gl(osDrawable);
>    glReadBuffer(GL_FRONT);
>    glReadPixels(me->xviewport,me->yviewport,me->widthvp,me->heightvp,
>                 GL_RGBA,GL_UNSIGNED_BYTE,me->screenshot_dest-
> >data[0]);
>    me->signal(&me->screenshot_complete);
>
>    me->unlock();
>
>    gdk_gl_drawable_gl_end (osDrawable);
>
>    return FALSE;
> }
>
> It appears that gdk_gl_drawable_gl_begin() is failing here. What
> could cause that? Both the context and drawable being passed are
> valid pointers. However, I did notice that
> gdk_gl_context_get_gl_drawable(me->osContext) returned NULL, which
> I thought was odd.
>
> I'm not positive that my glReadPixels() is valid either, but I
> want to get past this hurdle before worrying about that one.
>
> Any ideas?
> _______________________________________________
> gtkglext-list mailing list
> gtkglext-list@...
> http://mail.gnome.org/mailman/listinfo/gtkglext-list
>
_______________________________________________
gtkglext-list mailing list
gtkglext-list@...
http://mail.gnome.org/mailman/listinfo/gtkglext-list

Re: GdkGLPixmap troubles

by Lindley :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Okay, this is really odd.

I figured out why the on-screen case was working, that was just a remnant of my old code. But the GdkGLPixmap approach still isn't behaving itself. See the below code, with this inserted at the "OPENGL DRAWING HERE" point:

glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3d(1,0,0);
glBegin(GL_LINES);
glVertex2d(me->ortho.x,me->ortho.y+me->ortho.height);
glVertex2d(me->ortho.x+me->ortho.width,me->ortho.y);
glEnd();

Obviously, this should draw a simple red line diagonally from one corner of the image to the other, since I'm using the same values for the vertexes as I did for the glOrtho() call.

However, the attached image is what comes out. One corner right, the other....not. *Something* fishy is going on....

----- Original Message -----
From: Lindley M French <lfrench1@...>
Date: Wednesday, August 26, 2009 3:59 pm
Subject: Re: [GtkGLExt] GdkGLPixmap troubles

> Well, I've solve the initial issue---I was trying to cast a
> GdkPixmap when I should have been trying to cast a GdkGLPixmap.
> The bad cast warning was hidden because I'd forgotten I'd closed
> stderr on that program.
>
> However, the images aren't coming out right when the "host window"
> isn't on-screen. This is odd, since the pixmap is supposed to be
> sharing lists, textures, etc with the window's context, but not
> otherwise related to anything on-screen.
>
> It *looks* to me like what's getting drawn when the window is off-
> screen is a small part of the image, almost as if the orthographic
> projection were messed up; but I've checked that, it's fine. So is
> the viewport. So it must be something else?
>
> ----- Original Message -----
> From: Lindley M French <lfrench1@...>
> Date: Wednesday, August 26, 2009 2:46 pm
> Subject: [GtkGLExt] GdkGLPixmap troubles
>
> > I'm trying to allow an offscreen render to a pixmap to occur
> now,
> > instead of trying to force an expose event while a window is
> > offscreen like I was before.
> >
> > I've looked over the example code in pixmap.c that comes with
> > GtkGLExt, but my adaptation of it isn't working.
> >
> > My configure-event handler:
> >
> > gboolean reshapeGL(GtkWidget *widget, GdkEventConfigure *evnt,
> > gpointer data)
> > {
> >    GUIWindow* me = (GUIWindow*)data;
> >    GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
> >    GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
> >
> >    assert(pthread_equal(me->mainthread, pthread_self()));
> >    fprintf(stderr,"reshaping window %d, %d %d %d %d\n",me-
> > >window_id,evnt->x,evnt->y,evnt->width,evnt->height);
> >
> >    if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
> >        return FALSE;
> >
> >    me->lock();
> >    me->xviewport = evnt->x;
> >    me->widthvp = evnt->width;
> >    me->yviewport = evnt->y;
> >    me->heightvp = evnt->height;
> >    glViewport(me->xviewport,me->yviewport,me->widthvp,me->heightvp);
> >    me->unlock();
> >
> >    gdk_gl_drawable_gl_end (gldrawable);
> >
> >    if (me->osPixmap)
> >        g_object_unref(me->osPixmap);
> >    if (me->osContext)
> >        gdk_gl_context_destroy(me->osContext);
> >    me->osPixmap = gdk_pixmap_new (widget->window,
> >                                   widget->allocation.width,
> >                                   widget->allocation.height,
> >                                   -1);
> >    GdkGLConfig *glconfig = gdk_gl_config_new_by_mode (
> >        GdkGLConfigMode(GDK_GL_MODE_RGB    |
> >                        GDK_GL_MODE_SINGLE));
> >    GdkGLDrawable *osDrawable = GDK_GL_DRAWABLE (
> >        gdk_pixmap_set_gl_capability (me->osPixmap,
> >                                      glconfig,
> >                                      NULL));
> >    me->osContext = gdk_gl_context_new (osDrawable,
> >                                        glcontext,
> >                                        FALSE,
> >                                        GDK_GL_RGBA_TYPE);
> >    
> >    return FALSE;
> > }
> >
> > That all works fine so far as I can tell. There may be some
> issues
> > with when exactly I'm supposed to unref something; the whole
> > reference counting scheme is less than well-documented. However,
> > I'm not concerned about that for now.
> >
> > I also have this function, which is not linked to any particular
> > event:
> > gboolean doTakeScreenshot(gpointer data)
> > {
> >    GUIWindow *me = (GUIWindow *)data;
> >
> >    assert(pthread_equal(me->mainthread, pthread_self()));
> >
> >    me->lock();
> >
> >    GdkGLDrawable *osDrawable = GDK_GL_DRAWABLE(me->osPixmap);
> >    if (!osDrawable || !me->osContext)
> >    {
> >        fprintf(stderr, "Warning, no offscreen pixbuf configured
> > in aeGraphWindow::doTakeScreenshot.\n");
> >        me->signal(&me->screenshot_complete);
> >        me->unlock();
> >        return FALSE;
> >    }
> >
> >    if (!gdk_gl_drawable_gl_begin (osDrawable, me->osContext))
> >    {
> >        me->signal(&me->screenshot_complete);
> >        me->unlock();
> >        return FALSE;
> >    }
> >    
> >    // OPENGL DRAWING HERE
> >    
> >    gdk_gl_drawable_wait_gl(osDrawable);
> >    glReadBuffer(GL_FRONT);
> >    glReadPixels(me->xviewport,me->yviewport,me->widthvp,me-
> >heightvp,>                 GL_RGBA,GL_UNSIGNED_BYTE,me-
> >screenshot_dest-
> > >data[0]);
> >    me->signal(&me->screenshot_complete);
> >
> >    me->unlock();
> >
> >    gdk_gl_drawable_gl_end (osDrawable);
> >
> >    return FALSE;
> > }
> >
> > It appears that gdk_gl_drawable_gl_begin() is failing here. What
> > could cause that? Both the context and drawable being passed are
> > valid pointers. However, I did notice that
> > gdk_gl_context_get_gl_drawable(me->osContext) returned NULL,
> which
> > I thought was odd.
> >
> > I'm not positive that my glReadPixels() is valid either, but I
> > want to get past this hurdle before worrying about that one.
> >
> > Any ideas?
> > _______________________________________________
> > gtkglext-list mailing list
> > gtkglext-list@...
> > http://mail.gnome.org/mailman/listinfo/gtkglext-list
> >
> _______________________________________________
> gtkglext-list mailing list
> gtkglext-list@...
> http://mail.gnome.org/mailman/listinfo/gtkglext-list
>


_______________________________________________
gtkglext-list mailing list
gtkglext-list@...
http://mail.gnome.org/mailman/listinfo/gtkglext-list

test1.png (5K) Download Attachment

Re: GdkGLPixmap troubles

by Jean Bréfort :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Exporting a GL view is just a nightmare. Things seem to depend upon the
used driver. The solutioin I use can be seen at
http://svn.savannah.gnu.org/viewvc/trunk/gchemutils/libs/gcu/glview.cc?annotate=1098&root=gchemutils
starting from line 368. Not sure it works in all cases.

Regards,
Jean

Le mercredi 26 août 2009 à 15:59 -0400, Lindley M French a écrit :

> Well, I've solve the initial issue---I was trying to cast a GdkPixmap when I should have been trying to cast a GdkGLPixmap. The bad cast warning was hidden because I'd forgotten I'd closed stderr on that program.
>
> However, the images aren't coming out right when the "host window" isn't on-screen. This is odd, since the pixmap is supposed to be sharing lists, textures, etc with the window's context, but not otherwise related to anything on-screen.
>
> It *looks* to me like what's getting drawn when the window is off-screen is a small part of the image, almost as if the orthographic projection were messed up; but I've checked that, it's fine. So is the viewport. So it must be something else?
>
> ----- Original Message -----
> From: Lindley M French <lfrench1@...>
> Date: Wednesday, August 26, 2009 2:46 pm
> Subject: [GtkGLExt] GdkGLPixmap troubles
>
> > I'm trying to allow an offscreen render to a pixmap to occur now,
> > instead of trying to force an expose event while a window is
> > offscreen like I was before.
> >
> > I've looked over the example code in pixmap.c that comes with
> > GtkGLExt, but my adaptation of it isn't working.
> >
> > My configure-event handler:
> >
> > gboolean reshapeGL(GtkWidget *widget, GdkEventConfigure *evnt,
> > gpointer data)
> > {
> >    GUIWindow* me = (GUIWindow*)data;
> >    GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
> >    GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
> >
> >    assert(pthread_equal(me->mainthread, pthread_self()));
> >    fprintf(stderr,"reshaping window %d, %d %d %d %d\n",me-
> > >window_id,evnt->x,evnt->y,evnt->width,evnt->height);
> >
> >    if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
> >        return FALSE;
> >
> >    me->lock();
> >    me->xviewport = evnt->x;
> >    me->widthvp = evnt->width;
> >    me->yviewport = evnt->y;
> >    me->heightvp = evnt->height;
> >    glViewport(me->xviewport,me->yviewport,me->widthvp,me->heightvp);
> >    me->unlock();
> >
> >    gdk_gl_drawable_gl_end (gldrawable);
> >
> >    if (me->osPixmap)
> >        g_object_unref(me->osPixmap);
> >    if (me->osContext)
> >        gdk_gl_context_destroy(me->osContext);
> >    me->osPixmap = gdk_pixmap_new (widget->window,
> >                                   widget->allocation.width,
> >                                   widget->allocation.height,
> >                                   -1);
> >    GdkGLConfig *glconfig = gdk_gl_config_new_by_mode (
> >        GdkGLConfigMode(GDK_GL_MODE_RGB    |
> >                        GDK_GL_MODE_SINGLE));
> >    GdkGLDrawable *osDrawable = GDK_GL_DRAWABLE (
> >        gdk_pixmap_set_gl_capability (me->osPixmap,
> >                                      glconfig,
> >                                      NULL));
> >    me->osContext = gdk_gl_context_new (osDrawable,
> >                                        glcontext,
> >                                        FALSE,
> >                                        GDK_GL_RGBA_TYPE);
> >    
> >    return FALSE;
> > }
> >
> > That all works fine so far as I can tell. There may be some issues
> > with when exactly I'm supposed to unref something; the whole
> > reference counting scheme is less than well-documented. However,
> > I'm not concerned about that for now.
> >
> > I also have this function, which is not linked to any particular
> > event:
> > gboolean doTakeScreenshot(gpointer data)
> > {
> >    GUIWindow *me = (GUIWindow *)data;
> >
> >    assert(pthread_equal(me->mainthread, pthread_self()));
> >
> >    me->lock();
> >
> >    GdkGLDrawable *osDrawable = GDK_GL_DRAWABLE(me->osPixmap);
> >    if (!osDrawable || !me->osContext)
> >    {
> >        fprintf(stderr, "Warning, no offscreen pixbuf configured
> > in aeGraphWindow::doTakeScreenshot.\n");
> >        me->signal(&me->screenshot_complete);
> >        me->unlock();
> >        return FALSE;
> >    }
> >
> >    if (!gdk_gl_drawable_gl_begin (osDrawable, me->osContext))
> >    {
> >        me->signal(&me->screenshot_complete);
> >        me->unlock();
> >        return FALSE;
> >    }
> >    
> >    // OPENGL DRAWING HERE
> >    
> >    gdk_gl_drawable_wait_gl(osDrawable);
> >    glReadBuffer(GL_FRONT);
> >    glReadPixels(me->xviewport,me->yviewport,me->widthvp,me->heightvp,
> >                 GL_RGBA,GL_UNSIGNED_BYTE,me->screenshot_dest-
> > >data[0]);
> >    me->signal(&me->screenshot_complete);
> >
> >    me->unlock();
> >
> >    gdk_gl_drawable_gl_end (osDrawable);
> >
> >    return FALSE;
> > }
> >
> > It appears that gdk_gl_drawable_gl_begin() is failing here. What
> > could cause that? Both the context and drawable being passed are
> > valid pointers. However, I did notice that
> > gdk_gl_context_get_gl_drawable(me->osContext) returned NULL, which
> > I thought was odd.
> >
> > I'm not positive that my glReadPixels() is valid either, but I
> > want to get past this hurdle before worrying about that one.
> >
> > Any ideas?
> > _______________________________________________
> > gtkglext-list mailing list
> > gtkglext-list@...
> > http://mail.gnome.org/mailman/listinfo/gtkglext-list
> >
> _______________________________________________
> gtk-list mailing list
> gtk-list@...
> http://mail.gnome.org/mailman/listinfo/gtk-list
>

_______________________________________________
gtkglext-list mailing list
gtkglext-list@...
http://mail.gnome.org/mailman/listinfo/gtkglext-list

Parent Message unknown Re: GdkGLPixmap troubles

by Stephane Popinet-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Lindley, Jean,

> Exporting a GL view is just a nightmare. Things seem to depend upon the
> used driver. The solutioin I use can be seen at
> http://svn.savannah.gnu.org/viewvc/trunk/gchemutils/libs/gcu/glview.cc?annotate=1098&root=gchemutils
> starting from line 368. Not sure it works in all cases.

Yes, I can confirm that doing offscreen openGL rendering in a portable
way truly is a nightmare. It depends on the openGL driver and some
drivers are so dodgy that they even tell you that they support
offscreen openGL rendering when they don't.

OSMesa is a good alternative, however it is not that well supported either...

I would imagine offscreen openGL rendering to be something many people
want to do but I am puzzled by the lack of ressources on the topic on
the web. Are people using some other mechanism we are not aware of?

Thanks for your code Jean, I will have a look and see if I can use it
to improve mine (http://gfs.sf.net).

cheers

Stephane
_______________________________________________
gtkglext-list mailing list
gtkglext-list@...
http://mail.gnome.org/mailman/listinfo/gtkglext-list

Re: GdkGLPixmap troubles

by Lindley :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Well, the "right" way to do it is to to EXT_framebuffer_object, which most graphics cards support these days. However, I'm trying to avoid introducing a GLEW or GLee dependency, and I hate dealing with OpenGL extensions manually. It's the principal of the thing.

----- Original Message -----
From: Stephane Popinet <s.popinet@...>
Date: Wednesday, August 26, 2009 5:20 pm
Subject: Re: [GtkGLExt] GdkGLPixmap troubles

> Hi Lindley, Jean,
>
> > Exporting a GL view is just a nightmare. Things seem to depend
> upon the
> > used driver. The solutioin I use can be seen at
> >
> http://svn.savannah.gnu.org/viewvc/trunk/gchemutils/libs/gcu/glview.cc?annotate=1098&root=gchemutils> starting from line 368. Not sure it works in all cases.
>
> Yes, I can confirm that doing offscreen openGL rendering in a portable
> way truly is a nightmare. It depends on the openGL driver and some
> drivers are so dodgy that they even tell you that they support
> offscreen openGL rendering when they don't.
>
> OSMesa is a good alternative, however it is not that well
> supported either...
>
> I would imagine offscreen openGL rendering to be something many people
> want to do but I am puzzled by the lack of ressources on the topic on
> the web. Are people using some other mechanism we are not aware of?
>
> Thanks for your code Jean, I will have a look and see if I can use it
> to improve mine (http://gfs.sf.net).
>
> cheers
>
> Stephane
> _______________________________________________
> gtkglext-list mailing list
> gtkglext-list@...
> http://mail.gnome.org/mailman/listinfo/gtkglext-list
>
_______________________________________________
gtkglext-list mailing list
gtkglext-list@...
http://mail.gnome.org/mailman/listinfo/gtkglext-list

Re: GdkGLPixmap troubles

by Lindley :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ack, that looks messy. Anyway, here's my current code----all the objects and checks are sucessful, right up to the creation of the GdkPixbuf, but the damn thing is blank---no image in it. I even glClear()'d the buffer to green so I'd know it was getting *something*, but.....nope.

configure-event handler:

gboolean reshapeGL(GtkWidget *widget, GdkEventConfigure *evnt, gpointer data)
{
    GUIWindow* me = (GUIWindow*)data;
    GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
    GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);

    assert(pthread_equal(me->mainthread, pthread_self()));

    if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
        return FALSE;

    me->lock();
    me->viewport.x = evnt->x;
    me->viewport.width = evnt->width;
    me->viewport.y = evnt->y;
    me->viewport.height = evnt->height;
    me->unlock();

    gdk_gl_drawable_gl_end (gldrawable);

    if (me->osPixmap)
        gdk_gl_pixmap_destroy(me->osPixmap);
    if (me->osContext)
        gdk_gl_context_destroy(me->osContext);
    GdkPixmap *pixmap = gdk_pixmap_new (widget->window,
                                        widget->allocation.width,
                                        widget->allocation.height,
                                        -1);
    GdkGLConfig *glconfig = gdk_gl_config_new_by_mode (
        GdkGLConfigMode(GDK_GL_MODE_RGB    |
                        GDK_GL_MODE_SINGLE));
    me->osPixmap = gdk_pixmap_set_gl_capability (pixmap,
                                                 glconfig,
                                                 NULL);
    me->osContext = gdk_gl_context_new (GDK_GL_DRAWABLE(me->osPixmap),
                                        glcontext,
                                        FALSE,
                                        GDK_GL_RGBA_TYPE);
    g_object_unref(glconfig);
   
    return FALSE;
}

And here's my function to generate the Pixbuf:

gboolean doTakeScreenshot(gpointer data)
{
    GUIWindow *me = (GUIWindow*)data;

    assert(pthread_equal(me->mainthread, pthread_self()));

    me->lock();

    GdkGLDrawable *osDrawable = GDK_GL_DRAWABLE(me->osPixmap);
    if (!osDrawable || !me->osContext)
    {
        fprintf(stderr, "Warning, no offscreen pixbuf configured in GUIWindow::doTakeScreenshot.\n");
        me->signal(&me->screenshot_complete);
        me->unlock();
        return FALSE;
    }

    if (!me->screenshot_dest)
    {
        fprintf(stderr, "Warning, no screenshot destination found in GUIWindow::doTakeScreenshot.\n");
        me->signal(&me->screenshot_complete);
        me->unlock();
        return FALSE;
    }

    if (!gdk_gl_drawable_gl_begin (osDrawable, me->osContext))
    {
        me->signal(&me->screenshot_complete);
        me->unlock();
        return FALSE;
    }

    glViewport(me->viewport.x,me->viewport.y,me->viewport.width,me->viewport.height);
 
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    fprintf(stderr,"Taking screenshot of window %d.\n",me->window_id);

    // Need to flip the y axis for screenshots
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(me->ortho.x,me->ortho.x+me->ortho.width,
me->ortho.y+me->ortho.height,me->ortho.y,0,1);
    glMatrixMode(GL_MODELVIEW);
   
    glClearColor(0,1,0,1);
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3d(1,0,0);
    glBegin(GL_LINES);
    glVertex2d(me->ortho.x,me->ortho.y+me->ortho.height);
    glVertex2d(me->ortho.x+me->ortho.width,me->ortho.y);
    glEnd();
   
    gdk_gl_drawable_wait_gl(osDrawable);

    gdk_gl_drawable_gl_end (osDrawable);

    me->osBuffer = gdk_pixbuf_get_from_drawable(me->osBuffer,
                                                gdk_gl_pixmap_get_pixmap(me->osPixmap),
                                                NULL,//gdk_color_get_system(),
                                                0,0,0,0,-1,-1);
   
    if (me->osBuffer)
    {
        color_img *img = me->screenshot_dest;
        int pbheight =   gdk_pixbuf_get_height    (me->osBuffer);
        int pbwidth  =   gdk_pixbuf_get_width     (me->osBuffer);
        int pbstride =   gdk_pixbuf_get_rowstride (me->osBuffer);
        int pbchannels = gdk_pixbuf_get_n_channels(me->osBuffer);
        unsigned char *pixels = gdk_pixbuf_get_pixels(me->osBuffer);
       
        assert(pbchannels == 3);
       
        for (int i = 0; i < pbheight; i++)
        {
            for (int j = 0; j < pbwidth; j++)
            {
                memcpy(img->data[i][j],pixels + i*pbstride + j*pbchannels, pbchannels);
                img->data[i][j][3] = 255;
            }
        }
    }

    me->signal(&me->screenshot_complete);

    me->unlock();

    return FALSE;
}

I breakpoint on the line after the gdk_pixbuf_get_pixels() call, and check the first few bytes----always 0. They should be (0,1,0) patterns since that's what I cleared the background too, or (1,0,0) if I happened to get a pixel with the red line on it.

Any idea what's wrong? If I don't hear back I'm scrapping the pixmap code as worthless and going to the tried-and-true render-to-texture via EXT_framebuffer_object approach. Even if that does require introducing a GLEW dependency.

----- Original Message -----
From: Stephane Popinet <s.popinet@...>
Date: Wednesday, August 26, 2009 5:20 pm
Subject: Re: [GtkGLExt] GdkGLPixmap troubles

> Hi Lindley, Jean,
>
> > Exporting a GL view is just a nightmare. Things seem to depend
> upon the
> > used driver. The solutioin I use can be seen at
> >
> http://svn.savannah.gnu.org/viewvc/trunk/gchemutils/libs/gcu/glview.cc?annotate=1098&root=gchemutils> starting from line 368. Not sure it works in all cases.
>
> Yes, I can confirm that doing offscreen openGL rendering in a portable
> way truly is a nightmare. It depends on the openGL driver and some
> drivers are so dodgy that they even tell you that they support
> offscreen openGL rendering when they don't.
>
> OSMesa is a good alternative, however it is not that well
> supported either...
>
> I would imagine offscreen openGL rendering to be something many people
> want to do but I am puzzled by the lack of ressources on the topic on
> the web. Are people using some other mechanism we are not aware of?
>
> Thanks for your code Jean, I will have a look and see if I can use it
> to improve mine (http://gfs.sf.net).
>
> cheers
>
> Stephane
> _______________________________________________
> gtkglext-list mailing list
> gtkglext-list@...
> http://mail.gnome.org/mailman/listinfo/gtkglext-list
>
_______________________________________________
gtkglext-list mailing list
gtkglext-list@...
http://mail.gnome.org/mailman/listinfo/gtkglext-list

Parent Message unknown Re: GdkGLPixmap troubles

by Jose Commins-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


    Hi, just to note a few caveats when dealing with GL contexts.

    First, before performing any context reference operations, the GL widget should be +realized+ to manipulate any references inside.  I have included some source code that I use in one of my apps to enlighten. with typecasts to make it easier to associate types:

    // Get OpenGL rendering context.
    gtk_widget_realize ((GtkWidget *) yourGLCapableWidget);
    (GdkGLContext *) theSharedGlContext = gtk_widget_get_gl_context ((GtkWidget *) yourGLCapableWidget);
    // Initialise the other GL areas with the same shared context.
    (GtkWidget *) anotherGLWidget = GTK_WIDGET (gtk_builder_get_object (yourGTKBuilderXml, "GLwidget2"));
    // Add OpenGL-capability to the other widget, sharing the same context.
    gtk_widget_set_gl_capability ((GtkWidget *) anotherGLWidget, glConfig, (GdkGLContext *) theSharedGlContext, TRUE, GDK_GL_RGBA_TYPE);

... etc

    Note that 'gtk_widget_realize' is essential for the following functions to reference data within.

    Another caveat is that some drivers align texture data, depending on hardware - after the storage->framebuffer phase the alignment can vary if the hardware is not capable of non-powers-of-two textures.  You may find that the driver will texture-split any non-power-of-two rectangles.  The solution to this is to make sure that if the driver/hardware does not support non-power-of-two textures, to use the stride value in retrieving data back from the framebuffer.

Regards,
    Jose.

_______________________________________________
gtkglext-list mailing list
gtkglext-list@...
http://mail.gnome.org/mailman/listinfo/gtkglext-list

Parent Message unknown Re: GdkGLPixmap troubles

by Jose Commins-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


    Lindley, I think I've just spotted what the problem may be.  In your code you have this:

gboolean reshapeGL(GtkWidget *widget, GdkEventConfigure *evnt, gpointer data)
{
GUIWindow* me = (GUIWindow*)data;

    There's a quirk in using the 'gpointer data' object in a GTK function - it actually gets swapped in the stack if you do so, and is *not recommended* :P.
    The best approach is to not use the 'gpointer data' at all; instead, if you want to pass your user data to a GTK function, attach a GObject to it like so - in this example I am attaching it to the window containing the GL context:

    (-in place of setting the user data in your initialisation code-)
    g_object_set_data ((GObject *)theWindowWithYourGLContext, "myUserData", &theActualData);

    And then use something like this to retrieve it:

gboolean reshapeGL(GtkWidget *widget, GdkEventConfigure *evnt, gpointer data)
{
    GUIWindow* me = g_object_get_data ((GObject *)gtk_widget_get_toplevel (widget), "myUserData")));

    In your reshape (and other) functions that need it.

Regards,
        Jose.


_______________________________________________
gtkglext-list mailing list
gtkglext-list@...
http://mail.gnome.org/mailman/listinfo/gtkglext-list