目次
目的
OpenGLをやってみたいけどOpenGL, GLFW, GLUT, GLEWなどいろいろ種類があってわけがわからずどっから手を付ければいいかわからない人のための記事です。
この記事は以下の文書の序盤の大いに参考にしました。WindowsやmacOSでの例なども詳細にそしてわかりやすく書いてありますし、ちゃんと勉強したい人は最初からこちらを読むといいと思います。
ただ、Ubuntuで実装する際にapt
経由でインストールしたときはgccのオプション指定が少し異なるので、そこらへんを参考にしていただければと思います。
OpenGLとは
OpenGL
まずOpenGLとはコンピュータグラフィックスなどに必要なグラフィックス表示機能を抽象化し、整理したグラフィックスライブラリです。ただ、ここで注意が必要なのはOpenGLはあくまでグラフィックスの演算部分を担当するだけであり、実際に画面に表示するのはOSにもっと近い部分が担当します。OpenGLはそれに描画する内容を渡す役割を持ちます。
GLUT
OpenGLはプラットフォーム非依存ではありますが、多少プラットフォームごとに異なる実装が必要となるためその部分を吸収したツールキットがいくつか存在します。
そのなかにGLUT (OpenGL Utility Toolkit) があり、マルチプラットフォーム対応であるため、UNIX/Linux、Windows、macOS 間で共通なコードを書くことができます。
しかしながら、オリジナルのサイトでじゃメンテナンスがあまりされていないようです。
GLUT - The OpenGL Utility Toolkit
freeGLUT
GLUTの代わりに、GLUTと互換性を持ったfreeGLUTが開発されています。
GLFW
GLUT以外のオープンソースマルチプラットフォーム対応ライブラリとしてGLFWがあります。他のツールキットに比べて小さめのキットで学習用にはちょうどいいようです。
GLEW
OpenGLの拡張機能を手軽に使うことができるようにするためのマルチプラットフォーム対応ライブラリがGLEW (The OpenGL Extension Wrangler Library)です。
GLFWの特徴として以下のようなことが挙げられていました。1
- コンパクト
- マルチプラットフォーム
- OpenGLのバージョンやプロファイルが指定可能
- 最初からでダブルバッファリング
- イベントループを自分で書く
- ポーリング方式とコールバック方式のどちらにも対応
- マルチウィンドウやマルチモニタに対応
- ユーザ定義のポインタを保存できる
- 入力デバイスの取り扱い方法が異なる
- GLUTにあってGLFWにない機能
- CubeやSphere、Teapotのような図形を表示する機能は省かれている
- ビットマップフォントをレンダリングする機能がない
- ポップアップメニュー表示機能がない
環境
Version | |
---|---|
OS | Ubuntu16.04 |
OpenGL | |
GLFW | |
GLEW |
※Ubuntu以外でやりたい方は元の文書からどうぞ 1
環境構築
$ sudo apt-get install -y libx11-dev xorg-dev \
libglu1-mesa libglu1-mesa-dev \
libgl1-mesa-glx libgl1-mesa-dev
$ sudo apt install -y libglfw3 libglfw3-dev
$ sudo apt install -y libglew-dev
背景色のみ表示するコードを書いてみる
コード
同一ディレクトリ内に以下のMakefile
とmain.cpp
ファイルを作成します。
CXXFLAGS = -g -Wall -std=c++11
LDLIBS = -lGL \
-lglfw
OBJECTS = $(patsubst %.cpp,%.o,$(wildcard *.cpp))
TARGET = sample
${TARGET} : ${OBJECTS}
${LINK.cc} $^ ${LOADLIBES} ${LDLIBS} -o $@
.PHONY : clean
clean :
-${RM} ${TARGET} ${OBJECTS} *~ .*~ core
#include <cstdlib>
#include <iostream>
#include <GLFW/glfw3.h>
int main()
{
////////////////////////////////////////////////////////////////////////////////
// GLFW の初期化 (GLFW)
if (glfwInit() == GL_FALSE){
// 初期化に失敗した処理
std::cerr << "Can't initialize GLFW" << std::endl;
return 1;
}
////////////////////////////////////////////////////////////////////////////////
// 終了時の処理登録 (GLFW)
atexit(glfwTerminate);
////////////////////////////////////////////////////////////////////////////////
// ウィンドウを作成 (GLFW)
GLFWwindow * const window(glfwCreateWindow(/* int width = */ 640,
/* int height = */ 480,
/* const char * title = */ "Hello!",
/* GLFWmonitor * monitor = */ NULL,
/* GLFWwindow * share = */ NULL));
if (window == NULL){
// ウィンドウ作成に失敗した処理
std::cerr << "Can't create GLFW window." << std::endl;
return 1;
}
// 作成したウィンドウを処理対象とする (GLFW)
glfwMakeContextCurrent(/* GLFWwindow * window = */ window);
// 背景色 (OpenGL)
glClearColor(/* GLfloat red = */ 0.2f,
/* GLfloat green = */ 0.2f,
/* GLfloat blue = */ 0.2f,
/* GLfloat alpha = */ 0.0f);
////////////////////////////////////////////////////////////////////////////////
// ループ処理
// ウィンドウが開いている間繰り返す
while (glfwWindowShouldClose(/* GLFWwindow * window = */ window) == GL_FALSE){
// ウィンドウを消去 (GLFW)
glClear(/* GLbitfield mask = */ GL_COLOR_BUFFER_BIT);
// 描画処理
// カラーバッファ入れ替え <= ダブルバッファリング (GLFW)
glfwSwapBuffers(window);
// イベント待ち (GLFW)
glfwWaitEvents();
}
return 0;
}
解説
- GLFW の初期化
- glfwInit()
- ウィンドウ作成
- GLFW: Window reference
-
glfwCreateWindow()
- ウィンドウを作成したとしてもそのウィンドウが描画の対象にしていされていないので次の
glfwMakecontextCurrent()
で処理対象にします。
- ウィンドウを作成したとしてもそのウィンドウが描画の対象にしていされていないので次の
-
glfwMakeContextCurrent()
- ウィンドウを処理対象に指定
-
glClearColor()
- 最初のカラーバッファ設定
- ループ処理
-
glfwWindowShouldClose()
- ウィンドウを閉じるかどうかの判断
-
glClear()
- maskに指定したバッファを塗りつぶす
-
glfwWailEvents()
- マウスの操作などのイベント待ち
- イベント発生後に処理再開
-
glfwWindowShouldClose()
- ダブルバッファリングのバッファ入れ替え
-
glfwSwapBuffers()
- ダブルバッファリングにおけるカラーバッファの入れ替え
-
glfwSwapBuffers()
- ウィンドウを閉じ、終了処理
-
glfwTerminate()
- GLFWの終了処理
- 初期化成功したときにプログラム終了前にこの関数の実行が必要
-
glfwTerminate()
実行
$ ./sample
図形を描画してみる
結構、長くなりそうなので近いうちに別記事で ( _ _ )
参照
- OpenGL Wiki
- OpenGL SDK
- How to Install OpenGL on Ubuntu Linux
- GLEW: The OpenGL Extension Wrangler Library
- GLEWについて - PukiWiki for PBCG Lab
- linux - How to print the ld(linker) search path - Stack Overflow