DirectX示例翻译和解析StateManager Sample

本例子是DirectX示例【StateManager Sample】

前言

     本篇DirectX的例子,讲的是如何使用EffectStateManager来对Effect中的StateManager进行管理。通过对场景中的对象进行排序,从而减少StateManager的重新辅助,以实现系统性能的提高。
     要实现本例的效果,系统需要的环境是加载和渲染Effect,实现抽象类EffectStateManager。
     本例由于数据量或者我的电脑性能太好,没有发现有大的差异。


StateManager Sample(状态管理器[0])

     This sample demonstrates how to implement a set of callbacks using the ID3DXEffectStateManager to measure the number and types of state changes in a render loop managed by the effect system. The sample also demonstrates how to use the callbacks to override the default state management, which gives an application the option of implementing a custom approach to state filtering. An application that is CPU-bound is very likely to improve performance dramatically by controlling the amount of redundant state changes that occur in a complex render loop.

     这个例子展示了如何使用ID3DXEffectStateManager 的回调函数,对效果系统(Effect System[1])管理的一个渲染周期进行状态改变次数和类型的监控。 这个例子同样展示了如何使用回调函数来重载默认的状态管理器,这种方式可以让用户自定义状态过滤(state filtering)。在一个比较复杂的渲染周期中,减少冗余的状态改变,是极可能改善基于CPU-bound应用的性能。

How The Sample Works

This sample renders a scene composed of several mesh objects including a gazebo, trees, rocks, terrain, and a skybox. Each mesh may be composed of multiple materials (snow, wood, etc). Each material is implemented by a different effect. Because of the scene complexity, the render sequence has many state changes to render the variety of materials and objects. The render sequence is created after calling these functions in OnCreateDevice:

     在本例子中,环境是由多个模型构建的,包括一个毛房,一些树和石头,地面还有天空。每一个模型由多个材质组成(比如雪,木头)。每个材质也有不同的效果(Effect)。因为环境的复杂性,所以为了渲染不同类型的材质和对象,渲染过程中会有多个状态发生改变。系统在设备创建后(OnCreateDevice)会自动的调用渲染过程。
  • BuildSceneFromX - This method loads the scene .x file, which specifies each of the meshes and their world transform. Each mesh then loads it's corresponding materials, which consists of an effect instance and the associated textures (if any).
  • BuildSceneFromX-这个方法加载.x文件并添加到场景中,加载后会产生对应的Mesh并初始化它在场景中的位置。每个模型同时会加载模型的材质信息列表,一个材质信息包含一个效果实例(effect instance)还有它的材质(如果存在)(这个x模型非常规x模型,还扩展了其他信息)
  • QueueAndSortRenderables - This method does two things. First, it adds to the render queue all the state changes necessary to render the scene. Second, it reorders the queue according to the type of device, and the state manager.
  • QueueAndSortRenderables -这个方法做两件事情。一,它把渲染场景需要的状态改变全部添加到渲染队列中。二,对渲染队列和状态管理器进行排序,排序的方法会根据设备的类型。
  • SetStateManager - This method propagates the state manager to each of the effects in preparation for rendering
  • SetStateManager - 这个方法在每个效果渲染前设置它的状态管理器。

    The sample demonstrates the benefits of filtering redundant state changes with a per device. When a device is created (IDirect3D9::CreateDevice), the type of device is specified with D3DDEVTYPE. A pure device (created with D3DCREATE_PUREDEVICE) filters a smaller subset of possible state change commands. It is very fast because is essentially streams the pipeline commands striaght to the hardware. A pure device does not do any validation of parameters, and does little or no redundant state filtering. In constrast, a non-pure device (created without D3DCREATE_PUREDEVICE) will check each state change for redundancy, and discard them. This reduces the amount of work that the device will need to perform.

    这个例子展示了通过过滤掉冗余的状态改变而带来的优势。当一个device创建的时候会设定一个D3DDEVTYPE值。一个
pure device(通过D3DCREATE_PUREDEVICE参数创建)会选择一个较小的可能状态改变命令集,它之所以运行快是因为它从本质上将管道数据(pipeline commands)直接交给硬件。相反的,一个非pure device(创建的时候没有添加D3DCREATE_PUREDEVICE参数)会检查每一个状态改变,如果是冗余的状态改变,还有丢弃。(pure device)减少了设备需要做的事情。
    

      The ID3DXEffectStateManager makes it possible to write custom user handlers for state changes. You can measure the number of state changes, that are happening, or even write handlers that perform custom processing (such as filtering out redundant state changes). This is precisely what the StateManager sample does. When you run the sample, it defaults to: running a pure device, and filtering redundant states with ID3DXEffectStateManager. This is done by creating a CPureDeviceStateManager class which derives from ID3DXEffectStateManager.

     ID3DXEffectStateManager可以实现当状态改变时的自定义方法。你可以计算出有多少个状态改变,或者甚至写一个处理方法来自定义处理过程(比如过程掉冗余的状态改变)。这些也是StateManager 做的事情。当你跑这个例子的时候,它默认是运行在pure device上的,并通过ID3DXEffectStateManager过滤冗余的状态。本例子中CPureDeviceStateManager类实现了接口ID3DXEffectStateManager来实现过滤。
     
     CPureDeviceStateManager counts the state changes, filters redundant IDirect3DDevice9::SetRenderState, IDirect3DDevice9::SetSamplerState and IDirect3DDevice9::SetTextureStageState commands, and invokes the corresponding Direct3D command. The number of redundant state changes that were filtered is returned to the application
     CPureDeviceStateManager 计算有多高状态改变,屏蔽了冗余的 IDirect3DDevice9::SetRenderStateIDirect3DDevice9::SetSamplerState and IDirect3DDevice9::SetTextureStageStatecommands方法,同时实现了一些相关的Direct3D 命令。并屏蔽的多余的状态改变的数量会告知系统。

      

     本例子中:

