Use a screenshot of a WPF visual as a texture in Mogre.
25 March 2009Hello,
Here is my first post about WPF and Mogre, maybe it will helps some people...
The subject of today is "How to use a screenshot of a WPF elements and put it as an texture on your Mogre object"...
Why ? Because WPF enable you to create very rich interface and so great image to place on you differents elements...
By the way, I let you follow the link at the end of the post to learn how to blend Mogre in WPF and how to take a screenShot of a WPF visual.
The steps to follow are these :
- Create a screenshot of the WPF visual (any visual can be used),
- Put the bitmap in a stream and then to a buffer,
- Use some unsafe code to create a Mogre MemoryStream and a mogre image,
- Use this image to create a texture,
- Use this texture in a material,
- Put it on the mesh of your choice
Create a screenshot of the WPF visual
The original code is from thomas lebrun and can be found in any good WPF book :
Visual theVisual = this ; //Put the aimed visual here. double width = Convert.ToDouble(theVisual.GetValue(FrameworkElement.WidthProperty)); double height = Convert.ToDouble(theVisual.GetValue(FrameworkElement.HeightProperty)); if (double.IsNaN(width) || double.IsNaN(height)) { throw new FormatException("You need to indicate the Width and Height values of the UIElement."); } RenderTargetBitmap render = new RenderTargetBitmap( Convert.ToInt32(width), Convert.ToInt32(this.GetValue(FrameworkElement.HeightProperty)), 96, 96, PixelFormats.Pbgra32); // Indicate which control to render in the image render.Render(this); Stream oStream = new MemoryStream(); PngBitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(render)); encoder.Save(oStream); oStream.Flush();
Put the bitmap in a stream and then to a buffer
//Back to the start of the stream oStream.Position = 0; //read all the stream BinaryReader oBinaryReader = new BinaryReader(oStream); byte[] pBuffer = oBinaryReader.ReadBytes((int)oBinaryReader.BaseStream.Length); oStream.Close(); //No more needed TextureManager.Singleton.Remove(sName); //Remove eventually texture with the same name
Create the texture
unsafe { GCHandle handle = GCHandle.Alloc(pBuffer, GCHandleType.Pinned); byte* pUnsafeByte = (byte*)handle.AddrOfPinnedObject(); void* pUnsafeBuffer = (void*)handle.AddrOfPinnedObject(); MemoryDataStream oMemoryStream = new MemoryDataStream(pUnsafeBuffer, (uint)pBuffer.Length); DataStreamPtr oPtrDataStream = new DataStreamPtr(oMemoryStream); oMogreImage = oMogreImage.Load(oPtrDataStream, "png"); TextureManager.Singleton.LoadImageW(sName, ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME, oMogreImage); //handle.Free(); }
Use this texture in a material
Here is the code of how you can create a material with this texture:
_dynamicMaterial = MaterialManager.Singleton.Create(SCREENSHOT_MATERIAL_NAME, ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME); Pass pass = _dynamicMaterial.GetTechnique(0).GetPass(0); TextureUnitState tus = pass.CreateTextureUnitState(SCREENSHOT_TEXTURE_NAME); _dynamicMaterial.GetTechnique(0).GetPass(0).AddTextureUnitState(tus);
Then you just have to use it as a normal texture...
An example:
Here is a little screenshot of the results. I display a cube with the face using as a texture a screenshot of the window in which it is....
- By JonathanANTOINE@falsemail.com
- - 3D (Mogre)
- - Tags :
Comments
Excelent post!
I'm try to take screenshot for a visual that is not visible on the screen. Something that can be used for an automatic processing of images. Load images from a foder, eliminate background color and export to transparent png.
I wander how vista take screenshot of applications in taskbar when mouse roll over
Regards
@cristi : Thx... But I have no ideas of how vista does it's stuff...
Hi,
could you post the code of the mesh tool that u have developed
Thanks,
Karthik
@[karthik] : Sorry, I can't because the code is owned by my company
Why not just using WPF and its 3D capabilities? It's so much easier to use Viewport2DVisual3D! And you can make it interective...
@Dmitry : Because you can't do all the things you can do with a 3D engine....
Why using XNA when you can use DirectX ... ?
With a 3D engine as Mogre you have all the framework of Mogre available plus all the plugins which can be connected...
Thanks for information!