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

引言
本文解释了如何在托管DirectX应用程序中模拟镜子。这种技术有很多用途,但我目前能想到的最好的用途是在驾驶模拟中制作后视镜。
Using the Code
镜子效果是通过将相同的场景(通常使用不同的摄像机角度)渲染到纹理中,然后将此纹理应用于三角形或简单地应用于精灵来实现的。 我将把它应用于精灵。
渲染到表面
首先,我们需要声明这些变量
private Texture renderTexture = null;
private Surface renderSurface = null;
private RenderToSurface rts = null;
private const int renderSurfaceSize = 128;
renderTexture
是我们将要渲染到的纹理。renderSurface
是我们将从纹理中获得的表面。从技术上讲,我们将渲染到这个表面。rts
是RenderToSurface
类型的对象,这是一个帮助类,用于,没错,你猜对了,渲染到表面。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
。 请注意,其创建中使用的参数与设备创建中使用的参数类似。 然后我们创建我们的纹理,然后从纹理创建实际的表面。
假设要渲染的唯一对象是Mesh
,mesh
。 那么代码是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日:初始帖子