Introduction
Hello, here is my first post about WPF and Mogre, maybe it will help 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 enables you to create a very rich interface and a great image to place on your different 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 listed below:
- 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 ;
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);
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
oStream.Position = 0;
BinaryReader oBinaryReader = new BinaryReader(oStream);
byte[] pBuffer = oBinaryReader.ReadBytes((int)oBinaryReader.BaseStream.Length);
oStream.Close();
TextureManager.Singleton.Remove(sName);
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);
}
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 screenshot of the results. I display a cube with the face using as a texture a screenshot of the window in which it is....
Link: How to blend Mogre in WPF
CodeProject