4.2.1.4 カメラ


カメラ

In Crystal Space there is an interface called `iView' which encapsulates both `iCamera' and `iClipper2D' instances. In principle you can use those classes directly but using `iView' is easier. Now, edit `simple.h' to make use of `iView':

クリスタルスペースでは、`iView`というインターフェイスがある。それは、`iCamera`と`iClipper2D`をカプセル化したものです。原則として、あなたはこれらのクラス(`iCamera`と`iClipper2D`のこと)を直接使用することができます。しかし、`iView`を使用するほうが簡単です。さて、`iView`を使うために`simple.h`を編集しましょう。

...
class Simple
{
private:
 ...
 csRef<iView> view;
 ...
 void ProcessFrame ();
 void FinishFrame ();
 ...

Then, edit `simple.cpp' and make the following changes at the end of our Application() function:

そして、`simple.cpp`を編集し、Application()機能の最後に、次の変更を行ましょう。

bool Simple::Application ()
{
 ...
 view.AttachNew(new csView (engine, g3d));
 iGraphics2D* g2d = g3d->GetDriver2D ();
 view->SetRectangle (0, 0, g2d->GetWidth (), g2d->GetHeight ());
 ...
 view->GetCamera ()->SetSector (room);
 view->GetCamera ()->GetTransform ().SetOrigin (csVector3 (0, 5, -3));

 return true;
}

So, first we create a view for our world and a particular 3D renderer. The view has a current sector which is passed to the camera and is set by SetSector?(). The camera also has a position in that sector which you can set by first getting the camera with GetCamera?() and then setting the position (which is a `csVector3') with SetPosition?(). The view also holds a clipping region which corresponds to the area on the window that is going to be used for drawing the world. Crystal Space supports convex polygons as viewing areas, but in this case we use a simple rectangle the same size as the window. We set this viewing rectangle with SetRectangle?().

このように、まず、ワールドのビューと、特定の3Dレンダを作成します。ビューは、カメラに渡されSetSector?()によりセットされた現在のセクタを持っています。カメラはセクタ内の位置を持っています。セクタ内の位置は、はじめにGetCamera?()でカメラを取得し、SetPosition?()を使用して位置(`csVector3`)を設定することで、セットすることができます。ビューはまた、クリップ範囲を持っています。クリップ範囲は、ワールドを描画するために使用するウィンドウの領域に一致します。Crystal Spaceは、視覚領域として凸面のポリゴンをサポートします。しかし、この例では、ウィンドウと同じサイズの単純な四角を使用します。SetRectangle?()により視覚領域をセットします。

The call to create a new view is a bit special. See the discussion on smart pointers for a detailed discussion (see section Correctly Using Smart Pointers).

新しいビューを作成する呼び出しは、少々特別です。詳細は議論は、スマートポインタの議論をご覧下さい。(see section Correctly Using Smart Pointers).

Now, this still isn't enough. We have a camera but the camera is not used. We have to write code that actually draws the screen. We will do this in the functions ProcessFrame?() and FinishFrame?(). Note that Crystal Space is event driven so the actual drawing needs to be triggered by the event handler. Add the following code somewhere in the source file:

さて、これではまだ十分ではありません。カメラはありますが、カメラは使用されません。私たちは、スクリーンに描画するコードを書かなければなりません。ProcessFrame?()とFinishFrame?()で描画するコードを書きます。注意して下さい。Crystal Space はイベント駆動型です。そのため、実際の描画はイベントハンドラにより開始する必要があります。ソースファイルのどこかに、次のコードを追加して下さい。

void Simple::ProcessFrame ()
{
 // Tell 3D driver we're going to display 3D things.
 if (!g3d->BeginDraw(
   engine->GetBeginDrawFlags() | CSDRAW_3DGRAPHICS))
   return;

 // Tell the camera to render into the frame buffer.
 view->Draw ();
}

void Simple::FinishFrame ()
{
 g3d->FinishDraw ();
 g3d->Print (0);
}

Drawing the screen is done in two steps. First there is the part that is done in ProcessFrame?(). Here, we will actually fill the display. In this case we let the engine do most of that work by calling view->Draw(). But, in principle, you can do any kind of drawing here.

スクリーンへの描画は、2ステップです。1つめは、ProcessFrame?()で完了している処理です。ここでは、実際にディスプレイを塗りつぶしています。この例では、view->Draw()を呼ぶことで、大抵の仕事をエンジンにさせています。しかし、原則として、どんな種類の描画も、ここで行うことができます。

In ProcessFrame?() we first have to indicate to the 3D rasterizer that we want to start drawing 3D graphics. This call makes sure that the needed buffers are set up and performs all necessary initialization. The engine often needs extra settings for this as well so you must call engine->GetBeginDrawFlags?() to get these flags and bitwise-or them with the ones that you want.

ProcessFrame?()で、私たちは、まず3Dグラフィックスの描画を開始したいので、3Dラスタライザを指定しなければなりません。この呼び出しでは、必要なバッファがセットアップされ、必要な初期化が実行されなければなりません。エンジンは、初期化のために、特別な設定を必要とします。そのため、あなたは、フラグを取得するためにengine->GetBeginDrawFlags?()を呼び、欲しい1つのフラグを使用してビット単位のORをしなければなりません。

The second part is in FinishFrame?() where we actually dump the frame to the screen. The reason this is split is that other components (plugins) in Crystal Space may choose to listen to events and draw additional things on top of the 3D view rendered in ProcessFrame?(). When a frame needs to be rendered, the Crystal Space framework will send four messages:

第2には、FinishFrame?()の中です。FinishFrame?()では、スクリーンに、フレームをダンプしています。分割されている理由は、Crystal Spaceの他のコンピュータ(プラグイン)は、イベントを聞き取りを選択し、ProcessFrame?()の中でレンダされる3Dビューの最前面に追加したものを描画するかもしれないためです。

  • `csevPreProcess?' is sent first. This allows plugins to preprocess things before drawing can happen.
  • `csevProcess' follows. In this pass the application will render.
  • `csevPostProcess?' is after that. This is the pass that can be used by external components to render on top of the view rendered by the application.
  • `csevFinalProcess?' is last. In this pass the application will display the frame on screen.
  • `csevPreProcess?`は、はじめに送られます。ここでは、描画が発生する前に、プラグインの前準備をします。
  • `csevProcess`は次のようです。この時は、アプリケーションがレンダします。
  • `csevPostProcess?`は`csevProcess`の後です。アプリケーションによりレンダされるビューの最前面にレンダする特別なコンポーネントのために使用します。
  • `csevFinalProcess?`は最後です。アプリケーションは、スクリーン上にフレームを映し出します。

Compile and run this example. For the first time you should see something: A solid wall. Congratulations, you have created your first almost useful Crystal Space application.

この例をコンパイルして、実行して下さい。初めてなにか見ることができるでしょう。固体の壁です。おめでとうございます。はじめてとても役に立つ Crystal Space アプリケーションを作成しました。