Click here to Skip to main content
Licence CPOL
First Posted 14 Jul 2006
Views 29,160
Downloads 472
Bookmarked 17 times

Simulating Mirror in a Managed DirectX Application

By AmitDey | 14 Jul 2006
Simulating Mirror in a Managed DirectX Application

1

2
2 votes, 66.7%
3
1 vote, 33.3%
4

5
3.67/5 - 3 votes
μ 3.67, σa 1.01 [?]
Sample Image - DirectXMirror.gif

Introduction

This article explains how to simulate a mirror in a Managed DirectX application. This technique has many uses, but the best one I can think of right now is to make a rear-view mirror in a driving simulation.

Using the Code

The Mirror effect is achieved by rendering the same scene (generally with a different camera angle) into a texture, and then applying this texture to a triangle(s) or simply to a sprite. I am going to apply it to a sprite.

Rendering Into Surface

First of all, we need to declare these variables :

private Texture renderTexture = null;
private Surface renderSurface = null;
private RenderToSurface rts = null;
private const int renderSurfaceSize = 128;
  • renderTexture is the texture we will be rendering to.
  • renderSurface is the surface which we get from the texture. Technically we will be rendering to this surface.
  • rts is an object of type RenderToSurface, which is a helper class used to, yes you guessed right, render to the surface.
  • renderSurfaceSize is the length of the side of my square mirror (You can easily create a rectangular mirror, as you will see later.)

Now we initialize the mirror variables. This initialization should be done after the device creation and before Application.Run(). Here is the code:

rts = new RenderToSurface(device, RenderSurfaceSize, RenderSurfaceSize,
    Format.X8R8G8B8, true, DepthFormat.D16);
renderTexture = new Texture(device, RenderSurfaceSize, RenderSurfaceSize, 
    1,Usage.RenderTarget, Format.X8R8G8B8, Pool.Default);
renderSurface = renderTexture.GetSurfaceLevel(0);

First we create the object rts of the helper class. Note that the arguments used in its creation are similar to the arguments used in device creation. Then we create our texture and then the actual surface from the texture.

Assume that the only object to render is a Mesh, mesh. So the code for this is mesh.DrawSubset(0);

Here is the code for rendering into the surface :

private void RenderIntoSurface()
{
    // Render to this surface
    Viewport view = new Viewport();
    view.Width = RenderSurfaceSize;
    view.Height = RenderSurfaceSize;
    view.MaxZ = 1.0f;
    
    rts.BeginScene(renderSurface, view);

    device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.DarkBlue, 1.0f,
        0);
    device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4,
        this.Width / this.Height, 1.0f, 100.0f);

    device.Transform.View = Matrix.LookAtLH(new Vector3(0,0, -3.0f),
        new Vector3(0,0,0), new Vector3(0, 1,0));

    mesh.DrawSubset(0);

    rts.EndScene(Filter.None);
}

Note that this code is very similar to our normal rendering method. There is a begin call, an end call, camera transforms, and the Mesh rendering. The view matrix specified here is the actual view angle of the mirror.

Rendering the Sprite

We will want to render to the surface before rendering to our main window, hence add this line as the first statement in your OnPaint method.

RenderIntoSurface()

Now we need to render the sprite. Given below is the code to render the sprite using the surface. This code is to be added in between the device.BeginScene() and device.EndScene() call.

using (Sprite s = new Sprite(device))
{
    s.Begin(SpriteFlags.None);
    s.Draw(renderTexture, new Rectangle(0, 0, RenderSurfaceSize,
         RenderSurfaceSize),  new Vector3(0, 0, 0), new Vector3(0, 0, 1.0f),
        Color.White);
    s.End();
}

Just to clear the confusion, I will give the full OnPaint code:

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
    //This renders into the mirror
    RenderIntoSurface();
    device.Clear(ClearFlags.Target| ClearFlags.ZBuffer, 
                 System.Drawing.Color.CornflowerBlue, 1.0f, 0);
            
    device.BeginScene();            
    SetupCamera();
    mesh.DrawSubset(0);
    using (Sprite s = new Sprite(device))
    {
        s.Begin(SpriteFlags.None);
        s.Draw(renderTexture, new Rectangle(0, 0, RenderSurfaceSize,
            RenderSurfaceSize),  new Vector3(0, 0, 0), 
            new Vector3(82, 5, 1.0f), Color.White);
        s.End();
    }
    device.EndScene();
            
    device.Present();
    this.Invalidate();
}

References

I would like to mention that I have referred to the book "Managed DirectX 9 Kick Start: Graphics and Game Programming" for writing this article.

History

  • 14th July, 2006: Initial post

License

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

About the Author

AmitDey

Software Developer
Microsoft India
India India

Member

Follow on Twitter Follow on Twitter
My Name is Amit Dey.
I work in Microsoft as a Software Developer for the last 3 Years.
 
My MSDN Blog

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionFlip screen image in c++/opengl Pinmemberiasouza11:02 12 Sep '07  
GeneralMesh flip Pinmembermirano0:10 1 Sep '06  
GeneralGood .... PinmemberSendilkumar.M19:40 16 Jul '06  
GeneralRe: Good .... PinmemberAmitDey1:31 19 Jul '06  

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

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120210.1 | Last Updated 14 Jul 2006
Article Copyright 2006 by AmitDey
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid