【问题标题】:GTK+ Threading with OpenGL's GLUT/FreeGLUTGTK+ 线程与 OpenGL 的 GLUT/FreeGLUT
【发布时间】:2014-03-12 06:50:27
【问题描述】:

我是 C/C++ 编程的新手,所以如果你觉得有些愚蠢,请原谅...

我目前正在处理一个涉及 opengl、glut/freeglut 和 gtk+ 的 Visual Studio C++ 2010 项目。

OpenGL 用于获取输入图像,根据各种参数操作其像素,然后调用 glDrawPixels() 从缓冲区中绘制像素以显示在 glut/freeglut 窗口中。

现在我正在尝试制作一个 UI,以便用户可以调整参数并在运行时查看生成的图像。

到目前为止,我有一个包含所有 GTK 小部件的 GTK 窗口,以及一个包含 OpenGL 图像的 glut/freeglut 窗口。它的工作原理是,当点击 UI 上的按钮时,会创建一个新的 GTK 线程来显示 glut/freeglut 窗口(其中包含 OpenGL 渲染的图像。

我的问题是,如何使 glut/freeglut 渲染更新的 OpenGL 图像并将其显示在同一个 glut/freeglut 窗口中?我不确定它是否与 GTK 线程有关,或者它只是 glut/freeglut,或两者兼而有之。有人有什么建议吗?

这是我的精简代码:

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

【问题讨论】:

  • 重新检查您的问题逻辑。您对上面粘贴的代码的要求很高。与上述代码相比,我没有发现任何问题/差异。
  • 感谢您检查我的代码,drahnr。每次单击按钮时,我提供的代码实际上都会打开一个新的过剩窗口,这不是我想要的。我只想要两个窗口(和两个线程),一个是 gtk UI 本身,另一个是具有 glut 显示窗口的线程。

标签: c opengl gtk glut freeglut


【解决方案1】:

第一件事:Free-/GLUT 不是 OpenGL 的一部分。它是一个与 GTK+ 类似的范围(只是更简单)的 3rd 方库。如果您使用的是 GTK+,则不需要 GLUT。相反,您应该使用GTKGlExt 提供的 GTK+ OpenGL Widget。

我目前正在从事一个涉及 opengl、glut/freeglut 和 gtk+ 的 Visual Studio C++ 2010 项目。

为什么要混合使用 GLUT 和 GTK+?绝对没有理智的理由这样做。 GLUT 是一个简单的应用程序框架(创建窗口,提供事件循环),GTK+ 是一个应用程序框架(创建窗口,提供事件循环,有小部件)。

选择一个,不要混用。

我不确定它是否与 GTK 线程有关,或者它只是 glut/freeglut,或两者兼而有之。有人有什么建议吗?

问题是,您有两个库为做同样的事情(处理用户输入事件)而争斗。

【讨论】:

  • 好吧,使用 GLUT 和 GTK+ 听起来确实是个坏主意。我确实遇到了 GTKGlExt,但它似乎是用 C++ 编写的,我不太习惯。想知道是否有任何好的教程可以让我开始使用它。
  • @user3409114:GTKGlExt 是用 C 编写的,就像 GTK 本身一样。
  • 看看这个问题stackoverflow.com/questions/3815806/gtk-and-opengl-bindings。 @datenwolf 我不确定GtkGLExt 是不是他要找的东西。
  • @drahnr:好吧,要么使用 GtkGLExt 要么使用 GtkGLArea - 遗憾的是 GTK 默认没有附带 OpenGL 小部件。另一方面,Clutter 服务于完全不同的目的,超出了您的范围:它是一个小部件工具包和简单的框架,编写在 OpenGL 之上(使用部分 g... 库)。它对于编写动态 UI 非常有用,因为您需要将它们用于多媒体应用程序(例如在电视机顶盒或类似设备中)。
  • @datenwolf 考虑到他目前的设置,我想说去GtkGLArea,我无法通过谷歌搜索GtkGLExt 版本或维护的git repo(官方git.gnome.org/browse/gtkglext 已经死了3 年在水中)。
猜你喜欢
  • 2012-06-07
  • 2014-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多