Welcome to MSDN Blogs Sign in | Join | Help
How to Draw WPF 3D Wireframe Graphics

 A question I periodically see on forums and discussions with WPF 3D graphics users is, "how do I draw wireframe" content for 3D. This isn't supported out of the box, but couple strategies I would suggest are:

 

  • The out of band 3DTools library from members of the WPF 3D team includes "ScreenSpaceLines" which allows for wireframe rendering of lines.

http://www.codeplex.com/3DTools

  •  Charles Petzold has also posted about wireframe rendering with his own implementation.

http://www.charlespetzold.com/blog/2007/08/310158.html

Visual Verification Testing Video

As some of you may know, the TestApi library includes Visual Verification technologies for testing.

If you are interested in the core patterns of this method of testing, check out this video!

 

WPF Test API

I am pleased to announce the the WPF team has embarked to componentize a library of common API's for use by Developers and Testers. This is a complement to the materials on the WPF Application Quality Guide and the materials available on the WPF Testing blog. I encourage you to check it out, and provide feedback or questions.


The Alpha Release covers:
TestApi v.0.1 provides the following APIs:

  • Visual Verification
  • Input Injection
  • UI Automation Helpers
  • WPF Dispatcher Helpers
  • Command-Line Parser


The ZIP package contains:

  • Binaries
  • Documentation (conceptual documents and API documentation)
  • Source Code
  • Samples
WPF Application Quality Guide online
Give it a look on WindowsClient.Net.
XAML 3D Tools & Tech

I periodically run into queries for  tools for modelling 3D content for use with XAML. Here are some notable resources to consider:

  1. Xaml Exporter for Blender
  2. Zam3D Modeller
  3. Maya to XAML converter
  4. Viewer 3DS 3DS to XAML Converter
  5. OBJ to XAML support in Expression Blend (Mini Cube Walkthrough)

In addition, there are a number of libraries for generating 3D primitive content such as planes, spheres, cubes, etc in circulation on various community sites. Creating a 3D content library is a good way to test your knowledge of 3D, but if re-inventing the wheel isn't your thing, Charles Petzold has scoped out some quality content in this space:

  1. MSDN 3D Text Tutorial
  2. Petzold.Media3D library complementing his WPF 3D book

I would recommend getting conversant with using both modelling tools and generating content via code. Some cursory considerations to ponder when considering how to represent 3D content:

  • Ease of Representation - If you want to represent a bunch of cubes/spheres with different textures in each case, you'd probably be crazy to try create and texture those separately in a modelling tool. Likewise, representing shapes from the naturual world, like animals, from primitive 3D shapes could quickly get to be painful.
  • Binary/Data file size - For instance, a high resolution sphere can be represented on disk much more cheaply with the algorithm, than the corresponding mesh.
  • Load time - Trade-off of disk time vs potentially non-trivial generating algorithms
  • Texturing - Which approach allows you to texture your content satisfactorily - Can you represent multiple material "layers" in an effective way, do you want to utilize techniques such as level of detail rendering, etc... Specialized 3D tools are targeted to the work of "skinnning" the texture coordinates complex models.
  • Flexibility - For instance, if you want to do techniques such as "Level of Detail" rendering, a generated content approach can provide you more flexibility than modelled content. Modellers/Artists *love* it when you ask them to turn their 300k poly masterpiece into 80 triangles. This usually translates to running mesh simplification tools on existing models, or just hack out some workflow tool to perform that work in batches, followed by some fine tuning at the end. In this context, generating the appropriate mesh complexity at run time is preferable to at design time.

I'm happy to hear from customers working on their WPF apps! Let me know if you have any questions, feedback or comments. Thanks!

Handy WPF 3D samples

An independent dev over in germany prepared some nice WPF 3D tutorials which I thought some folks might find interesting:

Viewport3D in XBAP

Rendering 3D Studio Models With WPF

Storyboard/Input based animation

All his WPF articles are posted at this location.

 

In addition theWPFBlog has shared a 3D carousel sample.

UIElement3D extensibility - 3D Video Carousel

Recently I've been working on a screencast, which goes over some advanced aspects of working with Element3D. In the meantime, this sample demonstrates WPF's Orcas Beta 2 UIElement 3D technology, covering the essentials for how you can make your own reusable UIElement3D controls for 3D. I have two in here:

  1. A "KeepCaseUIElement3D", a representation of a real world DVD case, with the added twist of playing video on the inside. It's API consumes Uri's for cover images and a media source, rather than traditional models, meshes, and materials in 3D .
  2. A "MovieCarousel" - a simple 3D carousel layout control which re-orients itself to position the object which was last clicked towards the user.

You will need to operate with the WPF V3.5(Orcas) Beta 2 Bits. You can get the Visual Studio Orcas Beta 2 installation with WPF from here.

A set of streaming WPF tutorial Videos

Concepts you can see in practice with this sample include:

  • Creating interactive 3D controls as interactive containers on non-interactive 3D models (Hint - Leverage existing 3D Xaml with little effort)
  • Creating a Custom Visual3D container type
  • Use of StaticResources from Application.Resources to separate mesh details from overall structure
  • Databinding a mesh texture to consume a local DP exposed as a URI, via a data binding type converter
  • 3D Layout - Cylinder Layout Helper class
  • Playing Video as a material on 3D

If you have any questions on the details of this sample, feel free to send me a message, or leave a relevant comment- odds are fair other folks have similar questions, which could make for interesting future blog postings!

 Thanks!

Details on the 3D Earth Rendering Sample

Yesterday I posted a some screenshots of a 3D earth sample involving a mix of materials to achieve interesting visual effects.

Attached is the sample application(Requires V3.5 to run), and the essential core source code, which can be placed in a new WPF project, in conjunction with a set of suitable textures. It is built to run on WPF V3.5 as it incorporates the new ContainerUIElement3D type, to allow for interactivity over the 3D content such as ModelVisual3D objects. This provides a good opportunity to get a practical understanding of WPF's Material types(described in detail on the post linked here).

This scene was built from a set of 5 images:

  • Cloud map image with alpha channel or a Cloud Opacity map applied onto the OpacityMask
  • Earth daytime map
  • Earth nighttime map
  • Earth Specular map

The Geometry as you may expect was composed of a pair of spheres centered on the same point. The inner sphere model is used for the earth's surface, and has:

  • A daytime map applied on a diffuse material. This image is set to full opacity, so no blending of objects behind it will occur, and it will be softly illuminated by external lighting.
  • The nighttime map is applied on an emissive material. This material has an additive effect where it is rendered, with lighting having no impact(emissive materials render at full intensity). To cut the lighting out of the daytime surface, a moving OpacityMask can be applied.
  • A map of the earth's watery, reflective surfaces applied using a specular material. Specular materials, like emissive materials have an additive rendering effect, providing bright highlights on the ocean surfaces, while having no contribution over land.

The Cloud Model uses the same geometry as the earth, with a minor scale transform applied to make the clouds slightly extend beyond the radius of the earth. The clouds are rendered as a Diffuse Material, with the clouds applied. When used with the opacity mask, this produces a mixed effect of fully obscured cloud regions and fully transparent areas. This effect could be carried further with a series of low opacity, blueish diffuse materials to represent the Earth's atmosphere.

Finally, I placed these two models within a ContainerUIElement3D, applied an animated Rotation Transform to represent the Earth's daily spin. You may have heard - with UIElement behavior on 3D, we can now easily develop 3D UI behaviors, without worrying about hit testing and eventing plumbing. Here, I connected mouse event handlers from XAML and prepared corresponding 3D behavior in response to the events.

Combined materials for Interesting 3D Planet renderings in WPF

I have been doing experiments with the materials we provide with WPF to render an interesting facsimile of the surface of the earth. Using a collection from http://planetpixelemporium.com/earth.html, I was able to achieve some nice visual effects:

Demo and source is available at this post.

WPF V3.5 Beta 2 - Goodies in 3D-land!

Kurt recently put out an overview on the V3.5 interactive 3D feature additions (UIElement3D types and Viewport2DVisual3D) which are available in the new WPF V3.5 Beta 2. Give it a look!

WPF input Interop over DirectX Airspace

