2009年8月3日 星期一

WPF功能 - 3D 繪圖

3D繪圖是WPF的特色之一, 利用WPF提供的3D功能, 你可以在應用程式中製做出很棒3D特效.
下面會先介紹WPF 3D繪圖的基本概念, 並且以3D Cube的範例作為說明.


1. 座標系統
圖1 顯示WPF使用的2D和3D座標系, WPF的3D座標系和Direct3D一樣, 是採用右手座標系(OpenGL是使用左手座標系)

[圖 1] 2D和3D座標系統


2. 3D畫布
你可以使用Viewport3D(
投影3D場景的平面)來當作一個3D畫布, 類似2D中Window或Grid.


<Viewport3D>
Children
</Viewport3D>



3. 相機 - Camera
你必須在3D場景中指定相機的位置方向和視野, WPF 提供兩種攝影機, 如下:

a. OrthographicCamera - 垂直投射的攝影機, 它不會因為攝影機的距離而改變尺寸, 適合CAD或2D繪圖

b. PerspectiveCamera - 透視投射的攝影機, 離攝影機越遠的物體, 看起來會縮小和變短, 類似真實世界所看到的影像


另外Camera中還一些參數可設定:
  • Position(攝影機的座標 )
  • LookDirection(攝影機拍攝的方向 )
  • UpDirection(攝影機的法向量 )
  • FiledOfView(攝影機的拍攝角度 , PerspectiveCamera才可以設定)
  • Width(觀景的寬度, OrthographicCamera 才可以設定)
攝影機在XAML的寫法如下所示:


<Viewport3D.Camera>
<PerspectiveCamera x:Name="camera"
Position="0,0,5"
LookDirection="0,0,-10"
UpDirection="0,1,0"
FieldOfView="45" />
</Viewport3D.Camera>


1. 3D模型
- ModelVisual3D

a. Light

如果在3D場景中沒有打光的話, 畫面會是一片黑暗.

WPF提供下面幾種光源, 供使用者使用:

  • AmbientLight(周遭光源, 光線來自四處)
  • DirectionalLight(方向光源, 類似太陽光)
  • PointLight(點光源, 類似燈泡或蠟燭)
  • SpotLight(聚光燈)
下面程式碼(XAML)顯示燈光的使用:

<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight x:Name="light" Direction="-1,-1,-1" Color="White"/>
</ModelVisual3D.Content>
</ModelVisual3D>


b. MeshGeometry3D
WPF是利用
三角形建立來3D模型, 其相關的參數如下:

  • Position(三角形的頂點)
  • TriangleIndices(指定頂點的連接順序)
  • Normals(三角形面的法向量, 可指定正面和反面)
  • TextureCoordinates(指定貼圖座標)
下面的程式碼顯示如何產生一個矩形的平面:


<MeshGeometry3D
Positions="-1 -1 0 1 -1 0 -1 1 0 1 1 0"
Normals="0 0 1 0 0 1 0 0 1 0 0 1"
TextureCoordinates="0 1 1 1 0 0 1 0"
TriangleIndices="0 1 2 1 3 2" />
</GeometryModel3D.Geometry>


c. Material
我們可以為3D模型加上材質, WPF提供下面這些材質來作設定.
  • DiffuseMaterial
  • SpecularMaterial
  • EmissiveMaterial
下列程式碼式碼(XAML)顯示顯示如何使用材質:


<GeometryModel3D.Material>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<SolidColorBrush Color="Cyan">
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>


看完上面介紹後, 我們就用XAML寫一個3D Cube. 程式碼如下所示:

<Window x:Class="WPF3DCube.Window1"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="Window1" Height="407" Width="342">

<Grid>

<Viewport3D Name="viewport3D1">



<!--Setup Camera-->

<Viewport3D.Camera>

<PerspectiveCamera

x:Name="camera"

Position="6 5 4"

LookDirection="-6 -5 -4"

FieldOfView="30">

</PerspectiveCamera>

</Viewport3D.Camera>



<!--Setup Light-->

<ModelVisual3D>

<ModelVisual3D.Content>

<DirectionalLight x:Name="light"

Direction="-1,-1,-1"

Color="White"/>

</ModelVisual3D.Content>          

</ModelVisual3D>



<ModelVisual3D>

<ModelVisual3D.Content>                  

<GeometryModel3D>


<!--Build 3D Cube-->

<GeometryModel3D.Geometry>

<MeshGeometry3D x:Name="cube"

Positions="0 0 0  1 0 0
0 1 0  1 1 0
0 0 1  1 0 1
0 1 1  1 1 1"

TriangleIndices="2 3 1  2 1 0  7 1 3
7 5 1  6 5 7  6 4 5
6 2 0  2 0 4  2 7 3
2 6 7  0 1 5  0 5 4">

</MeshGeometry3D>                          

</GeometryModel3D.Geometry>                    



<!--Setup Material-->

<GeometryModel3D.Material>                         

<DiffuseMaterial x:Name="matDiffuseMain">

<DiffuseMaterial.Brush>

<SolidColorBrush Color="Bisque"/>

<DiffuseMaterial.Brush>

</DiffuseMaterial>

</GeometryModel3D.Material>



</GeometryModel3D>

</ModelVisual3D.Content>

</ModelVisual3D>

</Viewport3D>

</Grid>
</Window>


其結果如下所示:


[圖 2] 3D Cube

參考文章 :
MSDN - WPF 3D Graphics
CodeProject :
WPF 3D Primer

沒有留言:

張貼留言