スプライト描画

レンダラーが描画を行う方法には、これまでに扱ってきた直接描画の他に、 スプライト描画という方法が存在します。ここでは、このスプライト描画について説明します。

- 目次 -

スプライト描画

スプライト描画とは、本来ゲームなどでの 2DCG 全盛期に、ハードウェアで実装されていた同名の機能を、 ソフトウェア的に実装したものです。 スプライト描画の概念は、アニメ映像の制作過程における、 セル画の概念と非常によく似ています。 具体的には、まず描画する図形や画像の数だけ、 スプライトと呼ばれる「層」をレンダラーに登録しておきます。 そして、描画時にそれらのスプライトをレンダラーで重ねて合成し、1 枚の絵を生成します。

スプライト描画が特に威力を発揮するのは、 アニメーション処理などを行う時です。 例えば、アニメーションの中に、動くものと動かないものあったとしましょう。 この場合、画面に表示する絵を直接描画で用意すると、アニメーションのフレーム毎に「 まず背景をクリアし、 そして全ての図形や画像を draw 系関数で描画する 」という処理を行わなければなりません。

そこでスプライト描画を使用すると、 最初に全ての図形や画像をスプライトとして登録しておき、あとは毎回の描画時に、 動かしたいスプライトだけを動かせば済むので、プログラムの記述がシンプルになる場合があります。

なお、スプライト描画は、処理速度面でも直接描画より少し有利です。ただ、専用ハードウェア上での描画ならともかく、VCSSLのようなスクリプト言語上での描画機能においては、よほどスプライト枚数が多い使い方(数万〜数十万枚など)でない限り、気にするほどの体感差は生じません。単純に、どちらの方がコードをシンプルに書けるかという観点で選べばOKです。

スプライトの基本操作

直接描画と異なり、スプライトはプログラム実行中に動かしたり、 色を変えたりなど、動的に活用します。 そこで、具体的なスプライトの生成を扱う前に、 スプライトを動的に活用するための基本操作について述べておきます。

スプライトの生成

実際のスプライトには様々な種類のものがありますが、それらは全てnew〜Sprite 関数で生成し ます。〜の部分にはスプライトの種類に固有の名称が入ります。具体的な生成は次章で扱います。

- 関数の形式 -
int new〜Sprite ( 〜 )

この関数は、スプライトを生成し、そのスプライトに固有の識別番号である「スプライトID」を返します。

スプライトの登録

生成したスプライトは、レンダラーに登録しなければ描画されません。 レンダラーにスプライトを登録するには、mountSprite 関数を使用します。

- 関数の形式 -
void mountSprite ( int spriteID, int rendererID )

引数は以下の通りです:

スプライトの描画

レンダラーにすべてのスプライトを登録したら、 それらのスプライトを重ね合わせて合成し、1 枚のグラフィックスに描画する必要があります。 これには paintGraphics2D 関数を使用します。

- 関数仕様 -
void paintGraphics2D ( int rendererID )

引数は以下の通りです:

この関数をコールするまで、スプライトの合成は行われないのでご注意ください。

各種スプライト

スプライトには、線や幾何学図形を描画するもの、 テキストを描画するもの、画像を描画するものなど、様々な種類のものが存在します。 以下では、各種スプライトの生成と使用方法を扱います。

なお、以下に登場する関数は全て、戻り値として、生成したスプライトのIDを返します。

点スプライト

点スプライトを生成するには、newPointSprite 関数を使用します。

- 関数の形式 -
int newPointSprite ( int x, int y, int radius )

引数は以下の通りです:

線スプライト

線スプライトを生成するには、newLineSprite 関数を使用します。

- 関数の形式 -
int newLineSprite ( int x1, int y1, int x2, int y2 )

引数は以下の通りです:

長方形スプライト

長方形スプライトを生成するには、newRectangleSprite 関数を使用します。

- 関数の形式 -
int newRectangleSprite ( int x, int y, int width, int height, bool fill )

引数は以下の通りです:

楕円スプライト

楕円スプライトを生成するには、newEllipseSprite 関数を使用します。

- 関数の形式 -
int newEllipseSprite ( int x, int y, int width, int height, bool fill )

引数は以下の通りです:

楕円は、上で指定した長方形領域に内接するように描画されます。

多角形スプライト

多角形スプライトを生成するには、newPolygonSprite 関数を使用します。

- 関数の形式 -
int newPolygonSprite ( int x[ ], int y[ ], bool fill )

引数は以下の通りです:

折れ線スプライト

折れ線スプライトを生成するには、newPolylineSprite 関数を使用します。

- 関数の形式 -
int newPolylineSprite ( int x[ ], int y[ ] )

引数は以下の通りです:

テキストスプライト

テキストスプライトを生成するには、newTextSprite 関数を使用します。

- 関数の形式 -
int newTextSprite ( int x, int y, int lineWidth, int lineHeight, string text )

引数は以下の通りです:

フォントサイズの設定

テキストの描画に使用するフォントの大きさを変更したい場合は、setSpriteFontSize 関数を使用します。