I've seen that the Airspace regions constraints have been a concern for some folks interested in using DirectX with their WPF applications. Based on this, here is a follow-up to an earlier sample I posted, this time using Layered windows to intercept input, allowing for the provision of rich WPF context menus, tooltips, and traditional mouse actions over the airspace of an interop region. It is pretty much the same as before, with one major change - the introduction of an "AirspaceOverlay" decorator.

 This decorator wraps around your interop content, and accepts an "OverlayChild" which is presented in a layered window over the content in the AirspaceOverlay control. In the example below, I used a canvas with a tooltip and some code-behind to also demonstrate a context menu. Here's a code snippet of the usage:

<MDXControl:AirspaceOverlay>

    <MDXControl:AirspaceOverlay.OverlayChild>

        <Canvas ToolTip = "A tooltip over a DirectX surface" Background="#01000000" Name="Overlay" />

    </MDXControl:AirspaceOverlay.OverlayChild>

    <!--Your Non-WPF Airspace Interop content goes here-->  

</MDXControl:AirspaceOverlay>

Known considerations:

  • Embedding of AirspaceOverlay in a Viewbox - due to region sizing issues, overlay placeent does not work correctly.
  • Hit testing within the transparent window will not occur on fully transparent regions, but will continue to propagate down to the interop surface. On the flip side, partially opaque regions will intercept input, preventing it from being recieved on the interop layer. This input handling behavior can be tweaked from the Win32 API's.
  • Focus will by default switch between the parent and layered child window. I return focus on mouse behavior to the parent in this implementation.
  • This sample is targeted to rectangular regions. By applying a custom shape consistent with the region below, irregular airspace regions can be overlaid with little additional effort.

I hope this helps some food for thought for folks looking at similar interop scenarios. Ok, have fun with the code, and feel free to send in questions.

WPF 3D Transparency Depth-Order Sorting

Just a quick post here - When making WPF 3D apps, transparency can make for some powerful visual effects. The trouble is that any re-orientation of your scene or the camera will ruin the rendering order of your transparent content to obscure content which should be visible under a transparent surface. Below, we have a little carousel of partially transparent photos rendered on DiffuseMaterials. As per the rendering rules with DiffuseMaterials, only content which is closer to the camera will be rendered. The area highlighted in red is being rendered prematurely, which obscures the background content from being rendered at all.

Unsorted Scene

To get over this issue with transparency, we must re-order the sequence of transparent content rendering, such that we progressively go from content most distant to the camera, to content in closest proximity.

To deal with this, I created a simple helper to handle sorting of models to sort in order of distance to camera. Below, we have the helper method interface - it takes the camera position, a collection of models and a World transform to offset the models by(This would be all of the accumulated parent transforms, except for the transforms on the Models themselves), and sorts this collection of Models in order of distance to the camera. Here's the API from the attached Code, followed by a carousel of depth sorted images:

public static void AlphaSort(Point3D CameraPosition, Model3DCollection Models, Transform3D WorldTransform)

Some performance considerations with Depth-Order Sorting favoring transparency:

  1. Limit the scope of models to be sorted to as small a set as possible. Two reasons exist for this. The first is that additional models will require a linearithmic growth of sort time - the CLR Array.Sort algorithm employed with the attached solution operates with an average complexity of O(n log n) and a worst case of O(n^2). The second issue is about GPU fill rate - by sorting in favour of distant objects, we are maximizing the number pixels to render to screen(We get no hardware culling benefits, because everything is in front of what we have rendered so far). On the flip side, if you have a  complex scene with lots of opaque, overlapping content, sorting in favour of objects closest to the camera could potentially get you an improved framerate, if sorting is infrequent.
  2. Frequency of sorting - With any kind of scene, the supplied sorting operation is not a cheap call to use for real time rendering. As such, I would caution against using this algorithm via CompositionTarget.Rendering. Instead, you may want to give some thought about an invalidation threshold based sorting mechanism. With a 3D arrangement like a carousel, you can work out a safe "interval" of change, within which the content can move, without requiring a re-sort.

This sample is just intended as a quick starting point for folks who want to get some depth sorting on their transparent content. It is not tailored to target 3D tree-walking, and most folks can find optimizations for sorting based on domain specific assumptions about their application in terms of graph representation, caching, and all the other common tricks at an application developer's disposal.

