Click here to Skip to main content
15,886,724 members
Articles / Multimedia / DirectX
Article

Simulating Mirror in a Managed DirectX Application

Rate me:
Please Sign up or sign in to vote.
3.67/5 (3 votes)
14 Jul 2006CPOL2 min read 49.9K   882   18   4
Simulating Mirror in a Managed DirectX Application
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 :

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

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

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

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

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

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


Written By
Software Developer
India India
I am a Software Developer from Hyderabad, India

My MSDN Blog

My Windows Phone Apps

Comments and Discussions

 
QuestionFlip screen image in c++/opengl Pin
iasouza12-Sep-07 10:02
iasouza12-Sep-07 10:02 
GeneralMesh flip Pin
mirano31-Aug-06 23:10
mirano31-Aug-06 23:10 
GeneralGood .... Pin
Sendilkumar.M16-Jul-06 18:40
Sendilkumar.M16-Jul-06 18:40 
GeneralRe: Good .... Pin
AmitDey19-Jul-06 0:31
AmitDey19-Jul-06 0:31 

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.