Windowsの標準的コンパイラといえば,間違いなくVisual C++であろう.しかし今回はUnix (X11)環境とのクロスコンパイルの親和性を考えて,Mingw[1]を使うことにする.
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で探せばよい.
まず,自分で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).
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が出来上がる.
まずGLUI[6]のソースコードglui_v2_1_beta.zipをダウンロード・展開する.以降/tmp/gluiに展開したものとする.
このままではコンパイルが通らないので,以下のように若干の修正を加える.
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).
ここまでで
/mingw/include/GL/glut.h /mingw/lib/libglui.a /mingw/include/glui.h /mingw/lib/libglut32.a
が新たに作成された.テストとしてGLUIのソースに含まれるexample5.cppをコンパイルしてみる.
まずexample5.cppをコンパイルするには,以下のようにmain()の戻り値を修正する必要がある.
--- 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標準のもののみであることを確認する.
先ほどのようにexample5.exeなどをコンパイル・実行すると,起動時にdosプロンプトが出現して見苦しい.これには有名な対処法があり,リンク時に-mwindowsをつけるだけである(4).
gtk+などのライブラリでは,コンパイル時にプラットフォーム間の差異を吸収するため,適切なCFLAGSなどを出力するためのシェルスクリプトが用意されている.残念ながら現在のgluiにはそのようなものが存在しないため,自分で勝手に作ってしまう.
#!/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`
のように使う.
GLUT / GLUIはOpenGLにのみ依存するため,プラットフォーム間の移植性に優れ,また非常にシンプルなAPIであることから,windows上でも開発環境も容易に構築でき,ちょっとした3Dビューワなどを作成するには大変便利である.
しかしそれは一方で欠点ともなり,たとえばファイル選択ダイアログや,色選択ダイアログ,スライダ,プログレスバー,…など,最近のGUIツールキットが標準的に備える機能が存在しない.また基本的にCを基準としたGLUTのAPIの制限から,ソースコードではグローバル変数が多用され,あまり美しいとはいえない.
もしGLUT / GLUIの枠を超えた,より充実したGUI環境が必要で,WindowsやX11に縛られない移植性が必要ならば,Qt[8]やFOX[9],wxWidgets[10](5)などが候補となるのではないだろうか.
| [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/ |