GLFW3 による OpenGL 入門 (1)

第1章 はじめに

1.1    本書の目的

本書は OpenGL (http://www.opengl.org) と呼ばれるグラフィックス表示のためのアプリケーションプログラムインタフェース (Application Program Interface, API) を使用して、グラフィックスアプリケーションを作成する方法について解説します。

ただし、OpenGL 自体はグラフィックスハードウェアを制御する機能しか持っていないので、実際にグラフィックスアプリケーションを作成するには、コンピュータグラフィックス (CG) の理論の知識も必要になります。そのため現実のアプリケーション開発では、CG の各種の理論や手法を実装したミドルウェアがよく用いられます。

しかし本書では、直接 OpenGL の API を使ってアプリケーションプログラムを作成する方法について解説します。そのために本書では、CG の基礎的な理論の解説も行います。これは、仮にミドルウェアを用いてグラフィックスアプリケーションを開発するとしても、CG の理論の理解が不可欠だからです。

本書が想定する読者は、学校の授業などで C あるいは C++ を勉強したものの、自分では実際にプログラムを組んだ経験があまりないという、そう、そこの君!○○君 (実在の人物) のことだよ。したがって、本書ではプログラミング言語として C++ を用いますが、iostream や vector など C++ の基本的なライブラリを使用する以外は、ほとんど “better C” としてしか C++ の機能を使用しません。

1.2    OpenGL

三次元コンピュータグラフィックス (3D Computer Graphics, 3D CG) を使った画面表示は、現在ではパソコンやゲーム機のみならず、携帯電話やスマートフォン、カーナビなど、幅広い領域で利用されています。しかし 3D CG の処理は、現在のパソコンの CPU の高い計算能力をもってしても、負荷の高いものになります。特にリアルタイム 3D CG によって快適な応答性能を得るには、やはり専用ハードウェアによる支援が不可欠になります。

この専用ハードウェア、いわゆるグラフィックスハードウェアは、パソコンの CPU に匹敵するか、あるいは、それ以上の複雑さを持っています。したがって、これを有効に活用するには、グラフィックス表示に要求される機能を整理し、グラフィックスハードウェアの機能を抽象化する、高機能なグラフィックスライブラリが必要になります。

グラフィックスライブラリは、通常コンピュータのハードウェア全体を制御するオペレーティングシステム (OS) の機能の一部として提供されます。アプリケーションプログラムはこれを介してグラフィックスハードウェアを制御するので、このようなグラフィックスライブラリはアプリケーションプログラムインタフェース (API) と呼ばれます。パソコンの OS として最も普及している Microsoft 社の Windows には、一般的な二次元のグラフィックス表示を行う Graphics Device Interface (GDI) や、二次元グラフィックスおよびリアルタイム3D CG の表示機能などを包含した DirectX (3D CG 部分は Direct3D) という API が用意されています。

ところが Windows には、これらとは別に、OpenGL と呼ばれるグラフィックス表示用の API が用意されています。OpenGL は Microsoft 社が DirectX を用意する以前から Windows に組み込まれていた、リアルタイム 3D CG に対応したグラフィックス API です。

この OpenGL は、最初シリコングラフィックス社 (Silicon Graphics, Inc.、後に Silicon Graphics International Corp., SGI) により開発されました。同社はもともと IRIX と呼ばれる UNIX 系 OS を搭載した、エンジニアリングワークステーション (Engineering Work Station, EWS) と呼ばれるコンピュータのメーカーでした。OpenGL は同社の EWS のグラフィックス表示に用いられていたグラフィックスライブラリ (GL、OpenGL と区別するために IRIS GL と呼ばれることがあります) を、プラットホーム (ハードウェアや OS などのコンピュータの基盤) に依存する部分を分離して再実装したものです。OpenGL はその後オープンソースソフトウェアとして公開され、現在は Khronos Group (http://www.khronos.org) という団体によって規格が策定されています。

EWS は主にコンピュータ支援設計 (Computer Aided Design, CAD) などの技術的用途に用いられるコンピュータです。しかし、パソコンの性能の向上により、この目的にもパソコンが使用されるようになりました。その結果、EWS で動作していたアプリケーションをパソコンに移行する必要性が生じ、そのために Windows 上にも OpenGL が移植されました。

当時はこれら以外のグラフィックスライブラリもいくつか存在しましたが、パソコン用 OS の Windows による寡占化が進んだ結果、グラフィックスライブラリも DirectX と OpenGL の二つ以外は実質的に淘汰されてしまいました。このうち DirectX は Microsoft 社の専有物のため、OS として Windows を採用しているパソコン以外で共通に使用できるグラフィックスライブラリは、現在では事実上 OpenGL しかありません。しかし、これは言い換えれば、Windows パソコンを含むコンピュータ関連機器のほとんどが、3D CG 表示用の API として OpenGL (または、組み込み機器向けの OpenGL ES) を採用しているとも言えます。

OpenGL がこのように広く使われるようになった背景には、もちろん OpenGL しか選択肢がなかったということもありますが、その仕様がプラットホームから独立していることも大きな要因でしょう。これにより、OpenGL はさまざまな機器に導入されました。Apple 社のパソコンの OS である Mac OS X や、UNIX やオープンソースで開発されている Linux の画面表示に用いられているX Window System も、OpenGL を使用してグラフィックス表示を行うことが可能です。また、パソコンに限らず、スマートフォンの OS である Apple 社の iOS や Google 社の Android も、OpenGL ES を採用しています。

1.3    GLFW

1.3.1     ツールキット

OpenGL はプラットホームに依存しないグラフィックス API ですが、アプリケーションプログラムからこの機能を使用するためには、やはりプラットホームごとに異なる手順で「お膳立て」をする必要があります。しかし、その部分の実装はそれなりに面倒なものになるため、それをうまく包み隠して簡単に使えるようにしたツールキットがいくつも提案されています。

中でも GLUT (OpenGL Utility Toolkit) は、OpenGL を開発した Silicon Graphics のエンジニア (当時) が作った、使いやすいツールキットです。また GLUT はマルチプラットホームに対応しているため、これを使ったソースプログラムは Unix / Linux、Windows、Mac OS X の間で共通にすることができます。GLUT は OpenGL の初期の頃に作られたものですが、OpenGL の学習や OpenGL を使った簡単なプログラムの作成を手軽に始めることができるため、今でも有用なツールキットとして利用されています。

しかし、オリジナルの GLUT は既に長い間メンテナンスされていません。代わりに GLUT 互換の freeglut (http://freeglut.sourceforge.net) や OpenGLUT (http://openglut.sourceforge.net) というツールキットが開発されていますが、これらは本書の執筆時点では Mac OS X には対応していません。また、Mac OS X には以前から標準で GLUT が搭載されていましたが、これは OpenGL 2.1 にしか対応しておらず、Mac OS X のバージョン 10.7 (Lion) 以降で使用可能になった OpenGL 3.2 Core Profile や、10.9 (Mavericks) 以降で使用可能になった OpenGL 4.1 を (公式には) 使用することができません[1]。加えて 10.9 では、ついに GLUT の使用自体が非推奨となりました。

1.3.2     GLFW の概要

GLUT が使えないとなると、代わりのものを探す必要があります。OpenGL に対応していて、GLUT のようにマルチプラットホームで使用できるツールキットには、FLTKQtSDL などさまざまなものがあります。中でも Qt は非常に高機能なツールキットであり、CG 関連のいくつかの主要なアプリケーションがこれを使って開発されています。

しかし、OpenGL の学習のためにあれこれ試したり、ちょっとしたプログラムを書いたりするには、Qt などはちょっと大きすぎる気がします。そこで、GLUT の代わりになる簡単で小さなツールキットとして、GLFW (http://www.glfw.org/) があります。

上記の GLFWのホームページでは、GLFW はウィンドウを作成し、OpenGL のコンテキストを作って、入力 (デバイス) を管理する、無料の、オープンソースの、マルチプラットホームのライブラリであると説明されています。ライセンスには zlib/libpng license を採用しています。

1.3.3     GLFW の特徴

GLFW は次のような特徴を持っています。

l 非常にコンパクトである

OpenGL と組み合わせて使うツールキットの中では非常にコンパクトであり、OpenGL のウィンドウを管理するための最小限の機能を提供しています。

l マルチプラットホームである

GLUT と同様に Windows / Mac OS X / Linux でソースプログラムを共通化できます。

l OpenGL のバージョンやプロファイルが指定できる

Mac OS X バージョン 10.7 (Lion) 以降では OpenGL のバージョン 3.2 の Core Profile、10.9 (Mavericks) 以降では OpenGL のバージョン 4.1 を指定することができます。

l 最初からダブルバッファリングになっている

ダブルバッファリングはアニメーション表示を行うための必須の機能ですが、GLFW ではこれが標準で有効になっています。GLUT にあるシングルバッファのモードは用意されていません。

l イベントループを自分で書く

OpenGL などによるグラフィックス表示では、OS からの描画要求 (イベント) にもとづいて、くり返し描画処理を行う必要があります。このくり返しをイベントループと呼びます。このループにおいて、描画処理を行った後に次のイベントが発生するまで待つようにすれば、マウスやキーボードの操作によって画面表示を更新する対話的なアプリケーションを作成することができます。一方、イベントを待たずに描画処理を行うことにより、画面表示が時間とともに更新されるアニメーション表示を行うこともできます。

l ポーリング方式とコールバック方式のどちらにも対応している

GLFW のプログラミングは、どのようなイベントが発生したのか (マウスをドラッグしたのか、キーボードをタイプしたのか、など) をイベントループの中で調べて (ポーリング) 対応する処理を記述する方式が基本です。しかし、必要に応じてイベントごとに実行する関数 (コールバック関数) を登録する方式で記述することもできます。

l マルチウィンドウやマルチモニタに対応している

OpenGL のレンダリングコンテキストを管理する機能を持っており、マルチウィンドウやマルチモニタに対応したアプリケーションプログラムを作成することができます。

l 入力デバイスの取り扱い方法が異なる

キーボードからの入力は GLUT のように文字として得ることができるほか、Shift キーなどの文字のキー以外のものを含む特定のキーの状態を調べることもできます。また、マウスホイールやジョイスティックのデータを取得することもできます。

l GLFW にない機能

一方 GLUT にあって GLFW にない機能もいくつかあります。例えば Cube や Sphere、Teapot のような図形を表示する機能は省かれています。またビットマップフォントをレンダリングする機能もありません。ポップアップメニューを表示する機能も用意されていません。

最初からダブルバッファリングになっていることや、キーボードやマウス、ジョイスティックの扱い方を見ると、GLFW は GLUT に比べてかなりゲーム向きに作られているように思われます。また GLUT にあって GLFW に無い機能の多くは、現在の OpenGLでは非推奨となった機能を使っています。



[1] gl3w というツールを使えば GLUT で OpenGL バージョン 3.2 以降の機能を使用できます。