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 IMPLEMENT_STANDARD_RTTIEXT(D3DHost_View,OpenGl_View)
25 // =======================================================================
26 // function : d3dFormatError
28 // =======================================================================
29 TCollection_AsciiString D3DHost_View::d3dFormatError (const long theErrCode)
33 case D3D_OK: return "OK";
34 case D3DERR_DEVICELOST: return "Device lost";
35 case D3DERR_DEVICEREMOVED: return "Device removed";
36 case D3DERR_DRIVERINTERNALERROR: return "Driver internal error";
37 case D3DERR_OUTOFVIDEOMEMORY: return "Out of video memory";
38 case D3DERR_INVALIDCALL: return "Invalid call";
39 default: return TCollection_AsciiString ("Error #") + int(theErrCode) + ")";
43 // =======================================================================
44 // function : D3DHost_View
46 // =======================================================================
47 D3DHost_View::D3DHost_View (const Handle(Graphic3d_StructureManager)& theMgr,
48 const Handle(D3DHost_GraphicDriver)& theDriver,
49 const Handle(OpenGl_Caps)& theCaps,
50 Standard_Boolean& theDeviceLostFlag,
51 OpenGl_StateCounter* theCounter)
52 : OpenGl_View (theMgr, theDriver, theCaps, theDeviceLostFlag, theCounter),
55 myD3dParams (new D3DPRESENT_PARAMETERS()),
56 myRefreshRate (D3DPRESENT_RATE_DEFAULT),
59 memset(myD3dParams.operator->(), 0, sizeof(D3DPRESENT_PARAMETERS));
61 myD3dParams->Windowed = TRUE;
62 myD3dParams->SwapEffect = D3DSWAPEFFECT_DISCARD;
63 myD3dParams->BackBufferFormat = D3DFMT_X8R8G8B8;
64 myD3dParams->BackBufferCount = 1;
65 myD3dParams->BackBufferHeight = 2;
66 myD3dParams->BackBufferWidth = 2;
67 myD3dParams->EnableAutoDepthStencil = FALSE;
68 myD3dParams->AutoDepthStencilFormat = D3DFMT_D16_LOCKABLE;
69 myD3dParams->FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
70 myD3dParams->PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
73 // =======================================================================
74 // function : ~D3DHost_View
76 // =======================================================================
77 D3DHost_View::~D3DHost_View()
79 if (!myD3dWglFbo.IsNull())
81 myD3dWglFbo->Release (myWorkspace->GetGlContext().operator->());
82 myD3dWglFbo.Nullify();
84 if (myD3dDevice != NULL)
86 myD3dDevice->Release();
96 // =======================================================================
97 // function : SetWindow
99 // =======================================================================
100 void D3DHost_View::SetWindow (const Handle(Aspect_Window)& theWindow,
101 const Aspect_RenderingContext theContext)
103 if (!myD3dWglFbo.IsNull())
105 myD3dWglFbo->Release (myWorkspace->GetGlContext().operator->());
106 myD3dWglFbo.Nullify();
108 if (myD3dDevice != NULL)
110 myD3dDevice->Release();
114 OpenGl_View::SetWindow (theWindow, theContext);
116 if (!myWindow.IsNull())
119 d3dCreateRenderTarget();
123 // =======================================================================
124 // function : d3dInitLib
126 // =======================================================================
127 bool D3DHost_View::d3dInitLib()
129 if (myD3dLib == NULL)
131 IDirect3D9Ex* aD3dLibEx = NULL;
132 // we link against d3d (using Direct3DCreate9 symbol), thus it should be already loaded
133 HMODULE aLib = GetModuleHandleW (L"d3d9");
136 // retrieve D3D9Ex function dynamically (available only since Vista+)
137 typedef HRESULT (WINAPI* Direct3DCreate9Ex_t)(UINT , IDirect3D9Ex** );
138 Direct3DCreate9Ex_t Direct3DCreate9ExProc = (Direct3DCreate9Ex_t )GetProcAddress (aLib, "Direct3DCreate9Ex");
139 if (Direct3DCreate9ExProc != NULL)
141 Direct3DCreate9ExProc(D3D_SDK_VERSION, &aD3dLibEx);
144 myD3dLib = aD3dLibEx;
145 myIsD3dEx = aD3dLibEx != NULL;
146 if (myD3dLib == NULL)
148 myD3dLib = Direct3DCreate9 (D3D_SDK_VERSION);
151 return myD3dLib != NULL;
154 // =======================================================================
155 // function : d3dInit
157 // =======================================================================
158 bool D3DHost_View::d3dInit()
162 myWorkspace->GetGlContext()->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
163 GL_DEBUG_TYPE_ERROR_ARB,
165 GL_DEBUG_SEVERITY_HIGH_ARB,
166 "Direct3DCreate9 failed!");
170 UINT anAdapterId = D3DADAPTER_DEFAULT;
172 // setup the present parameters
173 D3DDISPLAYMODE aCurrMode;
174 memset(&aCurrMode, 0, sizeof(aCurrMode));
175 if (myD3dLib->GetAdapterDisplayMode (anAdapterId, &aCurrMode) == D3D_OK)
177 myD3dParams->BackBufferFormat = aCurrMode.Format;
178 myRefreshRate = aCurrMode.RefreshRate;
180 myD3dParams->Windowed = TRUE;
181 myD3dParams->BackBufferWidth = myWindow->Width();
182 myD3dParams->BackBufferHeight = myWindow->Height();
183 myD3dParams->hDeviceWindow = (HWND )myWindow->PlatformWindow()->NativeHandle();
185 // create the Video Device
186 HRESULT isOK = myD3dLib->CreateDevice (anAdapterId, D3DDEVTYPE_HAL,
187 (HWND )myWindow->PlatformWindow()->NativeHandle(),
188 D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE,
189 myD3dParams.get(), &myD3dDevice);
195 return myD3dDevice != NULL;
198 // =======================================================================
199 // function : d3dReset
201 // =======================================================================
202 bool D3DHost_View::d3dReset()
204 if (myD3dDevice == NULL)
209 myD3dParams->Windowed = TRUE;
210 myD3dParams->BackBufferWidth = myWindow->Width();
211 myD3dParams->BackBufferHeight = myWindow->Height();
212 myD3dParams->hDeviceWindow = (HWND )myWindow->PlatformWindow()->NativeHandle();
213 myD3dParams->FullScreen_RefreshRateInHz = !myD3dParams->Windowed ? myRefreshRate : 0;
215 HRESULT isOK = myD3dDevice->Reset(myD3dParams.get());
216 return isOK == D3D_OK;
219 // =======================================================================
220 // function : d3dCreateRenderTarget
222 // =======================================================================
223 bool D3DHost_View::d3dCreateRenderTarget()
225 if (myD3dWglFbo.IsNull())
227 myD3dWglFbo = new D3DHost_FrameBuffer();
229 if (!myD3dWglFbo->Init (myWorkspace->GetGlContext(),
238 myD3dDevice->SetRenderTarget (0, myD3dWglFbo->D3dColorSurface());
242 // =======================================================================
243 // function : d3dBeginRender
245 // =======================================================================
246 void D3DHost_View::d3dBeginRender()
248 if (myD3dDevice == NULL)
253 // clear the back buffer
254 myD3dDevice->Clear (0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
255 myD3dDevice->BeginScene();
258 // =======================================================================
259 // function : d3dEndRender
261 // =======================================================================
262 void D3DHost_View::d3dEndRender()
264 if (myD3dDevice != NULL)
266 myD3dDevice->EndScene();
270 // =======================================================================
271 // function : d3dSwap
273 // =======================================================================
274 bool D3DHost_View::d3dSwap()
276 if (myD3dDevice == NULL)
281 const HRESULT isOK = myD3dDevice->Present (NULL, NULL, NULL, NULL);
284 TCollection_ExtendedString aMsg = TCollection_ExtendedString()
285 + "Direct3D9, Present device failed, " + d3dFormatError (isOK);
286 myWorkspace->GetGlContext()->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
287 GL_DEBUG_TYPE_ERROR_ARB,
289 GL_DEBUG_SEVERITY_HIGH_ARB,
292 return isOK == D3D_OK;
295 // =======================================================================
298 // =======================================================================
299 void D3DHost_View::Redraw()
301 if (!myWorkspace->Activate()
302 || myD3dDevice == NULL)
306 else if (!myFBO.IsNull())
308 OpenGl_View::Redraw();
312 Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
313 myToFlipOutput = Standard_True;
314 myD3dWglFbo->LockSurface (aCtx);
316 OpenGl_View::Redraw();
318 myD3dWglFbo->UnlockSurface (aCtx);
319 myToFlipOutput = Standard_False;
320 if (aCtx->caps->buffersNoSwap)
325 // blit result to the D3D back buffer and swap
328 IDirect3DSurface9* aBackbuffer = NULL;
329 myD3dDevice->GetBackBuffer (0, 0, D3DBACKBUFFER_TYPE_MONO, &aBackbuffer);
330 myD3dDevice->StretchRect (myD3dWglFbo->D3dColorSurface(), NULL, aBackbuffer, NULL, D3DTEXF_LINEAR);
331 aBackbuffer->Release();
337 // =======================================================================
338 // function : RedrawImmediate
340 // =======================================================================
341 void D3DHost_View::RedrawImmediate()
343 Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
344 if (!myTransientDrawToFront
345 || !myBackBufferRestored
346 || (aCtx->caps->buffersNoSwap && !myMainSceneFbos[0]->IsValid()))
351 else if (!myWorkspace->Activate()
352 || myD3dDevice == NULL)
356 else if (!myFBO.IsNull())
358 OpenGl_View::Redraw();
362 myToFlipOutput = Standard_True;
363 myD3dWglFbo->LockSurface (aCtx);
365 OpenGl_View::RedrawImmediate();
367 myD3dWglFbo->UnlockSurface (aCtx);
368 myToFlipOutput = Standard_False;
369 if (aCtx->caps->buffersNoSwap)
374 // blit result to the D3D back buffer and swap
377 IDirect3DSurface9* aBackbuffer = NULL;
378 myD3dDevice->GetBackBuffer (0, 0, D3DBACKBUFFER_TYPE_MONO, &aBackbuffer);
379 myD3dDevice->StretchRect (myD3dWglFbo->D3dColorSurface(), NULL, aBackbuffer, NULL, D3DTEXF_LINEAR);
380 aBackbuffer->Release();
386 // =======================================================================
389 // =======================================================================
390 void D3DHost_View::Resized()
392 const Standard_Integer aWidthOld = myWindow->Width();
393 const Standard_Integer aHeightOld = myWindow->Height();
394 OpenGl_View::Resized();
395 if (aWidthOld == myWindow->Width()
396 && aHeightOld == myWindow->Height())
401 if (!myD3dWglFbo.IsNull())
403 myD3dWglFbo->Release (myWorkspace->GetGlContext().operator->());
405 if (!myWorkspace->GetGlContext()->caps->buffersNoSwap)
409 d3dCreateRenderTarget();