GTK + Threading с помощью OpenGL GLUT / FreeGLUT

Я новичок в программировании на C / C ++, поэтому, пожалуйста, извините, если вам что-то покажется глупым ...

В настоящее время я работаю над проектом Visual Studio C ++ 2010, который включает opengl, glut / freeglut и gtk +.

OpenGL используется для получения входного изображения, управления его пикселями на основе различных параметров перед вызовом glDrawPixels () для рисования пикселей из буфера для отображения в окне перенасыщения / свободного перенасыщения.

Теперь я пытаюсь создать пользовательский интерфейс, чтобы пользователь мог настраивать параметры и видеть результирующее изображение во время выполнения.

На данный момент у меня есть одно окно GTK, которое содержит все виджеты GTK, и окно перенасыщения / свободного перенасыщения, в котором размещается изображение OpenGL. Принцип работы таков: при нажатии кнопки в пользовательском интерфейсе создается новый поток GTK для отображения окна перенасыщения / свободного накопления (которое содержит визуализированное изображение OpenGL.

У меня вопрос: как сделать так, чтобы перенасыщение / свободное накопление отображало обновленное изображение OpenGL и отображало его в том же окне перенасыщения / свободного накопления? Я не уверен, связано ли это с потоками GTK, или это просто перенасыщение / свободное поглощение, или и то, и другое. Есть ли у кого-нибудь совет?

Вот урезанный код, который у меня есть:

#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();
}

person user3409114    schedule 12.03.2014    source источник
comment
Еще раз проверьте логику вашего вопроса. Вы в значительной степени просите код, который вы вставили выше. Я не вижу никаких проблем / различий по сравнению с приведенным выше кодом.   -  person drahnr    schedule 12.03.2014
comment
Спасибо за проверку моего кода, drahnr. Коды, которые я предоставил, фактически открывают новое окно перенасыщения каждый раз, когда я нажимаю кнопку, а это не то, что я хочу. Мне нужно только два окна (и два потока), одно - это сам пользовательский интерфейс gtk, а другое - поток, у которого есть окно отображения перенасыщения.   -  person user3409114    schedule 12.03.2014


Ответы (1)


Перво-наперво: Free- / GLUT не является частью OpenGL. Это сторонняя библиотека с аналогичной областью (только намного проще), как GTK +. Если вы используете GTK +, вам не нужен GLUT. Вместо этого вам следует использовать виджет GTK + OpenGL, предоставляемый GTKGlExt.

В настоящее время я работаю над проектом Visual Studio C ++ 2010, который включает opengl, glut / freeglut и gtk +.

Зачем вам смешивать GLUT и GTK +? Для этого нет абсолютно никаких разумных причин. GLUT - это простая структура приложения (создает окна, предоставляет цикл событий), GTK + - это структура приложения (создает окна, предоставляет цикл событий, имеет виджеты).

Выберите одно, не смешивайте их.

Я не уверен, связано ли это с потоками GTK, или это просто перенасыщение / свободное поглощение, или и то, и другое. Есть ли у кого-нибудь совет?

Проблема в том, что у вас есть две библиотеки, которые борются за одно и то же (обработка событий ввода пользователя).

person datenwolf    schedule 12.03.2014
comment
Ладно, иметь GLUT и GTK + - плохая идея. Я наткнулся на GTKGlExt, но, похоже, он написан на C ++, что мне не очень нравится. Интересно, есть ли какое-нибудь хорошее руководство, которое могло бы помочь мне начать с ним. - person user3409114; 12.03.2014
comment
@ user3409114: GTKGlExt написан на C, как и сам GTK. - person datenwolf; 12.03.2014
comment
Взгляните на этот вопрос stackoverflow.com/questions/3815806/gtk- и-opengl-привязки. @datenwolf Я не уверен, что GtkGLExt - это то, что он ищет. - person drahnr; 13.03.2014
comment
@drahnr: Либо используйте GtkGLExt, либо GtkGLArea - жаль, что GTK по умолчанию не имеет виджета OpenGL. Беспорядок, с другой стороны, служит совершенно другой цели, выходящей за рамки вашей компетенции: это набор инструментов для виджетов и простая структура, написанная поверх OpenGL (с использованием частей библиотек g…). Это в основном полезно для написания динамических пользовательских интерфейсов, поскольку они вам нужны для мультимедийных приложений (например, в приставках для телевизоров или аналогичных). - person datenwolf; 13.03.2014
comment
@datenwolf, учитывая его текущую настройку, я бы сказал, что нужно GtkGLArea, я не мог найти GtkGLExt версию или репозиторий git, который поддерживается (официальный git.gnome.org/browse/gtkglext мертв на 3 года). - person drahnr; 13.03.2014
comment
Спасибо за все ваши замечательные предложения. Я обязательно проверю GTKGLArea, как некоторые из вас упомянули, надеюсь, это поможет мне выполнить мою работу. - person user3409114; 13.03.2014