65.9K
CodeProject 正在变化。 阅读更多。
Home

在 Managed DirectX 应用程序中模拟镜像

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.67/5 (3投票s)

2006年7月14日

CPOL

2分钟阅读

viewsIcon

50988

downloadIcon

914

在 Managed DirectX 应用程序中模拟镜像

Sample Image - DirectXMirror.gif

引言

本文解释了如何在托管DirectX应用程序中模拟镜子。这种技术有很多用途,但我目前能想到的最好的用途是在驾驶模拟中制作后视镜。

Using the Code

镜子效果是通过将相同的场景(通常使用不同的摄像机角度)渲染到纹理中,然后将此纹理应用于三角形或简单地应用于精灵来实现的。 我将把它应用于精灵。

渲染到表面

首先,我们需要声明这些变量

private Texture renderTexture = null;
private Surface renderSurface = null;
private RenderToSurface rts = null;
private const int renderSurfaceSize = 128;
  • renderTexture是我们将要渲染到的纹理。
  • renderSurface是我们将从纹理中获得的表面。从技术上讲,我们将渲染到这个表面。
  • rtsRenderToSurface类型的对象,这是一个帮助类,用于,没错,你猜对了,渲染到表面。
  • renderSurfaceSize是我的正方形镜子的边长(你可以很容易地创建一个矩形镜子,稍后你就会看到。)

现在我们初始化镜子变量。 此初始化应在设备创建之后和Application.Run()之前完成。 这是代码

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);

首先,我们创建辅助类的对象rts。 请注意,其创建中使用的参数与设备创建中使用的参数类似。 然后我们创建我们的纹理,然后从纹理创建实际的表面。

假设要渲染的唯一对象是Meshmesh。 那么代码是mesh.DrawSubset(0);

这是渲染到表面的代码

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);
}

请注意,此代码与我们的普通渲染方法非常相似。 有一个 begin 调用,一个 end 调用,摄像机变换和Mesh 渲染。 此处指定的视图矩阵是镜子的实际视图角度。

渲染精灵

我们希望在渲染到主窗口之前渲染到表面,因此将此行添加为OnPaint方法中的第一个语句。

RenderIntoSurface()

现在我们需要渲染精灵。 下面是使用表面渲染精灵的代码。 此代码要添加到device.BeginScene()device.EndScene()调用之间。

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();
}

为了避免混淆,我将给出完整的OnPaint代码

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();
}

参考文献

我想提一下,在撰写本文时,我参考了书籍《Managed DirectX 9 Kick Start: Graphics and Game Programming》。

历史

  • 2006年7月14日:初始帖子
© . All rights reserved.