Please feel free to link to this page.
TOP PDF ver.
Powered by SmartDoc

OpenGL, GLUT, and GLUI with MinGW

初版 2004/8/9
Shohei NOBUHARA
OpenGL, GLUT, GLUIでプログラムを作ると,X11, Windowsといったプラットフォームの差をこれらのライブラリがほぼ吸収してくれて,クロスコンパイルが可能となる.しかしlinux + X11という環境では,各種ディストリビューションによって簡単にコンパイル環境が整うが,windowsの場合はちょっとした作業が必要となる.ここではこの作業についてメモしておく.

目次

1 はじめに

Windowsの標準的コンパイラといえば,間違いなくVisual C++であろう.しかし今回はUnix (X11)環境とのクロスコンパイルの親和性を考えて,Mingw[1]を使うことにする.

2 MinGW環境の構築

MinGWはそのサブセットがCygwin[2]にも含まれるが,今回はオリジナルのMinGWを使う.bitWalkによるインストーラ版[3]を使うのが簡単であろう.またbashやmakeなどのツールはmsys[4]を使うことにする(1).mingwがc:\mingwに,msysがc:\msysにインストールされ,msysのrxvtから/mingw/bin/gcc.exeなどが見えているものとする.

またもし/mingw/usr/include/GLというディレクトリが存在しない場合,どこからかgl.h glext.h glu.hを手に入れる必要がある.これはgoogleで探せばよい.

  1. mingwはbitWalkによるmingw_045.exemingw_tools_042.exeを使用し,msysはsourceforge.netからMSYS-1.0.10.exeを使用した.

3 GLUTのコンパイル

まず,自分でGLUTをコンパイルするのが面倒な場合は,opengl.orgからglut37.zipをダウンロードすることができる.ただしこの場合は,出来上がるバイナリがglut32.dllに依存する形になるので,実行ファイルを配布する際はこれもあわせて配布するように注意が必要である.

以下では,glutのスタティックリンク版を自分でコンパイルする方法について説明する.最初に,オリジナルのソースファイルglut-3.7.6-src.zipを開発元[5]からダウンロード・展開する.これを/tmp/glut-3.7.6とする.今回はglut部分のみをコンパイルするため,/tmp/glut-3.7.6/lib/glutに移り,以下のMakefileを作成する(2)

リスト 1 lib/glut/Makefile
OBJS    = \
	glut_8x13.o     glut_9x15.o     glut_bitmap.o   glut_bwidth.o   \
	glut_cindex.o   glut_cmap.o     glut_cursor.o   glut_dials.o    \
	glut_dstr.o     glut_event.o    glut_ext.o      glut_fullscrn.o \
	glut_gamemode.o glut_get.o      glut_hel10.o    glut_hel12.o    \
	glut_hel18.o    glut_init.o     glut_input.o    glut_joy.o      \
	glut_key.o      glut_keyctrl.o  glut_keyup.o    glut_mesa.o     \
	glut_modifier.o glut_mroman.o   glut_overlay.o  glut_roman.o    \
	glut_shapes.o   glut_space.o    glut_stroke.o   glut_swap.o     \
	glut_swidth.o   glut_tablet.o   glut_teapot.o   glut_tr10.o     \
	glut_tr24.o     glut_util.o     glut_vidresize.o                \
	glut_warp.o     glut_win.o      glut_winmisc.o  win32_glx.o     \
	win32_menu.o    win32_util.o    win32_winproc.o win32_x11.o     \
	glutres.o

CFLAGS = -Wall -s -march=pentium4 -O2 -fomit-frame-pointer -ffast-math \
    -I../../include
CC = gcc
LIBS   = -lglu32 -lopengl32 -lwinmm -lkernel32 -luser32 -lgdi32

all     : libglut32.a
# all   : glut32.dll

libglut32.a   : $(OBJS) mingglut.def
        ar -rsv $@ $^

glut32.dll : $(OBJS) mingglut.def
dllwrap --def mingglut.def -o glut32.dll $(OBJS) $(LIBS) --output-lib \
    libglut32.a

mingglut.def : $(OBJS)
        dlltool  --export-all-symbols --output-def mingglut.def $(OBJS)

glutres.o : glut.rc
        windres glut.rc glutres.o

clean   :
        rm -f *.o

あとは

$ make
$ cp libglut32.a /mingw/lib
$ cp ../../include/GL/glut.h /mingw/include/GL

とする.ちなみにダイナミックリンク版が作りたい場合は,

$ make glut32.dll

とすれば,libglut32.aとglut32.dllが出来上がる.

  1. 行頭のホワイトスペースはTABであることに注意.

4 GLUIのコンパイル

まずGLUI[6]のソースコードglui_v2_1_beta.zipをダウンロード・展開する.以降/tmp/gluiに展開したものとする.

このままではコンパイルが通らないので,以下のように若干の修正を加える.

リスト 2 glui.patch
diff -rdNu glui.orig/glui.h glui/glui.h
--- glui.orig/glui.h    Fri Jul  9 16:38:46 1999
+++ glui/glui.h Mon Aug  2 15:20:51 2004
@@ -295,8 +295,8 @@
parent_node= child_head = child_tail = next_sibling = prev_sibling = NULL;
   }; 
 
-  friend GLUI_Rollout;
-  friend GLUI_Main;
+  friend class GLUI_Rollout;
+  friend class GLUI_Main;
 };
 
 
@@ -559,11 +559,11 @@
 
   /********** Friend classes *************/
 
-  friend GLUI_Control;
-  friend GLUI_Rotation;
-  friend GLUI_Translation;
-  friend GLUI;
-  friend GLUI_Master_Object;
+  friend class GLUI_Control;
+  friend class GLUI_Rotation;
+  friend class GLUI_Translation;
+  friend class GLUI;
+  friend class GLUI_Master_Object;
 
 
   /********** Misc functions *************/
