Image を描画する

C# DirectX で ofscreen Surface にイメージをロードして描画します。
イベントハンドラを使わずに、メッセージループから直接描画します。

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

プロジェクトの設定

  1. 次のファイルを格納して下さい。
    /******************************************************************/
    /*★ Direct Draw でメッセージループから Image を描画    前田 稔 ★*/
    /******************************************************************/
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using Microsoft.DirectX;
    using Microsoft.DirectX.DirectDraw;
    
    namespace DXDraw
    {
        public class DXDraw : Form
        {
            String  ImgFile = "C:\\Data\\Test\\emiko_s.bmp";
            private Device draw = null;         // DrawDevice object.
            private Surface primary = null;     // primary destination surface.
            private Surface offscreen = null;   // offscreen surface(bitmap loaded).
            private Rectangle dest;
    
            public DXDraw()
            {
                ClientSize = new System.Drawing.Size(480, 480);
                Text = "DXDraw";
                CreateSurfaces();               // Surface was lost. Recreate them.
            }
    
            // This function Draws the offscreen bitmap surface to the primary visible surface.
            private void Draw()
            {
                if (null == primary)    return;
                if (FormWindowState.Minimized == WindowState)   return;
                Height = Height < 50 ? 50 : Height;
    
                // Get the new client size to Draw to.
                dest = new Rectangle(PointToScreen(new Point(0,0)), ClientSize);
    
                try
                {
                    primary.Draw(dest, offscreen, DrawFlags.Wait);
                }
                catch(SurfaceLostException)
                {
                    CreateSurfaces(); // Surface was lost. Recreate them.
                }
            }
    
            // This function is where the surfaces and clipper object are created.
            private void CreateSurfaces()
            {
                // DrawDevice を生成
                draw = new Device();
                draw.SetCooperativeLevel(this, CooperativeLevelFlags.Normal);
                // primary Surface を生成
                SurfaceDescription description = new SurfaceDescription();
                description.SurfaceCaps.PrimarySurface = true;
                primary = new Surface(description, draw);
                // offscreen(Image) Surface を生成
                description.Clear();
                offscreen = new Surface(ImgFile, description, draw);
            }
    
            //☆ Main() メソッド
            static void Main()
            {
                using (DXDraw frm = new DXDraw())
                {
                    frm.CreateSurfaces();      // Create Draw Surfaces
                    frm.Show();
    
                    // メッセージループ
                    while(frm.Created)
                    {
                        frm.Draw();
                        Application.DoEvents();
                    }
                }
            }
        }
    }
    
  2. ImgFile は描画する画像ファイルの名前です。
    draw は Direct Draw Device の定義です。
    primary は primary(front) surface の定義です。
    offscreen は、直接画面と結び付けられていない surface です。
    今回は offscreen に画像ファイルからイメージを入力して描画します。
    dest はウインドウのサイズを取得する矩形領域です。
        String  ImgFile = "C:\\Data\\Test\\emiko_s.bmp";
        private Device draw = null;         // DrawDevice object.
        private Surface primary = null;     // primary destination surface.
        private Surface offscreen = null;   // offscreen surface(bitmap loaded).
        private Rectangle dest;
        
  3. SurfaceDescription を設定して new Surface() で primary surface を取得します。
    offscreen Surface を生成してイメージを入力するのは簡単です。
    new Surface(ImgFile, description, draw) 一行で、画像を読み込んで格納してくれます。
        private void CreateSurfaces()
        {
            // DrawDevice を生成
            draw = new Device();
            draw.SetCooperativeLevel(this, CooperativeLevelFlags.Normal);
            // primary Surface を生成
            SurfaceDescription description = new SurfaceDescription();
            description.SurfaceCaps.PrimarySurface = true;
            primary = new Surface(description, draw);
            // offscreen(Image) Surface を生成
            description.Clear();
            offscreen = new Surface(ImgFile, description, draw);
        }
        
  4. 後は「ofscreen を使って図形を描画する」と同じように描画できるのですが、今回はメッセージループから描画します。
    new DXDraw() で Form を生成して frm.CreateSurfaces() で surface を取得します。
    次に frm.Show() でウインドウを表示してメッセージループに入ります。
    frm.Draw() が画像を描画するメソッドの呼び出しです。
    このままでは frm.Draw(); が何度も呼ばれて「同じ画像を繰り返し描画する」ことになります。
    対策はアニメーションの描画などを参照して下さい。
        //☆ Main() メソッド
        static void Main()
        {
            using (DXDraw frm = new DXDraw())
            {
                frm.CreateSurfaces();      // Create Draw Surfaces
                frm.Show();
    
                // メッセージループ
                while(frm.Created)
                {
                    frm.Draw();
                    Application.DoEvents();
                }
            }
        }
        
  5. void Draw() は前回と同じです。
    メッセージループから常に描画するので、DXDraw_SizeChanged などは不要です。

【演習】

  1. 画像の上から TEXT を重ねて表示して下さい。
  2. ofscreen を使って図形を描画する と同じようにイベントハンドラから描画して下さい。

超初心者のプログラム入門(C# Frame Work)