GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Fri Oct 31, 2014 5:56 pm

All times are UTC




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: GtkGLExt, labels, and smooth scrolling
PostPosted: Wed Dec 19, 2007 5:13 pm 
Offline
Familiar Face

Joined: Wed Dec 19, 2007 5:06 pm
Posts: 13
I'm using GtkGLExt to display a 2D OpenGL drawing in a drawing_area widget. Since OpenGL doesn't have native text support, and I'd prefer to keep library dependency to a minimum, I'd like to see if I can draw text on it simply using GtkLabels.

At the moment my hierarchy is:
Code:
GtkWindow
   GtkVbox
      GtkFixed
         GtkEventBox
            GtkDrawingArea (OpenGL-ized)
         GtkLabel
      GtkButton


(Hope that indenting takes....)

Eventually I'd like to replace the GtkFixed with something that can scroll, but swapping it for a GtkLayout doesn't seem as easy as the tutorial makes it sound.

Anyway, at the moment the label always draws behind the DrawingArea's OpenGL. Is there a way to control the order in which things are drawn inside a GtkFixed (or similar) widget?

I know that GtkGLExt contains functions to ensure OpenGL drawing is finished before Gtk drawing is done and vice versa, but I get the impression that's only within a single widget.


Last edited by Lindley on Thu Dec 20, 2007 3:12 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 19, 2007 8:52 pm 
Offline
Familiar Face

Joined: Wed Dec 19, 2007 5:06 pm
Posts: 13
Figured out scrolling, mostly, by replacing my EventBox with a ScrollingWindow and replacing the button with an HScale.

Scaling works, but it'd be nice if the current part of the view you're looking at *remained* the part of the view you're looking at as you scale. I suspect doing this would require something to be done to the Adjustments controlling the scroll bars of the ScrollingWindow, but I'm not entirely sure what. Any help?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 19, 2007 10:29 pm 
Offline
Never Seen the Sunlight

Joined: Wed Sep 21, 2005 12:07 am
Posts: 563
Location: Portland, OR USA
I'm not sure exactly what you're trying to do... could you paste your code?

_________________
Micah Carrick - Forum Administrator
http://www.micahcarrick.com


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 19, 2007 11:08 pm 
Offline
Familiar Face

Joined: Wed Dec 19, 2007 5:06 pm
Posts: 13
I'm trying to draw a scrollable 2D OpenGL image, with labels identifying various things on it. Since OpenGL doesn't support text, my options are:
1) Use an OpenGL text library. Such things exist, but I'd prefer not to introduce additional dependencies like that if GTK can cover me.
2) Use GTK labels which appear at fixed positions on top of the OpenGL drawing. This may not be possible since I've read that GTK doesn't like overlapping widgets. Yet, it appears to not cause too many issues at the moment; the label is merely behind the OpenGL drawing.
3) Draw text directly with GDK. I haven't tried this yet.

Even if labels aren't possible, I'd like to get a zoom control working which controls the size of the drawing_area within the scrollable_window; the glViewport call will ensure that the OpenGL scales along with the drawing_area's size. This is mostly done; the trick is getting the scrollbars to show the same relative portion of the drawing_area when the zoom is changed. I have code below that *should* do this, but in practice it tends to "shake" the image a bit as I drag the zoom control. The amount of stutter depends on how fast I drag it. Eliminating this stutter is my primary concern just now; getting labels working is second.

In simplified form:

Code:
static gboolean reshapeGL(GtkWidget *widget, GdkEvent *evnt, gpointer data)
{
    GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
    GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);

    if (!inited)
        initGL(widget,evnt,data);

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

    glViewport(0,0,800*currScale,800*currScale);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(xmin,xmax,ymin,ymax,0,1);

    gdk_gl_drawable_gl_end (gldrawable);

    return FALSE;
}

static gboolean drawGL(GtkWidget *widget, GdkEvent *evnt, gpointer data)
{
    GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
    GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);

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

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    draw(currentscene);// Not important, just a bunch of glVertex etc calls

    if (gdk_gl_drawable_is_double_buffered(gldrawable))
        gdk_gl_drawable_swap_buffers(gldrawable);
    else
        glFlush();

    gdk_gl_drawable_gl_end (gldrawable);

    return FALSE;
}

static gboolean adjustZoom(GtkRange *range, GtkScrollType scroll, gdouble value, gpointer data)
{
    GtkWidget *drawarea = GTK_WIDGET(data);
    gtk_widget_set_size_request(drawarea, value*800,value*800);
    return FALSE;
}

static gboolean scrollbar_bounds_changed(GtkAdjustment *adj, gpointer data)
{
    double prevperc = *((double*)data);

    currScale = (adj->upper - adj->lower)/800.0;
    adj->value = prevperc * (adj->upper - adj->lower) - adj->page_size/2.0;
    g_signal_emit_by_name(G_OBJECT(adj), "value-changed");
    return FALSE;
}

