ホームへ戻る

 4.4章 バイリニア補間をして滑らかに拡大・移動する

 今回はDXライブラリの非公開関数の紹介です。

DXライブラリに存在する関数は、リファレンスページに載っている関数だけではありません。
実は1000個以上の非公開関数が存在します。(DxLib.hの中を見れば分かります)
DXライブラリは非常に容易に使えるよう最小限の機能のみ表に出しているようですが、せっかくある機能なのでドンドン使っていきましょう。
(非公開関数なだけに今後仕様変更などあるかもしれませんが・・)

例えば、画像の描画は整数型の座標位置を渡すDrawGraph系の関数を使っていました。
しかし、実数の座標を渡すことが出来るDrawGraphF系の関数が存在します。
小数を含むピクセル位置に描画するというとピンと来ないかもしれませんが、例えば0.5ピクセル位置に描画すると、
隣り合うピクセルが中間の色を示して補間してくれるのです。
これが何故必要なのかを示す為、以下のサンプルをご覧ください。


#include "DxLib.h"

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更,初期化,裏画面設定

        int Image;
        float x=0, y=20;
        Image = LoadGraph("画像/キャラクタ00.png");

        // while( 裏画面を表画面に反映, メッセージ処理, 画面クリア )
        while( !ScreenFlip() && !ProcessMessage() && !ClearDrawScreen() ){
                x    += 1.f;
                y    += 0.1f;
                DrawGraph    ( (int)x, (int)y, Image, TRUE );
        }

        DxLib_End();
        return 0;
}

実行結果


xが1に対して、yが0.1の角度で移動しています。
しかし、小数を含むピクセルに描画出来ないので、結果的に以下のような見た目で移動してしまいます。



サンプルの実行結果はよく見ないと分からない程度かもしれませんが、
シューティングのレーザー等が全てこのようにウゴウゴ移動していると見た目気持ち悪く見えてしまいます。
特に、わずかにレーザーが傾いていたりすると、顕著に表れます。



そこで、小数ピクセルに描画出来るDrawGraphF系の関数を使います。
ただ、先ほど中間ピクセルに描画すると補間してくれると言いましたが、この補間の設定はデフォルトでOFFになっています。
補間処理を行うには補間処理を行いたい関数を書く前に

SetDrawMode( DX_DRAWMODE_BILINEAR );

と書きます。
「バイリニア」「ニアレスト」という言葉を聞いたことがあるでしょうか。
フォトショップなど画像編集ソフトで、画像を拡大縮小する時に指定する補間処理のアルゴリズムです。
詳細な説明はここでは省略しますが、とりあえず

バイリニア …補間処理あり
ニアレスト …補間処理なし

と覚えておけばよいでしょう。
バイリニアで線形補間すると、実数ピクセルを補間してくれたり、拡大時に補間してくれたりするのですが、
補間処理をするせいで、ぼやけた見た目になることが欠点です。
そこで、必要な描画のみバイリニアで行い、すぐニアレストに戻してやりましょう。

以下、補間処理なし、ありの2通りのサンプルを示しますので見比べてみて下さい。

[補間処理なし]


#include "DxLib.h"

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更,初期化,裏画面設定

        int Image;
        float x=0, y=20, size=1;
        Image = LoadGraph("画像/キャラクタ00.png");

        // while( 裏画面を表画面に反映, メッセージ処理, 画面クリア )
        while( !ScreenFlip() && !ProcessMessage() && !ClearDrawScreen() ){
                x    += 1.f;
                y    += 0.1f;
                size += 0.02f;
                DrawRotaGraphF( 320, 240, size, 0, Image, TRUE );//拡大表示
                DrawGraphF    ( x, y, Image, TRUE );//右斜めに移動しながら表示
        }

        DxLib_End();
        return 0;
}

実行結果


ウゴウゴ移動してみて、かつ拡大した時の粗いピクセルがはっきり見えると思います。次に補間処理ありです。

[補間処理あり]


#include "DxLib.h"

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更,初期化,裏画面設定

        int Image;
        float x=0, y=20, size=1;
        Image = LoadGraph("画像/キャラクタ00.png");

        // while( 裏画面を表画面に反映, メッセージ処理, 画面クリア )
        while( !ScreenFlip() && !ProcessMessage() && !ClearDrawScreen() ){
                x    += 1.f;
                y    += 0.1f;
                size += 0.02f;
                SetDrawMode( DX_DRAWMODE_BILINEAR );
                DrawRotaGraphF( 320, 240, size, 0, Image, TRUE );
                DrawGraphF    ( x, y, Image, TRUE );
                SetDrawMode( DX_DRAWMODE_NEAREST );
        }

        DxLib_End();
        return 0;
}

実行結果


綺麗に移動しており、かつ拡大した時も粗さが軽減していると思います。

「拡大する時」「滑らかに移動させたい時」にはバイリニア補間処理が出来る事を覚えておいてください。

→分からないことがあれば掲示板で質問して下さい


- Remical Soft -