- 関数の形式 -
void setSpriteFontSize ( int spriteID, int fontSize )

引数は以下の通りです:

pt というのはフォントの大きさを指定する一般的な単位で、画面表示する際に一つの基準となるのは大体12pt 前後でしょう。10pt だとやや細かい文字、15pt だと少し大きめの文字となります。ここで注意しなければならないのは、1pt が何ピクセルに対応するかというのは環境によって異なるという点です。著しく異なる事はありませんが、一文字あたり数ピクセルずれる事はよくあります。従って、テキストを描画する際は、あまりシビアではなく、ある程度ずれる事を想定したレイアウトをする事が推奨されます。

画像スプライト

画像スプライトを生成するには、newImageSprite 関数を用します。

- 関数仕様 -
int newImageSprite (
  int x, int y, int width, int height, int graphicsID
)

引数は以下の通りです:

引数x, x には、画像を描画する左上頂点の座標を、width, height には幅と高さを指定します。最後の引数graphicsID には、描画するグラフィックスデータのID を指定します。

引数に指定するグラフィックスデータIDには、GraphicsライブラリのnewGraphics( string fileName )関数で画像ファイルから読み込んだものや、別のレンダラーで描画したものなどが利用できます。

プログラム例

それでは、上で扱った各種描画関数を使用してみましょう。以下のように記述し、実行してみてください。

なお、画像の描画を行う場合は、プログラムと同じフォルダに「Test.png」という名前のPNG 形式画像ファイルを置いてから実行してください(こちらからダウンロードできます)。


import Graphics;
import Graphics2D;
import GUI;

// グラフィックスデータとレンダラーの生成
int graphicsID = newGraphics( );
int rendererID = newGraphics2DRenderer( 800, 600, graphicsID );

// 表示画面の生成
int windowID = newWindow( 0, 0, 800, 600, " Hello 2DCG ! " );
int labelID = newImageLabel( 0, 0, 800, 600, graphicsID );
mountComponent( labelID, windowID );

// 背景色を白に設定してクリア
setGraphics2DColor( rendererID, 255, 255, 255, 255 );
clearGraphics2D( rendererID );



// =========================
// 描画処理 ここから
// =========================


// (0,0)と(100,100)を結ぶ線スプライトを生成(赤色)
int lineSpriteID = newLineSprite( 0, 0, 100, 100 );
setSpriteColor( lineSpriteID, 255, 0, 0, 255 );
mountSprite( lineSpriteID, rendererID );


// (100,100)に(500×300)の長方形スプライトを生成(青色)
int rectSpriteID = newRectangleSprite( 100, 100, 500, 300, true );
setSpriteColor( rectSpriteID, 0, 0, 255, 255 );
mountSprite( rectSpriteID, rendererID );


// (100,100)に(500×300)の楕円スプライトを生成(緑色)
int ovalSpriteID = newEllipseSprite( 100, 100, 500, 300, true );
setSpriteColor( ovalSpriteID, 0, 255, 0, 255 );
mountSprite( ovalSpriteID, rendererID );


// 多角形、折れ線スプライト用のx 配列、y 配列を用意
int x[ 3 ];
x[ 0 ] = 100;
x[ 1 ] = 300;
x[ 2 ] = 300;

int y[ 3 ];
y[ 0 ] = 100;
y[ 1 ] = 100;
y[ 2 ] = 300;


// x 配列、y 配列を頂点とする多角形スプライトを生成(黄色)
int pgSpriteID = newPolygonSprite( x, y, true );
setSpriteColor( pgSpriteID, 255, 255, 0, 255 );
mountSprite( pgSpriteID, rendererID );


// x 配列、y 配列を頂点とする折れ線スプライトを生成(赤色)
int plSpriteID = newPolylineSprite( x, y );
setSpriteColor( plSpriteID, 255, 0, 0, 255 );
mountSprite( plSpriteID, rendererID );


// (100,100)にテキストスプライトを生成(黒色)
string text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int txtSpriteID = newTextSprite( 300, 50, 250, 35, text );
setSpriteColor( txtSpriteID, 0, 0, 0, 255 );
setSpriteFontSize( txtSpriteID, 30 );
mountSprite( txtSpriteID, rendererID );


// 画像ファイル「Test.png」を読み込み、画像スプライトを生成
int graphicsID2 = newGraphics( "Test.png" );
int imSpriteID = newImageSprite( 350, 100, 300, 200, graphicsID2 );
mountSprite( imSpriteID, rendererID );


// =========================
// 描画処理 ここまで
// =========================


// 登録されているスプライトを合成して描画
paintGraphics2D( rendererID );

// 画面の描画
paintComponent( labelID );
paintComponent( windowID );
Sample.vcssl

このプログラムを実行すると、白いウィンドウが表示され、その上に様々な図形が表示されます。

実行結果

※ 文字に使用されるフォントは、環境によって異なります。フォントを明示したい場合にはsetSpriteFont( int SpriteID, string fontName )関数を使用してください。