Click here to Skip to main content
15,902,492 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.3K   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 
GeneralRe: Interesting approach! Pin
JaredThirsk29-Mar-11 20:45
JaredThirsk29-Mar-11 20:45 
Good to know! I'll have to give it a try!
Do you have input hooked up? Or do animations (for button hover, etc.)?

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.