CEGUI 对RTT纹理的支持------Gamebryo实现渲染到CEGUI窗口

  最近在纠结新版CEGUI的特性研究和拓展。验证并实现几个CEGUI的特性:

1、CEGUI对Shader的支持拓展。

2、CEGUI用Shader实现灰化,多纹理图片叠层。

3、Gamebryo渲染到CEGUI窗口纹理(装备预览)。

 

以下完整解释下第三点的实现,Gamebryo是在Frame System帧系统实现的:

1、构建一个NiRenderClick其作为渲染主角,其渲染结果作为输出,渲染到CEGUI窗口:

RTTHandleClick.h class RTTHandleClick : public NiRenderClick { public: RTTHandleClick(); ~RTTHandleClick(){}; // Functions for reporting statistics about the most recent frame. virtual unsigned int GetNumObjectsDrawn() const; virtual float GetCullTime() const; virtual float GetRenderTime() const; protected: virtual void PerformRendering(unsigned int uiFrameID); WorldManager* m_pkWorldManager; // Rendering statistics. float m_fRenderTime; }; RTTHandleClick.cpp void RTTHandleClick::PerformRendering(unsigned int uiFrameID) { NiDX9Renderer* pkD3DRenderer = NiDX9Renderer::GetRenderer(); NiRenderer* pkRenderer = NiRenderer::GetRenderer(); //......................... //中间省略大堆渲染状态处理 m_pkWorldManager->BeginCamera(); m_pkWorldManager->DrawRTT();//实际渲染角色方法,自己要渲染什么写里面 m_pkWorldManager->EndCamera(); //......................... //中间省略大堆渲染状态处理 }

 

2、同样构建一个CEGUIHandleClick作为CEGUI的渲染。

 

class CEGUIHandleClick : public NiRenderClick { public: CEGUIHandleClick(); ~CEGUIHandleClick(){}; // Functions for reporting statistics about the most recent frame. virtual unsigned int GetNumObjectsDrawn() const; virtual float GetCullTime() const; virtual float GetRenderTime() const; protected: virtual void PerformRendering(unsigned int uiFrameID); // Rendering statistics. float m_fRenderTime; };

 

3、构建一个RunHandleStep,继承于NiDefaultClickRenderStep。

然后把上面两个Click加入此Step:


 m_pkRTTClick = NiNew RTTHandleClick;
 m_pkCEGUIClick = NiNew CEGUIHandleClick;
 AppendRenderClick(m_pkRTTClick);
 AppendRenderClick(m_pkCEGUIClick);

 

同时注册两个方法,一个Step前后回调函数:
 SetPreProcessingCallbackFunc(CopyRTGBufferToTexture,this);
 SetPostProcessingCallbackFunc(SetUITexture,this);

 

4、让RTTHandleClick渲染到纹理:

NiTexture::FormatPrefs kPrefs; kPrefs.m_ePixelLayout = NiTexture::FormatPrefs::TRUE_COLOR_32; kPrefs.m_eAlphaFmt = NiTexture::FormatPrefs::SMOOTH; NiDX9Renderer* pkD3DRenderer = NiDX9Renderer::GetRenderer(); //构建一张可渲染纹理 m_spRenderTexture = NiRenderedTexture::Create(width, height, NiRenderer::GetRenderer(), kPrefs); //后面详细构建RenderGroup过程 m_spRenderGroup = m_pRenderManger->CreateRenderTargetGroupFromTexture(m_spRenderTexture);

 

注意 m_spRenderGroup =   NiRenderTargetGroup::Create(

m_spRenderTexture->GetBuffer(), pkD3DRenderer, true, true);

m_spRenderGroup =  m_pRenderManger->CreateRenderTargetGroupFromTexture(m_spRenderTexture);

 

NiRenderTargetGroup的构建有两种方法,我们不能取其默认的第一种,因为Usage为D3DUSAGE_RENDERTARGET的Texture不能进行反锯齿, 而且Pool必须为D3DPOOL_DEFAULT. 如果想利用RenderTarget做为纹理又想反锯齿, 可以先把场景渲染到一个CreateRenderTarget创建的Surface(或BackBuffer)上, 再用IDirect3DDevice9::StretchRect拷贝到纹理上。

 

我详细列出CreateRenderTargetGroupFromTexture的代码细节:

 

NiRenderTargetGroupPtr AFRendererManager::CreateRenderTargetGroupFromTexture(NiRenderedTexture* pRenderedTexture) { NIASSERT(pRenderedTexture); NiRenderer* pkRenderer = 0; pkRenderer = NiRenderer::GetRenderer(); LPDIRECT3DSURFACE9 pkRenderSurface = CreateMSAARenderTargetSurface(pRenderedTexture); NIASSERT(pkRenderSurface); Ni2DBuffer* pkColorBuffer = NULL; NiDX92DBufferData* pkColorBufferData = NiDX9Direct3DBufferData::Create(pkRenderSurface, pkColorBuffer); NI_UNUSED_ARG(pkColorBufferData); NIASSERT(pkColorBufferData && pkColorBuffer); // pkColorBufferData now has a reference to the surface, so we can // release the original reference. pkRenderSurface->Release(); // Create NiRenderTargetGroup using default depth/stencil buffer // We know that the size and MS levels of the new render target // surface are identical to the default back buffer, so we know the // default depth/stencil buffer is compatible. NiRenderTargetGroupPtr spPostEffectTargetGroup = NiRenderTargetGroup::Create( pkColorBuffer, pkRenderer, true); return spPostEffectTargetGroup; } LPDIRECT3DSURFACE9 AFRendererManager::CreateMSAARenderTargetSurface(NiRenderedTexture* pkRenderedTexture) { NIASSERT(pkRenderedTexture); NiRenderer* pkRenderer = 0; pkRenderer = NiRenderer::GetRenderer(); NIASSERT(pkRenderer); NiDX9Renderer* pkDX9Renderer = NiDynamicCast(NiDX9Renderer, pkRenderer); NIASSERT(pkDX9Renderer); // Get MultiSamplers parameters D3DPRESENT_PARAMETERS* pkD3DPresentParams = pkDX9Renderer->GetPresentParams(); D3DMULTISAMPLE_TYPE kMultiSampleType = pkD3DPresentParams->MultiSampleType; unsigned int kMultiSampleQuality = (unsigned int)pkD3DPresentParams->MultiSampleQuality; // Get pixel format information from rendered texture D3DFORMAT eFormat = NiDX9PixelFormat::DetermineD3DFormat( *pkRenderedTexture->GetPixelFormat()); // Create render target surface LPDIRECT3DDEVICE9 pkDevice = pkDX9Renderer->GetD3DDevice(); LPDIRECT3DSURFACE9 pkRenderSurface = NULL; HRESULT hr = E_FAIL; hr = pkDevice->CreateRenderTarget(pkRenderedTexture->GetWidth(), pkRenderedTexture->GetHeight(), eFormat, kMultiSampleType, kMultiSampleQuality, FALSE, &pkRenderSurface, NULL); NIASSERT(SUCCEEDED(hr) && pkRenderSurface); return pkRenderSurface; }

 

创建一个RenderTargetSurface,然后把Surface拷到NiDX92DBufferData,然后通过NiDX92DBufferData构建NiRenderTargetGroup。

 

5、在RenderStep执行后的回调SetUITexture中。(前面SetPostProcessingCallbackFunc(SetUITexture,this),已经注册)

注意SetUITexture代码细节:

bool RunHandleStep::SetUITexture(NiRenderStep* pkCurrentRenderClick, void* pvCallbackData) { RunHandleStep* pkThis = (RunHandleStep*) pvCallbackData; NiDX9TextureData* pkData = (NiDX9TextureData*)pkThis->m_spRenderTexture->GetRendererData(); LPDIRECT3DTEXTURE9 rttTexture= (LPDIRECT3DTEXTURE9)pkData->GetD3DTexture(); // m_pSample->SetRttTexture(rttTexture); GameGUISystem::Create()->SetRttTexture(rttTexture); //D3DXSaveTextureToFile(("F://TEST_A.tga"),D3DXIFF_TGA,rttTexture,NULL); return true; } bool GameGUISystem::SetRttTexture(LPDIRECT3DTEXTURE9 pTextureData) { WindowManager& winMgr = WindowManager::getSingleton(); CEGUI::Direct3D9Renderer* pRender = static_cast<CEGUI::Direct3D9Renderer*>(CEGUI::System::getSingleton().getRenderer()); Window* background = winMgr.getWindow("Demo7/Window3/RTT"); if (!m_pImageset) { Texture& tex = pRender->createTexture(pTextureData); m_pImageset = &(ImagesetManager::getSingleton().create("RTTImage", tex)); m_pImageset->defineImage("RttImage", Point(0.0f, 0.0f),tex.getSize(), CEGUI::Point(0.0f,0.0f)); } Texture* texture = m_pImageset->getTexture(); ((Direct3D9Texture*)texture)->setDirect3D9Texture(pTextureData); background->setProperty("Image", "set:RTTImage image:RttImage"); return true; }

 

就如此简单。哈哈。大家实现了没。。

 

 

你可能感兴趣的:(Parameters,float,reference,shader,statistics,Direct3D)