4

游戏引擎场景编辑器实现:Direct3D只绘制一次

 11 months ago
source link: https://gwb.tencent.com/community/detail/133965
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

游戏引擎场景编辑器实现:Direct3D只绘制一次

发表于2023-08-29
评论0 239浏览

在阅读《DirectX 12 3D游戏开发实战》,也就是DirectX的龙书。 
看到第4章:Direct3D的初始化的代码。 
Direct3D的初始化的代码的Draw函数,我添加了flag,让Draw函数只绘制场景一次,绘制后,交换前后台缓冲区。 
这样窗口使用的一直是仅一次绘制的前台缓冲区的图像数据。

void InitDirect3DApp::Draw(const GameTimer& gt) 
{  
   //flag的作用:只绘制一次 
   static bool flag = false; 
   if (flag == true) {  
       return; 
    } 

// Reuse the memory associated with command recording. 
   // We can only reset when the associated command lists have finished execution on the GPU. 
   ThrowIfFailed(mDirectCmdListAlloc->Reset()); 

// A command list can be reset after it has been added to the command queue via ExecuteCommandList. 
   // Reusing the command list reuses memory. 
   ThrowIfFailed(mCommandList->Reset(mDirectCmdListAlloc.Get(), nullptr)); 

// Indicate a state transition on the resource usage. 
   mCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(CurrentBackBuffer(), 
 D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET)); 

// Set the viewport and scissor rect.  This needs to be reset whenever the command list is reset. 
   mCommandList->RSSetViewports(1, &mScreenViewport); 
   mCommandList->RSSetScissorRects(1, &mScissorRect); 

// Clear the back buffer and depth buffer. 
   mCommandList->ClearRenderTargetView(CurrentBackBufferView(), Colors::LightSteelBlue, 0, nullptr); 
   mCommandList->ClearDepthStencilView(DepthStencilView(), D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, 1.0f, 0, 0, nullptr); 

// Specify the buffers we are going to render to. 
   mCommandList->OMSetRenderTargets(1, &CurrentBackBufferView(), true, &DepthStencilView()); 

// Indicate a state transition on the resource usage. 
   mCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(CurrentBackBuffer(), 
 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); 

// Done recording commands. 
   ThrowIfFailed(mCommandList->Close()); 

// Add the command list to the queue for execution. 
   ID3D12CommandList* cmdsLists[] = { mCommandList.Get() }; 
   mCommandQueue->ExecuteCommandLists(_countof(cmdsLists), cmdsLists); 

// swap the back and front buffers 
   ThrowIfFailed(mSwapChain->Present(0, 0)); 
   mCurrBackBuffer = (mCurrBackBuffer + 1) % SwapChainBufferCount; 

flag = true; 

// Wait until frame commands are complete.  This waiting is inefficient and is 
   // done for simplicity.  Later we will show how to organize our rendering code 
   // so we do not have to wait per frame. 
   FlushCommandQueue(); 

用UE、Unity的时候,游戏引擎的场景编辑器里界面呈现游戏场景,在我们不碰场景编辑器的时候,场景编辑器始终是一个画面。 
如果游戏引擎为场景编辑器里的画面一直不断地渲染场景,交换前后台缓冲,会非常消耗性能。 
在用户没有碰场景编辑器时,即场景编辑器里的场景没有摄像机移动、角度变换,选定物体,平移、缩放、旋转物体,添加物体时,场景编辑器里的画面是不变的。 
所以,在用户没有碰场景编辑器时,游戏引擎只需要为场景编辑器里的场景绘制一次,交换一次前后台缓冲即可。 
这样,窗口的图像数据始终是一个画面。 
在用户使用场景编辑器时,才需要进行用户交互时长的渲染、呈现(交换前后台缓冲区指针)。 
如此,可以节省性能。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK