基于 pygtk + vtk 实现三维数据可视化(一)
Gtk+ 与三维图形渲染
Gtk+ 虽然优秀,但我当初考虑使用它来做三维图形渲染窗口时,发现官方没有提供对 OpenGL 图形渲染的集成支持。同类 GUI 库,譬如 Qt 与 wxWidgets,官方提供了一个专门用于渲染 OpenGL 图形的 widget(窗口部件)。
Gtk+有一个第三方库 gtkglarea,实现了用于显示 OpenGL 图形的 widget,但是这个库年久失修,并且没有跟进 Gtk+ 2.x,现在这个项目已经死掉了。
取 gtkglarea 项目而代之的是 gtkglext 项目。与 gtkglarea 相比,gtkglext 的实现更贴近于 gtk+ 的底层,从而也更灵活,可以让 gtk+ widget 从根本上兼容 OpenGL 图形渲染。我很奇怪为什么 gtk+ 官方不考虑将 gtkglext 并入 gtk+ 的标准组件中。
Gtk+ 与 VTK
虽然借助 gtkglext 库,gtk+ 程序可以很方便的实现 OpenGL 图形渲染,但是对基于 OpenGL 实现的高级三维图形渲染库 Vtk 的支持却很让人头疼。因为 Vtk 是 C++ 库,而 gtk+ 是 C 库,二者之间的对接很困难。
考虑到采用 C++ 语言对 C 库的实现进行封装,要比采用 C 语言来封装一个 C++ 库更方便。如果用 C++ 语言对 gtk+ 库进行封装,从而将 gtk+ 与 vtk 放在同一种编程语言环境中,这样就可以有效降低 gtk+ 与 vtk 对接难度。再考虑如果采用可以同时实现与 C/C++ 混合编程的第三种编程语言,譬如 Python,基于该语言分别对 gtk+ 库与 vtk 库进行封装,也可以将 gtk+ 与 vtk 放到同一种编程语言环境中。
其实我觉得 vtk 采用 C++ 来实现是很不高明的,虽然采用 C++ 可以提高编程效率,但是随之而来的问题是降低了库的灵活性。如果 vtk 的实现像 OpenGL 那样体现为平坦的 C 库,那么现在就可以很方便做 C++、Python、Java、ruby 等高级语言的封装了。这只是我的个人浅见,这种浅见主要来自于 gtk+ 的成功,看看现在 gtk+ 的那么多种语言绑定就知道 vtk 有多么笨重了。
总之,要多快好省地实现 Gtk+ 与 Vtk 的对接,就应当为它们营造一个均等的编程语言环境。既然 Vtk 是笨重的 C++ 库,那么这等重任应当落在 gtk+ 身上了,这就涉及到 gtk+ 的语言绑定。
基于 python 的 Gtk+ 与 vtk 库的对接
Gtk+ 2.x 是一套非常成熟的跨平台 GUI 开发库,采用 C 语言实现,但是通过对库接口的封装 (Wrapper) 可以实现与各种高级语言的灵活绑定 (binding),具体可参考 Gtk+ Bindings。目前应用比较广泛的 gtk+ Wrapper 是 gtkmm 与 pygtk,它们分别实现了 gtk+ 库接口的 c++ 绑定与 python 绑定。
当初我是从 C/C++ 开始学习编程的,但对 C++ 一向都心存畏惧,总也上升不到大牛们所谓的艺术高度。后来初次接触 python 时,一下子被其简洁明快的编程思想与风格深深地吸引住了。虽然一直都没怎么真正使用 python 写过程序,但是随着对 python 与 C 的混合编程能力的逐步了解,我对 C++ 残存的留恋也随风飘散了。用 C 来实现平坦的底层库,用 python 对库接口进行组装,这样即可满足程序的运行效率,又同时兼顾了程序实现效率。正是出于对 python 与 c 的信赖,我选择 pygtk 来做 GUI 程序,而不是 gtkmm。
对于本文所讨论的问题,即 gtk+ 与 vtk 的对接,由于 vtk 也提供了 python 绑定,这样基于 pygtk 与 vtk 的 python 绑定,再利用 gtkglext 库提供的 OpenGL 图形渲染功能,实现Gtk+ 与 vtk 库的对接就变得简单了。