CmD3D9RenderWindow.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  1. #include "CmD3D9RenderWindow.h"
  2. #include "CmInput.h"
  3. #include "CmCoreThread.h"
  4. #include "CmViewport.h"
  5. #include "CmException.h"
  6. #include "CmD3D9RenderSystem.h"
  7. #include "CmRenderSystem.h"
  8. #include "CmBitwise.h"
  9. #include "Win32/CmPlatformWndProc.h"
  10. #include "CmD3D9VideoModeInfo.h"
  11. #include "CmD3D9DeviceManager.h"
  12. namespace BansheeEngine
  13. {
  14. D3D9RenderWindow::D3D9RenderWindow(const RENDER_WINDOW_DESC& desc, HINSTANCE instance)
  15. : RenderWindow(desc), mInstance(instance), mIsDepthBuffered(true), mIsChild(false)
  16. {
  17. mDevice = NULL;
  18. mIsFullScreen = false;
  19. mIsExternal = false;
  20. mHWnd = 0;
  21. mActive = false;
  22. mClosed = false;
  23. mDisplayFrequency = 0;
  24. mDeviceValid = false;
  25. }
  26. D3D9RenderWindow::~D3D9RenderWindow()
  27. { }
  28. void D3D9RenderWindow::initialize_internal()
  29. {
  30. HINSTANCE hInst = mInstance;
  31. mMultisampleType = D3DMULTISAMPLE_NONE;
  32. mMultisampleQuality = 0;
  33. mMultisampleCount = mDesc.multisampleCount;
  34. mVSync = mDesc.vsync;
  35. mVSyncInterval = mDesc.vsyncInterval;
  36. HWND parentHWnd = 0;
  37. HWND externalHandle = 0;
  38. NameValuePairList::const_iterator opt;
  39. // parentWindowHandle -> parentHWnd
  40. opt = mDesc.platformSpecific.find("parentWindowHandle");
  41. if(opt != mDesc.platformSpecific.end())
  42. parentHWnd = (HWND)parseUnsignedInt(opt->second);
  43. // externalWindowHandle -> externalHandle
  44. opt = mDesc.platformSpecific.find("externalWindowHandle");
  45. if(opt != mDesc.platformSpecific.end())
  46. externalHandle = (HWND)parseUnsignedInt(opt->second);
  47. mIsChild = parentHWnd != 0;
  48. if (!externalHandle)
  49. {
  50. DWORD dwStyle = WS_VISIBLE | WS_CLIPCHILDREN;
  51. DWORD dwStyleEx = 0;
  52. HMONITOR hMonitor = NULL;
  53. MONITORINFO monitorInfo;
  54. RECT rc;
  55. // If we specified which adapter we want to use - find it's monitor.
  56. if (mDesc.monitorIndex != -1)
  57. {
  58. IDirect3D9* direct3D9 = D3D9RenderSystem::getDirect3D9();
  59. for (UINT32 i=0; i < direct3D9->GetAdapterCount(); ++i)
  60. {
  61. if (i == mDesc.monitorIndex)
  62. {
  63. hMonitor = direct3D9->GetAdapterMonitor(i);
  64. break;
  65. }
  66. }
  67. }
  68. // If we didn't specified the adapter index, or if it didn't find it
  69. if (hMonitor == NULL)
  70. {
  71. POINT windowAnchorPoint;
  72. // Fill in anchor point.
  73. windowAnchorPoint.x = mDesc.left;
  74. windowAnchorPoint.y = mDesc.top;
  75. // Get the nearest monitor to this window.
  76. hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTOPRIMARY);
  77. }
  78. // Get the target monitor info
  79. memset(&monitorInfo, 0, sizeof(MONITORINFO));
  80. monitorInfo.cbSize = sizeof(MONITORINFO);
  81. GetMonitorInfo(hMonitor, &monitorInfo);
  82. unsigned int winWidth, winHeight;
  83. winWidth = mDesc.width;
  84. winHeight = mDesc.height;
  85. UINT32 left = mDesc.left;
  86. UINT32 top = mDesc.top;
  87. // No specified top left -> Center the window in the middle of the monitor
  88. if (left == -1 || top == -1)
  89. {
  90. int screenw = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
  91. int screenh = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
  92. // clamp window dimensions to screen size
  93. int outerw = (int(winWidth) < screenw)? int(winWidth) : screenw;
  94. int outerh = (int(winHeight) < screenh)? int(winHeight) : screenh;
  95. if (left == -1)
  96. left = monitorInfo.rcWork.left + (screenw - outerw) / 2;
  97. else if (mDesc.monitorIndex != -1)
  98. left += monitorInfo.rcWork.left;
  99. if (top == -1)
  100. top = monitorInfo.rcWork.top + (screenh - outerh) / 2;
  101. else if (mDesc.monitorIndex != -1)
  102. top += monitorInfo.rcWork.top;
  103. }
  104. else if (mDesc.monitorIndex != -1)
  105. {
  106. left += monitorInfo.rcWork.left;
  107. top += monitorInfo.rcWork.top;
  108. }
  109. mWidth = mDesiredWidth = mDesc.width;
  110. mHeight = mDesiredHeight = mDesc.height;
  111. mTop = top;
  112. mLeft = left;
  113. if (mDesc.fullscreen && !mIsChild)
  114. {
  115. dwStyleEx |= WS_EX_TOPMOST;
  116. dwStyle |= WS_POPUP;
  117. mTop = monitorInfo.rcMonitor.top;
  118. mLeft = monitorInfo.rcMonitor.left;
  119. }
  120. else
  121. {
  122. if (parentHWnd)
  123. {
  124. if(mDesc.toolWindow)
  125. dwStyleEx = WS_EX_TOOLWINDOW;
  126. else
  127. dwStyle |= WS_CHILD;
  128. }
  129. if (!parentHWnd || mDesc.toolWindow)
  130. {
  131. if (mDesc.border == WindowBorder::None)
  132. dwStyle |= WS_POPUP;
  133. else if (mDesc.border == WindowBorder::Fixed)
  134. dwStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION |
  135. WS_SYSMENU | WS_MINIMIZEBOX;
  136. else
  137. dwStyle |= WS_OVERLAPPEDWINDOW;
  138. }
  139. _adjustWindow(mDesc.width, mDesc.height, dwStyle, &winWidth, &winHeight);
  140. if (!mDesc.outerDimensions)
  141. {
  142. // Calculate window dimensions required
  143. // to get the requested client area
  144. SetRect(&rc, 0, 0, mWidth, mHeight);
  145. AdjustWindowRect(&rc, dwStyle, false);
  146. mWidth = rc.right - rc.left;
  147. mHeight = rc.bottom - rc.top;
  148. // Clamp window rect to the nearest display monitor.
  149. if (mLeft < monitorInfo.rcWork.left)
  150. mLeft = monitorInfo.rcWork.left;
  151. if (mTop < monitorInfo.rcWork.top)
  152. mTop = monitorInfo.rcWork.top;
  153. if (static_cast<int>(winWidth) > monitorInfo.rcWork.right - mLeft)
  154. winWidth = monitorInfo.rcWork.right - mLeft;
  155. if (static_cast<int>(winHeight) > monitorInfo.rcWork.bottom - mTop)
  156. winHeight = monitorInfo.rcWork.bottom - mTop;
  157. }
  158. }
  159. // Register the window class
  160. // NB allow 4 bytes of window data for D3D9RenderWindow pointer
  161. WNDCLASS wc = { 0, PlatformWndProc::_win32WndProc, 0, 0, hInst,
  162. LoadIcon(0, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW),
  163. (HBRUSH)GetStockObject(BLACK_BRUSH), 0, "D3D9Wnd" };
  164. RegisterClass(&wc);
  165. // Create our main window
  166. // Pass pointer to self
  167. mIsExternal = false;
  168. mHWnd = CreateWindowEx(dwStyleEx, "D3D9Wnd", mDesc.title.c_str(), dwStyle,
  169. mLeft, mTop, winWidth, winHeight, parentHWnd, 0, hInst, this);
  170. mStyle = dwStyle;
  171. }
  172. else
  173. {
  174. mHWnd = externalHandle;
  175. mIsExternal = true;
  176. }
  177. RECT rc;
  178. // top and left represent outer window coordinates
  179. GetWindowRect(mHWnd, &rc);
  180. mTop = rc.top;
  181. mLeft = rc.left;
  182. // width and height represent interior drawable area
  183. GetClientRect(mHWnd, &rc);
  184. mWidth = rc.right;
  185. mHeight = rc.bottom;
  186. mName = mDesc.title;
  187. mIsDepthBuffered = mDesc.depthBuffer;
  188. mIsFullScreen = mDesc.fullscreen && !mIsChild;
  189. mColorDepth = mDesc.colorDepth;
  190. mActive = true;
  191. mClosed = false;
  192. D3D9RenderSystem* rs = static_cast<D3D9RenderSystem*>(RenderSystem::instancePtr());
  193. rs->registerWindow(*this);
  194. RenderWindow::initialize_internal();
  195. }
  196. void D3D9RenderWindow::destroy_internal()
  197. {
  198. if (mDevice != NULL)
  199. {
  200. mDevice->detachRenderWindow(this);
  201. mDevice = NULL;
  202. }
  203. if (mHWnd && !mIsExternal)
  204. {
  205. DestroyWindow(mHWnd);
  206. }
  207. mHWnd = 0;
  208. mActive = false;
  209. mClosed = true;
  210. RenderWindow::destroy_internal();
  211. }
  212. void D3D9RenderWindow::setFullscreen(UINT32 width, UINT32 height, float refreshRate, UINT32 monitorIdx)
  213. {
  214. THROW_IF_NOT_CORE_THREAD;
  215. if (mIsChild)
  216. return;
  217. const D3D9VideoModeInfo& videoModeInfo = static_cast<const D3D9VideoModeInfo&>(RenderSystem::instance().getVideoModeInfo());
  218. UINT32 numOutputs = videoModeInfo.getNumOutputs();
  219. if (numOutputs == 0)
  220. return;
  221. UINT32 actualMonitorIdx = std::min(monitorIdx, numOutputs - 1);
  222. const D3D9VideoOutputInfo& outputInfo = static_cast<const D3D9VideoOutputInfo&>(videoModeInfo.getOutputInfo(actualMonitorIdx));
  223. bool oldFullscreen = mIsFullScreen;
  224. mStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_POPUP;
  225. mWidth = width;
  226. mHeight = height;
  227. mDisplayFrequency = Math::roundToInt(refreshRate);
  228. mIsFullScreen = true;
  229. HMONITOR hMonitor = outputInfo.getMonitorHandle();
  230. MONITORINFO monitorInfo;
  231. memset(&monitorInfo, 0, sizeof(MONITORINFO));
  232. monitorInfo.cbSize = sizeof(MONITORINFO);
  233. GetMonitorInfo(hMonitor, &monitorInfo);
  234. mTop = monitorInfo.rcMonitor.top;
  235. mLeft = monitorInfo.rcMonitor.left;
  236. if (oldFullscreen) // Was previously fullscreen, just changing the resolution
  237. {
  238. //SetWindowPos(mHWnd, HWND_TOPMOST, mLeft, mTop, mWidth, mHeight, SWP_NOACTIVATE);
  239. }
  240. else
  241. {
  242. //SetWindowPos(mHWnd, HWND_TOPMOST, mLeft, mTop, mWidth, mHeight, SWP_NOACTIVATE);
  243. SetWindowLong(mHWnd, GWL_STYLE, mStyle);
  244. SetWindowPos(mHWnd, 0, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
  245. }
  246. // Invalidate device, which resets it
  247. mDevice->invalidate(this);
  248. mDevice->acquire();
  249. }
  250. void D3D9RenderWindow::setFullscreen(const VideoMode& mode)
  251. {
  252. THROW_IF_NOT_CORE_THREAD;
  253. setFullscreen(mode.getWidth(), mode.getHeight(), mode.getRefreshRate(), mode.getOutputIdx());
  254. }
  255. void D3D9RenderWindow::setWindowed()
  256. {
  257. THROW_IF_NOT_CORE_THREAD;
  258. if (!mIsFullScreen)
  259. return;
  260. mIsFullScreen = false;
  261. mStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW;
  262. unsigned int winWidth, winHeight;
  263. _adjustWindow(mWidth, mHeight, mStyle, &winWidth, &winHeight);
  264. SetWindowLong(mHWnd, GWL_STYLE, mStyle);
  265. SetWindowPos(mHWnd, HWND_NOTOPMOST, 0, 0, winWidth, winHeight,
  266. SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE);
  267. mDevice->invalidate(this);
  268. mDevice->acquire();
  269. }
  270. void D3D9RenderWindow::setHidden(bool hidden)
  271. {
  272. THROW_IF_NOT_CORE_THREAD;
  273. mHidden = hidden;
  274. if (!mIsExternal)
  275. {
  276. if (hidden)
  277. ShowWindow(mHWnd, SW_HIDE);
  278. else
  279. ShowWindow(mHWnd, SW_SHOWNORMAL);
  280. }
  281. }
  282. bool D3D9RenderWindow::isActive() const
  283. {
  284. if (isFullScreen())
  285. return isVisible();
  286. return mActive && isVisible();
  287. }
  288. bool D3D9RenderWindow::isVisible() const
  289. {
  290. return (mHWnd && !IsIconic(mHWnd));
  291. }
  292. void D3D9RenderWindow::move(INT32 top, INT32 left)
  293. {
  294. THROW_IF_NOT_CORE_THREAD;
  295. if (mHWnd && !mIsFullScreen)
  296. {
  297. mLeft = left;
  298. mTop = top;
  299. SetWindowPos(mHWnd, 0, top, left, 0, 0,
  300. SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
  301. }
  302. }
  303. void D3D9RenderWindow::resize(UINT32 width, UINT32 height)
  304. {
  305. THROW_IF_NOT_CORE_THREAD;
  306. if (mHWnd && !mIsFullScreen)
  307. {
  308. mWidth = width;
  309. mHeight = height;
  310. unsigned int winWidth, winHeight;
  311. _adjustWindow(width, height, mStyle, &winWidth, &winHeight);
  312. SetWindowPos(mHWnd, 0, 0, 0, winWidth, winHeight,
  313. SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  314. }
  315. }
  316. void D3D9RenderWindow::getCustomAttribute( const String& name, void* pData ) const
  317. {
  318. // Valid attributes and their equivalent native functions:
  319. // D3DDEVICE : getD3DDevice
  320. // WINDOW : getWindowHandle
  321. if( name == "D3DDEVICE" )
  322. {
  323. IDirect3DDevice9* *pDev = (IDirect3DDevice9**)pData;
  324. *pDev = _getD3D9Device();
  325. return;
  326. }
  327. else if( name == "WINDOW" )
  328. {
  329. HWND *pHwnd = (HWND*)pData;
  330. *pHwnd = _getWindowHandle();
  331. return;
  332. }
  333. else if( name == "isTexture" )
  334. {
  335. bool *b = reinterpret_cast< bool * >( pData );
  336. *b = false;
  337. return;
  338. }
  339. else if( name == "D3DZBUFFER" )
  340. {
  341. IDirect3DSurface9* *pSurf = (IDirect3DSurface9**)pData;
  342. *pSurf = mDevice->getDepthBuffer(this);
  343. return;
  344. }
  345. else if( name == "DDBACKBUFFER" )
  346. {
  347. IDirect3DSurface9* *pSurf = (IDirect3DSurface9**)pData;
  348. *pSurf = mDevice->getBackBuffer(this);
  349. return;
  350. }
  351. else if( name == "DDFRONTBUFFER" )
  352. {
  353. IDirect3DSurface9* *pSurf = (IDirect3DSurface9**)pData;
  354. *pSurf = mDevice->getBackBuffer(this);
  355. return;
  356. }
  357. }
  358. void D3D9RenderWindow::swapBuffers()
  359. {
  360. THROW_IF_NOT_CORE_THREAD;
  361. if (mDeviceValid)
  362. mDevice->present(this);
  363. }
  364. Vector2I D3D9RenderWindow::screenToWindowPos(const Vector2I& screenPos) const
  365. {
  366. POINT pos;
  367. pos.x = screenPos.x;
  368. pos.y = screenPos.y;
  369. ScreenToClient(mHWnd, &pos);
  370. return Vector2I(pos.x, pos.y);
  371. }
  372. Vector2I D3D9RenderWindow::windowToScreenPos(const Vector2I& windowPos) const
  373. {
  374. POINT pos;
  375. pos.x = windowPos.x;
  376. pos.y = windowPos.y;
  377. ClientToScreen(mHWnd, &pos);
  378. return Vector2I(pos.x, pos.y);
  379. }
  380. void D3D9RenderWindow::copyToMemory(const PixelData &dst, FrameBuffer buffer)
  381. {
  382. THROW_IF_NOT_CORE_THREAD;
  383. mDevice->copyContentsToMemory(this, dst, buffer);
  384. }
  385. void D3D9RenderWindow::_windowMovedOrResized()
  386. {
  387. THROW_IF_NOT_CORE_THREAD;
  388. if (!mHWnd || IsIconic(mHWnd))
  389. return;
  390. updateWindowRect();
  391. RenderWindow::_windowMovedOrResized();
  392. }
  393. /************************************************************************/
  394. /* D3D9 IMPLEMENTATION SPECIFIC */
  395. /************************************************************************/
  396. void D3D9RenderWindow::_adjustWindow(unsigned int clientWidth, unsigned int clientHeight,
  397. DWORD style, unsigned int* winWidth, unsigned int* winHeight)
  398. {
  399. // NB only call this for non full screen
  400. RECT rc;
  401. SetRect(&rc, 0, 0, clientWidth, clientHeight);
  402. AdjustWindowRect(&rc, style, false);
  403. *winWidth = rc.right - rc.left;
  404. *winHeight = rc.bottom - rc.top;
  405. // adjust to monitor
  406. HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST);
  407. // Get monitor info
  408. MONITORINFO monitorInfo;
  409. memset(&monitorInfo, 0, sizeof(MONITORINFO));
  410. monitorInfo.cbSize = sizeof(MONITORINFO);
  411. GetMonitorInfo(hMonitor, &monitorInfo);
  412. LONG maxW = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
  413. LONG maxH = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
  414. if (*winWidth > (unsigned int)maxW)
  415. *winWidth = maxW;
  416. if (*winHeight > (unsigned int)maxH)
  417. *winHeight = maxH;
  418. }
  419. void D3D9RenderWindow::_buildPresentParameters(D3DPRESENT_PARAMETERS* presentParams) const
  420. {
  421. // Set up the presentation parameters
  422. IDirect3D9* pD3D = D3D9RenderSystem::getDirect3D9();
  423. D3DDEVTYPE devType = D3DDEVTYPE_HAL;
  424. if (mDevice != NULL)
  425. devType = mDevice->getDeviceType();
  426. ZeroMemory( presentParams, sizeof(D3DPRESENT_PARAMETERS) );
  427. presentParams->Windowed = !mIsFullScreen;
  428. presentParams->SwapEffect = D3DSWAPEFFECT_DISCARD;
  429. presentParams->BackBufferCount = 1;
  430. presentParams->EnableAutoDepthStencil = mIsDepthBuffered;
  431. presentParams->hDeviceWindow = mHWnd;
  432. presentParams->BackBufferWidth = mWidth;
  433. presentParams->BackBufferHeight = mHeight;
  434. presentParams->FullScreen_RefreshRateInHz = mIsFullScreen ? mDisplayFrequency : 0;
  435. if (presentParams->BackBufferWidth == 0)
  436. presentParams->BackBufferWidth = 1;
  437. if (presentParams->BackBufferHeight == 0)
  438. presentParams->BackBufferHeight = 1;
  439. if (mVSync)
  440. {
  441. // D3D9 only seems to support 2-4 presentation intervals in fullscreen
  442. if (mIsFullScreen)
  443. {
  444. switch(mVSyncInterval)
  445. {
  446. case 1:
  447. default:
  448. presentParams->PresentationInterval = D3DPRESENT_INTERVAL_ONE;
  449. break;
  450. case 2:
  451. presentParams->PresentationInterval = D3DPRESENT_INTERVAL_TWO;
  452. break;
  453. case 3:
  454. presentParams->PresentationInterval = D3DPRESENT_INTERVAL_THREE;
  455. break;
  456. case 4:
  457. presentParams->PresentationInterval = D3DPRESENT_INTERVAL_FOUR;
  458. break;
  459. };
  460. // check that the interval was supported, revert to 1 to be safe otherwise
  461. D3DCAPS9 caps;
  462. pD3D->GetDeviceCaps(mDevice->getAdapterNumber(), devType, &caps);
  463. if (!(caps.PresentationIntervals & presentParams->PresentationInterval))
  464. presentParams->PresentationInterval = D3DPRESENT_INTERVAL_ONE;
  465. }
  466. else
  467. {
  468. presentParams->PresentationInterval = D3DPRESENT_INTERVAL_ONE;
  469. }
  470. }
  471. else
  472. {
  473. presentParams->PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
  474. }
  475. presentParams->BackBufferFormat = D3DFMT_R5G6B5;
  476. if(mColorDepth > 16)
  477. presentParams->BackBufferFormat = D3DFMT_X8R8G8B8;
  478. if (mColorDepth > 16)
  479. {
  480. if(FAILED( pD3D->CheckDeviceFormat(mDevice->getAdapterNumber(),
  481. devType, presentParams->BackBufferFormat, D3DUSAGE_DEPTHSTENCIL,
  482. D3DRTYPE_SURFACE, D3DFMT_D24S8)))
  483. {
  484. if(FAILED( pD3D->CheckDeviceFormat(mDevice->getAdapterNumber(),
  485. devType, presentParams->BackBufferFormat, D3DUSAGE_DEPTHSTENCIL,
  486. D3DRTYPE_SURFACE, D3DFMT_D32)))
  487. {
  488. presentParams->AutoDepthStencilFormat = D3DFMT_D16;
  489. }
  490. else
  491. {
  492. presentParams->AutoDepthStencilFormat = D3DFMT_D32;
  493. }
  494. }
  495. else
  496. {
  497. if(SUCCEEDED( pD3D->CheckDepthStencilMatch( mDevice->getAdapterNumber(), devType,
  498. presentParams->BackBufferFormat, presentParams->BackBufferFormat, D3DFMT_D24S8)))
  499. {
  500. presentParams->AutoDepthStencilFormat = D3DFMT_D24S8;
  501. }
  502. else
  503. {
  504. presentParams->AutoDepthStencilFormat = D3DFMT_D24X8;
  505. }
  506. }
  507. }
  508. else
  509. presentParams->AutoDepthStencilFormat = D3DFMT_D16;
  510. D3D9RenderSystem* rsys = static_cast<D3D9RenderSystem*>(BansheeEngine::RenderSystem::instancePtr());
  511. D3DMULTISAMPLE_TYPE multisampleType;
  512. DWORD multisampleQuality;
  513. rsys->determineMultisampleSettings(mDevice->getD3D9Device(),
  514. mMultisampleCount, mMultisampleHint, presentParams->BackBufferFormat, mIsFullScreen,
  515. &multisampleType, &multisampleQuality);
  516. presentParams->MultiSampleType = multisampleType;
  517. presentParams->MultiSampleQuality = (multisampleQuality == 0) ? 0 : multisampleQuality;
  518. }
  519. IDirect3DDevice9* D3D9RenderWindow::_getD3D9Device() const
  520. {
  521. return mDevice->getD3D9Device();
  522. }
  523. IDirect3DSurface9* D3D9RenderWindow::_getRenderSurface() const
  524. {
  525. return mDevice->getBackBuffer(this);
  526. }
  527. D3D9Device* D3D9RenderWindow::_getDevice() const
  528. {
  529. return mDevice;
  530. }
  531. void D3D9RenderWindow::_setDevice(D3D9Device* device)
  532. {
  533. mDevice = device;
  534. mDeviceValid = false;
  535. }
  536. bool D3D9RenderWindow::_isDepthBuffered() const
  537. {
  538. return mIsDepthBuffered;
  539. }
  540. void D3D9RenderWindow::updateWindowRect()
  541. {
  542. RECT rc;
  543. BOOL result;
  544. // Update top left parameters
  545. result = GetWindowRect(mHWnd, &rc);
  546. if (result == FALSE)
  547. {
  548. mTop = 0;
  549. mLeft = 0;
  550. mWidth = 0;
  551. mHeight = 0;
  552. return;
  553. }
  554. mTop = rc.top;
  555. mLeft = rc.left;
  556. // width and height represent drawable area only
  557. result = GetClientRect(mHWnd, &rc);
  558. if (result == FALSE)
  559. {
  560. mTop = 0;
  561. mLeft = 0;
  562. mWidth = 0;
  563. mHeight = 0;
  564. return;
  565. }
  566. mWidth = rc.right - rc.left;
  567. mHeight = rc.bottom - rc.top;
  568. }
  569. bool D3D9RenderWindow::_validateDevice()
  570. {
  571. mDeviceValid = mDevice->validate(this);
  572. return mDeviceValid;
  573. }
  574. }