Re: [GtkGLExt] GdkGLPixmap troubles



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 niwa co nz>
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 gnome org
> http://mail.gnome.org/mailman/listinfo/gtkglext-list
> 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]