Introduction
This is a very simple 3D app, which is written in WPF. This is fully 3D application which also has zooming control on mouse wheel, and manual horizontal rotation on keyboard arrows.
The reason why I published this article is to show other people and developers the possibilities of the WPF framework!
Background
Possibilities of this app are unlimited. The only question is "Can your hardware take that?!"
Using the Code
This app is entirely straightforward. From the developers point of view, it has a few textboxes, buttons, one MediaElement
(for those who have not worked with WPF, MediaElement
is a control which can be used for media files playing), listview
... as I already said, pretty straightforward, but this app has a few exceptions in regard to normal desktop application. For those who have done work with 3D programming, most of this would be familiar.
I mentioned 3D programming because this app was made in that way. Here, I have ViewPort3D
control, Camera control, Lights control and 3D Model without which all of this wouldn't make any sense! Let's see how all of this looks like in XAML code (I show how this looks like in XAML because it's much easier to make a 3D scene from here):
<Grid>
<Viewport3D x:Name="view" ClipToBounds="False" RenderOptions.EdgeMode="Aliased">
-->
<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>
-->
<AxisAngleRotation3D x:Name="camRotation" Axis="0,1,0" Angle="0"/>
</RotateTransform3D.Rotation>
</RotateTransform3D>
</PerspectiveCamera.Transform>
</PerspectiveCamera>
</Viewport3D.Camera>
-->
<ModelVisual3D>
<ModelVisual3D.Content>
<AmbientLight Color="White" />
</ModelVisual3D.Content>
</ModelVisual3D>
</Grid>
This was a simple example of how you can make a 3D scene in WPF and XAML. Now when we have our 3D scene, we need to make a 3D model which needs to be rendered. Many of you now think, that can't be easy, but it is!
The only thing that you need for this is your brain and a little math, but also you can use some extern softwares to make more complicated 3D models. (3D Studio Max, Blender, Maya....)
Before I proceed, I want to say for those who can and want to make 3D Models, that Blender is a great tool for 3D animations, and can also export models directly to XAML, but also in *.x, and many others extensions. Also, what is most important is that it's FREE ;)
Blender can be downloaded from here.
Let's now look at how we can make one side of the cube and add something to it:
<!---->
<!---->
<Viewport2DVisual3D Material="{StaticResource CubeSideMaterial}">
<!---->
<Viewport2DVisual3D.Geometry>
<!---->
<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>
<!---->
<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>
Here we can see how 3D Mesh can be made. This is a very simple mesh and it has only four points, but it is also a good example. One important thing about TriangleIndices is that connection of points in one triangle must be in counterclockwise direction, and that triangles need to face each other like this:
Positions="0,1,0 0,0,0 1,0,0 1,1,0"
TriangleIndices="0 1 2 0 2 3"
But you can experiment with that and you will see what happens! ;)
One more thing that I will say is about the media player, and media seeking position. The reason why I mention this is because I had problems with setting this up before I found some article which helped me to solve this. To do media seeking, I put a slider control which is a normal thing :) But when you look at things a little closer and think that the slider will be updated on some time interval, and that on every update will be run slider ValueChanged_Event
, you can't make media seeking with slider ValueChanged_Event
and you don't make media glitches while playing!
But one interesting thing in WPF is that you can make Events for every part of the control, and that's where it was found that you can make an event handler for slider thumb dragging only (but one important thing is that you need to distinguish Drag and Drop Event Handlers from Thumb Dragging Event).
<Slider x:Name="PositionSlider" Thumb.DragCompleted="PositionSlider_DragCompleted"
Style="{DynamicResource SimpleSlider}" />
private void PositionSlider_DragCompleted
(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
{
mediaPlayer.Position = TimeSpan.FromMilliseconds(PositionSlider.Value);
}
That's all what I did think that is important. If you have additional questions, post a message!
Thanks, Crashandburn.
Points of Interest
I just want to add a few words here about how this is a great and useful thing... just think about how it would be if someone makes a 3D operating system, or how you can make big business applications in a single window?!!!
Running Tutorial
For those who only want to run this app, they will need .NET 3.0 Framework, which you can download here and, I think but I'm not sure - Windows Media Player 10 or later!
Executable is located in \bin\Debug directory, and the login information is:
- Username: crash
- Password: burn
History
- 20th October, 2009: Initial post