Chinaunix首页 | 论坛 | 博客
  • 博客访问: 174361
  • 博文数量: 43
  • 博客积分: 827
  • 博客等级: 准尉
  • 技术积分: 487
  • 用 户 组: 普通用户
  • 注册时间: 2012-01-26 19:19
文章分类

全部博文(43)

文章存档

2015年(1)

2014年(1)

2013年(5)

2012年(36)

我的朋友

分类: WINDOWS

2012-05-06 17:10:56

Driver Renderer Process

在Irrlicht中一种渲染类型代表一个Renderer,在driver创建的时候会将内置的最基本的Renderer初始化好,并且每一个Renderer对应于一个Material Type。
因此在后面对Scene Node的setMaterialType时候就是设定RendererType。

在一个SceneNode的render中完成的过程:
Irrlicht主要是针对于FFP(Fixed Function Pipeline),
1: 设定好World Transform

2: 调用driver::setMaterial,将自己的Material设定到Driver中,一个SMaterial结构中包含了在Driver的Render State信息,Material属性信息等。注意的是,在setMaterial中调用了setActiveTexture,也就是说这里设定好了Texture(IDirect3DDevice9::SetTexture).
//! sets a material
void CD3D9Driver::setMaterial(const SMaterial& material)
{
        Material = material;
        OverrideMaterial.apply(Material);

        for (u32 i=0; i
        {
                // Set all the textures and tranform for the textures
                setActiveTexture(i, Material.getTexture(i));
                setTransform((E_TRANSFORMATION_STATE) ( ETS_TEXTURE_0 + i ),
                                material.getTextureMatrix(i));
        }
}

3: 调用Driver的渲染接口,在这个过程主要是设定好Render State
        1: 设定好顶点格式(FVF,因为Irrlicht主要针对于FFP),调用setVertexShader(vType);完成
        2: 根据LastMaterial和当前的Material的比较设定好Driver的状态(主要是通过IDirect3DDevice9::SetRenderState和SetTextureState以及SetSamplerState来完成);而这一步在setRenderStates3DMode()中完成
                在setRenderStates3DMode()中:
                        1: LastRenderer::OnUnsetMaterial():这里主要是对原有的Renderer做一些Unset操作
                        2: CurRenderer::OnSetMaterial():这里主要是针对一些该Renderer的静态性的设定        
                        3: CurRenderer::OnRender():这里主要是对该Renderer的一些动态数据的设定
        3: 根据Primitive Type渲染


////////////////////////////////////////////////////////////////////////////////////////////////
针对于setRenderState3DMode说明:
        
if (ResetRenderStates || LastMaterial != Material)
{
        // unset old material

                if (CurrentRenderMode == ERM_3D &&
                        LastMaterial.MaterialType != Material.MaterialType &&
                        LastMaterial.MaterialType >= 0 && LastMaterial.MaterialType < (s32)MaterialRenderers.size())
                        MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial();

        // set new material.

        if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size())
                        // Set some static data associate with the renderer, e.g.  The Render State with Device,
                        // The shader or some constant with the shader.NB. if the renderer is shader, then the 
                        // OnSetMaterial of the CallBack of Shader will be called.
                        MaterialRenderers[Material.MaterialType].Renderer->OnSetMaterial(
                                Material, LastMaterial, ResetRenderStates, this);
}

// Do per-frame
bool shaderOK = true;
if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size())
        // Set some dynamic data with render. e.g. The constants of shader.
        // The OnSetConstants of the CallBack of the shader will be called.
        shaderOK = MaterialRenderers[Material.MaterialType].Renderer->OnRender(this, LastVertexType);

LastMaterial = Material;                // Only here LastMaterial is set, So LastMaterial records the last frame material.

ResetRenderStates = false;

CurrentRenderMode = ERM_3D;

return shaderOK;

可见对于静态部分的设定,是仅当要重设状态或者当前Renderer和上一次的Renderer不同的时候才会:
LastRenderer::OnUnsetMaterial
CurRenderer::OnSetMaterial
所以这两个操作主要是对于一些静态性的设定,比如SetXXXState,SetVertexShader, SetPixelShader和Shader中不会改变的常量。

而对于CurRenderer::OnRender是每一次渲染都会被调用,因此他里面是动态的数据,比如Vertex Shader和Pixel Shader中会变化的数据。

////////////////////////////////////////////////////////////////////////////////////////////////
OnSetMaterial : Called by the IVideoDriver implementation the let the renderer set its needed render states. This is called during the IVideoDriver::setMaterial() call. When overriding this, you can set some renderstates or for example a vertex or pixel shader if you like.
OnSetMaterial中会对Device的Render State进行设定,对于Shader,会调用CallBack的OnSetMaterial。

OnRender : Called every time before a new bunch of geometry is being drawn using this material with for example drawIndexedTriangleList() call. OnSetMaterial should normally only be called if the renderer decides that the renderstates should be changed, it won't be called if for example two drawIndexedTriangleList() will be called with the same material set. This method will be called every time. This is useful for example for materials with shaders, which don't only set new renderstates but also shader constants.
对于一般的FFP中的Renderer,什么也没有做
而对于ShaderRenderer的OnRender中,CallBack的OnSetConstants会被调用,给予机会对Constant进行设定。

所以这两个接口要明白他们各自应该设定什么。前者是静态的设定,后者是动态的设定。
///////////////////////////////////////////////////////////////////////////////////////////////
在Irrlicht中使用Shader

Irrlicht主要是用于FFP,所以他对Shader的支持是很有限的

对于一个Shader Renderer他不属于内置的Renderer,因此要进行添加,IGPUProgrammingService接口提供了针对于Shader的功能
比如:
1:添加一个Shader Renderer
2:设定Constant

在添加了一个Shader Renderer后会返回一个Material Type,这个Type就代表了这个Shader Renderer。后面如果一个Scene Node要使用这个Renderer,就调用setMaterialType 进行设定。
一个Shader Renderer绑定有一个IShaderConstantSetCallBack CallBack接口,它里面主要就是
OnSetMaterial和OnRender两个接口,而作用在上面已经有介绍。

对于Irrlicht中使用Shader,他没有对Vertex Declaration支持,并且一个Shader Renderer绑定一个CallBack。

流程图示:







阅读(1358) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~