引擎技术研究之渲染到目标

 

渲染到目标,通俗地说就是把特定场景的物体放在目标上显示。这个目标可以是纹理,窗口等。本文介绍的是把场景渲染到纹理,并以图片的形式保存起来。

其原理如下:

在初始化时创建一纹理Texture,获取指向该纹理的指针,接着创建深度表面,并获取指向其的指针DepthSurface。在渲染时先获取系统的默认的渲染目标和深度模板表面,再设置Texture的表面为渲染目标,并通过DepthSurface设置深度模板表面,接着渲染场景中的物体,并保存该纹理到制定路径,最后恢复系统的默认的渲染目标和深度模板表面。

二 具体步骤:

设计一渲染目标类RenderTarget,负责纹理,深度表面的创建,以及设置渲染目标,深度表面等。现介绍其实现:

初始化函数:该函数接收外界传入的widthheight作为纹理的宽和高,

其功能有:1 是根据widthheight创建纹理,调用IDirect3DDevice9接口的

CreateTexture(width,height,1,D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,

D3DPOOL_DEFAULT,&mpRTT,NULL);

mpRTT为指向该纹理的指针。

2 根据widthheigh创建深度表面,调用IDirect3DDevice9接口的

CreateDepthStencilSurface(width,height,D3DFMT_D24S8,

D3DMULTISAMPLE_NONE,0,TRUE,&mpDepthSurface,NULL);

mpDepthSurface为指向该深度表面的指针

渲染函数:首先要获取一个系统设备指针device,定义并初始化IDirect3DSurface9类型指针    pOldZBufferpRenderSurface pBackBuffer

接着获取系统默认的渲染目标device->GetRenderTarget(0,&pBackBuffer);

获取系统d3d默认深度表面device->GetDepthStencilSurface(&pOldZBuffer);

   设置mpRTT纹理的表面作为渲染目标

           mpRTT->GetSurfaceLevel(0,&pRenderSurface);

       device->SetRenderTarget(0,pRenderSurface);

再设置深度表面 device->SetDepthStencilSurface(mpDepthSurface);

执行场景物体的渲染操作后,再恢复系统默认设置

       device->SetRenderTarget(0,pBackBuffer);

       device->SetDepthStencilSurface(pOldZBuffer);

最后释放引用  SAFE_RELEASE(pBackBuffer);SAFE_RELEASE(pRenderSurface);

三 监听器模式实现:

现讨论一下场景物体的渲染部分:

因某些场景的不同而需要进行特殊的渲染操作,这样就要求根据不同场景调用不同的渲染流程。这样需用到一设计模式:监听器模式。

其原理如下:先设置调用哪一种监听器,再根据不同的监听器执行其相应的渲染操作。

实现如下:

1 先定义一虚基类:Listener,定义两个纯虚函数:

virtual void Execute()=0;   virtual void AfterExecute()=0;

再定义两个Listener的子类:ReflectListenerCurrentSceneListener 并改写其纯虚函数,可在Execute()里进行场景物体模型的渲染操作,AfterExecute()执行相关的重置操作。

2 在场景类Scene的私有成员列表中定义:

RenderTarget                  *mpReflectTarget;

ReflectListener               *mpSceneRenderer;

RenderTarget                  *m_pCurrentSceneTarget;

CurrentSceneListener          *m_pCurrentListener;

即一个监听器对应一个渲染目标。

3 RenderTarget私有成员列表中定义:Listener  *mpRenderListener;

并添加对应的设置监听器的接口函数 SetRenderEvent(Listener *pListener)

再添加一成员函数__Rend(),其在RenderTarget类的Rend()中调用,__Rend()首先要进行清理操作:执行IDirect3DDevice9接口的

Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(255,255,255),1.0f, 0);

再执行:mpRenderListener->Execute();mpRenderListener->AfterExecute();

这样可根据不同的监听器执行不同的渲染流程。

4 在场景类的初始化函数执行:

    m_pCurrentListener=new CurrentSceneListener();

    m_pCurrentSceneTarget=new RenderTarget();

    m_pCurrentSceneTarget->Initial("currentsceneTarget",1024,1024);

    m_pCurrentSceneTarget->SetRenderEvent(m_pCurrentListener);

  同理可使用ReflectListener监听器。

   5 因本文描述的是渲染目标到纹理,并以图片的格式保存,那可在Scene的析构函数里执行场景物体的渲染操作:   m_pCurrentSceneTarget->Render();

这样保存的是运行界面关闭时的那个场景画面。

四 概括一下流程:

   Scene的初始化函数执行RenderTargetInitial(),接着设置监听器SetRenderEvent(),再在 Scene的析构函数里执行RenderTargetRender()Render()调用RenderTarget__Render(),    __Render()调用相应监听器的 Execute() AfterExecute(),在Execute()进行场景物体的渲染操作。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值