|
Delphi2010 Direct2D(1) 2010/12/05 |
Delphi6等で、これまで絵などを描画するには、イメージ(Image)コンポーネントやペイントボックス(PaintBox)コンポーネントなどの TCanvas に対して、ペン設定・ブラシ設定・フォント設定をして、線や円や塗り潰しや文字などの描画を行うようになっていました(WindowsGDI)。このほか、OpenGLを利用する事は出来ますし、標準のコンポーネントでサポートはされていませんが、DirectXを利用する事は出来ました(※独自で作るには敷居が高いかもしれません;私は堀浩行氏の「DelphiX」を Delphi5で利用させて頂いています)。OpenGLは基本的に3Dですね。DirectXには、2Dの「DirectDraw」と 3Dの「Direct3D」があります。しかしDelphiで DirectXを利用する事を記載している書籍というのは非常に少ないです。敷居も高い(※上記の書籍「DelphiX」はDelphi3/4/5・DirectX7対応となっていますので少々古い)ため、DirectXを利用したい場合は大抵、Microsoft Visual C++ や Visual BASIC を利用するようです。
さて、通常のTCanvasへの描画は、WindowsGDIが利用されるわけですが、これは、WindowsXpまではVGAカードのハードウェアアクセラレータで動作したためそれなりの速度で描画されたのですが、WindowsVista/7の場合には、そのVGAカードのハードウェアアクセラレーションは効かず、CPUが描画のほとんどを一手に引き受けるようになっています。元々がグラフィック関連に特化していないCPUでの動作ですので、やはり、遅くなってしまいます。高速なCPUであればあるほど、高速に描画されますが・・・。という訳で、WindowsVista/7 では、DirectX(3DであればOpenGLも)での描画が推奨されるようになっています。
しかしDelphiで DirectX を利用するには敷居が高い。
そこで、Windows7 から新規対応となった「Direct2D」に、Delphi2010も対応されているようです。感覚的には、DirectXの DirectDrawに似ているような気もしますが、Direct2D という新しいAPIのようです。Windows7 以前のWindowsではサポートされないとの事です。
テスト31(フォルダ「031」)として新規作成しておきます。
ヘルプによれば、Direct2Dの使い方には2種類あって、
・従来の GDI キャンバスと新しい Direct2D キャンバスとで描画面を共有する。
・Direct2D キャンバスだけを使用する。 |
との事ですが後者はWindowsメッセージをキャプチャして処理を行うとの事で多少ややこしいですから、この前者だけ見てみます。
まずは画面を用意します。Direct2Dは作図先のWindowsハンドルが必要となりますので、Windowsハンドルを持たないペイントボックス(PaintBox)コンポーネント上には描けません。ここではパネルを用意し、その上に作図する事にします。比較のため、従来のWindowsGDIパターンの作図も行うようにしてみます。こちらが左のパネル Panel1、右側のパネル Panel2 が Direct2D であるとします。パネル Panel1 の上にペイントボックス PaintBox1 を配置(Align=alClient)しています。
ラベル Label1 には、Direct2D が使えるかどうかを表示します。起動時に確認します。ラベル Label2・Label3には、掛かった時間を表示します。ボタン Button1 を押したらスタートです。内容は単純です。線を何本か描かせているだけです。
まずは、uses節に「Direct2D」と「D2D1」を追記します。フォーム Form1 の Private宣言のところで変数を追加します。
type
TForm1 = class(TForm)
Label1: TLabel;
・・・
private
{ Private 宣言 }
D2DCanvas : TDirect2DCanvas ;
D2DCanvasFlag : Boolean ;
public
{ Public 宣言 }
end; |
D2DCanvasFlag が True であれば Direct2Dは利用可能、False であれば不可、とします。D2DCanvas 上にDirect2D作図を行うようにします。Direct2Dが使えるかどうかを起動時(OnShow時)に確認し、終了時には、解放するようにしておきます。
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if (D2DCanvasFlag) then
D2DCanvas.Free;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
// Direct2D が使えるかどうかのチェック
D2DCanvasFlag := False ;
if TDirect2DCanvas.Supported then begin
try
D2DCanvas := TDirect2DCanvas.Create(Panel2.Handle);
D2DCanvasFlag := True ;
except
;
end;
end;
if (D2DCanvasFlag) then
Label1.Caption := 'Direct2D<OK>'
else
Label1.Caption := 'Direct2D<NG>';
end; |
そしてボタンを押した時の処理を記述します。
procedure TForm1.Button1Click(Sender: TObject);
var
t : TDateTime ;
i,j : integer ;
begin
// ----- クリア -----
// WindowsGDI
with PaintBox1.Canvas do begin
Brush.Color := clWhite ;
Pen.Color := clBlue;
Rectangle(0, 0, 150, 150);
end;
// Direct2D
if (D2DCanvasFlag) then begin
D2DCanvas.BeginDraw;
try
with D2DCanvas do begin
Brush.Color := clWhite ;
Pen.Color := clBlue;
Rectangle(0, 0, 150, 150);
end;
except
;
end;
D2DCanvas.EndDraw;
end;
// ----- 作図テスト -----
// WindowsGDI
t := Now ;
with PaintBox1.Canvas do begin
for j:=0 to 1000 do begin
for i:=0 to 150 do begin
Pen.Color := i + j*256 ;
MoveTo(0,i);
LineTo(75,i);
Pen.Color := i+151 + j*256 ;
LineTo(150,i);
end;
end;
end;
Label2.Caption := TimeToStr(Now - t) ;
// Direct2D
if (D2DCanvasFlag) then begin
t := Now ;
D2DCanvas.BeginDraw;
try
with D2DCanvas do begin
for j:=0 to 1000 do begin
for i:=0 to 150 do begin
Pen.Color := i + j*256 ;
MoveTo(0,i);
LineTo(75,i);
Pen.Color := i+151 + j*256 ;
LineTo(150,i);
end;
end;
end;
except
;
end;
D2DCanvas.EndDraw;
Label3.Caption := TimeToStr(Now - t) ;
end;
end; |
実行内容は、最初にクリアをして、線を何本か作図して、その時間を表示します。Direct2Dの場合、D2DCanvas.BeginDraw 〜 D2DCanvas.EndDraw で囲っていて内部で例外処理をしています。(ヘルプによる) 内容は、見て分かるとおり、ほとんど同じです。保存・コンパイル(再構築)・実行を行います。
↓
通常の WindowsGDI での描画は、描画をしている様子が見て分かります。何度か点滅するかのように実行されます。しかし、Direct2D のほうは、描画の途中経過は分からず最終結果だけが最後にぱっと表示されます。見る分には余り面白くないかもしれませんがその分?速いと思います。但し、作図中は、作図しているかどうかが分かりませんので例えば「描画中です」等の何らかのメッセージを表示させたほうがいいかもしれません。
|
|
バッチファイル
BASIC
C言語のお勉強
拡張子な話
DOSプログラム
Delphi
>Delphi入門編
>Delphi2010
▲2010/12/04
2010/12/05
▼2010/12/08
シェアウェア
Script!World
データベース
|