Resources for getting into WPF 3D

Periodically, I need to refer folks to good resources for ramping up on WPF 3D functionality. Here are the ones I commonly refer to:

Mike Hodnick has a great, succinct WPF 3D tutorial, which is an excellent resource to get up and running with the technology. If there is any one tutorial to try- I would say go there.

Charles Petzold has helped countless Windows UI developers ramp up on the technologies - his 3D book blog has a lot of good insights for developers, without making heavy assumptions about a reader's 3D theory knowledge as other resources sometimes do. He has a lot of interesting nuggets on his 3D book blog, often demonstrating the power of XAML, as well as a 3D samples page. As he is a frequent contributor to MSDN magazine, I periodically encounter his articles introducing users to technology like the MeshGeometry3D type which can be quite helpful.

The 3D Team blog and Daniel Lehenbauer's blog are more topical resources, with references to a lot of cool new applications, or addressing common questions.

The 3D tools package isn't a tutorial per-se, but a library of goodies for use with WPF, by the 3D team. Any serious WPF 3D developer should be aware of the cool offerings in this package.

Depending on your application domain, you may want to see this "casual" game developer's tutorial for WPF3D - "Creating 3D Webgames using ATMO NQAL 2.0". The tilt on this series of tutorials is quite distinctive, and delves into quite a bit of application details. Definitely different from your typical WPF/3D tutorial :)

Books:

WPF Unleashed - Adam Nathan brought in Daniel Lehenbauer (3D dev team lead for V1 WPF) to prepare the 3D chapter in this title. An excellent ramp up to 3D.

3D Programming for Windows - Charles Petzold's new book on WPF 3D is now available. I haven't had a chance to get my hands on this one yet, but based on his blog and prior writings, you can expect a detailed coverage of the subject.

WPF - Designing Canvas based 2D Controls

I have been playing with Expression Design a little bit, and am quite excited about the designability options it allows. It's really sweet how quickly one can create vector content in it, which can be turned into interactive controls, with shared code-based behaviors attached to each shape. One process I have been exploring is the ideal way to modify my content as I go along, as I tweak graphics in iterations.

My favourite approach thus far is to export Designer content as a ResourceDictionary, which can be loaded(or potentially reload without compilation) on the fly, without having to make any changes to the xaml exported by Expression. This means you can painlessly tune 2D designs, export them and they just load up, without any supporting code changes needed once the pipeline is in place. 

 

Here's how I go at it:

1.   Create shapes, and give each shape object a distinctive name. Sorry about the lame programmer art.

Expression Designer with Objects

2.   Export XAML to Resource Dictionary Form. Group by Objects, Path output type as drawing brush.

3.   Reference the Resource Dictionary, and populate each each object into your control by iterating through the dictionary. For flexible, custom layout, I prefer to extract the geometries for use as Paths in a Canvas, and prepare a User control out of that. You may prefer to recieve your content in a more general form, ie - directly as a drawingbrush. Below is the sample app using the canvas with the loaded dictionary content, along with textboxes overlayed with the object names, and mouseover-driven bitmap effects. The source code for use in a standard WPF project is attached.

4.   For extra credit, we apply that canvas onto an interactive 3D surface as per the Codeplex WPF 3D Tools bits. And here, life gets interesting, as we can have interactive 2D content on a 3D surface, which we can change on the fly in Expression Designer!

 

Essential Details from attached code:

//Load the Resource from your exported xaml - Your uri path will differ
Resources.Source = new Uri("pack://application:,,,/CanvasControl;component/ResourceSet.xaml");

