Question

I am fairly new to C/C++ programming, so please excuse me if something sounds stupid to you...

I am currently working on a Visual Studio C++ 2010 project that involves opengl, glut/freeglut, and gtk+.

The OpenGL is used to take an input image, manipulate its pixels based on various parameters before calling glDrawPixels() to draw the pixels from buffer for display in a glut/freeglut window.

Now I am trying to make a UI so user can adjust the parameters and see the resulting image at runtime.

What I have so far is one GTK window that contains all of the GTK widgets, and a glut/freeglut window that houses the OpenGL image. How it works is that when the button on the UI is clicked, a new GTK thread is created to display the glut/freeglut window (that contains the OpenGL rendered image.

My question is, how do I make glut/freeglut to render updated OpenGL image and display it in the same glut/freeglut window? I am not sure if it has to do with GTK threading or it's just glut/freeglut, or both. Does anyone have any advice?

Here's the stripped down code I have:

#include<freeglut.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <gtk/gtk.h>

GtkWidget *window;
GtkWidget *vbox, *hbox;
GtkWidget *button;
gint tmp_pos;
GThread *thread;   
gint progress = 0;
G_LOCK_DEFINE_STATIC(progress);
GError *error = NULL;

void display()
    {
      glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
      glRasterPos2i(x_offset,y_offset);
      glDrawPixels(x2-x1+1,y2-y1+1,GL_LUMINANCE,GL_UNSIGNED_BYTE,tmp_buf);
      glFlush();
    }

static gpointer runGL(gpointer data)
{
  glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);

  glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
  if(Running_Mode==0)
    glutInitWindowSize(3*Test_Size,Test_Size); /* 500 x 500 pixel window */
  else
    glutInitWindowSize(Test_Size,Test_Size); /* 500 x 500 pixel window */
  glutInitWindowPosition(600,0); /* place window top left on display */
  glutCreateWindow("Simulation"); /* window title */
  glutDisplayFunc(display); /* display callback invoked when window opened */
  myinit(); /* set attributes */
  glutMainLoop(); /* enter event loop */    
  return (NULL);
}

/* create a g_thread for glut window */
void GLThread()
{
   thread = g_thread_create(runGL, (gpointer)button, TRUE, &error);
   g_print("Thread created");
   if(!thread)
   {
      g_print("Error: %s\n", error->message);
      return(-1);
   }
}


int main(int argc,char **argv)
{
    glutInit(&argc,argv);

    if(! g_thread_supported())
        g_thread_init( NULL );

    gdk_threads_init();

    /* Obtain gtk's global lock */
    gdk_threads_enter();
    gtk_init (&argc, &argv);

    /* create a new window */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_size_request (GTK_WIDGET (window), 200, 100);
    gtk_window_set_title (GTK_WINDOW (window), "GTK Entry");
    g_signal_connect (window, "destroy",
                      G_CALLBACK (gtk_main_quit), NULL);
    g_signal_connect_swapped (window, "delete-event",
                              G_CALLBACK (gtk_widget_destroy), 
                              window);

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

    hbox = gtk_hbox_new (FALSE, 0);
    gtk_container_add (GTK_CONTAINER (vbox), hbox);
    gtk_widget_show (hbox); 

    button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);

    /* call the GLThread function when the button is clicked */
    g_signal_connect_swapped (button, "clicked", G_CALLBACK (GLThread), window);

    gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
    gtk_widget_set_can_default (button, TRUE);
    gtk_widget_show (button);   
    gtk_widget_show(window);

    gtk_main();
    gdk_threads_leave();
}
Was it helpful?

Solution

First things first: Free-/GLUT is not a part of OpenGL. It's a 3rd party library with a similar scope (just much more simpler) like GTK+. If you're using GTK+ you don't need GLUT. Instead you should use the GTK+ OpenGL Widget provided by GTKGlExt.

I am currently working on a Visual Studio C++ 2010 project that involves opengl, glut/freeglut, and gtk+.

Why would you want to mix GLUT and GTK+? There's absolutely no sane reason to do this. GLUT is a simple application framework (creates windows, provides the event loop), GTK+ is an application framework (creates windows, provides the event loop, has widgets).

Choose one, don't mix them.

I am not sure if it has to do with GTK threading or it's just glut/freeglut, or both. Does anyone have any advice?

The problem is, that you have two libraries fighting to do the same thing (processing user input events).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top