I have uploaded the demo project in 2 parts. (Sorry OGRE is quite large and I couldn't upload 1 file.)
Extract both of the zip files into the same place before running the demo.
e.g. in winzip click "extract" -> "c:\temp" (same process for both)
Your directory structure should look like this once completed doing so:
..\OgreInWpf\Media (MUST EXIST)
..\OgreInWpf\Release (goto this folder to run the demos)
With This You Can... the 10 second overview
- Blend a First Class Gaming Graphics Engine into a First Class Presentation System.
- Spill your coffee over your keyboard as you see just how cool your UI look and feel can be.
- Visual Studio 2008
- .Net framework 3.5 (Service Pack 1)
- A reasonable graphics card. This project might not run on all computers. I have only tested it on NVidia cards.
Viewport3D control in the WPF is pretty useful, but it lacks the cool tweakiness of a proper graphics engine, e.g:
- performance critical features like scene paging and "level of detail" meshes allowing large meshes to be displayed using different configurations; a hi-polygon version when near to the camera for when high definition is important, and with a low-polygon version when far away from the camera.
- GPU (Graphics Processor) scripts for DirectX Pixel Shaders to achieve scene blurring, or to simulate night vision goggles. Now, I'm not talking about the GPU code itself, because the new 3.5 SP1 framework has got GPU Bitmap effects, I'm talking about making it easy and maintainable to apply these kinky features by having a scripting resource mechanism so you don't even have to write a line of code to include fancy first rate materials features in your scene. (Well one line This allows you to change the object's materials easily and without any re-compiling. No mess, no fuss.
- Proper package resource management for your textures, scripts, GPU Shaders, animations etc.
- Plenty of other stuff which you'll need, even before you get to the physics, sound, AI and actual gaming side...
As you can see there really is a lot of technology that goes into a modern game and animation effects. Now, graphics aside what about all this behaving itself on your desktop, reading office documents, allowing a user to work in an interface that's funky, themable, supports data binding, web services, swanky smoke effects, etc...
Missing the good old days of Pac-man and DOS ?. It all seemed so much simpler back then. I know I sometimes do.... um, miss DOS, not seem simple. Though I know people that might argue that point.
Not convinced...ok, ok, say your boss comes to you and says, "Frank", cause that's your name...you know, or Bob.
"Frank" he says, "we need to write an application for the 'Smokey Cheese Company', that has, ok, get this, a swift little smoke effect on the main screen, see, bellowing smoke into the air -", (I can do this you say to yourself, you know, graphics isn't too hard) ...", the boss continues, " - over their scrolling logo and displays a list of stuff from a web service where the user can click - "
Ok now it's getting a bit harder all of a sudden because graphics engines don't have very good UI controls (the boss still hasn't stopped talking by the way)
- "..blah blah, by Friday!", the boss finishes.
Unfortunately Bob is out for tea.
The Fluffy Bunny Of Doom syndrome.
Each a do-able task in their own right?. Integration people, that's what I'm talking about.
Enter Stage (left): The OgreImage Class
Sweet particle effects
Realtime TV compositor effect
OgreImage class is just like any of the other WPF
ImageSource classes. An image source can be used as a brush for a background, for text, or displayed in an
Image control and the
OgreImage is no different, except that it has all the functionality of a First Class Graphics Engine. It has been based on the new
D3DImage (system.windows.interop.d3dimage.aspx) class which is part of the Framework 3.5 SP 1 update.
I have, in the simplest way implemented the process of hosting the OGRE engine in the DirectX context of the
D3DImage class. That is to say, you will still need to interact with the OGRE library via the MOGRE library as any other .NET OGRE application, but won't have to deal with screen re-sizing and DirectX device loss/management issues. One thing I have implemented is asynchronous loading of the OGRE resources and have included a progress event system to allow for the a progress indicator implementation (see example). I've done this because OGRE Engine can take a while to start-up.
There is currently no implementation of a control similar to the
Viewport3D, but I'm hoping to expand on this project and to xaml-fy it more to allow for the entire scene to be constructed in xaml.
How To Use It
Exactly like you might have displayed a bitmap in the
Image control you could do the following:
This would include the
OgreImage class in your page displayed via the
Image control. The events of interest are:
ResourceLoadItemProgress event which is called for every resource loaded. Here you can get the name of the resource and a scalar (0 -> 1) indicating the progress of the entire loading process.
private void OgreImage_ResourceLoadItemProgress
(object sender, ResourceLoadEventArgs e)
_progressName.Text = e.Name;
_progressScale.ScaleX = e.Progress;
The Initialised event. This event is called just after all the resources have been loaded (and before the first frame is rendered). In this event the scene can be constructed.
Please refer to the Ogre wiki on how to use Ogre
void _image_InitScene(object sender, RoutedEventArgs e)
var sb = (Storyboard)this.Resources["StartEngine"];
SceneManager sceneMgr = _ogreImage.SceneManager;
Light l = sceneMgr.CreateLight("MainLight");
l.Position = new Vector3(20F, 80F, 50F);
_ogreMesh = sceneMgr.CreateEntity
_ogreNode = sceneMgr.RootSceneNode.CreateChildSceneNode
_fountainNode = sceneMgr.RootSceneNode.CreateChildSceneNode();
ParticleSystem.DefaultNonVisibleUpdateTimeout = 5;
PreRender event. This event is called before the frame is rendered. Here you can update or change any of the scene nodes.
void _image_PreRender(object sender, System.EventArgs e)
if (_ogreImage.Camera.Viewport != _viewport)
_viewport = _ogreImage.Camera.Viewport;
_ogreNode.Rotate(new Vector3(0, 1, 0), new Degree(0.1f));
Resizing the Ogre Viewport
Also, to get the Ogre viewport to resize itself when the
Image size changes you need to manually resize the
OgreImage image on the size event of the
private void RenterTargetControl_SizeChanged
(object sender, SizeChangedEventArgs e)
if (_ogreImage == null) return;
_ogreImage.ViewportSize = e.NewSize;
To keep the app responsive during a window drag exercise I've made the
OgreImage class delay its processing of the resize. This will make the image wait for a couple of milliseconds (200 by default) until the size has stabilized. Have a look at the
Starting it all. "Graphics, you haz dem."
One more thing to do is to start the engine. Currently this is done manually by calling the
InitOgreAsync method. The reason why the engine can't start automatically is because it requires a valid windows handle to initialize itself and this isn't available while the page xaml is busy loading. I'm sure it won't be too difficult to come up with a clever solution, but I'll let you guys do that.
The control can be initialized on the window's
private void Window_Loaded(object sender, RoutedEventArgs e)
_ogreImage = (OgreImage)RenterTargetControl.Source;
Binding to the OGRE Library and Media
The OGRE library is quite a monster to get setup for a project. I have only included the essential DLLs and media in this article's download because the full MOGRE setup is quite large. If you would like to develop using MOGRE you will need to download the full SDK which is a hefty 40 meg.
The executables in this project have been compiled into the "Release" folder of the article's download where all the OGRE/MOGRE "Release" DLLs and resource config files are. They are quite large so there's only one instance of them. That is to say, all the VS projects have been configured to have their build output go directly into the Release folder.
If you'd like to re-compile the MogreWpf.Interop.dll (a c++ project) you'll need to set the MOGRE_HOME environment variable in windows to include the "<..>\MogreSDK" path....once you've downloaded the MOGRE SDK. Also compile it in "Release" mode to match the Ogre and Mogre DLLs for this project's download.
Points of Interest
- The WPF now supports GPU Bitmap effects (a-series-on-gpu-based-effects-for-wpf)
This article doesn't use them, it just might interest you to know that it's now possible to do funky stuff in the WPF.
- Ogre is a pretty good object oriented graphics library. If you like graphics programming you should have a look at it. It is mature library, is fun to use and has a good Texture Material and Particle Effects scripting language.
And there you have it. A 3D graphics engine blended into your WPF window. Ooooooh,....shiny!
Ok, this wouldn't be the best way to create a 2000 "frames per second" game. It would be best to leave the OGRE Engine to use its native windowing system, but it will keep your boss loving you at your day job.
Note: Before you make all kinds of promises to 'said' boss, read the OGRE and MOGRE licenses first, and also I'm not sure the implementation of the
OgreImage is 100% reliable at all times. I have had some funny crashes, though it seems pretty stable at the moment after my last code tweak'ins (fluffy bunnies aside). However it should give you a good place to start your "next level" graphics journey.
- 2008-09-09 - Initial publication