AFsoft WebSite(エーエフソフト・ウェブサイト)
 

オペレーティング・システムについて

プログラミングについて
ホームページについて
キャドについて
電子カタログについて
書籍・雑誌
イベント
リンク集
Delphi2010 Direct2D(7) 2010/12/13

今回ももう少し、Direct2Dについて見ていきます。
前回は、角の丸い長方形(矩形)の描画 DrawRoundedRectangleメソッド、および、塗り潰しの角の丸い長方形の描画 FillRoundedRectangleメソッドについて見ましたので、今回はまず、楕円の描画 DrawEllipseメソッドについて見てみます。これまで同様、ボタン1つ Button9 を追加し、それをクリックしたら描画テストを行うようにします。

 
長方形(矩形)の描画 DrawRectangleメソッド および
塗り潰し長方形の描画 FillRectangleメソッド での引数は
D2D_RECT_F型で Single型の Left値・Top値・Right値・Bottom値を、
角の丸い長方形の描画 DrawRoundedRectangleメソッド および
塗り潰しの角の丸い長方形の描画 FillRoundedRectangleメソッドでの引数は D2D1_ROUNDED_RECT型で D2D_RECT_F型のrect値、Single型の radiusX・radiusY値を持ちましたが、このDrawEllipseメソッドでの引数は、D2D1_ELLIPSE型であり、これは、D2D_POINT_2F型のpoint値(これは更に Single型の X値・Y値)、Single型の radiusX・radiusY値を持ちます。まずは簡単なテストから。
procedure TForm1.Button9Click(Sender: TObject);
var
 e : D2D1_ELLIPSE ;
begin
 if not(D2DCanvasFlag) then exit;
 with D2DCanvas do begin
  BeginDraw;
  RenderTarget.Clear (D2D1ColorF(clWhite));  // 背景:白色
  Pen.Color := clMaroon ;
  Pen.Style := psSolid ;
  Pen.Width := 1 ;
  Brush.Color := clYellow ;
  Brush.Style := bsSolid ;
  
  e.point.x := 100 ;
  e.point.y := 120 ;
  e.radiusX := 80 ;
  e.radiusY := 60 ;
  DrawEllipse(e);
  
  EndDraw;
 end;
end;
保存・コンパイル(再構築)・実行を行います。以下のようになります。

 
想定通りブラシの設定をしていますが無視されます。
 
それではこれまでと同様に速度チェックをしてみます。これまでは j:=1〜1000/i:=0〜200としていましたが今回は遅いのでj:=1〜1000/i:=0〜100と半分にしています。
procedure TForm1.Button9Click(Sender: TObject);
var
 t : TDateTime ;
 mes : string ;
 i,j : integer ;
 e : D2D1_ELLIPSE ;
begin
 t := Now ;
 with PaintBox1.Canvas do begin
  Pen.Style := psSolid ;
  Pen.Width := 1 ;
  Brush.Style := bsClear ;
  for j:=1 to 1000 do begin
   for i:=0 to 100 do begin
    Pen.Color := RGB(Random(256),Random(256),Random(256)) ;
    Ellipse(i,i,200-i,200-i);
   end;
  end;
 end;
 mes := 'GDI:' + TimeToStr(Now - t) ;
 
 if not(D2DCanvasFlag) then exit;
 t := Now ;
 with D2DCanvas do begin
  BeginDraw;
  RenderTarget.Clear (D2D1ColorF(clWhite)); // 背景:白色
  Pen.Style := psSolid ;
  Pen.Width := 1 ;
  Brush.Style := bsClear ;
  for j:=1 to 1000 do begin
   for i:=0 to 100 do begin
    Pen.Color := RGB(Random(256),Random(256),Random(256)) ;
    Ellipse(i,i,200-i,200-i);
   end;
  end;
  EndDraw;
 end;
 mes := mes + ' BI:' + TimeToStr(Now - t) ;
 
 t := Now ;
 with D2DCanvas do begin
  BeginDraw;
  Pen.Style := psSolid ;
  Pen.Width := 1 ;
  for j:=1 to 1000 do begin
   for i:=0 to 100 do begin
    Pen.Color := RGB(Random(256),Random(256),Random(256)) ;
    e.point.x := 100 ;
    e.point.y := 100 ;
    e.radiusX := i ;
    e.radiusY := i ;
    DrawEllipse(e);
   end;
  end;
  EndDraw;
 end;
 mes := mes + ' Direct2D:' + TimeToStr(Now - t) ;
 
 StatusBar1.SimpleText := mes ;
