前回まででなんとか初期化は終わりました。コンパイルしてエラーを起こさず起動すれば万事順調(の予定)です。そういうわけで、今回はまともに何かを書きます。もちろん何かとは『真っ黒な画面』をです。
private void timer__Tick(object sender, EventArgs e)
{
//非表示時と最小化時は描画しない。(無駄だから)
if(!this.Visible)return;
if(this.WindowState == FormWindowState.Minimized)return;
//真っ黒に塗る
secondarySuface_.ColorFill(Color.Black);
Rectangle rect =new Rectangle();
rect.Size =this.ClientSize;
rect.Location =this.PointToScreen(this.ClientRectangle.Location);
primarySurface_.Draw(rect,secondarySuface_,DrawFlags.Wait);
}
メインコードはこれだけです。でも、関数名見て分かる人がいるかもしません。タイマーが必要です。
指定した色でサーフィスを塗りつぶしてくれます。と言う事は、このページが読み終われば、別な色で塗りつぶす事も出来るわけです。(あんまり役に多々なそうですね)
色々な使い方が出来そうな関数ですが、今回はサーフィスからサーフィスへの転送に使用しています。この際。何故か座標が必要らしいです。と言うわけで座標を取得するのですが、特にロケーション。ウィンドウが最小化時にはエラーの元となる値を返します。ですから、最初の2行のif文は消さないでください。重要です。
それでは今までの事をふまえてソースコードを載せます。
using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.DirectDraw;
namespace DDrawTest1
{
public class Program
{
/// <summary>
/// アプリケーションのエントリポイント
/// </summary>
/// <param name="argv"></param>
public static void Main(string []argv)
{
Application.Run(new DDrawTest());
}
}
// ウィンドウを作りたいのでフォームを継承
public class DDrawTest:Form
{
//クライアント領域のサイズ
const int clientHeight =600;
const int clientWight =800;
public DDrawTest():base()
{
//固定サイズのフォーム
this.FormBorderStyle = FormBorderStyle.FixedSingle;
//サイダかボタン無し
this.MaximizeBox = false;
//クライアント領域サイズ
this.ClientSize = new Size(clientWight,clientHeight);
this.directDrawInitialize();
this.timer_ =new Timer();
timer_.Interval=100;
timer_.Tick+=new EventHandler(timer__Tick);
timer_.Start();
}
private Device device_;
private Surface primarySurface_;
private Surface secondarySuface_;
private Clipper clipper_;
//ここが心臓部DirectDrawの初期化
private void directDrawInitialize()
{
//デバイスを作成
device_ = new Device();
//デバイスの協調レベルを設定
device_.SetCooperativeLevel(this,CooperativeLevelFlags.Normal);
//サーフィスを作成するための情報
SurfaceCaps caps =new SurfaceCaps();
SurfaceDescription desc =new SurfaceDescription();
//プライマリサーフィスの作成
caps.PrimarySurface =true;
desc.SurfaceCaps =caps;
primarySurface_ =new Surface(desc ,device_);
//情報をリセット(セカンダリサーフィスを作るため)
caps.Clear();
desc.Clear();
//セカンダリサーフィスの作成
desc.Width = clientWight;
desc.Height =clientHeight;
desc.SurfaceCaps =caps;
secondarySuface_ = new Surface(desc,device_);
//クリッパーの作成
clipper_ =new Clipper(device_);
clipper_.Window =this;
//プライマリサーフェスにクリッパーをセット
primarySurface_.Clipper =clipper_;
}
private Timer timer_;
private void timer__Tick(object sender, EventArgs e)
{
//非表示時と最小化時は描画しない。(無駄だから)
if(!this.Visible)return;
if(this.WindowState == FormWindowState.Minimized)return;
//真っ黒に塗る
secondarySuface_.ColorFill(Color.Black);
Rectangle rect =new Rectangle();
rect.Size =this.ClientSize;
rect.Location =this.PointToScreen(this.ClientRectangle.Location);
primarySurface_.Draw(rect,secondarySuface_,DrawFlags.Wait);
}
}
}
どうでしょうか?昔懐かしきコマンドラインのフリーズしたような状況が再現されていると思われます。ここまで来たらもう大丈夫。自分で出来ると言いたいところなのですが、ここからの文献がないんですよ。やっぱり「Direct3D」おすすめします。