diff -rdNu glui.orig/makefile glui/makefile
--- glui.orig/makefile  Fri Jul  9 16:38:44 1999
+++ glui/makefile       Mon Aug  9 17:03:01 2004
@@ -12,9 +12,9 @@
 
 
 #for sgi   -- comment out the lines below to use on HP
-CC=CC -g0 -o32
+#CC=CC -g0 -o32
 #CC=gcc
-#CC=g++ -O3
+CC=g++ -O2
 CPPFLAGS=-I${GLUT_INC_LOCATION} #-w 
 GLLIBS=-L${GLUT_LIB_LOCATION} -lglut -lGL -lGLU
 LPATH=${GLUTPATH} 

要するにfriendにclassをつけて,コンパイラを指定するだけ.あとは

$ mkdir bin lib
$ make
$ cp lib/libglui.a /mingw/lib/
$ cp glui.h /mingw/include/

とすればよい(3)

  1. サンプルプログラムのコンパイルが些細なエラーで止まるかもしれないが,とりあえずライブラリができていればよい.

5 テスト

ここまでで

/mingw/include/GL/glut.h  /mingw/lib/libglui.a
/mingw/include/glui.h     /mingw/lib/libglut32.a

が新たに作成された.テストとしてGLUIのソースに含まれるexample5.cppをコンパイルしてみる.

まずexample5.cppをコンパイルするには,以下のようにmain()の戻り値を修正する必要がある.

リスト 3 example5.patch
--- glui.orig/example5.cpp      Fri Jul  9 16:38:44 1999
+++ glui/example5.cpp   Mon Aug  9 17:10:50 2004
@@ -310,7 +310,7 @@
 
 /**************************************** main() ********************/
 
-void main(int argc, char* argv[])
+int main(int argc, char* argv[])
 {
   /****************************************/
   /*   Initialize GLUT and create window  */
@@ -478,5 +478,7 @@
   /**** Regular GLUT main loop ****/
   
   glutMainLoop();
+
+  return 0;
 }

つぎに,この状態で

$ make example5

としても,リンクでエラーがでる.これは,ソースに含まれるmakefileがX11のライブラリとリンクするように指定しているため.そこで,

$ g++ -o example5.exe example5.cpp -lglui -lglut32 -lglu32 \
    -lopengl32 -lwinmm -lgdi32

のように,windows環境で必要なライブラリを指定する.

このexample5.exeが動作することを確認し,また,dependencywalker[7]を使って,リンクしているDLLがWindows標準のもののみであることを確認する.

6 Tips

6.1 DOS窓を消す

先ほどのようにexample5.exeなどをコンパイル・実行すると,起動時にdosプロンプトが出現して見苦しい.これには有名な対処法があり,リンク時に-mwindowsをつけるだけである(4)

  1. VC (cl.exe)の/SUBSYSTEM:WINDOWSのようなもの.

6.2 glui-configスクリプト

gtk+などのライブラリでは,コンパイル時にプラットフォーム間の差異を吸収するため,適切なCFLAGSなどを出力するためのシェルスクリプトが用意されている.残念ながら現在のgluiにはそのようなものが存在しないため,自分で勝手に作ってしまう.

リスト 4 glui-config
#!/bin/sh
case `uname` in 
  Linux*)
  if [ x$1 == x--libs ]; then
    echo -n "-lglui"
  fi
  ;;
  MINGW*)
  if [ x$1 == x--libs ]; then
    echo -n "-lglui -lglut32 -lglu32 -lopengl32 -lwinmm -lgdi32 -mwindows"
  fi
  ;;
esac

あとはMakefileで

LDFLAGS         = `./glui-config --libs`

のように使う.

7 まとめ

GLUT / GLUIはOpenGLにのみ依存するため,プラットフォーム間の移植性に優れ,また非常にシンプルなAPIであることから,windows上でも開発環境も容易に構築でき,ちょっとした3Dビューワなどを作成するには大変便利である.

しかしそれは一方で欠点ともなり,たとえばファイル選択ダイアログや,色選択ダイアログ,スライダ,プログレスバー,…など,最近のGUIツールキットが標準的に備える機能が存在しない.また基本的にCを基準としたGLUTのAPIの制限から,ソースコードではグローバル変数が多用され,あまり美しいとはいえない.

もしGLUT / GLUIの枠を超えた,より充実したGUI環境が必要で,WindowsやX11に縛られない移植性が必要ならば,Qt[8]やFOX[9],wxWidgets[10](5)などが候補となるのではないだろうか.

  1. 旧wxWindows.

参考文献

[1]Colin Peters et al. MinGW - Minimalist GNU for Windows. http://www.mingw.org/
[2]Red Hat, Inc.. Cygwin. http://www.cygwin.com/
[3]bitWalk Co., Ltd.. MinGW Programming Kit. http://www63.tok2.com/home/bitwalk/mingw.html
[4]Colin Peters et al. MinGW - Minimal SYStem. http://www.mingw.org/msys.shtml
[5]Nate Robins. The OpenGL Utility Toolkit. http://www.xmission.com/~nate/glut.html
[6]Paul Rademacher. GLUI User Interface Library. http://www.cs.unc.edu/~rademach/glui/
[7]Steve P. Miller. Dependency Walker. http://www.dependencywalker.com/
[8]Trolltech, Inc.. Qt. http://www.trolltech.com/
[9]Jeroen van der Zijp. FOX toolkit. http://www.fox-toolkit.org/
[10]Julian Smart et al. wxWidgets. http://www.wxwindows.org/