1 // Created on: 2015-06-10
2 // Created by: Kirill Gavrilov
3 // Copyright (c) 2015 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
18 #include <D3DHost_View.hxx>
20 #include <D3DHost_GraphicDriver.hxx>
21 #include <TCollection_ExtendedString.hxx>
23 // =======================================================================
24 // function : d3dFormatError
26 // =======================================================================
27 TCollection_AsciiString D3DHost_View::d3dFormatError (const long theErrCode)
31 case D3D_OK: return "OK";
32 case D3DERR_DEVICELOST: return "Device lost";
33 case D3DERR_DEVICEREMOVED: return "Device removed";
34 case D3DERR_DRIVERINTERNALERROR: return "Driver internal error";
35 case D3DERR_OUTOFVIDEOMEMORY: return "Out of video memory";
36 case D3DERR_INVALIDCALL: return "Invalid call";
37 default: return TCollection_AsciiString ("Error #") + int(theErrCode) + ")";
41 // =======================================================================
42 // function : D3DHost_View
44 // =======================================================================
45 D3DHost_View::D3DHost_View (const Handle(Graphic3d_StructureManager)& theMgr,
46 const Handle(D3DHost_GraphicDriver)& theDriver,
47 const Handle(OpenGl_Caps)& theCaps,
48 Standard_Boolean& theDeviceLostFlag,
49 OpenGl_StateCounter* theCounter)
50 : OpenGl_View (theMgr, theDriver, theCaps, theDeviceLostFlag, theCounter),
53 myD3dParams (new D3DPRESENT_PARAMETERS()),
54 myRefreshRate (D3DPRESENT_RATE_DEFAULT),
57 memset(myD3dParams.operator->(), 0, sizeof(D3DPRESENT_PARAMETERS));
59 myD3dParams->Windowed = TRUE;
60 myD3dParams->SwapEffect = D3DSWAPEFFECT_DISCARD;
61 myD3dParams->BackBufferFormat = D3DFMT_X8R8G8B8;
62 myD3dParams->BackBufferCount = 1;
63 myD3dParams->BackBufferHeight = 2;
64 myD3dParams->BackBufferWidth = 2;
65 myD3dParams->EnableAutoDepthStencil = FALSE;
66 myD3dParams->AutoDepthStencilFormat = D3DFMT_D16_LOCKABLE;
67 myD3dParams->FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
68 myD3dParams->PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
71 // =======================================================================
72 // function : ~D3DHost_View
74 // =======================================================================
75 D3DHost_View::~D3DHost_View()
77 if (!myD3dWglFbo.IsNull())
79 myD3dWglFbo->Release (myWorkspace->GetGlContext().operator->());
80 myD3dWglFbo.Nullify();
82 if (myD3dDevice != NULL)
84 myD3dDevice->Release();
94 // =======================================================================
95 // function : SetWindow
97 // =======================================================================
98 void D3DHost_View::SetWindow (const Handle(Aspect_Window)& theWindow,
99 const Aspect_RenderingContext theContext)
101 if (!myD3dWglFbo.IsNull())
103 myD3dWglFbo->Release (myWorkspace->GetGlContext().operator->());
104 myD3dWglFbo.Nullify();
106 if (myD3dDevice != NULL)
108 myD3dDevice->Release();
112 OpenGl_View::SetWindow (theWindow, theContext);
114 if (!myWindow.IsNull())
117 d3dCreateRenderTarget();
121 // =======================================================================
122 // function : d3dInitLib
124 // =======================================================================
125 bool D3DHost_View::d3dInitLib()
127 if (myD3dLib == NULL)
129 IDirect3D9Ex* aD3dLibEx = NULL;
130 // we link against d3d (using Direct3DCreate9 symbol), thus it should be already loaded
131 HMODULE aLib = GetModuleHandleW (L"d3d9");
134 // retrieve D3D9Ex function dynamically (available only since Vista+)
135 typedef HRESULT (WINAPI* Direct3DCreate9Ex_t)(UINT , IDirect3D9Ex** );
136 Direct3DCreate9Ex_t Direct3DCreate9ExProc = (Direct3DCreate9Ex_t )GetProcAddress (aLib, "Direct3DCreate9Ex");
137 if (Direct3DCreate9ExProc != NULL)
139 Direct3DCreate9ExProc(D3D_SDK_VERSION, &aD3dLibEx);
142 myD3dLib = aD3dLibEx;
143 myIsD3dEx = aD3dLibEx != NULL;
144 if (myD3dLib == NULL)
146 myD3dLib = Direct3DCreate9 (D3D_SDK_VERSION);
149 return myD3dLib != NULL;
152 // =======================================================================
153 // function : d3dInit
155 // =======================================================================
156 bool D3DHost_View::d3dInit()
160 myWorkspace->GetGlContext()->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
161 GL_DEBUG_TYPE_ERROR_ARB,
163 GL_DEBUG_SEVERITY_HIGH_ARB,
164 "Direct3DCreate9 failed!");
168 UINT anAdapterId = D3DADAPTER_DEFAULT;
170 // setup the present parameters
171 D3DDISPLAYMODE aCurrMode;
172 memset(&aCurrMode, 0, sizeof(aCurrMode));
173 if (myD3dLib->GetAdapterDisplayMode (anAdapterId, &aCurrMode) == D3D_OK)
175 myD3dParams->BackBufferFormat = aCurrMode.Format;
176 myRefreshRate = aCurrMode.RefreshRate;
178 myD3dParams->Windowed = TRUE;
179 myD3dParams->BackBufferWidth = myWindow->Width();
180 myD3dParams->BackBufferHeight = myWindow->Height();
181 myD3dParams->hDeviceWindow = (HWND )myWindow->PlatformWindow()->NativeHandle();
183 // create the Video Device
184 HRESULT isOK = myD3dLib->CreateDevice (anAdapterId, D3DDEVTYPE_HAL,
185 (HWND )myWindow->PlatformWindow()->NativeHandle(),
186 D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE,
187 myD3dParams.get(), &myD3dDevice);
193 return myD3dDevice != NULL;
196 // =======================================================================
197 // function : d3dReset
199 // =======================================================================
200 bool D3DHost_View::d3dReset()
202 if (myD3dDevice == NULL)
207 myD3dParams->Windowed = TRUE;
208 myD3dParams->BackBufferWidth = myWindow->Width();
209 myD3dParams->BackBufferHeight = myWindow->Height();
210 myD3dParams->hDeviceWindow = (HWND )myWindow->PlatformWindow()->NativeHandle();
211 myD3dParams->FullScreen_RefreshRateInHz = !myD3dParams->Windowed ? myRefreshRate : 0;
213 HRESULT isOK = myD3dDevice->Reset(myD3dParams.get());
214 return isOK == D3D_OK;
217 // =======================================================================
218 // function : d3dCreateRenderTarget
220 // =======================================================================
221 bool D3DHost_View::d3dCreateRenderTarget()
223 if (myD3dWglFbo.IsNull())
225 myD3dWglFbo = new D3DHost_FrameBuffer();
227 if (!myD3dWglFbo->Init (myWorkspace->GetGlContext(),
236 myD3dDevice->SetRenderTarget (0, myD3dWglFbo->D3dColorSurface());
240 // =======================================================================
241 // function : d3dBeginRender
243 // =======================================================================
244 void D3DHost_View::d3dBeginRender()
246 if (myD3dDevice == NULL)
251 // clear the back buffer
252 myD3dDevice->Clear (0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
253 myD3dDevice->BeginScene();
256 // =======================================================================
257 // function : d3dEndRender
259 // =======================================================================
260 void D3DHost_View::d3dEndRender()
262 if (myD3dDevice != NULL)
264 myD3dDevice->EndScene();
268 // =======================================================================
269 // function : d3dSwap
271 // =======================================================================
272 bool D3DHost_View::d3dSwap()
274 if (myD3dDevice == NULL)
279 const HRESULT isOK = myD3dDevice->Present (NULL, NULL, NULL, NULL);
282 TCollection_ExtendedString aMsg = TCollection_ExtendedString()
283 + "Direct3D9, Present device failed, " + d3dFormatError (isOK);
284 myWorkspace->GetGlContext()->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
285 GL_DEBUG_TYPE_ERROR_ARB,
287 GL_DEBUG_SEVERITY_HIGH_ARB,
290 return isOK == D3D_OK;
293 // =======================================================================
296 // =======================================================================
297 void D3DHost_View::Redraw()
299 if (!myWorkspace->Activate()
300 || myD3dDevice == NULL)
304 else if (myFBO != NULL)
306 OpenGl_View::Redraw();
310 Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
311 myToFlipOutput = Standard_True;
312 myD3dWglFbo->LockSurface (aCtx);
313 myFBO = myD3dWglFbo.get();
314 OpenGl_View::Redraw();
316 myD3dWglFbo->UnlockSurface (aCtx);
317 myToFlipOutput = Standard_False;
318 if (aCtx->caps->buffersNoSwap)
323 // blit result to the D3D back buffer and swap
326 IDirect3DSurface9* aBackbuffer = NULL;
327 myD3dDevice->GetBackBuffer (0, 0, D3DBACKBUFFER_TYPE_MONO, &aBackbuffer);
328 myD3dDevice->StretchRect (myD3dWglFbo->D3dColorSurface(), NULL, aBackbuffer, NULL, D3DTEXF_LINEAR);
329 aBackbuffer->Release();
335 // =======================================================================
336 // function : RedrawImmediate
338 // =======================================================================
339 void D3DHost_View::RedrawImmediate()
341 Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
342 if (!myTransientDrawToFront
343 || !myBackBufferRestored
344 || (aCtx->caps->buffersNoSwap && !myMainSceneFbos[0]->IsValid()))
349 else if (!myWorkspace->Activate()
350 || myD3dDevice == NULL)
354 else if (myFBO != NULL)
356 OpenGl_View::Redraw();
360 myToFlipOutput = Standard_True;
361 myD3dWglFbo->LockSurface (aCtx);
362 myFBO = myD3dWglFbo.get();
363 OpenGl_View::RedrawImmediate();
365 myD3dWglFbo->UnlockSurface (aCtx);
366 myToFlipOutput = Standard_False;
367 if (aCtx->caps->buffersNoSwap)
372 // blit result to the D3D back buffer and swap
375 IDirect3DSurface9* aBackbuffer = NULL;
376 myD3dDevice->GetBackBuffer (0, 0, D3DBACKBUFFER_TYPE_MONO, &aBackbuffer);
377 myD3dDevice->StretchRect (myD3dWglFbo->D3dColorSurface(), NULL, aBackbuffer, NULL, D3DTEXF_LINEAR);
378 aBackbuffer->Release();
384 // =======================================================================
387 // =======================================================================
388 void D3DHost_View::Resized()
390 const Standard_Integer aWidthOld = myWindow->Width();
391 const Standard_Integer aHeightOld = myWindow->Height();
392 OpenGl_View::Resized();
393 if (aWidthOld == myWindow->Width()
394 && aHeightOld == myWindow->Height())
399 if (!myD3dWglFbo.IsNull())
401 myD3dWglFbo->Release (myWorkspace->GetGlContext().operator->());
403 if (!myWorkspace->GetGlContext()->caps->buffersNoSwap)
407 d3dCreateRenderTarget();