State Changes(状态改变数)Filtered State Changes(过滤的状态改变数)Number of Rocks(石头的个数)% Reduction in State Changes(减少状态改变比例)
120381-31
79713856200-48

  

Another Performance Tip: Reordering The Render Sequence

另一个性能提示:记录渲染序列

      In addition to filtering redundant state changes, another option to improve performance is to re-order the render sequence. This can have an impact especially on a non-pure device, or in a scenario that is more limited by the amount of matrix transforms that are set (as opposed to the number of materials used). For example, here is a render sequence that is ordered by each mesh object:

    除了减少多余的状态改变,另外一个改善性能的是方法是对渲染序列进行排序。这么做对一个非纯设备(non-pure device)尤其有用,还有对那些限定转换矩阵数量的场景(而不是限定使用材质的数量)。例如,下面是一个根据每个模型进行排序的渲染序列代码。

// Render each mesh object
For each instance of mesh x
    Setup transforms (ID3DXEffect SetMatrix)
    For each material of mesh x
        Set up material (ID3DXEffect Begin/BeginPass)
        Draw

This is the same sequence re-ordered by material:

// Render each effect to minimize state changes
For each material y
    Set up material (ID3DXEffect Begin/Begin Pass)
    For each instance of material y
      Set up transforms (ID3DXEffect SetMatrix)
      Draw

     Each sequence is better in some situations and worse in others. An application that has lots of materials may reduce the number of redundant state changes by ordering by material.

   一个(渲染)序列可能在一些场景中比较好,而另外一些场景中表现的比较差。一个应用可以通过对材质的排序从而减少渲染状态的改变。

       For further information about measuring the performance of a CPU bound scenario using similar techniques to a profiler, see Accurately Profiling Direct3D API Calls (Direct3D 9).

    更多的关于如何衡量基于CPU bound性的场景中的CPU性能    可以使用类似技术的工具,请参看Accurately Profiling Direct3D API Calls (Direct3D 9).


翻译完毕,下面是代码讲解

    1 类解释

CInstance 一个可渲染对象,包括渲染数据(比如CMeshObject),它      的位置。
CMeshObject一个渲染模型,包括一组材质(vector <CMaterial*>),模型(mesh),名称(m_wsName)等
CRenderable 等价于CInstance,只是提供了一些比较材质等的方法。
  CMaterial 材质,包括效果CEffect,还有纹理列表(<CTexture*> m_vecTextures)
CTexture 纹理信息,除了纹理数据,包括还有名称等
CEffect 效果信息,处理Effect还包括Device.Transform的一些矩阵信息
CEffectInstance    绑定模型材质到Effect中。
CStateManagerInterface  实现接口ID3DXEffectStateManager,从而达到管理StateManager的效果,它下面实现两个具体的EffectStateManager,
一个是CPureDeviceStateManager,另外一个是CBaseStateManager,而CPureDeviceStateManager也是继承
CBaseStateManager
CPureDeviceStateManager 这个类维护State的参照表。包括samplerStage,textureStateStage,RenderStates。在设置State的时候设置哪些参数
发生了改变,并进行计数。
  
  


  2 方法解释

  • HRESULT CTexture::Create( LPDIRECT3DDEVICE9 pDevice, LPCWSTR wszFilename, CTexture** ppTexture )
  • 创建纹理(会根据纹理的名称去重)(支持2D,3D材质的加载)
  • HRESULT CTexture::GetNormalMapPtr( LPDIRECT3DBASETEXTURE9* ppTexture )
  • 从一个高度图(height map)创建法线贴图
  • STDMETHOD( SetRenderState )( THIS_ D3DRENDERSTATETYPE d3dRenderState, DWORD dwValue )
  • 设置RenderState并且计算状态改变的量。同类型的还有SetSamplerState,SetTextureStageState
  • HRESULT CEffect::SetStateManager( LPD3DXEFFECTSTATEMANAGER pManager )
  • Effect对象设置StateManager。

[名1]  StateManager Sample  状态管理器
[名2] Effect System 效果系统
[名3] state filtering  状态过滤
[名4] pipeline commands  管道数据
[名5] pure device  纯设备
[名5] non-pure device  虚拟设备(非纯设备)
[名6] texture   纹理
[名7] material 材质
[名8] Normal Map 法线贴图

[注1]    CPU bound 指的是系统的 硬盘/内存 效能 相对 CPU 的效能 要好很多,此时,系统运作,大部分的状况是 CPU Loading 100%,CPU 要读/写 I/O (硬盘/内存),I/O在很短的时间就可以完成,而 CPU 还有许多运算要处理,CPU Loading 很高)
[注2] Normal Map 参考http://www.cnblogs.com/kex1n/archive/2011/08/26/2154582.html,
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值