基于Visual C#的DirectX开发实例 ——二维显示

七、二维显示

DirectX中大部分二维显示都由Sprite来完成,如动画、公告板、二维文字等。在DirectX中有专门的Sprite类用于简化sprite的绘制和处理,下面来看一下Sprite类的一些方法:

方法

定义

说明

Begin

public void Begin(SpriteFlags flags);

开始绘制Sprite

Dispose

public overridevoid Dispose();

立即释放用Sprite托管的资源

Draw

public void Draw(Texture srcTexture,Rectangle srcRectangle,Vector3 center,Vector3 position,Color color);

绘制一个Sprite对象(如图片)

Draw2D

public void Draw2D(Texture srcTexture, Point rotationCenter,float rotationAngle,Point position, Color color );

绘制一个Sprite对象用于二维空间中显示

End

public void End();

结束绘制Sprite

SetWorldViewLH

public void SetWorldViewLH( Matrix world, Matrix view );

Sprite设置一个左手法则的世界—视图变换,该方法要用于billboarding(电子版)之前

SetWorldViewRH

public void SetWorldViewRH( Matrix world, Matrix view );

Sprite设置一个右手法则的世界—视图变换,该方法要用于billboarding(电子版)之前

Sprite

public Sprite(Device);

初始化一个Sprite

1、显示图片

首先在全局中定义图片对象变量,如下代码:

Texture showPicture;//定义图片对象

然后在初始化时导入图片,在InitializeDirect3D()函数中添加如下代码:

string imagePath = @"D:/My Documents/My Pictures/xzy.bmp";

showPicture = TextureLoader.FromFile(device, imagePath);

最后,在渲染函数Render()中添加用Sprite绘制图片的代码,如下代码:

Sprite sprite;//定义Sprite对象

sprite = new Sprite(device);//实例化Sprite对象

sprite.Begin(SpriteFlags.AlphaBlend);

System.Drawing.Point rotationPoint=new Point();

System.Drawing.Point position=new Point();

position.X = 100;

position.Y = 150;

sprite.Draw2D(showPicture, rotationPoint,0f, position, Color.White);

sprite.End();

运行程序,其结果如下图所示:

基于Visual C#的DirectX开发实例 ——二维显示

上面的代码中每次在调用Render()函数时都将创建一个Sprite,这将导致系统内存不断增加,为了避免重复地创建Sprite,可以采用如下两种方式:

1)方式一

在全局中定义Sprite,如下代码:

private Sprite sprite;//定义Sprite对象

然后在初始化函数InitializeDirect3D()中添加Sprite变量的实例化代码,如下代码:

sprite = new Sprite(device);

最后在Render()函数中添加如下代码:

sprite.Begin(SpriteFlags.AlphaBlend);

System.Drawing.Point rotationPoint = new Point();

System.Drawing.Point position = new Point();

position.X = 100;

position.Y = 150;

sprite.Draw2D(showPicture, rotationPoint, 0f, position, Color.White);

sprite.End();

2)方式二

如果不采用前面的方式,也可以直接在代码“sprite.End();”后添加如下代码:

sprite.Dispose();//释放Sprite对象

前面显示图片是采用SpriteDraw2D()方法来实现,下面介绍采用SpriteDraw ()方法来实现:

1)首先在全局中定义Sprite变量及图片对象,如下代码:

private Sprite sprite;//定义Sprite对象

private Texture showPicture;//定义图片对象

2)在初始化函数InitializeDirect3D()中添加Sprite变量和图片对象的实例化代码,如下代码:

sprite = new Sprite(device);

string imagePath = @"D:/My Documents/My Pictures/xzy.png";

showPicture = TextureLoader.FromFile(device, imagePath);

3)在渲染Render()函数中添加显示图片,如下代码:

int spriteX = 10;

sprite.Begin(SpriteFlags.AlphaBlend);

sprite.Draw(showPicture, Vector3.Empty, new Vector3(spriteX, 50, 0), Color.White.ToArgb());

spriteX += showPicture.GetLevelDescription(0).Width + 10;

