Direct Draw で Image を表示する

CLI の環境で Direct Draw で Form を生成して Image を表示します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プロジェクトの設定

  1. C++/CLI DirectX の Draw で Form を生成して Image を表示します。
    3Dに吸収された Draw 機能ですが、C++/CLI ではまだまだ使うことが出来ます。 (^_^;
    3Dに比べてプログラミングも容易で描画速度も速いので、3D機能を使わないのであればお勧めです。
    VC++ のプロジェクトで作成すると非常に多くのファイルが自動的に作成されるのですが、今回作成するファイルは drimage.cpp の一本だけです。
    コンパイルと実行の方法は Command Line から DirectX を動かす を参照して下さい。
    ファイル名 説明
    DRImage.cpp Direct Draw Image
  2. #using で実行に必要な DLL(Dynamic Link Library) をリンクします。
    using namespace は名前空間の設定で、修飾しなくても Class を参照できるようにしています。
        #using <System.dll>
        #using <System.Windows.Forms.dll>
        #using <System.Drawing.dll>
        #using <Microsoft.DirectX.dll>
        #using <Microsoft.DirectX.DirectDraw.dll>
    
        using namespace System;
        using namespace System::Windows::Forms;
        using namespace System::Drawing;
        using namespace Microsoft::DirectX;
        using namespace Microsoft::DirectX::DirectDraw;
        
  3. DXDraw は Direct Draw のフォーム(Window) を生成するクラスです。
    ^draw は Direct Draw のデバイスで ^ はポインタを意味します。
    ^primary は画像を描画する primary surface です。
    surface とはウインドウの描画に直接関係するメモリ領域で、高速に描画するためにビデオボード上に確保されます。
    ^offscreen は画像を入力する offscreen surface で、ここから primary に転送します。
    dest は Rectangle(矩形)構造体で、ウインドウの大きさを取得します。
    Constructor では初期値として null を設定します。
    this->Text = "Dirext Draw"; は caption の設定です。
    this->ClientSize に Form の大きさを設定します。
    今回表示する画像は、幅,高さ共に 480 ピクセルぐらいのものを用意して下さい。
    CreateSurfaces(); メソッドで Direct Draw の初期化を行います。
        ref class DXDraw : public System::Windows::Forms::Form
        {
            Microsoft::DirectX::DirectDraw::Device  ^draw;      // DrawDevice object.
            Microsoft::DirectX::DirectDraw::Surface ^primary;   // primary destination surface.
            Microsoft::DirectX::DirectDraw::Surface ^offscreen; // offscreen surface(bitmap loaded).
            Rectangle dest;
    
          public:
            // Constructor
            DXDraw()
            {
                draw = nullptr;
                primary = nullptr;
                offscreen = nullptr;
                // caption の設定
                this->Text = "Dirext Draw";
                this->ClientSize = System::Drawing::Size(480, 480);
                CreateSurfaces();
            }
        
  4. Direct Draw の初期化を行う CreateSurfaces(); メソッドです。
    draw = gcnew Device(); で Direct Draw のデバイスを取得します。
    SetCooperativeLevel で Windowed Mode に設定します。
    gcnew SurfaceDescription() で primary Surface を生成します。
    gcnew Surface("C:\\Data\\Test\\emiko_s.bmp", description, draw) で offscreen Surface を生成して画像を入力します。
    "C:\\Data\\Test\\emiko_s.bmp" が、画像が格納されているフォルダーとファイルの名前です。
    適当な画像を調達してきて下さい。
        void CreateSurfaces()
        {
            // DrawDevice を生成
            draw = gcnew Device();
            draw->SetCooperativeLevel(this, CooperativeLevelFlags::Normal);
            // primary Surface を生成
            SurfaceDescription ^description = gcnew SurfaceDescription();
            description->SurfaceCaps->PrimarySurface = true;
            primary = gcnew Surface(description, draw);
            // offscreen(Image) Surface を生成
            description->Clear();
            offscreen = gcnew Surface("C:\\Data\\Test\\emiko_s.bmp", description, draw);
        }
        
  5. Draw() メソッドでは、ウインドウの大きさに合わせて、画像を表示します。
    マウスの操作でウインドウのサイズを変えると、画像の大きさも変わることを確認して下さい。 ヽ(^^ )
        void Draw()
        {
            if (primary==nullptr)   return;
            dest = Rectangle(PointToScreen(Point(0,0)), ClientSize);
            primary->Draw(dest, offscreen, DrawFlags::Wait);
        }
        
  6. main() メソッドでは gcnew DXDraw() で Form を生成します。
    メッセージループから frm->Draw(); で描画関数を呼び出していることに注目して下さい。 ヽ(^^ )
    ゲームプログラムでは、たとえ画面が変わらなくても毎回描画するのが基本です。
        int main()
        {
            DXDraw ^frm;
            frm = gcnew DXDraw();
            if (frm)
            {
                frm->CreateSurfaces();      // Create Draw Surfaces
                frm->Show();
    
                // メッセージループ
                while(frm->Created)
                {
                    frm->Draw();
                    Application::DoEvents();
                }
            }
            return 0;
        }
        

超初心者のプログラム入門(C/C++)