0

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();
}
  • Recheck your question logic. You are asking pretty much for the code you pasted above. I do not see any issue/difference compared to the above code. – drahnr Mar 12 '14 at 08:35
  • Thanks for checking my code, drahnr. The codes I provided actually open a new glut window every time I click on the button, and that's not what I want. I want only two windows (and two threads), one is the gtk UI itself, the other is the thread that has the glut display window. – user3409114 Mar 12 '14 at 10:13

1 Answers1

3

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).

datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • Okay, that does sound like a bad idea having GLUT and GTK+. I did come across GTKGlExt, but it seems to be written in C++, which I am not very comfortable with. Wonder if there's any good tutorial that could get me started with it. – user3409114 Mar 12 '14 at 15:19
  • @user3409114: GTKGlExt is written in C, just like GTK itself. – datenwolf Mar 12 '14 at 19:02
  • Have a look at this question http://stackoverflow.com/questions/3815806/gtk-and-opengl-bindings. @datenwolf I am not sure if `GtkGLExt` is what he is looking for. – drahnr Mar 13 '14 at 10:19
  • @drahnr: Well either use GtkGLExt or GtkGLArea – it's a shame that GTK doesn't come with a OpenGL widget by default. Clutter on the other hand servers a completely different purpose, outside your scope: It's a widget toolkit and simple framework written on top of OpenGL (using parts of the g… libraries). It's mostly useful for writing dynamic UIs as you need them for multimedia applications (like in TV Settop boxes or similar). – datenwolf Mar 13 '14 at 11:31
  • @datenwolf given his current setup I'd say go for `GtkGLArea` , I could not google-up a `GtkGLExt` version or git repo that is maintained (official https://git.gnome.org/browse/gtkglext/ is 3 years dead in the water). – drahnr Mar 13 '14 at 11:51
  • Thanks for all of your great suggestions. I will definitely check out GTKGLArea like some of you mentioned, hopefully it will help me to get my job done. – user3409114 Mar 13 '14 at 14:25