end;
保存・コンパイル(再構築)・実行を行います。





GDI描画に比べて7〜8倍程遅い感じです。それでは、線幅を「3」にしてみます。

これまで同様、GDIの場合はやはり遅くなりますが、Direct2Dの場合はやや速くなる感じです。次に線幅を「1」に、線種を二点鎖線(psDashDotDot)にしてみます。遅いのでj:1000回繰り返しを10回繰り返しに、つまり、1/100にします。





1/100にしても Direct2Dでは10秒も掛かってしまっています。次に線幅を「3」にしてみます。繰り返し回数は1/100のままです。GDIでは線幅指定時の線種指定は無効化され実線描画となります。

これまで同様、Direct2Dでは、線・長方形・角の丸い長方形の描画同様、線種指定時は、線幅「1」よりも線幅「3」のほうが速いようです。
 
 
次に、塗り潰し楕円の描画 FillEllipseメソッドについて見てみます。このメソッドの引数は、DrawEllipseメソッド同様、1つのD2D1_ELLIPSE型の引数を持ち、これは、D2D_POINT_2F型のpoint値(これは更に Single型の X値・Y値)、Single型の radiusX・radiusY値を持ちます。ボタン1つ Button10 を追加し、それをクリックしたら塗り潰し楕円を描くテストを行ってみます。まずは簡単なテストから。
procedure TForm1.Button10Click(Sender: TObject);
var
 e : D2D1_ELLIPSE ;
begin
 if not(D2DCanvasFlag) then exit;
 with D2DCanvas do begin
  BeginDraw;
  RenderTarget.Clear (D2D1ColorF(clWhite));  // 背景:白色
  Pen.Color := clMaroon ;
  Pen.Style := psSolid ;
  Pen.Width := 1 ;
  Brush.Color := clYellow ;
  Brush.Style := bsSolid ;
  
  e.point.x := 100 ;
  e.point.y := 120 ;
  e.radiusX := 80 ;
  e.radiusY := 60 ;
  FillEllipse(e);
  
  EndDraw;
 end;
end;
保存・コンパイル(再構築)・実行を行います。以下のようになります。

こちらも FillRectangle・FillRoundedRectangleメソッドと同様、ペン(Pen)での輪郭線が描画されません。ペンとブラシの順番を入れ替えても同じ、ブラシを「Brush.Handle := CreateBrush(clBlue);」のように置き換えても同じです。ヘルプには
楕円は、Penの値を使って輪郭が描画され、Brushの値を使って塗りつぶされます。
と記載されていますが無効化されている感じです。
 
それでは上記同様、速度チェックをしてみます。
procedure TForm1.Button10Click(Sender: TObject);
var
 t : TDateTime ;
 mes : string ;
 i,j : integer ;
 e : D2D1_ELLIPSE ;
begin
 t := Now ;
 with PaintBox1.Canvas do begin
  Pen.Style := psSolid ;
  Pen.Width := 1 ;
  Brush.Style := bsSolid ;
  for j:=1 to 1000 do begin
   for i:=0 to 100 do begin
    Pen.Color := RGB(Random(256),Random(256),Random(256)) ;
    Brush.Color := RGB(Random(256),Random(256),Random(256)) ;
    Ellipse(i,i,200-i,200-i);
   end;
  end;
 end;
 mes := 'GDI:' + TimeToStr(Now - t) ;
 
 if not(D2DCanvasFlag) then exit;
 t := Now ;
 with D2DCanvas do begin
  BeginDraw;
  RenderTarget.Clear (D2D1ColorF(clWhite)); // 背景:白色
  Pen.Style := psSolid ;
  Pen.Width := 1 ;
  Brush.Style := bsSolid ;
  for j:=1 to 1000 do begin
   for i:=0 to 100 do begin
    Pen.Color := RGB(Random(256),Random(256),Random(256)) ;
    Brush.Color := RGB(Random(256),Random(256),Random(256)) ;
    Ellipse(i,i,200-i,200-i);
   end;
  end;
  EndDraw;
 end;
 mes := mes + ' BI:' + TimeToStr(Now - t) ;
 
 t := Now ;
 with D2DCanvas do begin
  BeginDraw;
  Pen.Style := psSolid ;
  Pen.Width := 1 ;
  for j:=1 to 1000 do begin
   for i:=0 to 100 do begin
    Pen.Color := RGB(Random(256),Random(256),Random(256)) ;
    Brush.Color := RGB(Random(256),Random(256),Random(256)) ;
    e.point.x := 100 ;
    e.point.y := 100 ;
    e.radiusX := 100-i ;
    e.radiusY := 100-i ;
    FillEllipse(e);
   end;
  end;
  EndDraw;
 end;
 mes := mes + ' Direct2D:' + TimeToStr(Now - t) ;
 
 StatusBar1.SimpleText := mes ;
