Concise Sample of Managed Direct3D for 2D Rendering (9.0c)

自批:读者注意,以下都是肤浅之谈,诚不足作为参考。

继续沿袭大片贴源码风格,发一个Managed Direct3D的典型2D渲染实例: ) 采用了Sprite+Texture方式,速度其实也不算慢,代码也还算简洁可靠(除了控制Device Lost异常比较烦琐以外),尤其是在窗口模式下,要考虑的底层细节比DirectDraw要少得多,什么裁剪区域、页切换链等等,如果不想去碰它们,均可交给Direct3D自动管理,当然,如果需要的话也可以自行设置。

不爽的地方在于Direct3D对硬件要求起点比DirectDraw要高,实际2D绘制效率比起DirectDraw还是要慢不少;此外,Direct3D中以纹理绘制方式实现2D渲染决定了其局限性:纹理的形状必须是正方形的,则制作2D Sprite时也不得不将其制作成正方形的,这很不自然;更令人郁闷的是,纹理的象素尺寸必须是2的整数幂,否则在渲染时其尺寸将会被拉伸导致图像模糊、变形;上述两点要求对于传统的2D场景渲染而言都可以说是一些非常不合理的约束,不过我想至今还没有哪款2D Game是纯粹地用Direct3D来做的吧,呵呵,下面这个实例就当见识一下M$向我们所推荐的“未来”的2D渲染编程方式吧。

结论:对于2D的我还是喜欢用DirectDraw — Speed Rules!

None.gif // #define FULL_SCREEN
None.gif

None.gif
using  System;
None.gif
using  System.Drawing;
None.gif
using  System.Collections;
None.gif
using  System.ComponentModel;
None.gif
using  System.Windows.Forms;
None.gif
using  System.Data;
None.gif
using  System.Threading;
None.gif
None.gif
using  Microsoft.DirectX;
None.gif
using  Microsoft.DirectX.Direct3D;
None.gif
None.gif
namespace  MDirect3D
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public class AppFrm : System.Windows.Forms.Form
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private Device device;
InBlock.gif        
private Sprite sprite;
InBlock.gif        
private Texture[] texture=new Texture[2];
InBlock.gif
InBlock.gif        
private Rectangle[] textureSize=new Rectangle[2];
InBlock.gif        
private Vector3 centerPos = new Vector3(000);
InBlock.gif        
private Vector3 position = new Vector3(0,0,1);
InBlock.gif
InBlock.gif        
private int idx=0//纹理索引
InBlock.gif
    
InBlock.gif        
private PresentParameters PreparePresentParameters()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            PresentParameters presentParams 
= new PresentParameters();
InBlock.gif            
ContractedSubBlock.gifExpandedSubBlockStart.gif            
初始化设备参数#region 初始化设备参数
InBlock.gif            
#if FULL_SCREEN
InBlock.gif                presentParams.Windowed 
= false;
InBlock.gif                presentParams.BackBufferCount
=1;
InBlock.gif                presentParams.BackBufferWidth
=1024;
InBlock.gif                presentParams.BackBufferHeight
=768;
InBlock.gif                presentParams.BackBufferFormat
=Format.X8R8G8B8;
InBlock.gif                presentParams.SwapEffect 
= SwapEffect.Flip;
InBlock.gif            
#else
InBlock.gif                presentParams.Windowed 
= true;
InBlock.gif                presentParams.SwapEffect 
= SwapEffect.Discard;
InBlock.gif            
#endif
ExpandedSubBlockEnd.gif            
#endregion

InBlock.gif            
InBlock.gif            
return presentParams;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
private void InitializeGraphics()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ContractedSubBlock.gifExpandedSubBlockStart.gif            
初始化设备#region 初始化设备
InBlock.gif            device 
= new Device(0, DeviceType.Hardware, this,
InBlock.gif                CreateFlags.SoftwareVertexProcessing, PreparePresentParameters());
ExpandedSubBlockEnd.gif            
#endregion

