gtkglext
プライベートではUbuntuとMac OS Xを使っているんですが,現在両OSで動くプログラムを作っています。
そのプログラムはGUI側はそれぞれgtkとCocoaを使っていますが,3DCG描画処理や数値演算部分は共通の自作のライブラリとしてソースを共有しています。
以前,gtkを使ったGUIプログラムではgtkのウィンドウデータからX用のデータ箇所を拝借し,頑張ってOpenGL用の設定をしていました。
しかし,今回はCocoaと共通化するので以前のようなこ難しいやり方ではなく素直にgtkのウィンドウ上でOpenGL描画用のライブラリを使うことにしました
gtkglareaとgtkglext
gtk上でOpenGLを描画する為のライブラリにはgtkglareaとgtkglextの二つが有名です。
それぞれgtkとは次のような関係があります。
gtkgtlext | gtk+ (バージョン2.0)に対応 |
gtkglarea | gtk (バージョン1.0) に対応 |
現状は2.0なのでそれ用のgtkglextを選択。(gtk+の方がいまどきなスタイルです)
gtkglextを使ってOpenGLの描画
初期化処理ソースはこんな感じです
GtkWidget* drawarea = NULL; void init(std::ostream& out, Widget* box) { GdkGLConfig *glconfig; unsigned int mode = GDK_GL_MODE_RGB | GDK_GL_MODE_DEPTH | GDK_GL_MODE_DOUBLE; glconfig = gdk_gl_config_new_by_mode(static_cast<GdkGLConfigMode>(mode)); // 初期化失敗かどうかチェック if( glconfig == NULL ){ out << "Error" << endl; return -1; } // OpenGL用の描画エリアを新規作成 drawarea = gtk_drawing_area_new(); // 描画エリアの属性を設定 gtk_widget_set_size_request(drawarea, 480, 480); gtk_widget_set_gl_capability(drawarea, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE); // 描画用のコールバックを登録 g_signal_connect(G_OBJECT(drawarea, "expose_event", G_CALLBACK(OnDraw), NULL); // メインウィンドウのボックスに描画エリアを登録 gtk_box_pack_start(GTK_BOX(box), drawarea, TRUE, TRUE, 0);
描画用のソースは
gint OnDraw(GtkWidget* widget, GdkEventExpose* event, gpointer user_data) { GdkGLContext *glcontext = gtk_widget_get_gl_context(widget); GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget); if( !gdk_gl_drawable_gl_begin(gldrawable, glcontext) ) FALSE; // ここで三角形とか描きましょう gdk_gl_drawable_swap_buffers(gldrawable); return 0; }