end;
保存・コンパイル(再構築)・実行を行います。





 
次に、上記追加した箇所を CreateBrushを使うように変更してみます。速度比較はもういいので上の部分の繰り返し部を「2000」から「10」にしておきます。実行時間が勿体無いですので。
  ・・・
  Brush.Handle := CreateBrush(clAqua);
  e.point.x := 120 ;
  e.point.y := 150 ;
  e.radiusX := 100 ;
  e.radiusY := 80 ;
  FillEllipse(e);
  
  EndDraw;
 end;
 ・・・
のようにして実行しても正常に塗り潰しが描画されるのが分かります。

 
次に、半透明のブラシを作って描画してみます。ブラシの色はそのままとします。
  ・・・
  Brush.Handle := CreateBrush(clAqua);
  Brush.Handle.SetOpacity(0.5);
  e.point.x := 120 ;
  e.point.y := 150 ;
  e.radiusX := 100 ;
  e.radiusY := 80 ;
  FillEllipse(e);
  
  EndDraw;
 end;
 ・・・
というようにして実行してみます。すると・・・

となります。
 
次に、線形グラデーションのブラシを作成してみます。
  ・・・
  Brush.Handle := CreateBrush([clRed,clBlue]
           ,D2D1PointF(0,0), D2D1PointF(200,200));
  e.point.x := 120 ;
  e.point.y := 150 ;
  e.radiusX := 100 ;
  e.radiusY := 80 ;
  FillEllipse(e);
  ・・・
というようにして実行してみます。すると・・・

という具合になります。半透明にすると以下のような感じ。

 
次に円形グラデーションのブラシを作成してみます。
  ・・・
  Brush.Handle := CreateBrush([clAqua,clBlue]
       ,D2D1PointF(120,150),D2D1PointF(0,0),100,80);
  e.point.x := 120 ;
  e.point.y := 150 ;
  e.radiusX := 100 ;
  e.radiusY := 80 ;
  FillEllipse(e);
  ・・・
保存・コンパイル(再構築)・実行を行います。

という具合になります。半透明にすると以下のような感じ。

 
次に、前回作成した画像ファイル「brush1.bmp」を指定したブラシを作成してみます。
var
 ・・・
 bm : TBitmap ;
begin
  ・・・
  bm := TBitmap.Create ;
  bm.LoadFromFile(ExtractFilePath(Application.ExeName)+'brush1.bmp');
  Brush.Handle := CreateBrush(bm);
  bm.Free ;
  e.point.x := 120 ;
  e.point.y := 150 ;
  e.radiusX := 100 ;
  e.radiusY := 80 ;
  FillEllipse(e);
  ・・・
保存・コンパイル(再構築)・実行を行います。

という具合になります。半透明にすると以下のような感じ。

 
バッチファイル
BASIC
C言語のお勉強
拡張子な話
DOSプログラム
Delphi
>Delphi入門編
>Delphi2010
▲2010/12/12
 2010/12/13
▼2010/12/14
 
シェアウェア
Script!World
データベース
 
お問い合わせ
本サイトはリンクフリーです
リンクバナー
(C)Copyright 1999-2015. By AFsoft All Rights Reserved.