使用 WPF 创建 3D 应用程序






3.83/5 (8投票s)
WPF_3D_Application

引言
这是一个非常简单的 3D 应用程序,用 WPF 编写。这是一个完全的 3D 应用程序,它还具有鼠标滚轮缩放控制,以及键盘箭头的手动水平旋转功能。
我发布这篇文章的原因是为了向其他人和其他开发者展示 WPF 框架的可能性!
背景
此应用程序的可能性是无限的。唯一的问题是“您的硬件能承受吗?!”
Using the Code
这个应用程序完全是直接的。从开发者的角度来看,它包含几个文本框、按钮、一个 MediaElement
(对于那些没有使用过 WPF 的人来说,MediaElement
是一个可以用来播放媒体文件的控件)、listview
...正如我已经说过的,非常直接,但这个应用程序在正常桌面应用程序方面有一些例外。对于那些做过 3D 编程的人来说,其中大部分会很熟悉。
我提到 3D 编程是因为这个应用程序就是这样制作的。在这里,我有 ViewPort3D
控件、相机控件、灯光控件和 3D 模型,没有它们一切都将毫无意义!让我们看看这一切在 XAML 代码中是什么样的(我展示它在 XAML 中的样子是因为从这里创建一个 3D 场景要容易得多)。
<Grid>
<Viewport3D x:Name="view" ClipToBounds="False" RenderOptions.EdgeMode="Aliased">
<!--3D Scene-->
<Viewport3D.Camera>
<PerspectiveCamera x:Name="camera" FieldOfView="59"
Position="0.5,0.5,2" LookDirection="0,0,-1">
<PerspectiveCamera.Transform>
<RotateTransform3D x:Name="rot" CenterY="0.5" CenterX="0.5" CenterZ="-0.5">
<RotateTransform3D.Rotation>
<!-- rotation -->
<AxisAngleRotation3D x:Name="camRotation" Axis="0,1,0" Angle="0"/>
</RotateTransform3D.Rotation>
</RotateTransform3D>
</PerspectiveCamera.Transform>
</PerspectiveCamera>
</Viewport3D.Camera>
<!--Light-->
<ModelVisual3D>
<ModelVisual3D.Content>
<AmbientLight Color="White" />
</ModelVisual3D.Content>
</ModelVisual3D>
</Grid>
这是在 WPF 和 XAML 中创建 3D 场景的简单示例。现在我们有了 3D 场景,我们需要创建一个需要渲染的 3D 模型。你们中的许多人现在可能会想,这肯定不简单,但事实并非如此!
您需要的唯一东西就是您的大脑和一点数学知识,但您也可以使用一些外部软件来创建更复杂的 3D 模型。(3D Studio Max、Blender、Maya....)
在我继续之前,我想对那些能够并且想要制作 3D 模型的人说,Blender 是一个很棒的 3D 动画工具,它还可以直接导出模型到 XAML,也可以导出为 *.x 和许多其他格式。另外,最重要的是它是免费的;)
可以从 这里 下载 Blender。
现在让我们看看如何制作立方体的一个面并向其中添加一些内容。
<!-- cube front side -->
<!--
This is element which get controls and put them in 3D
(make all scaling and transforming cordinates for you that looks like it is in 3D)
-->
<Viewport2DVisual3D Material="{StaticResource CubeSideMaterial}">
<!--this is part where all drawing are done for this part-->
<Viewport2DVisual3D.Geometry>
<!--
meshgeometry3d give you possibility to put bunch of points
and to locate them in 3D and to connect them in what way
you like (for connecting points we use
TriangleIndices-because all 3d graphic rendering are done with triangles)
-->
<MeshGeometry3D Positions="0,1,0 0,0,0 1,0,0 1,1,0"
TextureCoordinates="0,0 0,1 1,1 1,0"
TriangleIndices="0 1 2 0 2 3"/>
</Viewport2DVisual3D.Geometry>
<!--
when we are finished our drawing we can put everything what we want in our
Viewport2DVisual3D control,and it will be rendered like normal desktop app
-->
<Grid x:Name="FrontPanel" Background="
{StaticResource BlackBackground}" ShowGridLines="False"
IsHitTestVisible="True" Margin="0">
<Grid.BitmapEffect>
<OuterGlowBitmapEffect GlowSize="2" />
</Grid.BitmapEffect>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="15"/>
<RowDefinition Height="15" MaxHeight="15" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Style="{DynamicResource SimpleButton}"
Grid.Row="3" Grid.Column="0"
Grid.ColumnSpan="2" Content="Ok"
Foreground="White" Click="Button_Click"
FlowDirection="LeftToRight" FontSize="3"
VerticalContentAlignment="Top"
Width="40"
Height="5"
Margin="0,2,0,2"
/>
<TextBox Grid.Row="1" Grid.Column="1"
Height="5" Width="45" Margin="1,1,2,1"
x:Name="textBox1" BorderThickness="0"
ClipToBounds="False" FontSize="3.5"
Padding="0,0.3,0,0"/>
<PasswordBox Grid.Row="2" Grid.Column="1"
Height="5" Width="45"
Margin="1,-9.5,2,1" x:Name="passwordBox1"
VerticalAlignment="Center" BorderThickness="0"
Padding="0,0.3,0,0" FontSize="3.5" />
<Label Grid.Row="1" Grid.Column="0"
x:Name="label1" Foreground="White"
FontSize="4" HorizontalAlignment="Left"
MinWidth="0" Padding="3,5,3,3"
Content="Username:"/>
<Label Grid.Row="2" Grid.Column="0"
FontSize="4" Foreground="White"
x:Name="label2" Margin="0,-3,0,0"
Padding="3" Content="Password:"/>
<Label FontSize="5" Foreground="White"
Grid.Row="0" Grid.Column="0"
Grid.ColumnSpan="2" x:Name="label3"
FontStyle="Oblique" FontWeight="Bold" Content="LogIn"/>
</Grid>
</Viewport2DVisual3D>
在这里我们可以看到如何制作 3D Mesh。这是一个非常简单的网格,只有四个点,但它也是一个很好的例子。关于 TriangleIndices 的一个重要事情是,一个三角形中的点连接必须是逆时针方向,并且三角形需要相互面向,像这样。
Positions="0,1,0 0,0,0 1,0,0 1,1,0"
TriangleIndices="0 1 2 0 2 3"
但是您可以尝试一下,您就会看到会发生什么!;)
我还将谈论媒体播放器和媒体搜寻位置。我提到这一点的原因是我在设置这个时遇到了一些问题,直到我找到了一篇帮助我解决这个问题的文章。为了进行媒体搜寻,我放了一个滑块控件,这很正常 :) 但是当您仔细观察并认为滑块会在某个时间间隔更新,并且每次更新都会运行滑块的 ValueChanged_Event
时,您就不能通过滑块的 ValueChanged_Event
来实现媒体搜寻,也不会在播放时出现媒体故障!
但 WPF 中一个有趣的事情是,您可以为控件的每个部分创建事件,正是在那里,您会发现您可以仅为滑块的拖动创建事件处理程序(但有一件重要的事情是,您需要区分拖放事件处理程序和滑块拖动事件)。
//slider control and thumb drag event
<Slider x:Name="PositionSlider" Thumb.DragCompleted="PositionSlider_DragCompleted"
Style="{DynamicResource SimpleSlider}" />
//and this is code behind
private void PositionSlider_DragCompleted
(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
{
mediaPlayer.Position = TimeSpan.FromMilliseconds(PositionSlider.Value);
}
这就是我认为重要的全部内容。如果您有其他问题,请留言!
谢谢,Crashandburn。
关注点
我只想在这里补充几句,说明这是一个多么棒且有用的东西……想想看,如果有人制作了一个 3D 操作系统,或者您如何在单个窗口中创建大型业务应用程序?!!
运行教程
对于那些只想运行此应用程序的人,他们将需要 .NET 3.0 Framework,您可以 在这里 下载,而且,我认为但不确定 - Windows Media Player 10 或更高版本!
可执行文件位于 \bin\Debug 目录中,登录信息是
- 用户名:crash
- 密码:burn
历史
- 2009年10月20日:首次发布