FMXフレームワークで3Dメッシュ(TMesh)を表示する ~Delphiでお手軽プログラミング
Delphiを起動して新規作成を行い、必要なコンポーネントをドラッグ&ドロップする
Delphi起動⇒ファイル⇒新規作成⇒マルチデバイスアプリケーションを選択し、「空のアプリケーション」を選択してOKボタンをクリックします。TTimer、TViewPort3D、TColorMaterialSource、TLightMaterialSourceをフォームへドラッグ&ドロップします。
ViewPort3D1にTLightをドラッグ&ドロップし、Light1の方向を適当に左下へ向けます。
ViewPort3D1にTMeshをドラッグ&ドロップします。
Timer1のプロパティ[Interval]を33にします。

ソースコードを記述する
Form1のイベントonCreateイベントに以下のソースコードを記述し、 Form1のメンバにphase変数を追加、DrawWireプロシージャを追加してソースコードを記述します。省略・・・・ type TForm1 = class(TForm) Timer1: TTimer; Viewport3D1: TViewport3D; ColorMaterialSource1: TColorMaterialSource; LightMaterialSource1: TLightMaterialSource; Light1: TLight; Mesh1: TMesh; procedure FormCreate(Sender: TObject); private { private 宣言 } public { public 宣言 } phase:single; //位相 procedure DrawWire(Sender: TObject; Context: TContext3D); end; var Form1: TForm1; implementation {$R *.fmx} procedure TForm1.DrawWire(Sender: TObject; Context: TContext3D); begin Context.DrawLines( TMesh(Sender).Data.VertexBuffer, TMesh(Sender).Data.IndexBuffer, ColorMaterialSource1.Material, 1 ); end; procedure TForm1.FormCreate(Sender: TObject); begin phase:=0; end;
Timer1ダブルクリックして以下のソースコードを記述します。
procedure TForm1.Timer1Timer(Sender: TObject); var xp,zp:integer; x,z:integer; y:single; idx:integer; begin xp:=20; //x方向のメッシュの数+1 zp:=15; //z方向のメッシュの数+1 Mesh1.MaterialSource:=LightMaterialSource1; //Mesh1.TwoSide:=true; Mesh1.Position.X:=0; Mesh1.Position.Y:=2; Mesh1.Position.Z:=0; Mesh1.Data.VertexBuffer.Length := xp*zp; Mesh1.Data.IndexBuffer.Length := (xp-1)*(zp-1)*3*2; //頂点バッファの作成 for x := 0 to xp-1 do begin for z := 0 to zp-1 do begin //y座標(高さ)を適当にCos*Sinにする y:=Cos(x/xp*pi()*4+phase)*Sin(z/zp*pi()*4+phase)*2; //頂点バッファに値を設定 Mesh1.Data.VertexBuffer.Vertices[x+z*xp]:= Point3D(x-xp/2, y, z-zp/2); end; end; //メッシュの作成 idx:=0; for x := 0 to xp-2 do begin for z := 0 to zp-2 do begin //3角形ポリゴン作成 左回り Mesh1.Data.IndexBuffer.Indices[idx]:=x+0+(z+0)*xp; inc(idx); Mesh1.Data.IndexBuffer.Indices[idx]:=x+0+(z+1)*xp; inc(idx); Mesh1.Data.IndexBuffer.Indices[idx]:=x+1+(z+0)*xp; inc(idx); //3角形ポリゴン作成 左回り Mesh1.Data.IndexBuffer.Indices[idx]:=x+1+(z+0)*xp; inc(idx); Mesh1.Data.IndexBuffer.Indices[idx]:=x+0+(z+1)*xp; inc(idx); Mesh1.Data.IndexBuffer.Indices[idx]:=x+1+(z+1)*xp; inc(idx); end; end; //法線ベクトルの自動計算 Mesh1.Data.CalcFaceNormals(); //稜線(ワイヤーフレーム)の描画が必要であれば以下の行のコメントを外す //Mesh1.OnRender:=DrawWire; //位相を変える phase:=phase+0.1; //再描画 Viewport3D1.Repaint; end;
実行する
実行ボタンを押して実行します。(デバッグ実行でもOKです。)実行する
実行中画面