第一次亲密接触

2007-5-23 第一次亲密接触
    这几天在网上看了一个系列文章的开头两章,按指示作出了一个hello world似的程序。
    网址:(中文)

http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/gamedevelopmentbeginning.mspx?mfr=true
   

    (英文)  http://blogs.msdn.com/coding4fun/archive/2006/11/02/938703.aspx
    还是像以前看到的那样,利用 OnPaint 来实现游戏循环。并且通过代码确保 Windows 只使用 OnPaint 事件处理程序来

重画屏幕:
        this.SetStyle ( ControlStyles.AllPaintingInWmPaint|ControlStyles.Opaque, true );
    在第二篇中,终于接触到了DirectX,搞了十多天,终于有点起步了。
    对于DirectX而言,将图形硬件(适配器 Adapter)抽象成设备(Device),这样程序就可以通过Device来操作,而不论实际

的显示设备是什么。DirectX 支持三种类型的设备:Hardware、References 和 Software。
    对于游戏程序而言,需要在任何时候都有一个可用的设备,因此,在所有代码之前就应该准备好Device对象。而如下的

代码则实现该目标:

 

  //  Get the ordinal for the default adapter
     int  adapterOrdinal  =  Manager.Adapters.Default.Adapter;
    
//  Get our device capabilities so we can check them to set up the CreateFlags
    Caps caps  =  Manager.GetDeviceCaps(adapterOrdinal, DeviceType.Hardware);
    CreateFlags createFlags;
    
//  Check the capabilities of the graphcis card is capable of
    
//  performing the vertex-processing operations
    
//  The HardwareVertexProcessing choice is the best
     if  (caps.DeviceCaps.SupportsHardwareTransformAndLight)
    
{
    createFlags 
= CreateFlags.HardwareVertexProcessing;
    }

    
else
    
{
    createFlags 
= CreateFlags.SoftwareVertexProcessing;
    }

    
//  If the graphics card supports vertex processing check if the device can
    
//  do rasterization, matrix transformations, and lighting and shading operations
    
//  This combination provides the fastest game experience
     if  (caps.DeviceCaps.SupportsPureDevice  &&  createFlags  ==  CreateFlags.HardwareVertexProcessing)
    
{
        createFlags 
|= CreateFlags.PureDevice;
    }

    
//  Set up the PresentParameters which determine how the device behaves
    PresentParameters presentParams  =   new  PresentParameters();
    presentParams.SwapEffect 
=  SwapEffect.Discard;
    
//  Make sure we are in windowed mode when we are debugging
#if  DEBUG
    presentParams.Windowed 
=   true ;
#endif
    
//  Now create the device
    device  =   new  Device(adapterOrdinal, DeviceType.Hardware,  this , createFlags, presentParams);

    如同注释所述,该代码分成四部分。
    1. 第一行代码只是获取默认适配器的名称(通常为 0)。与赌它为零不同,更安全的做法是使用 Manager 类来获取默

认适配器的名称。如果由于某种原因使得默认适配器的实际名称为 2,则采用这种方法不会出现问题。
 
    2. 接下来的一节代码用于确定传递给 Device 构造函数的 CreateFlags 枚举的设置,以及哪个设置控制设备创建后的

行为。我们再次使用 Manager 来获取默认适配器的功能(简称为 Caps)列表。然后使用此功能列表来确定是在硬件中执行

顶点处理(较快),还是在软件中执行(较慢,但保证始终工作)。这其实用词不当,因为 SoftwareVertexProcessing 实

际指使用 CPU 而 HardwareVertexProcessing 指使用 GPU。然后执行另一个检查,查看适配器是否支持纯设备,即图形卡可

以处理光栅化、矩阵转换以及打光和阴影计算。如果设备可以,而且前一个检查确定我们可以使用硬件顶点处理,则将

PureDevice 设置添加到 CreateFlags 枚举中。HardwareVertexProcessing 和 PureDevice 的组合为我们提供可能的最佳性

能,所以如果可能,要尽量使用它。
 
    3. 创建设备需要的最后一个参数是 PresentParameters 对象。这个对象确定设备向屏幕显示数据的方式,因此得名。

首先我们设置 SwapEffect 枚举,它确定缓冲和设备如何相互联系。我们通过选择 Discard 选项来简单地选择放弃后台缓冲

