グラフィックス(SDL + OpenGL, OpenSceneGraph)

OpenSceneGraph/0_9_X/2.最も単純なプログラム(キューブを描画する)

最終更新: 2015-04-20 (月) 08:44:43 (1495d)

概要

このページでは、OpenSceneGraph による最も単純なプログラムの例として、 キューブを描画するプログラムを示す。

スクリーンショット

上図は、本サンプルプログラムのスクリーンショットである。

ソースコード

filemain.cppアプリケーションのエントリポイントおよびプログラム全体
fileSampleVC6.zipVC6 のプロジェクト(ソース含む)
fileSampleVC7.zipVC7 のプロジェクト(ソース含む)

解説

OpenSceneGraph によるプログラムの基本

OpenSceneGraph の基本中の基本として覚えるべきこととして osgProducer::SceneViewerosg::Node の二つのクラスが存在する。 osg::Node クラスは、描画対象となるキューブや球、車や飛行機、ステージを照らす光源、 また、それらの組み合わせによるシーンデータを表す。 それに対して osgProducer::SceneViewer クラスは、osg::Node が表すシーンデータを実際に描画する役割を持っている。 以下に、二つのクラスの関係を図に表す。

osgProducer::SceneView と osg::Node クラスの関連

以上を踏まえた上で、OpenSceneGraph による3Dグラフィックスプログラミングの基本的な手順を示すと、

  • 描画対象を描画するためのビュワーを構築する。
  • ビュワーで描画するためのシーンデータを構築する。
  • 最後にビュワーに描画対象を描画するように指示する。

以上のようになる。対応するコードとして filemain.cpp の一部を以下に示す。

int main(int argc, char** args) {
	// ビュワーを構築し、シーンデータを設定する
	osgProducer::Viewer viewer(createViewer(400, 400));
	viewer.setSceneData(createSceneData());

	// ...
}

createViewer および createSceneData 関数は、ビュワーおよびシーンデータを構築する関数である。 二つの関数によって構築されたビュワーとシーンデータは、 osgProducer::Viewer の setSceneData メソッドを呼び出しによって関連付けられる。

ビュワーの構築

ビュワーの構築で行うべきことは、主に

  • ウィンドウの構築
  • カメラの設定

の二つである。まずは、ウィンドウの構築に関して filemain.cpp の一部を以下に示す。

static osgProducer::Viewer createViewer(int width, int height) {
	// ウィンドウを設定する
	Producer::RenderSurface* window = new Producer::RenderSurface();
	window->setWindowName("OpenSceneGraph Sample");
	window->setWindowRectangle(0, 0, width, height);

	// ...
}

ウィンドウを構築するには、Producer::RenderSurface クラスを構築する。 ここでは、タイトルバーに表示される文字列とウィンドウのサイズを設定している。

次にカメラの設定に関して filemain.cpp の一部を以下に示す。

static osgProducer::Viewer createViewer(int width, int height) {
	// ...

	// カメラを設定する
	Producer::Camera* camera = new Producer::Camera();
	camera->setRenderSurface(window);

	// ...
}

カメラを設定するには、Producer::Camera クラスを構築する。 この後、シーンデータとしてキューブを原点に設置する予定なので、 以上のコードでは、setViewByLookat メソッドを使って、 カメラが ( 0.0f, 0.0f,-30.0f) から ( 0.0f, 0.0f, 0.0f) を見るように設定している。

最後に、これらの情報を元にビュワーを構築する。filemain.cpp の一部を以下に示す。

static osgProducer::Viewer createViewer(int width, int height) {
	// ...

	// ビュワーを構築する
	Producer::CameraConfig* cameraConfig = new Producer::CameraConfig();
	cameraConfig->addCamera("Main Camera", camera);
	osgProducer::Viewer viewer(cameraConfig);
	viewer.setUpViewer();

	return viewer;
}

※ このコード中に存在する setUpViewer メソッドというのが実はかなりの曲者。 このメソッドの呼び出し一つでライトが勝手に点灯し、マウスで視点を変更できる機能が付加される。

描画対象の構築

描画対象には色々なものが存在する。

  • キューブや球などの単純なもの
  • 車や飛行機などの複雑なもの、
  • ステージを照らす光源など直接的に描画される物体とは少々異なる性質を持つもの
  • 以上の組み合わせによって表現されるシーンデータ

などなど。これを反映して osg::Node クラスにはいくつかの種類が存在する。 今回使用する osg::Geode クラスは、osg::Node クラスの一種である。

osg::Geode クラスに、osg::Cube を関連付けることでキューブを表示する描画対象ができあがる。 filemain.cpp の一部を示す。

static osg::Node* createSceneData() {
	// キューブを生成する
	osg::Shape* shape = new osg::Box(osg::Vec3(), 10.0f);
	osg::Drawable* drawable = new osg::ShapeDrawable(shape);
	osg::Geode* cube = new osg::Geode();
	cube->addDrawable(drawable);

	// ...
}

また、今回は osg::Material も関連付けることによってキューブの材質の設定も行った。 filemain.cpp の一部を示す。

static osg::Node* createSceneData() {
	// ...

	// 材質を生成する
	osg::Material* material = new osg::Material();
	material->setAmbient  (osg::Material::Face::FRONT, osg::Vec4( 0.1f, 0.1f, 0.1f, 1.0f));
	material->setDiffuse  (osg::Material::Face::FRONT, osg::Vec4( 0.0f, 1.0f, 0.0f, 1.0f));
	material->setSpecular (osg::Material::Face::FRONT, osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f));
	material->setShininess(osg::Material::Face::FRONT, 0.0f);

	// キューブに材質を設定する
	osg::StateSet* stateSet = cube->getOrCreateStateSet();
	stateSet->setAttribute(material);

	// ...
}

setAmbientsetDiffusesetSpecular メソッドは、 それぞれ材質の環境光、拡散光、鏡面光の反射係数を指定している。 また、setShininess メソッドは、材質の放射輝度係数を指定している。

以上。

コメント

コメントはありません。 コメント/OpenSceneGraph/0_9_X/2.最も単純なプログラム(キューブを描画する)

お名前: