Click here to Skip to main content
15,867,985 members
Articles / All Topics

Use a screenshot of a WPF visual as a texture in Mogre

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
19 Feb 2010CPOL1 min read 25.2K   5   5
How to use a screenshot of a WPF elements and put it as a texture on your Mogre object

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:

  1. Create a screenshot of the WPF visual (any visual can be used)
  2. Put the bitmap in a stream and then to a buffer
  3. Use some unsafe code to create a Mogre MemoryStream and a mogre image
  4. Use this image to create a texture
  5. Use this texture in a material
  6. 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:

C#
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

C#
//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

C#
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:

C#
_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....

WPF screenshot as a texture in Mogre

Link: How to blend Mogre in WPF

This article was originally posted at http://blog.lexique-du-net.com/index.php

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer http://wpf-france.fr
France (Metropolitan) France (Metropolitan)
Jonathan creates software, mostly with C#,WPF and XAML.

He really likes to works on every Natural User Interfaces(NUI : multitouch, touchless, etc...) issues.



He is awarded Microsoft MVP in the "Client Application Development" section since 2011.


You can check out his WPF/C#/NUI/3D blog http://www.jonathanantoine.com.

He is also the creator of the WPF French community web site : http://wpf-france.fr.

Here is some videos of the projects he has already work on :

Comments and Discussions

 
QuestionAlternative step: write to VisualBrush Pin
JaredThirsk19-Apr-12 7:40
JaredThirsk19-Apr-12 7:40 
QuestionA more performant alternative? Pin
JaredThirsk27-Mar-11 0:55
JaredThirsk27-Mar-11 0:55 
GeneralInteresting approach! Pin
JaredThirsk17-Mar-11 11:47
JaredThirsk17-Mar-11 11:47 
GeneralRe: Interesting approach! Pin
jmix9028-Mar-11 9:42
jmix9028-Mar-11 9:42 
It's pretty nice performant in fact Smile | :) (for my usage)
GeneralRe: Interesting approach! Pin
JaredThirsk29-Mar-11 20:45
JaredThirsk29-Mar-11 20:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.