注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

写着玩

Bob

 
 
 

日志

 
 
 
 

多窗口D3D程序  

2009-11-05 10:01:03|  分类: 3D |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

转自:http://topic.csdn.net/t/20050216/14/3785566.html

  在DX8中,对多窗口的支持是通过创建更多的Swap   Chains来提供的。SDK中没有相关的例子而且文档也只是泛泛而谈。这篇文章就是为了解决这个问题,它将向您展示应当如何一步步地实现在多个分离窗口中渲染多个视图。  
   
  第一步:设置父框架窗口  
   
  在多视图的应用程序中,我们需要从最高层次的框架——这个框架将包含所有在他用户区之内的子视图窗口——开始我们的旅程。当父框架创建的时候,我们需要创建Direct3D   Device接口,为其指定使用窗口模式,而且设置这最高层次的窗口句柄作为“焦点窗口”(Focus   Window怎么翻译   T_T?)的句柄:  
   
  g_pD3D=Direct3DCreate8(D3D_SDK_VERSION);  
  if   (!g_pD3D)   return   -1;  
  D3DPRESENT_PARAMETERS   d3dpp;    
  ZeroMemory(   &d3dpp,   sizeof(d3dpp)   );  
  d3dpp.Windowed   =   TRUE;  
  d3dpp.SwapEffect   =   D3DSWAPEFFECT_COPY;  
  //   Use   the   current   display   mode.   使用当前的显示模式  
  D3DDISPLAYMODE   mode;  
  if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT   ,   &mode)))   {  
          SAFE_RELEASE(g_pD3D);  
          return   -1;  
  }  
  d3dpp.BackBufferFormat   =   mode.Format;  
  d3dpp.BackBufferWidth   =   mode.Width;  
  d3dpp.BackBufferHeight   =   mode.Height;  
  d3dpp.EnableAutoDepthStencil=TRUE;  
  d3dpp.AutoDepthStencilFormat   =   D3DFMT_D16;  
  //   m_hWnd   is   handle   to   top   level   window         m_hWnd是最高层窗口的句柄  
  if(   FAILED(   g_pD3D->CreateDevice(   D3DADAPTER_DEFAULT,   D3DDEVTYPE_HAL,   m_hWnd,  
                                                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,  
                                                                      &d3dpp,   &g_pd3dDevice)   )   )   {  
          SAFE_RELEASE(g_pD3D);  
          return   -1;  
  }  
   
  注意上面代码处于简单考虑并没有去测试深度缓存的格式(?depth   format),而只是选择了一个确定的格式(D3DFMT_D16)。您的程序应该为需要渲染的Render   Target选择一个可接受的深度缓存格式。  
   
  Device都需要有帧缓存,这样子视图才能进行渲染,同时,深度缓冲也应当被不同的视图进行共享。帧缓存和深度缓存都被设置为全屏幕大小,以考虑到可能窗口会被改变大小的情况。如果不的话,窗口改变大小的时候,就需要Reset   Device和重新创建Swap   Chain。  
   
  Step   2   -   Setting   Up   View   Windows    
  第二步:设置子视图窗口  
   
  现在我们可以准备创建我们的子窗口也就是视图窗口,并把它们与交换链关联以使得他们可以被渲染到Device上。当窗口创建后,下面的代码将为子窗口创建一个交换链:  
   
  D3DPRESENT_PARAMETERS   d3dpp;    
  ZeroMemory(   &d3dpp,   sizeof(d3dpp)   );  
  d3dpp.Windowed   =   TRUE;  
  d3dpp.SwapEffect   =   D3DSWAPEFFECT_COPY;  
  //   Use   the   current   display   mode.     使用当前的显示模式  
  D3DDISPLAYMODE   mode;  
  g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT   ,   &mode);  
  d3dpp.BackBufferFormat   =   mode.Format;  
  //   m_hWnd   contains   child   window   handle     m_hWnd储存子窗口的句柄  
  d3dpp.hDeviceWindow=m_hWnd;  
  //   m_pSwapChain   is   IDirect3DSwapChain   *       m_pSwapChain是一个IDirect3DSwapChain*对象  
  g_pd3dDevice->CreateAdditionalSwapChain(&d3dpp,   &m_pSwapChain);  
   
  经过这些代码之后,m_pSwapChain变量就储存了IDirect3DSwapChain接口的指针,这个接口将储存子窗口视图区所对应的帧缓冲。  
   
  Step   3   -   Rendering   a   View  
  第三步:渲染视图  
   
  在渲染每个视图窗口之前,我们必须使得Device来渲染对应的帧缓冲,这我们就需要用到SetRenderTarget方法。我们向其中传入子窗口SwapChain交换链的后备缓冲BackBuffer,以及使用最开始跟着Device一起创建的深度缓冲。  
   
  LPDIRECT3DSURFACE8   pBack=NULL,pStencil=NULL;  
  m_pSwapChain->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&pBack);  
  g_pd3dDevice->GetDepthStencilSurface(&pStencil);  
  g_pd3dDevice->SetRenderTarget(pBack,pStencil);  
  pBack->Release();  
  pStencil->Release();  
   
  注意我们必须Release掉Stencil和BackBuffer的指针,因为GetBackBuffer和GetDepthStencilSurface这两个函数都会调用COM的AddRef方法,来增加相应COM接口的引用计数,因此如果不删除它们,将会导致内存泄露。  
   
  我们现在已经做好准备渲染视图窗口了。渲染的方法看起来和我们平常用的方法差不多,只是有一点:我们现在需要调用Swap   Chain的接口,而不是Device的接口。  
   
  g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,0x00000000,1.0,0);  
  if   (SUCCEEDED(g_pd3dDevice->BeginScene()))   {  
           
          //   rendering   code   goes   here     渲染代码写在这里  
   
          g_pd3dDevice->EndScene();  
  }  
  m_pSwapChain->Present(NULL,NULL,NULL,NULL);  
   
  Step   4   -   Handling   Resize   of   Child   Views  
  第四步,子窗口的Resize问题  
   
  如果窗口的视图区大小和SwapChain的大小不一,那么DirectX将通过Stretch   Blit来自动处理图像的伸缩变化。尽管这可能并不令人期待,因为这在视图区变大的时候将导致图像的模糊。  
   
  如果要解决这个问题,您需要为子窗口的WM_SIZE消息写一段处理代码,这段代码Release已经存在的Swap   Chain交换链,并且使用第二步中的代码创建一个崭新的Swap   Chain交换链。  

  评论这张
 
阅读(1020)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017