static gboolean scrollbar_value_changed(GtkAdjustment *adj, gpointer data)
{
    double *prevperc = (double*)data;

    *prevperc = (adj->value + adj->page_size/2.0) / (adj->upper - adj->lower);

    return FALSE;
}

int main(int argc, char*argv[])
{
    GtkWidget *window, *vbox, *layout, *scrolledwindow, *drawspace, *graphlabel;
    GtkWidget *zoomscale;
    GdkGLConfig *config;
    double v_scroll_perc = 0.5, h_scroll_perc = 0.5;
   
    gtk_init (&argc, &argv);
    gtk_gl_init(&argc, &argv);
   
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title (GTK_WINDOW (window), "Argon ST Character Graph");
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
    gtk_container_set_reallocate_redraws(GTK_CONTAINER (window), TRUE);

    vbox = gtk_vbox_new(FALSE, 10);
   
    gtk_container_add(GTK_CONTAINER(window), vbox);
    gtk_widget_show(vbox);

    layout = gtk_fixed_new();
    gtk_box_pack_start(GTK_BOX(vbox), layout, FALSE, FALSE, 0);
    gtk_widget_show(layout);

    config = gdk_gl_config_new_by_mode (GdkGLConfigMode(GDK_GL_MODE_RGB | GDK_GL_MODE_DOUBLE));

    scrolledwindow = gtk_scrolled_window_new(NULL,NULL);
    gtk_widget_set_size_request(scrolledwindow, 800,800);
    gtk_fixed_put(GTK_FIXED(layout), scrolledwindow, 0,0);
    gtk_widget_show(scrolledwindow);

    drawspace = gtk_drawing_area_new();
    gtk_widget_set_size_request(drawspace, 800,800);
    gtk_widget_add_events(drawspace, GDK_VISIBILITY_NOTIFY_MASK);
    gtk_widget_set_gl_capability(drawspace, config, NULL, TRUE, GDK_GL_RGBA_TYPE);
    gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolledwindow), drawspace);
    gtk_widget_show(drawspace);

    graphlabel = gtk_label_new("<span foreground='green' font_desc='36'>Dummy Label</span>");
    gtk_label_set_use_markup(GTK_LABEL(graphlabel),TRUE);
    gtk_fixed_put(GTK_FIXED(layout), graphlabel, 0,0);
    gtk_widget_show(graphlabel);

    zoomscale = gtk_hscale_new_with_range(1.0,15.0,.2);
    gtk_box_pack_start(GTK_BOX(vbox), zoomscale, TRUE, TRUE, 0);
    gtk_widget_show(zoomscale);

    g_signal_connect(G_OBJECT (zoomscale), "change-value", G_CALLBACK (adjustZoom), drawspace);
    g_signal_connect(G_OBJECT (gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrolledwindow))), "changed",
        G_CALLBACK(scrollbar_bounds_changed), &v_scroll_perc);
    g_signal_connect(G_OBJECT (gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(scrolledwindow))), "changed",
        G_CALLBACK(scrollbar_bounds_changed), &h_scroll_perc);
    g_signal_connect(G_OBJECT (gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrolledwindow))), "value-changed",
        G_CALLBACK(scrollbar_value_changed), &v_scroll_perc);
    g_signal_connect(G_OBJECT (gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(scrolledwindow))), "value-changed",
        G_CALLBACK(scrollbar_value_changed), &h_scroll_perc);

    g_signal_connect(G_OBJECT (drawspace), "realize", G_CALLBACK (initGL), NULL);
    g_signal_connect(G_OBJECT (drawspace), "configure_event", G_CALLBACK (reshapeGL), NULL);
    g_signal_connect(G_OBJECT (drawspace), "expose_event", G_CALLBACK (drawGL), NULL);
    g_signal_connect(G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL);

    // Set up current figure to draw

    gtk_widget_show(window);

    gtk_main();

    return 0;
}


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 19, 2007 11:32 pm 
Offline
Familiar Face

Joined: Wed Dec 19, 2007 5:06 pm
Posts: 13
By eliminating the currScale variable and calling glViewport with the configure event parameters directly, I've smoothed it somewhat. However, there's still some stutter.

I've tracked it to the fact that the ScrollableWindow is sending configure events to the drawing area *before* the Adjustment gets value_changed events. Is there any way to fix this?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 20, 2007 2:49 pm 
Offline
Familiar Face

Joined: Wed Dec 19, 2007 5:06 pm
Posts: 13
Okay, here's what's happening. The drawing area is being redrawn before the scroll value is changed, because I'm handling the zoom by calling gtk_widget_set_size_request().

I tried not allowing redraw until two value_changed events have been received (one for each dimension), but this didn't solve it either; the redraw occurs before the value_updated signal is handled.

I'm assuming this means that the value_updated signal is *not* what triggers a redraw, but merely does bookkeeping with regards to how the scroll bar is drawn. So which signal *does* trigger the dispatch of a redraw event? That's the one I need to handle.

Is there a way to ask GTK to printf all events?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC


Who is online

Users browsing this forum: Yahoo [Bot] and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group