2

对于 3D 建模项目,我使用 SDL 并包含在 GTK 小部件中(感谢 [GTKSDL],http ://gtksdl.sourceforge.net “直接链接到 GTKSDL”)。

小部件只是使用 GTK 加载 .obj 文件并使用 OpenGL 对其进行建模,然后将其显示在 SDL 小部件中。到目前为止,一切正常。

当我尝试使用 SDL 事件移动小部件中的对象时,问题就出现了。在 GTK 中集成 SDL 窗口之前,事件可以正常工作。此外,一旦显示 3D 模型,我就无法与 GTK 交互,因为显然 SDL 的事件循环正在等待某些东西,而无论我做什么,它都没有得到它。

我曾想过分叉这两个事件循环,但似乎 GTK 和 SDL 试图同时访问 X 服务器,这会产生多个冲突。我试图删除 SDL 中的无限循环,但它也不起作用。

我在 Devian,我在互联网上搜索了“GTKSdl”的实现,但它似乎已经过时了,有什么想法可以修补它吗?

更新:

我已经在使用 SDLPollEvent 和 g_idle add。因此,在我选择了一个文件(使用 GTK)之后,我填充了 struct "t_stage" 并使用 g_idle_add :

g_idle_add((GSourceFunc) &mainloop, stage);


gboolean            mainloop(t_stage *stage)
{
    SDL_Event     evt;

    while (SDL_PollEvent(&evt) != 0)
    {
      if (evt.type == SDL_MOUSEBUTTONDOWN)
       on_mouse_down(stage, &(evt.button));
      else if (evt.type == SDL_MOUSEBUTTONUP)
       on_mouse_up(stage, &(evt.button));
      else if (evt.type == SDL_MOUSEMOTION)
       on_mouse_move(stage, &(evt.motion));
      else if (evt.type == SDL_KEYDOWN)
       handle_key(stage, evt.key.keysym.sym, 1);
      else if (evt.type == SDL_KEYUP)
       handle_key(stage, evt.key.keysym.sym, 0);
    }
   apply_keys(stage);
   draw(stage, 0);
   return (1);
}

但事件仍未收到。有任何想法吗 ?

4

1 回答 1

2

GTKSDL 似乎是 2001 年创建的 alpha 质量小部件,从未维护过(我认为也没有广泛使用)。从那时起 GTK 发生了很大变化,所以我不确定它是否是最适合您的解决方案。

但是,您面临的一个问题是您不能在 GTK 的事件处理程序中使用无限循环(我知道,每个使用消息泵的事件驱动工具包也是如此)。如果你这样做,你只会阻止 GTK 有机会处理未决事件。有关如何解决此问题的更多信息,请查看将SDL 嵌入 GTK+

更新:

g_idle_add允许指定回调和传递给该回调的参数(gpointer data参数)。gpointer 只是指向 void 的指针。如果您需要回调以了解多个参数,则可以将结构的地址传递给它以读取/写入。

在您注册的回调中g_idle_add,您可以读取 SDL 事件。不要使用SDL_WaitEvent它,因为它会阻塞直到 SDL 事件发生,使用SDL_PollEvent(检索挂起的事件,如果有)或SDL_PeepEvents(检索所有挂起的事件,如果有的话)。这些函数是非阻塞的,如果没有事件挂起,它们会返回,而 SDL_WaitEvent 将阻塞,直到收到事件。

然后您可以处理这些事件,确保在您退出空闲处理程序之前不会花费太长时间,否则 GTK UI 将冻结。您可能还喜欢将这些事件转换为 GTK 事件,然后将它们分派给 GTK 以供其处理。

您还有一个SDL 与 GTK 1.2 集成的旧示例。我认为其中大部分都可以与 GTK 2 一起使用,基本思想就在那里,只需要更新代码以替换此后在 GTK 中不推荐使用的符号。

于 2012-04-17T14:38:06.227 回答