Irrlichtの基本事項

名前空間

Irrlichtのクラスや関数は、全てirrで始まる名前空間の下にある。例えば、ISceneManagerであれば、フルネームはirr::scene::ISceneManagerとなる。本記事では、irr::は基本的に省略するので注意すること。
(using namespace irr; を宣言した状態に相当)

データ型

Iで始まる物はインタフェースクラスであり、createXXXX系関数などにより生成するかgetXXXX系関数などで取得する。
Sで始まる物は構造体である。多くの構造体には自動的に初期値が設定されるが、たまにそうでない物もあるため注意が必要。例えば、video::SColor構造体は初期値設定されないため、何もしないと内容が不定となる。
(VC++の場合、Debug時は0xCCなどで初期化されるが、Release時は本当に不定になる)
この構造体を内包するS3DVertexなどについても、下記のようにColorメンバの初期化をしないと内容不定になるので注意。

video::S3DVertex vert[16];
for(int i = 0; i < sizeof(vert) / sizeof(vert[0]); i ++)
    vert[i].Color.set(0xffffffff);

モデル形式・ワークフロー

Irrlichtは多数の形式のメッシュを読めるが、これはスケルタルアニメーションを使わない場合に限られる。今どき同人ゲームでもスケルタルアニメーションを使うことは多いと考えられるため、現時点ではX形式が唯一の現実解かと思われる。  2017年時点ではFBX形式が業界標準となっているため、出来ればFBXを使いたいところ。コンバータないしビルトインFBXローダの実装が待たれる。  外部ライブラリを使ってFBXを読む実装は既にあるが、ライブラリの巨大化や性能面の問題を考えて今回はパスしました。

総頂点数の制約事項

同一のメッシュ内において、一つのマテリアルの総頂点数は65535以内にする必要がある。これをオーバーすると描画が破綻する。(エラーは等は出ない)
もしそれ以上必要な場合は、別名のマテリアルを作って65535頂点以下に分割する必要がある。この制約は、CMeshBufferクラスの頂点インデックスが16bit長であるという仕様に起因している。CMeshBuffer.hを参照。

読み込めるメッシュの形式

irr::scene::ISceneManager::getMeshの説明にirrlightが読めるフォーマット一覧と、その詳細仕様が記載されている。
ボーンアニメーションが読めるのはISkinnedMeshインタフェースの取り出せる物のみなので、b3d, x, ms3dのみ。現実的にはxファイルが適切。

初期化

サンプルはcreateDeviceで初期化する物が多いが、createDeviceExを使用したほうがよい。FSAAなど、createDeviceExにしか無い機能がある。
SIrrlichtCreationParametersはコンストラクタでデフォルト値が設定されるため、意味の分からない項目はそのままにしておくこと。

IrrlichtDevice* IRRCALLCONV createDeviceEx(
		const SIrrlichtCreationParameters& parameters);

下記の例は、Direct3D、1280x720フルスクリーン、32bpp強制、ボリュームシャドウ使用、Vsync有効、FSAA有効で初期化する。

SIrrlichtCreationParameters creationParams;
creationParams.DriverType = video::EDT_DIRECT3D9;
creationParams.WindowSize = core::dimension2d(1280, 720);
creationParams.Bits = 32;
creationParams.Fullscreen = true;
creationParams.Stencilbuffer = true;
creationParams.Vsync = true;
creationParams.AntiAlias = 2;

pIrrDevice = createDeviceEx(creationParams);

オブジェクトの消し方

ISceneNodeとその派生クラスについては、ISceneNode::removeで消す。ノードをremoveすると、子ノード含めて再帰的に消える。dropしてはならない。

例えば、下記のように作成したノードであるならば…

scene::IAnimatedMesh* meshTest = pSceneManager->getMesh("bldg1.x");
scene::IAnimatedMeshSceneNode* nodeTest =
    pSceneManager->addAnimatedMeshSceneNode(meshTest);
nodeTest->setPosition(core::vector3df(30, 0, 10)); // 位置を(30, 0, 10)に設定

下記のように消去する。

nodeTest->remove();

まめに消したりしなくても、Scene managerからclear()で一括消去もできる。シーン全体をクリーンナップする場合は、clear()で消すのが良い。
一時的に特定ノードを非表示にしたいなら、setVisibleを使う。

AnimatorやTriangleSelectorなどはdropして参照カウントが0になると消える。
当然ではあるが、自分でnewした物以外、delete演算子で消してはならない。

メッシュの管理

メッシュをロードするにはISceneManagerのgetMesh(filename)を呼び出す。ここで得られたメッシュの参照カウントは1になっている。この1とはキャッシュ機構が参照している分である。メッシュはキャッシュされているので、同じメッシュを何度getMeshしようとも、メモリ消費が増えず、参照カウントも増えない。
現在使われていないメッシュをアンロードしたい場合、IMeshCache::removeMeshでアンロードすること。dropしてはいけない。メッシュはキャッシュされており、dropしてもキャッシュ機構側は依然ロード済と認識しているので、drop後にそのメッシュをgetMeshで取得して使おうとするとクラッシュする。

現在使われていないメッシュを全部アンロードしたい場合は、IMeshCache::clearUnusedMeshes()を呼ぶ。

pSceneManager->getMeshCache()->clearUnusedMeshes();

ISceneManager::clearでシーンを消去した直後などに呼ぶとよい。いちいち手動で起動するガーベジコレクタのような物と考えると分かりやすい。

※ ここで言う「現在使われていない」とは、シーン内のどのノードからも参照されていない(≒表示されていない)ということ。getMeshでロードのみした物は「現在使われていない」扱いである。

ウィンドウハンドルの取得

Windowsにおいては、主に他のライブラリ等との連携を目的として、ウィンドウハンドルを要求される場面が多い。例えば、DirectSoundの初期化にはウィンドウハンドルが必須である。Irrlichtにおいては、下記の方法でウィンドウハンドルを取得可能である。

Direct3Dなら

HWND hwndApp = (HWND)(pIrrDevice->getVideoDriver()->getExposedVideoData().D3D9.HWnd);

OpenGLなら

HWND hwndApp = (HWND)(pIrrDevice->getVideoDriver()->getExposedVideoData().OpenGLWin32.HWnd);

ただし、現行実装においてはD3D9とOpenGLWin32は共用体になっており、いずれでも同じ値が返る。


Copyright by MUTATE Systems 2018
管理者宛メール