Cygwin で OpenGL の開発環境を構築する場合、unix 系と Windows 系、複数のやり方があるようなのだけど、情報が少ないように感じた、それで、自分で判った事をここにメモ程度に書いておこうと思う。
まず、Cygwin では、コンパイラが複数ある、通常のソースコードと、Windows の API(WIN32-API) をコンパイルできるもの(Mingwin 系)
そして、gcc3 系と、現在最新の gcc4 系
gcc3 系では、「-m」のオプションスイッチで、Windows 環境をコンパイルする事ができるが、gcc4 系では、この機能は無くなり、クロスコンパイラで、対応をするようになった。
基本的な事だが、windows 系の開発では、unix 系で普通に使えるライブラリーの多くは利用できない、windows で利用可能なようにポートされたライブラリーを別途入れる必要があり、ヘッダーのインクルードなども適切に記述する必要がある。
※たとえば、Windows で POSIX のスレッド(pthread)を使いたいなら、POSIX Threads for Win32 をインストールする必要がある。(cygwin では、gcc の windows 系クロスコンパイラに含まれている)
OpenGL のプログラム開発では、unix 系、Windows 系、どちらでも、開発を行う事が出来るけど、unix 系では、コンソールアプリケーション以外では、X-Window のアプリとして動作させなければならず、X サーバーを通して動作させる事になる。
Windows 系では、ネイティブなバイナリーを作成でき、実行コードを配布する場合も便利なので、自分は、Windows 系の開発環境でおこなっている。
※Linux や OS-X などでも少しの改修でリコンパイルでき、動作するように、している。
基本的には glut を使うので、動かすだけなら簡単と思う。
cygwin で利用できるコンパイラ
・gcc3 gcc version 3.xx コンパイラ、これだけインストールすると、単に gcc
・gcc4 gcc version 4.xx コンパイラ、gcc version 3.xx と両方インストールすると、gcc3 と gcc4
・i686-w64-mingw32 windows のソースコードをコンパイルできるクロスコンパイラ32/64 ビット
※32ビット、64ビットのバイナリー作成では、関連ライブラリーをスイッチするようだ。
メディアプレイヤーをコンパイルする場合に必要なライブラリー郡
(1)cygwin のインストーラーでインストール出来るもの
libz 圧縮、解凍ライブラリー(自分でソースコードをコンパイルして組み込む場合は不要)
pthread-win32 POSIX のスレッドライブラリー(PTHREAD-WIN32)
glut OpenGL glut ライブラリー
(2)自分でライブラリーの構築などを行うもの(基本的に全て、オープンソース)
boost boost ライブラリー(最新のバージョンを利用したい為、別途アーカイブを展開している。)
AL OpenAL ライブラリー
DX DirectX を gcc で使う為のヘッダー、ライブラリー(DirectSound、DirectInput を利用)
freetype2 TrueType を描画(レンダリング)する為のライブラリー
libjpeg_x86 JPEG をデコード・エンコードする為のライブラリー(x86バイナリー専用の高速版)
libpng PNG をデコード・円コードする為のライブラリー
mupdf PDF をレンダリングする為のライブラリー
openjpeg JPEG2000 ライブラリー
jbig2 JBIG2 ライブラリー
id3tag MP3-TAG ライブラリー
↑これらは、cygwin gcc でコンパイルして、ライブラリーを構築したので、別途アーカイブしてある。
今回は、OpenGL プログラムを走らせるだけなので、↑のライブラリー構築などは割愛する。
(1) 基本的なインストール
・まず、cygwin をインストールしなければならない、インストール方法は、非常に沢山他のサイトなどで詳しく説明されているので割愛する。
・重要なのは「必要なコンポーネント」と思う。(下のリストは、足りない物があったり、余分な物があるかもしれない)
・「Devel-gcc-mingw」関係を全部インストール
・「Devel-gcc4」関係をとりあえず全部インストール(※gcc4-core と gcc4-g++ があればOK)
・「Devel-gccmakedep」をインストール(Makefile で従属規則を自動生成するのに使う)
・「Devel-mingw64-i686」関係を全てインストール
・「Devel-make」(GNU Version)をインストール
(2)インストールを確認
・今回は、コンパイラとして「i686-w64-mingw32-gcc」を使うので、コンソールから、
i686-w64-mingw32-gcc --version
以下のようなメッセージが出れば、とりあえずコンパイラのインストールは成功。
i686-w64-mingw32-gcc (GCC) 4.5.3
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
(3)gcc3 系 mingw の OpenGL 関係をコピー(この手順が適正か判らないが・・・)
・i686-w64-mingw32 環境にも OpenGL 関係のヘッダーやライブラリーはあるのだが、イマイチ使いにくいので、gcc3 系の OpenGL ライブラリーを手動でコピーして使う、ライブラリーは互換性があるようなので、4系でも使えるようだが、gdb などでデバッグするような場合は問題が起こるかもしれない。
・元のファイルをリネームして一応保存しておき、mingw 関係のヘッダーなどをコピー
cd /usr/i686-w64-mingw32/sys-root/mingw/include/GL
mv gl.h gl_h
mv glu.h glu_h
cp /usr/include/w32api/GL/*.h .
cd /usr/i686-w64-mingw32/sys-root/mingw/lib
mv libopengl32.a libopengl32_a
mv libglu32.a libglu32_a
cp /usr/lib/w32api/libopengl32.a .
cp /usr/lib/w32api/libglu32.a .
cp /usr/lib/w32api/libglut32.a .
(4)OpenGL が動作するか確認
・まず、ソースコード「main.cpp」を入力
#include <cstdio>
#include <GL/glut.h>
static GLint faces[6][4] = { /* Vertex indices for the 6 faces of a cube. */
{0, 1, 2, 3}, {3, 2, 6, 7}, {7, 6, 5, 4},
{4, 5, 1, 0}, {5, 6, 2, 1}, {7, 4, 0, 3} };
static GLfloat v[8][3]; /* Will be filled in with X,Y,Z vertexes. */
static GLfloat g_angleX = 60.0f;
static GLfloat g_angleZ = -20.0f;
static void reshape_task(int width, int height)
{
}
static void idle_task()
{
glutPostRedisplay();
}
static void display_task()
{
int w = ::glutGet(GLUT_WINDOW_WIDTH);
int h = ::glutGet(GLUT_WINDOW_HEIGHT);
glViewport(0, 0, w, h);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Setup the view of the cube.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0, // field of view in degree
1.0, // aspect ratio
1.0, // Z near
10.0); // Z far
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 0.0, 5.0, // eye is at (0,0,5)
0.0, 0.0, 0.0, // center is at (0,0,0)
0.0, 1.0, 0.); // up is in positive Y direction
// Adjust cube position to be asthetic angle.
glTranslatef(0.0, 0.0, -1.0);
glRotatef(g_angleX, 1.0, 0.0, 0.0);
glRotatef(g_angleZ, 0.0, 0.0, 1.0);
g_angleX += 1.0f;
g_angleZ += 0.5f;
for(int i = 0; i < 6; ++i) {
struct rgb {
GLfloat r, g, b;
};
static const rgb col[6] = {
{ 1.0f, 1.0f, 1.0f },
{ 0.2f, 1.0f, 1.0f },
{ 1.0f, 0.2f, 1.0f },
{ 1.0f, 1.0f, 0.2f },
{ 0.2f, 0.2f, 1.0f },
{ 1.0f, 0.2f, 0.2f }
};
glColor3f(col[i].r, col[i].g, col[i].b);
glBegin(GL_QUADS);
glVertex3fv(&v[faces[i][0]][0]);
glVertex3fv(&v[faces[i][1]][0]);
glVertex3fv(&v[faces[i][2]][0]);
glVertex3fv(&v[faces[i][3]][0]);
glEnd();
}
glutSwapBuffers();
}
void init()
{
// Setup cube vertex data.
v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1;
v[4][0] = v[5][0] = v[6][0] = v[7][0] = 1;
v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1;
v[2][1] = v[3][1] = v[6][1] = v[7][1] = 1;
v[0][2] = v[3][2] = v[4][2] = v[7][2] = 1;
v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1;
// Use depth buffering for hidden surface elimination.
glEnable(GL_DEPTH_TEST);
}
int main(int argc, char** argv);
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(512, 512);
glutCreateWindow("test cube");
glutDisplayFunc(display_task);
glutReshapeFunc(reshape_task);
glutIdleFunc(idle_task);
init();
glutMainLoop();
return 0;
}
・続いて「Makefile」を入力
#-----------------------------------------------#
# GNU-Makefile for "gcc" #
#-----------------------------------------------#
TARGET = OpenGL_Test
PSOURCES = main.cpp
CSOURCES =
OPTLIBS = opengl32 glu32 glut32
INC_SYS =
# /usr/i686-w64-mingw32/sys-root/mingw/include
# /usr/boost_1_43_0
INC_LIB =
PINC_APP =
CINC_APP =
LIBDIR =
INC_S = $(addprefix -I, $(INC_SYS))
INC_L = $(addprefix -I, $(INC_LIB))
INC_P = $(addprefix -I, $(CINC_APP))
INC_C = $(addprefix -I, $(PINC_APP))
CINCS = $(INC_S) $(INC_L) $(INC_C)
PINCS = $(INC_S) $(INC_L) $(INC_P)
LIBS = $(addprefix -L, $(LIBDIR))
LIBN = $(addprefix -l, $(STDLIBS))
LIBN += $(addprefix -l, $(OPTLIBS))
#
# Compiler, Linker Options, Resource_compiler
#
CP = i686-w64-mingw32-g++
CC = i686-w64-mingw32-gcc
LK = i686-w64-mingw32-g++
RC =
POPT = -O3
COPT = -O3
LOPT =
COF = -o
LOF = -o
PFLAGS = -DWIN32
CFLAGS = -DWIN32
LFLAGS =
# -Wuninitialized -Wunused -Werror -Wshadow
CWARN = -Wimplicit -Wreturn-type -Wswitch -Wformat
OBJECTS = $(PSOURCES:.cpp=.o) $(CSOURCES:.c=.o)
.SUFFIXES :
.SUFFIXES : .res .hpp .h .c .cpp .o
$(TARGET).exe: $(OBJECTS) Makefile
$(LK) $(LOF)$(TARGET).exe $(LFLAGS) $(LIBS) $(OBJECTS) $(LIBN)
.c.o:
$(CC) $(COPT) $(CFLAGS) $(CINCS) $(CWARN) -c $< $(COF)$@
.cpp.o:
$(CP) $(POPT) $(PFLAGS) $(PINCS) $(CWARN) -c $< $(COF)$@
.rc.c:
$(RC) $< $@
all:
make clean
make depend
make $(TARGET)
install:
cp ./$(TARGET).exe /usr/local/bin/.
run:
./$(TARGET).exe
clean:
rm -f $(OBJECTS)
rm -f $(TARGET)
dllname:
objdump -p $(TARGET).exe | grep "DLL Name"
tarball:
chmod -x *.[hc]pp Makefile
rm -f $(TARGET)_$(shell date +%Y%m%d%H)_src.tgz
tar cfvz $(TARGET)_$(shell date +%Y%m%d%H)_src.tgz \
*.[hc]pp Makefile
chmod 444 $(TARGET)_$(shell date +%Y%m%d%H)_src.tgz
zip:
$(LK) $(LOF)$(TARGET).exe $(LFLAGS) $(LIBS) -mwindows $(OBJECTS) $(LIBN)
rm -f $(TARGET)_$(shell date +%Y%m%d%H).zip
zip $(TARGET)_$(shell date +%Y%m%d%H).zip *.exe *.dll
depend:
makedepend -Y -- $(CFLAGS) $(INC_P) -- $(CSOURCES) $(PSOURCES)
# DO NOT DELETE
(5) コンパイルと実行
・まずコンパイル
make
・実行
make run
・画面に、512×512のWindowが作られ、四角い箱が回転すれば成功!