OpenGLをC++11でラップしてみんとてするなり 第2回
OpenGLの機能を全てラップしたライブラリをブログ上で開発する気など毛頭ありませんので、OpenGLとC++11の紹介となるようなサンプルを幾つか作っていこうと思います。
今のところ、以下の4つの機能を実装していこうかと思いますが、他にも面白そうなネタが見つかれば、後々紹介しようかと思っています。
●glEnable()/glDisable()/glIsEnabled()
まずは単純に、GPUの特定機能をON/OFFするだけのこれらの関数をラップします。
何が単純かというと、これらを使う際には、操作対象を変更する関数を呼ぶ必要がないためで、設計は次のようになるでしょう。
●行列スタック操作
こちらはglEnable()等よりは少々複雑になり、「どの行列スタックを操作するか」という指定も入ってきます。
操作対象の行列スタックを間違えてしまうと表示が崩れますので、これは何としても避けたいところです。
●テクスチャ操作
テクスチャを扱う際は、操作対象を指定するだけでなく、操作対象を作成/破棄する必要もでてきます。
作成/破棄はコンストラクタ/デストラクタで容易に実装できるとして、問題はコピー処理です。
通常は、コピーをした際にはコピー元と同じ状態の新規テクスチャを作成したいところです。が、関数の戻り値としてテクスチャ・オブジェクトを返す時などには、テクスチャIDだけコピーだけできれば十分ですし、そうしなければパフォーマンスが悪くなります。
ここはC++11から導入されたムーブ・セマンティクスを活用して、パフォーマンスを確保しましょう。
●コンテキスト
OpenGLの一連の操作は、「コンテキスト」という単位で独立しています。コンテキストの切り替えはOS側が適切に行ってくれるため、ソースコード中で明示的にコンテキストを変更することはできません。
このため、OpenGLを使う上でコンテキストを意識する必要は通常はないのですが、OOP的な考え方をするならば「現在のコンテキストオブジェクトのメソッドとして、GL関数がある」となるでしょうか?
プログラム中で現在のコンテキスト以外の操作をすることはありませんが、複数のコンテキストが描画のために同じユーザー定義関数を呼ぶことは考えられます。関数側からコンテキストを区別できるよう、コンテキストを表すクラスも作ってしまうべきでしょう。
- コンストラクタ/デストラクタ:環境依存(glutを使うならウィンドウと1:1対応させる、wglを使うならwglCreateContext()/wglDeleteContext()を呼ぶ)
- コピー/代入:不可
- メソッド:理想的には、OpenGLの全ての関数をメソッド化したい
以上の4つの機能を実装していく予定です。
それでは次回をお楽しみに。