区,直接写入到前台缓冲区。在 If 语句中,我们确定应用程序是否在调试模式下运行。如果处于调试模式,我们不希望在

全屏模式下运行(这是默认情况),因为它使调试非常困难。使用这种方法确定配置好于对其硬编码而在发布游戏时忘了切

换回来。
 
    4. 最后一步是真正创建设备。我们传入默认适配器的序号、想要将设备绑定到的窗口、设备类型,然后传入前面创建的

CreateFlags 和 PresentParameters 对象。

    这段代码的实际结果就是使我们拥有一个有效的设备,可以用它在屏幕上进行绘制。
    OK,终于可以在程序中使用DirectX了,总算有点兴奋的感觉了。

  最后完成的代码如下:

 

using  System;
using  System.Collections.Generic;
using  System.ComponentModel;
using  System.Data;
using  System.Drawing;
using  System.Text;
using  System.Windows.Forms;
using  Microsoft.Samples.DirectX.UtilityToolkit;
using  Microsoft.DirectX;
using  Microsoft.DirectX.Direct3D;

namespace  BattleTank2005
{
    
public class GameEngine : Form
    
{
        
private double deltaTime;
        
private Device device;

        
private const DeviceType _deviceType = DeviceType.Reference;

    
/// <summary>
        
/// Required designer variable.
        
/// </summary>

        private System.ComponentModel.IContainer components = null;

        
/// <summary>
        
/// Clean up any resources being used.
        
/// </summary>
        
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>

        protected override void Dispose(bool disposing)
        
{
            
if (disposing && (components != null))
            
{
                components.Dispose();
            }

            
base.Dispose(disposing);
        }


        
Windows Form Designer generated code

        
public GameEngine()
        
{
            InitializeComponent();
            
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);

            
// Get the ordinal for the default adapter
            int adapterOrdinal = Manager.Adapters.Default.Adapter;

            
// Get our device capabilities so we can check them to set up the CreateFlags
            Caps caps = Manager.GetDeviceCaps(adapterOrdinal, _deviceType);
            CreateFlags createFlags;
            
// Check the capabilities of the graphcis card is capable of
            
// performing the vertex-processing operations
            
// The HardwareVertexProcessing choice is the best
            if (caps.DeviceCaps.SupportsHardwareTransformAndLight)
            
{
                createFlags 
= CreateFlags.HardwareVertexProcessing;
            }

            
else
            
{
                createFlags 
= CreateFlags.SoftwareVertexProcessing;
            }

            
// If the graphics card supports vertex processing check if the device can
            
// do rasterization, matrix transformations, and lighting and shading operations
            
// This combination provides the fastest game experience
            if (caps.DeviceCaps.SupportsPureDevice && createFlags == CreateFlags.HardwareVertexProcessing)
            
{
                createFlags 
|= CreateFlags.PureDevice;
            }

            
// Set up the PresentParameters which determine how the device behaves
            PresentParameters presentParams = new PresentParameters();
            presentParams.SwapEffect 
= SwapEffect.Discard;
            
// Make sure we are in windowed mode when we are debugging
#if DEBUG
            presentParams.Windowed 
= true;
#endif
            
// Now create the device
            device = new Device(
            adapterOrdinal,
            _deviceType,
            
this,
            createFlags,
            presentParams
            );


        }


        
protected override void OnPaint(PaintEventArgs e)
        
{
            deltaTime 
= FrameworkTimer.GetElapsedTime();
            
this.Text = string.Format("The framerate is {0}", FrameRate.CalculateFrameRate());


            FrameworkTimer.Start();
            device.Clear(ClearFlags.Target, Color.DarkBlue, 
1.0f0); device.Present();
            
this.Invalidate();
        }

    }


    
public class FrameRate
    
{
        
public static int CalculateFrameRate()
        
{
            
if (System.Environment.TickCount - lastTick >= 1000)
            
{
                lastFrameRate 
= frameRate;
                frameRate 
= 0;
                lastTick 
= System.Environment.TickCount;
            }

            frameRate
++;
            
return lastFrameRate;
        }

        
private static int lastTick;
        
private static int lastFrameRate;
        
private static int frameRate;


    }

}

 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值