InBlock.gif            
ContractedSubBlock.gifExpandedSubBlockStart.gif            
初始化纹理#region 初始化纹理
InBlock.gif            
//纹理资源创建类型: Pool.Managed - Device Lost之后无需再次创建
InBlock.gif
            texture[0= TextureLoader.FromFile(device, @"..\..\01.tga");
InBlock.gif            texture[
1= TextureLoader.FromFile(device, @"..\..\02.tga");
InBlock.gif
InBlock.gif            
for (int i=0;i<2;i++)
InBlock.gif                
using (Surface s = texture[i].GetSurfaceLevel(0))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    SurfaceDescription desc 
= s.Description;
InBlock.gif                    
//纹理的尺寸必须是2的整数次幂,否则会拉伸变形
InBlock.gif
                    textureSize[i] = new Rectangle(00, desc.Width, desc.Height); 
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            
#endregion

InBlock.gif
InBlock.gif            sprite 
= new Sprite(device);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
private void Restore()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ContractedSubBlock.gifExpandedSubBlockStart.gif            
恢复设备#region 恢复设备
InBlock.gif            PresentParameters[] ps
=new PresentParameters[1];
InBlock.gif            ps[
0]=PreparePresentParameters();
InBlock.gif            device.Reset(ps);
InBlock.gif
InBlock.gif            
//由于纹理资源创建类型为Pool.Managed
InBlock.gif            
//所以恢复device的时候无需再次创建
ExpandedSubBlockEnd.gif
            #endregion

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public void Draw()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (device==null || WindowState == FormWindowState.Minimized)
InBlock.gif                
return;
InBlock.gif
InBlock.gif            
int result=0;
InBlock.gif            device.CheckCooperativeLevel(
out result);
InBlock.gif            
InBlock.gif            
try 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
switch (result)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
case (int)ResultCode.Success:
ContractedSubBlock.gifExpandedSubBlockStart.gif                        
2D绘制过程#region 2D绘制过程
InBlock.gif
InBlock.gif                        device.BeginScene();
InBlock.gif                        device.Clear(ClearFlags.Target, Color.White , 
0.0f0);
InBlock.gif                        sprite.Begin(SpriteFlags.None);
InBlock.gif                        sprite.Draw(texture[idx], textureSize[idx], centerPos, position, Color.White);
InBlock.gif                        sprite.End();
InBlock.gif                        device.EndScene();
InBlock.gif                        device.Present();
InBlock.gif                        
InBlock.gif                        idx
^=1;
ExpandedSubBlockEnd.gif                        
#endregion

InBlock.gif                        
break;
InBlock.gif                    
case (int)ResultCode.DeviceNotReset:
ContractedSubBlock.gifExpandedSubBlockStart.gif                        
设备恢复过程#region 设备恢复过程
InBlock.gif                        Restore();
ExpandedSubBlockEnd.gif                        
#endregion

InBlock.gif                        
break;
InBlock.gif                    
case (int)ResultCode.DeviceLost:
InBlock.gif                        
break;
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }
 
InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
ContractedSubBlock.gifExpandedSubBlockStart.gif        
乱七八糟#region 乱七八糟
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 必需的设计器变量。
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        private System.ComponentModel.Container components = null;
InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 清理所有正在使用的资源。
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        protected override void Dispose( bool disposing )
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if( disposing )
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
if (components != null
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    components.Dispose();
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif            
base.Dispose( disposing );
ExpandedSubBlockEnd.gif        }

InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
Windows 窗体设计器生成的代码#region Windows 窗体设计器生成的代码
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
InBlock.gif        
/// 此方法的内容。
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        private void InitializeComponent()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
// 
InBlock.gif            
// AppFrm
InBlock.gif            
// 
InBlock.gif
            this.AutoScaleBaseSize = new System.Drawing.Size(513);
InBlock.gif            
this.ClientSize = new System.Drawing.Size(292266);
InBlock.gif            
this.Name = "AppFrm";
InBlock.gif            
this.Text = "Managed Direct 3D";
InBlock.gif            
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.AppFrm_KeyDown);
InBlock.gif
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif        
#endregion

ExpandedSubBlockEnd.gif        
#endregion

InBlock.gif
InBlock.gif        
public AppFrm()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            InitializeComponent();
InBlock.gif
InBlock.gif            
#if FULL_SCREEN
InBlock.gif                FormBorderStyle 
= FormBorderStyle.None;
InBlock.gif                WindowState 
= FormWindowState.Maximized;
InBlock.gif            
#endif
InBlock.gif
InBlock.gif            InitializeGraphics();
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
private void AppFrm_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (e.KeyCode==Keys.Escape) Close();
ExpandedSubBlockEnd.gif        }

InBlock.gif                
InBlock.gif        [STAThread]
InBlock.gif        
static void Main() 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            AppFrm frm
=new AppFrm();
InBlock.gif            frm.Show();
InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif            
消息循环#region 消息循环
InBlock.gif            
while (frm.Created)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                frm.Draw();
InBlock.gif                Thread.Sleep(
1000/60);
InBlock.gif                
try 
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    Application.DoEvents();
ExpandedSubBlockEnd.gif                }

InBlock.gif                
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
continue;
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }
 
ExpandedSubBlockEnd.gif            
#endregion

ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值