sprite.Draw(showPicture, new Rectangle(4, 4, 100, 100), Vector3.Empty, new Vector3(spriteX, 50, 0), Color.Green);

spriteX += showPicture.GetLevelDescription(1).Width;

sprite.Draw(showPicture, Rectangle.Empty, Vector3.Empty, new Vector3(spriteX, 50, 0), Color.Yellow);

sprite.End();

上面采用SpriteDraw ()方法的几种不同的重载函数,运行程序,其结果如下图所示:

基于Visual C#的DirectX开发实例 ——二维显示

2、二维图片动画

图片动画其实就是由一系列图片随着时间变化形成的,所以首先在全局中定义如下变量:

private const int frameCount = 8;//定义动画帧数目

private int currentFrame=0;//定义当前动画帧

private System.Windows.Forms.Timer aniTimer;//定义计时器

然后在初始化函数InitializeDirect3D()中设置图片、计时器等,首先修改图片来源为如下:

string imagePath = @"E:/DirectX/DirectX_C#/Media/火焰/fire.png";

接着就设置计时器的一些相关属性,如下代码:

aniTimer = new Timer();

aniTimer.Enabled = true;

aniTimer.Interval = 100;

aniTimer.Tick += new System.EventHandler(this.aniTimer_Tick);

其中最后一句代码是定义计时器的事件连接,所以对应定义事件函数aniTimer_Tick(),如下代码:

private void aniTimer_Tick(object sender, EventArgs e)

{

if (currentFrame >= frameCount-1)

{

currentFrame = 0;

}

else

{

currentFrame++;

}

}

最后在渲染函数Render()sprite.Begin()sprite.End()之间添加绘制图片,如下代码:

Rectangle originPicRect = new Rectangle(64 * currentFrame, 0, 64, 128);

sprite.Draw(showPicture, originPicRect, Vector3.Empty, new Vector3(50, 50, 0), Color.White.ToArgb());

运行程序,其结果如下图所示:

基于Visual C#的DirectX开发实例 ——二维显示

基于Visual C#的DirectX开发实例 ——二维显示

基于Visual C#的DirectX开发实例 ——二维显示

基于Visual C#的DirectX开发实例 ——二维显示

3、显示二维文字

首先在全局中定义SpriteFont等变量,如下代码:

private Sprite sprite;//定义Sprite对象

private System.Drawing.Font currentFont;//定义字体

private Microsoft.DirectX.Direct3D.Font myFont;//定义文字对象

然后在初始化函数InitializeDirect3D()中添加Sprite变量和文字对象的实例化代码,如下代码:

sprite = new Sprite(device);//实例化Sprite对象

currentFont = new System.Drawing.Font("Times New Roman", 28, FontStyle.Regular);//设置字体

myFont = new Microsoft.DirectX.Direct3D.Font(device, currentFont);//创建文字对象

最后在渲染函数Render()中添加绘制文字代码,如下代码:

sprite.Begin(SpriteFlags.AlphaBlend);

myFont.DrawText(sprite, "Hello,DirectX!", 200, 100, Color.Yellow);

sprite.End();

运行程序,其结果如下图所示:

基于Visual C#的DirectX开发实例 ——二维显示

通过指定前面代码sprite.Begin()方法中的参数SpriteFlags可以优化和提高性能,SpriteFlags的值有如下几种:

说明

SpriteFlags.SortTexture

在将图像绘制到屏幕之前先对图像进行排序,以便加快切换纹理的速度

SpriteFlags.AlphaBlend

可正确呈现字体,尤其适用于具有透明或半透明区域的子画面

SpriteFlags.SortDepthBackToFront

按照从前向后的顺序对子画面进行排序;如果您拥有几个要互相绘制到对方顶部的透明或半透明子画面,就可以使用此值

SpriteFlags.DoNotSaveState

可提高那些不能使用指定呈现状态的应用程序的性能

SpriteFlags.DoNotModifyRenderState

可通过使用当前呈现状态优化性能,且可用来获得特殊效果

SpriteFlags.ObjectSpace SpriteFlags.Billboard

可以绘制出具有各种不同的特殊效果的图像