■ SpriteTest3D概略
スプライト機能のサンプルプログラム「SpriteTest」に3Dオブジェクトを表示するスプライト、E3DRenderSpriteを追加したサンプルです。
追加したコードは、主に SpriteTest3D.cpp, SpriteTest3D.h にあります。
■ E3DRenderSprite 概略
E3DRenderSprite クラスは、3D 描画を行うためのオブジェクト HEGL_RENDER_POLYGON をラップした E3DRenderPolygon クラスから派生して、スプライトとしてのインターフェースから利用できるようにしたクラスです。
基本的な使い方は E3DRenderPolygon クラスとまったく同じです。唯一、RenderAllPolygon 関数を明示的に呼び出す必要が無い点が異なります。
E3DRenderSprite クラスは、描画に必要な最小矩形を自動的に(PrepareRendering 関数内で)求めて、スプライトインターフェースを通じて更新を促します。
■ レンダリング初期設定
レンダリングを行うには先ず、レンダリングオブジェクトを初期化しておかなければなりません。
このためには Initialize 関数を呼び出します。SpriteTest3D では次のように初期化しています。E3DRenderSprite::Initialize初めの4つのパラメータは、HEGL_RENDER_POLYGON オブジェクトの Initialize 関数に渡すものと同じです。
( *g_wndMain, NULL, g_wndMain->GetZBuffer(),
&(g_wndMain->GetScreenPosition()), 0x10000, 0x8000, mrfSingle ) ;
後ろの3つのパラメータはデフォルトのままでも良いのですが、デュアルプロセッサの判定を行わずに、シングルプロセッサのみでレンダリングするように設定します。
ところで、描画先の画像バッファにメインウィンドウのスプライトを指定していますが、描画先のスプライトには先に、レンダリングに必要な設定を行っておかなければなりません。
ESpriteWindow::Initialize 関数内では、以下のような初期化を行っています。CreateImage( EIF_RGB_BITMAP, 800, 600, 32, EGL_IMAGE_HAS_DC ) ;CreateImage 関数は通常のスプライトのみの場合でも必要ですが、後半の CreateZBuffer 関数、SetScreenPosition 関数は 3D 機能を利用する場合には必要となります。
ReverseVertically( ) ;
CreateZBuffer( ) ;
SetScreenPosition( E3DVector( 400, 300, 1024 ) ) ;
■ レンダリング処理
E3DRenderSprite クラスでは、表示を更新する必要が生じた場合レンダリング処理を実行します。
E3DModelInterface::UpdateParam 関数は表示を更新する必要があるときに呼び出されます。//まず、FlushAllPolygon 関数ですが、この関数を呼び出すことによって、以前の処理で設定されているポリゴンリストを削除しています。
// フレーム初期化
//
FlushAllPolygon( ) ;
//
// カメラ設定
//
SetViewPoint( E3DVector(0,0,0), E3DVector(0,0,1), 0 ) ;
//
// ライト設定
//
E3D_LIGHT_ENTRY eleLight[2] ;
eleLight[0].dwLightType = E3D_VECTOR_LIGHT ;
eleLight[0].rgbColor.dwPixelCode = 0xFFFFFF ;
eleLight[0].rBrightness = 1.0 ;
eleLight[0].vecLight.x = 1 ;
eleLight[0].vecLight.y = 1 ;
eleLight[0].vecLight.z = 1 ;
eleLight[0].vecLight.RoundTo1( ) ;
eleLight[1].dwLightType = E3D_AMBIENT_LIGHT ;
eleLight[1].rgbColor.dwPixelCode = 0x404040 ;
//
SetLightEntries( 2, eleLight ) ;
//
// ソートフラグ設定
//
SetSortingFlags( E3D_SORT_TRANSPARENT | E3D_SORT_OPAQUE ) ;
//
// モデル設定
//
E3DModelJoint joint( &m_model ) ;
joint.InitializeMatrix( ) ;
joint.RevolveOnX( m_rRevolveX ) ;
joint.RevolveOnY( m_rRevolveY ) ;
joint.MagnifyByVector( E3DVector( 0.15F, 0.15F, 0.15F ) ) ;
joint.Position() = m_vCenter ;
//
AddModel( joint ) ;
//
// レンダリング準備
//
PrepareRendering( ) ;
次に、カメラの設定、ライトの設定、ソートの設定を行っています。
これらの設定は、FlushAllPolygon 関数によって初期化されてしまうことは無いので、固定であれば初めに1度だけ呼び出しておくだけでもかまいません。次に、モデルを設定しています。
モデルの追加は AddModel 関数によって行います。
AddModel 関数にはジョイントオブジェクトを渡します。ジョイントオブジェクトは変換行列と移動のためのベクトルを保持していて、階層化することも出来ます。
実際にはカメラオブジェクトもジョイントです。(但し、カメラオブジェクトだけは E3DRenderPolygon オブジェクトが保持しているので、利用の仕方は他のジョイントとは異なります)
変換行列で回転、拡大の設定を行い、座標の移動量も設定します。全ての設定が完了したら PrepareRendering 関数を呼び出します。
この関数は E3DRenderPolygon クラスではポリゴンのソートを行うだけですが、E3DRenderSprite クラスでは描画更新領域の決定も自動的に行います。以上の処理が完了したら E3DRenderSprite オブジェクトは、画面の再描画が必要な場合にも自動的にポリゴンを描画します。