...
        //Here I produce a canvas generated from our exported resource
        private Canvas MakeCanvas()
        {
            Canvas c=new Canvas();
            //You can extract the bounds of the individual elements, or operate with a fixed size here
            c.Width = 443;
            c.Height = 355;
            foreach (DictionaryEntry de in Resources)
            {
                DrawingBrush db = (de.Value as DrawingBrush);
                if (db != null)
                {
                    DrawingGroup dg = (db.Drawing as DrawingGroup);
                    if (dg != null)
                    {
                        GeometryDrawing gd = (dg.Children[0] as GeometryDrawing);
                        if (gd != null)
                        {
                            Path path = new Path();
                            path.Name = (string)de.Key;

                            //Directly assign the pertinent properties of interest
                            path.Data = gd.Geometry;
                            path.Stroke = gd.Pen.Brush;
                            path.StrokeThickness = gd.Pen.Thickness;
                            path.Fill = gd.Brush;

                            
                            c.Children.Add(path);
                        }
                    }
                }
            }
            return c;
        }

Premiere Post! WPF w/ Direct3D Shader Interop and simple databinding

Based on some questions I’ve seen on the forums, with regards to WPF on the issue of Shader use and technologies, I have decided to prepare a sample which illustrates one approach by which DirectX content can be embedded in a WPF app. In particular, I render a single Managed DirectX surface containing a simple mesh rendered with shaders,  in a control embedded in a WPF app, and databound to a set of sliders to manipulate a color shift implemented via a pixel shader. This form can be helpful for teams that want to incorporate WPF as the overall UI technology(in place of GDI, MFC, winforms, etc) of their 3D heavy applications, for which a fair bit of DirectX code is often present.

In this example, I used Managed DirectX API for primary language consistency in this sample, but the HwndHost technology for interop can similarly be used to embed unmanaged DX 9/10. For this overview, I assume an working knowledge of Direct3D, in conjunction with some familiarity with WPF.

Screenshot.jpg 

1-The application references a custom control containing the Manged DX Device in the XAML layout(For non XAML junkies, keep in mind, this can just as easily be done in code):

Custom Namespaces:
  xmlns:local=clr-namespace:WPF_MDX_Interop_App
  xmlns:MDXControl=clr-namespace:WpfNuggets.ManagedDirectX;assembly=WpfNuggets.ManagedDirectX

… 

< MDXControl:ManagedDirectXControl>
  <
MDXControl:ManagedDirectXControl.RenderContent >
    <
local:AdjustableShader x:Name=AdjustableShader TextureFilename=Content\gradient1.bmp/>
  
MDXControl:ManagedDirectXControl.RenderContent>
MDXControl:ManagedDirectXControl>

2-Here’s the code for the custom control - this is a WindowsFormsHost which allows us to contain Winforms content in WPF. The Xaml visible RenderContent field is used here for encapsulating the rendering behavior we want to execute in DirectX:

public class ManagedDirectXControl : WindowsFormsHost
{
  public ManagedDirectXControl()
  {
    Child =
new ManagedDirectXDeviceWrapper();
  }
  public Renderable RenderContent
  {
   
get { return ((ManagedDirectXDeviceWrapper)Child).RenderContent; }
    set { ((ManagedDirectXDeviceWrapper)Child).RenderContent = value; }
  }
}

3-The ManagedDirectXDeviceWrapper code which is contained in the project attached below, is pretty routine DirectX code for initialization and a rendering loop tied to repaint events on the container control. There are many fine tutorials on that subject, so I won't reinvent that wheel of guidance. The wrapper will check for HW PS & VS shaders V1.1, and will silently fall back to software mode. If you would like active notification of the fallback, look at the “_alreadyNagged” field in that class. This class contains hooks which depend on the user supplied Renderable object.

4-Finally, the implementation of “ShaderRender” supplies a generic Quad mesh which gets textured and processed by user supplied shaders. The derived class “AdjustableShader” pre-defines a reference to a particular shader file, and exposes R,G,B properties for data binding use as targets, which provide parameters which are passed on to the pixel shader. Again, the mechanics of this is familiar territory in the DirectX world, so I'm not delving into that aspect here. You can get the VS Solution with projects for the Managed DX wrapper project, and a WPF sample app containing simple data binding to drive the pixel shader inputs for shifting the texture color. That code is available from here.

To work on the project you will need the following installed(Combined pre-req's for DX and WPF):

  1. Visual Studio 2005 
  2. DirectX SDK
  3. WPF Runtime or be running on Vista
  4. Orcas CTP for Visual Studio 2005(to support WPF VS project)

I would be glad to hear any questions, suggestions or other feedback...

Page view tracker