Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2011-09-20 |
2 | // Created by: Sergey ZERCHANINOV | |
973c2be1 | 3 | // Copyright (c) 2011-2014 OPEN CASCADE SAS |
b311480e | 4 | // |
973c2be1 | 5 | // This file is part of Open CASCADE Technology software library. |
b311480e | 6 | // |
d5f74e42 | 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 | |
973c2be1 | 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. | |
b311480e | 12 | // |
973c2be1 | 13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. | |
b311480e | 15 | |
c357e426 | 16 | #include <OpenGl_View.hxx> |
5f8b738e | 17 | |
c357e426 | 18 | #include <Aspect_RenderingContext.hxx> |
19 | #include <Aspect_Window.hxx> | |
20 | #include <Graphic3d_AspectFillArea3d.hxx> | |
21 | #include <Graphic3d_Texture2Dmanual.hxx> | |
22 | #include <Graphic3d_TextureEnv.hxx> | |
23 | #include <Graphic3d_Mat4d.hxx> | |
24 | #include <NCollection_Mat4.hxx> | |
bf75be98 | 25 | #include <OpenGl_Context.hxx> |
c357e426 | 26 | #include <OpenGl_FrameBuffer.hxx> |
30f0ad28 | 27 | #include <OpenGl_GlCore11.hxx> |
28 | #include <OpenGl_GraduatedTrihedron.hxx> | |
392ac980 | 29 | #include <OpenGl_GraphicDriver.hxx> |
30f0ad28 | 30 | #include <OpenGl_ShaderManager.hxx> |
bf75be98 | 31 | #include <OpenGl_Texture.hxx> |
c357e426 | 32 | #include <OpenGl_Window.hxx> |
30f0ad28 | 33 | #include <OpenGl_Workspace.hxx> |
f5b72419 | 34 | #include <OSD_Parallel.hxx> |
c357e426 | 35 | #include <Standard_CLocaleSentry.hxx> |
2166f0fa | 36 | |
f5b72419 | 37 | #include "../Graphic3d/Graphic3d_Structure.pxx" |
38 | ||
92efcf78 | 39 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,Graphic3d_CView) |
40 | ||
c357e426 | 41 | #ifdef HAVE_GL2PS |
42 | #include <gl2ps.h> | |
43 | #endif | |
2166f0fa | 44 | |
c357e426 | 45 | // ======================================================================= |
46 | // function : Constructor | |
47 | // purpose : | |
48 | // ======================================================================= | |
49 | OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr, | |
50 | const Handle(OpenGl_GraphicDriver)& theDriver, | |
51 | const Handle(OpenGl_Caps)& theCaps, | |
52 | Standard_Boolean& theDeviceLostFlag, | |
53 | OpenGl_StateCounter* theCounter) | |
54 | : Graphic3d_CView (theMgr), | |
55 | myDriver (theDriver.operator->()), | |
56 | myCaps (theCaps), | |
57 | myDeviceLostFlag (theDeviceLostFlag), | |
58 | myWasRedrawnGL (Standard_False), | |
c357e426 | 59 | myCulling (Standard_True), |
60 | myShadingModel (Graphic3d_TOSM_FACET), | |
c357e426 | 61 | myBackfacing (Graphic3d_TOBM_AUTOMATIC), |
b6472664 | 62 | myBgColor (Quantity_NOC_BLACK), |
c357e426 | 63 | myCamera (new Graphic3d_Camera()), |
c357e426 | 64 | myToShowGradTrihedron (false), |
f5b72419 | 65 | myZLayers (Structure_MAX_PRIORITY - Structure_MIN_PRIORITY + 1), |
c357e426 | 66 | myStateCounter (theCounter), |
0b0320e7 | 67 | myLastLightSourceState (0, 0), |
a1073ae2 | 68 | #if !defined(GL_ES_VERSION_2_0) |
3c4b62a4 | 69 | myFboColorFormat (GL_RGBA8), |
a1073ae2 | 70 | #else |
71 | myFboColorFormat (GL_RGBA), | |
72 | #endif | |
3c4b62a4 | 73 | myFboDepthFormat (GL_DEPTH24_STENCIL8), |
74 | myToFlipOutput (Standard_False), | |
c357e426 | 75 | myFrameCounter (0), |
76 | myHasFboBlit (Standard_True), | |
a1073ae2 | 77 | myToDisableOIT (Standard_False), |
78 | myToDisableOITMSAA (Standard_False), | |
7ccf8676 | 79 | myToDisableMSAA (Standard_False), |
c357e426 | 80 | myTransientDrawToFront (Standard_True), |
81 | myBackBufferRestored (Standard_False), | |
82 | myIsImmediateDrawn (Standard_False), | |
0b0320e7 | 83 | myTextureParams (new OpenGl_AspectFace()), |
84 | myBgGradientArray (new OpenGl_BackgroundArray (Graphic3d_TOB_GRADIENT)), | |
91c60b57 | 85 | myBgTextureArray (new OpenGl_BackgroundArray (Graphic3d_TOB_TEXTURE)), |
86 | // ray-tracing fields initialization | |
c357e426 | 87 | myRaytraceInitStatus (OpenGl_RT_NONE), |
88 | myIsRaytraceDataValid (Standard_False), | |
91c60b57 | 89 | myIsRaytraceWarnTextures (Standard_False), |
f5b72419 | 90 | myRaytraceBVHBuilder (new BVH_BinnedBuilder<Standard_ShortReal, 3, BVH_Constants_NbBinsBest> (BVH_Constants_LeafNodeSizeAverage, |
91 | BVH_Constants_MaxTreeDepth, | |
92 | Standard_False, | |
93 | OSD_Parallel::NbLogicalProcessors() + 1)), | |
94 | myRaytraceSceneRadius (0.0f), | |
95 | myRaytraceSceneEpsilon (1.0e-6f), | |
91c60b57 | 96 | myToUpdateEnvironmentMap (Standard_False), |
bd6a8454 | 97 | myRaytraceLayerListState (0) |
2166f0fa | 98 | { |
c357e426 | 99 | myWorkspace = new OpenGl_Workspace (this, NULL); |
2166f0fa | 100 | |
016e5959 | 101 | OpenGl_Light aLight; |
102 | aLight.Type = Graphic3d_TOLS_AMBIENT; | |
103 | aLight.IsHeadlight = Standard_False; | |
104 | aLight.Color.r() = 1.; | |
105 | aLight.Color.g() = 1.; | |
106 | aLight.Color.b() = 1.; | |
107 | myNoShadingLight.Append (aLight); | |
108 | ||
a1073ae2 | 109 | myCurrLightSourceState = myStateCounter->Increment(); |
110 | myMainSceneFbos[0] = new OpenGl_FrameBuffer(); | |
111 | myMainSceneFbos[1] = new OpenGl_FrameBuffer(); | |
112 | myMainSceneFbosOit[0] = new OpenGl_FrameBuffer(); | |
113 | myMainSceneFbosOit[1] = new OpenGl_FrameBuffer(); | |
114 | myImmediateSceneFbos[0] = new OpenGl_FrameBuffer(); | |
115 | myImmediateSceneFbos[1] = new OpenGl_FrameBuffer(); | |
116 | myImmediateSceneFbosOit[0] = new OpenGl_FrameBuffer(); | |
117 | myImmediateSceneFbosOit[1] = new OpenGl_FrameBuffer(); | |
118 | myOpenGlFBO = new OpenGl_FrameBuffer(); | |
119 | myOpenGlFBO2 = new OpenGl_FrameBuffer(); | |
120 | myRaytraceFBO1[0] = new OpenGl_FrameBuffer(); | |
121 | myRaytraceFBO1[1] = new OpenGl_FrameBuffer(); | |
122 | myRaytraceFBO2[0] = new OpenGl_FrameBuffer(); | |
123 | myRaytraceFBO2[1] = new OpenGl_FrameBuffer(); | |
c357e426 | 124 | } |
125 | ||
126 | // ======================================================================= | |
127 | // function : Destructor | |
128 | // purpose : | |
129 | // ======================================================================= | |
0b0320e7 | 130 | OpenGl_View::~OpenGl_View() |
2166f0fa | 131 | { |
bf75be98 | 132 | ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context |
0b0320e7 | 133 | OpenGl_Element::Destroy (NULL, myBgGradientArray); |
134 | OpenGl_Element::Destroy (NULL, myBgTextureArray); | |
135 | OpenGl_Element::Destroy (NULL, myTextureParams); | |
bf75be98 | 136 | } |
137 | ||
c357e426 | 138 | // ======================================================================= |
139 | // function : ReleaseGlResources | |
140 | // purpose : | |
141 | // ======================================================================= | |
bf75be98 | 142 | void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx) |
143 | { | |
536d98e2 | 144 | myGraduatedTrihedron.Release (theCtx.operator->()); |
30f0ad28 | 145 | |
bf75be98 | 146 | if (!myTextureEnv.IsNull()) |
147 | { | |
148 | theCtx->DelayedRelease (myTextureEnv); | |
149 | myTextureEnv.Nullify(); | |
150 | } | |
0b0320e7 | 151 | |
152 | if (myTextureParams != NULL) | |
153 | { | |
154 | myTextureParams->Release (theCtx.operator->()); | |
155 | } | |
156 | if (myBgGradientArray != NULL) | |
157 | { | |
158 | myBgGradientArray->Release (theCtx.operator->()); | |
159 | } | |
160 | if (myBgTextureArray != NULL) | |
bf75be98 | 161 | { |
0b0320e7 | 162 | myBgTextureArray->Release (theCtx.operator->()); |
bf75be98 | 163 | } |
91c60b57 | 164 | |
a1073ae2 | 165 | myMainSceneFbos[0] ->Release (theCtx.operator->()); |
166 | myMainSceneFbos[1] ->Release (theCtx.operator->()); | |
167 | myMainSceneFbosOit[0] ->Release (theCtx.operator->()); | |
168 | myMainSceneFbosOit[1] ->Release (theCtx.operator->()); | |
169 | myImmediateSceneFbos[0] ->Release (theCtx.operator->()); | |
170 | myImmediateSceneFbos[1] ->Release (theCtx.operator->()); | |
171 | myImmediateSceneFbosOit[0]->Release (theCtx.operator->()); | |
172 | myImmediateSceneFbosOit[1]->Release (theCtx.operator->()); | |
173 | myOpenGlFBO ->Release (theCtx.operator->()); | |
174 | myOpenGlFBO2 ->Release (theCtx.operator->()); | |
175 | myFullScreenQuad .Release (theCtx.operator->()); | |
176 | myFullScreenQuadFlip .Release (theCtx.operator->()); | |
c357e426 | 177 | |
91c60b57 | 178 | releaseRaytraceResources (theCtx); |
bf75be98 | 179 | } |
2166f0fa | 180 | |
c357e426 | 181 | // ======================================================================= |
182 | // function : Remove | |
183 | // purpose : | |
184 | // ======================================================================= | |
185 | void OpenGl_View::Remove() | |
bf75be98 | 186 | { |
c357e426 | 187 | if (IsRemoved()) |
bf75be98 | 188 | { |
c357e426 | 189 | return; |
bf75be98 | 190 | } |
191 | ||
c357e426 | 192 | myDriver->RemoveView (this); |
193 | myWindow.Nullify(); | |
194 | ||
195 | Graphic3d_CView::Remove(); | |
196 | } | |
197 | ||
7c3ef2f7 | 198 | // ======================================================================= |
199 | // function : SetTextureEnv | |
200 | // purpose : | |
201 | // ======================================================================= | |
202 | void OpenGl_View::SetCamera(const Handle(Graphic3d_Camera)& theCamera) | |
203 | { | |
204 | myCamera = theCamera; | |
205 | } | |
206 | ||
207 | // ======================================================================= | |
208 | // function : SetLocalOrigin | |
209 | // purpose : | |
210 | // ======================================================================= | |
211 | void OpenGl_View::SetLocalOrigin (const gp_XYZ& theOrigin) | |
212 | { | |
213 | myLocalOrigin = theOrigin; | |
214 | const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext(); | |
215 | if (!aCtx.IsNull()) | |
216 | { | |
217 | aCtx->ShaderManager()->SetLocalOrigin (theOrigin); | |
218 | } | |
219 | } | |
220 | ||
c357e426 | 221 | // ======================================================================= |
222 | // function : SetTextureEnv | |
223 | // purpose : | |
224 | // ======================================================================= | |
225 | void OpenGl_View::SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTextureEnv) | |
226 | { | |
227 | Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext(); | |
228 | if (!aCtx.IsNull() && !myTextureEnv.IsNull()) | |
229 | { | |
230 | aCtx->DelayedRelease (myTextureEnv); | |
231 | } | |
232 | ||
233 | myToUpdateEnvironmentMap = Standard_True; | |
234 | myTextureEnvData = theTextureEnv; | |
235 | myTextureEnv.Nullify(); | |
236 | initTextureEnv (aCtx); | |
237 | } | |
238 | ||
239 | // ======================================================================= | |
240 | // function : initTextureEnv | |
241 | // purpose : | |
242 | // ======================================================================= | |
243 | void OpenGl_View::initTextureEnv (const Handle(OpenGl_Context)& theContext) | |
244 | { | |
245 | if (myTextureEnvData.IsNull() | |
246 | || theContext.IsNull() | |
247 | || !theContext->MakeCurrent()) | |
bf75be98 | 248 | { |
249 | return; | |
250 | } | |
251 | ||
c357e426 | 252 | myTextureEnv = new OpenGl_Texture (myTextureEnvData->GetParams()); |
253 | Handle(Image_PixMap) anImage = myTextureEnvData->GetImage(); | |
e276548b | 254 | if (!anImage.IsNull()) |
c357e426 | 255 | { |
256 | myTextureEnv->Init (theContext, *anImage.operator->(), myTextureEnvData->Type()); | |
257 | } | |
258 | } | |
e276548b | 259 | |
c357e426 | 260 | // ======================================================================= |
261 | // function : SetImmediateModeDrawToFront | |
262 | // purpose : | |
263 | // ======================================================================= | |
264 | Standard_Boolean OpenGl_View::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer) | |
265 | { | |
266 | const Standard_Boolean aPrevMode = myTransientDrawToFront; | |
267 | myTransientDrawToFront = theDrawToFrontBuffer; | |
268 | return aPrevMode; | |
e276548b | 269 | } |
270 | ||
c357e426 | 271 | // ======================================================================= |
272 | // function : SetWindow | |
273 | // purpose : | |
274 | // ======================================================================= | |
275 | void OpenGl_View::SetWindow (const Handle(Aspect_Window)& theWindow, | |
a521d90d | 276 | const Aspect_RenderingContext theContext) |
e276548b | 277 | { |
c357e426 | 278 | myWindow = myDriver->CreateRenderWindow (theWindow, theContext); |
279 | Standard_ASSERT_RAISE (!myWindow.IsNull(), | |
280 | "OpenGl_View::SetWindow, " | |
281 | "Failed to create OpenGl window."); | |
e276548b | 282 | |
c357e426 | 283 | myWorkspace = new OpenGl_Workspace (this, myWindow); |
284 | myWorldViewProjState.Reset(); | |
91c60b57 | 285 | myToUpdateEnvironmentMap = Standard_True; |
c357e426 | 286 | myHasFboBlit = Standard_True; |
287 | Invalidate(); | |
288 | ||
289 | // Environment texture resource does not support lazy initialization. | |
290 | initTextureEnv (myWorkspace->GetGlContext()); | |
291 | } | |
292 | ||
293 | // ======================================================================= | |
294 | // function : Resized | |
295 | // purpose : | |
296 | // ======================================================================= | |
297 | void OpenGl_View::Resized() | |
298 | { | |
299 | if (myWindow.IsNull()) | |
300 | return; | |
301 | ||
302 | myWindow->Resize(); | |
303 | } | |
304 | ||
c357e426 | 305 | // ======================================================================= |
306 | // function : SetMinMaxValuesCallback | |
307 | // purpose : | |
308 | // ======================================================================= | |
309 | static void SetMinMaxValuesCallback (Graphic3d_CView* theView) | |
310 | { | |
311 | OpenGl_View* aView = dynamic_cast<OpenGl_View*>(theView); | |
312 | if (aView == NULL) | |
313 | return; | |
314 | ||
315 | Bnd_Box aBox = theView->MinMaxValues(); | |
316 | if (!aBox.IsVoid()) | |
2166f0fa | 317 | { |
c357e426 | 318 | gp_Pnt aMin = aBox.CornerMin(); |
319 | gp_Pnt aMax = aBox.CornerMax(); | |
320 | ||
321 | Graphic3d_Vec3 aMinVec ((Standard_ShortReal )aMin.X(), (Standard_ShortReal )aMin.Y(), (Standard_ShortReal )aMin.Z()); | |
322 | Graphic3d_Vec3 aMaxVec ((Standard_ShortReal )aMax.X(), (Standard_ShortReal )aMax.Y(), (Standard_ShortReal )aMax.Z()); | |
323 | aView->GraduatedTrihedronMinMaxValues (aMinVec, aMaxVec); | |
2166f0fa SK |
324 | } |
325 | } | |
326 | ||
c357e426 | 327 | // ======================================================================= |
328 | // function : GraduatedTrihedronDisplay | |
329 | // purpose : | |
330 | // ======================================================================= | |
331 | void OpenGl_View::GraduatedTrihedronDisplay (const Graphic3d_GraduatedTrihedron& theTrihedronData) | |
332 | { | |
333 | myGTrihedronData = theTrihedronData; | |
334 | myGTrihedronData.PtrView = this; | |
335 | myGTrihedronData.CubicAxesCallback = SetMinMaxValuesCallback; | |
336 | myGraduatedTrihedron.SetValues (myGTrihedronData); | |
337 | myToShowGradTrihedron = true; | |
338 | } | |
2166f0fa | 339 | |
c357e426 | 340 | // ======================================================================= |
341 | // function : GraduatedTrihedronErase | |
342 | // purpose : | |
343 | // ======================================================================= | |
344 | void OpenGl_View::GraduatedTrihedronErase() | |
2166f0fa | 345 | { |
c357e426 | 346 | myGTrihedronData.PtrView = NULL; |
347 | myGraduatedTrihedron.Release (myWorkspace->GetGlContext().operator->()); | |
348 | myToShowGradTrihedron = false; | |
2166f0fa SK |
349 | } |
350 | ||
c357e426 | 351 | // ======================================================================= |
352 | // function : GraduatedTrihedronMinMaxValues | |
353 | // purpose : | |
354 | // ======================================================================= | |
355 | void OpenGl_View::GraduatedTrihedronMinMaxValues (const Graphic3d_Vec3 theMin, const Graphic3d_Vec3 theMax) | |
356 | { | |
357 | myGraduatedTrihedron.SetMinMax (theMin, theMax); | |
358 | } | |
2166f0fa | 359 | |
c357e426 | 360 | // ======================================================================= |
361 | // function : BufferDump | |
362 | // purpose : | |
363 | // ======================================================================= | |
364 | Standard_Boolean OpenGl_View::BufferDump (Image_PixMap& theImage, const Graphic3d_BufferType& theBufferType) | |
365 | { | |
38d90bb3 | 366 | if (theBufferType != Graphic3d_BT_RGB_RayTraceHdrLeft) |
367 | { | |
368 | return myWorkspace->BufferDump(myFBO, theImage, theBufferType); | |
369 | } | |
370 | ||
371 | if (!myRaytraceParameters.AdaptiveScreenSampling) | |
372 | { | |
373 | return myWorkspace->BufferDump(myAccumFrames % 2 ? myRaytraceFBO2[0] : myRaytraceFBO1[0], theImage, theBufferType); | |
374 | } | |
375 | ||
376 | #if defined(GL_ES_VERSION_2_0) | |
377 | return false; | |
378 | #else | |
379 | if (theImage.Format() != Image_Format_RGBF) | |
380 | { | |
381 | return false; | |
382 | } | |
383 | ||
384 | const GLuint aW = myRaytraceOutputTexture[0]->SizeX(); | |
385 | const GLuint aH = myRaytraceOutputTexture[0]->SizeY(); | |
386 | if (aW / 3 != theImage.SizeX() || aH / 2 != theImage.SizeY()) | |
387 | { | |
388 | return false; | |
389 | } | |
390 | ||
391 | std::vector<GLfloat> aValues; | |
392 | try | |
393 | { | |
394 | aValues.resize (aW * aH); | |
395 | } | |
396 | catch (const std::bad_alloc&) | |
397 | { | |
398 | return false; | |
399 | } | |
400 | ||
401 | glBindTexture (GL_TEXTURE_RECTANGLE, myRaytraceOutputTexture[0]->TextureId()); | |
402 | glGetTexImage (GL_TEXTURE_RECTANGLE, 0, OpenGl_TextureFormat::Create<GLfloat, 1>().Format(), GL_FLOAT, &aValues[0]); | |
403 | glBindTexture (GL_TEXTURE_RECTANGLE, 0); | |
404 | for (unsigned int aRow = 0; aRow < aH; aRow += 2) | |
405 | { | |
406 | for (unsigned int aCol = 0; aCol < aW; aCol += 3) | |
407 | { | |
408 | float* anImageValue = theImage.ChangeValue<float[3]> ((aH - aRow) / 2 - 1, aCol / 3); | |
409 | float aInvNbSamples = 1.f / aValues[aRow * aW + aCol + aW]; | |
410 | anImageValue[0] = aValues[aRow * aW + aCol] * aInvNbSamples; | |
411 | anImageValue[1] = aValues[aRow * aW + aCol + 1] * aInvNbSamples; | |
412 | anImageValue[2] = aValues[aRow * aW + aCol + 1 + aW] * aInvNbSamples; | |
413 | } | |
414 | } | |
415 | ||
416 | return true; | |
417 | #endif | |
c357e426 | 418 | } |
419 | ||
420 | // ======================================================================= | |
421 | // function : Background | |
422 | // purpose : | |
423 | // ======================================================================= | |
424 | Aspect_Background OpenGl_View::Background() const | |
425 | { | |
b6472664 | 426 | return Aspect_Background (myBgColor.GetRGB()); |
c357e426 | 427 | } |
428 | ||
429 | // ======================================================================= | |
430 | // function : SetBackground | |
431 | // purpose : | |
432 | // ======================================================================= | |
433 | void OpenGl_View::SetBackground (const Aspect_Background& theBackground) | |
434 | { | |
b6472664 | 435 | myBgColor.SetRGB (theBackground.Color()); |
c357e426 | 436 | } |
437 | ||
438 | // ======================================================================= | |
439 | // function : GradientBackground | |
440 | // purpose : | |
441 | // ======================================================================= | |
442 | Aspect_GradientBackground OpenGl_View::GradientBackground() const | |
443 | { | |
444 | Quantity_Color aColor1, aColor2; | |
445 | aColor1.SetValues (myBgGradientArray->GradientColor (0).r(), | |
446 | myBgGradientArray->GradientColor (0).g(), | |
447 | myBgGradientArray->GradientColor (0).b(), Quantity_TOC_RGB); | |
448 | aColor2.SetValues (myBgGradientArray->GradientColor (1).r(), | |
449 | myBgGradientArray->GradientColor (1).g(), | |
450 | myBgGradientArray->GradientColor (1).b(), Quantity_TOC_RGB); | |
451 | return Aspect_GradientBackground (aColor1, aColor2, myBgGradientArray->GradientFillMethod()); | |
452 | } | |
2166f0fa | 453 | |
c357e426 | 454 | // ======================================================================= |
455 | // function : SetGradientBackground | |
456 | // purpose : | |
457 | // ======================================================================= | |
458 | void OpenGl_View::SetGradientBackground (const Aspect_GradientBackground& theBackground) | |
2166f0fa | 459 | { |
c357e426 | 460 | Quantity_Color aColor1, aColor2; |
461 | theBackground.Colors (aColor1, aColor2); | |
462 | myBgGradientArray->SetGradientParameters (aColor1, aColor2, theBackground.BgGradientFillMethod()); | |
463 | } | |
464 | ||
465 | // ======================================================================= | |
466 | // function : SetBackgroundImage | |
467 | // purpose : | |
468 | // ======================================================================= | |
469 | void OpenGl_View::SetBackgroundImage (const TCollection_AsciiString& theFilePath) | |
470 | { | |
471 | // Prepare aspect for texture storage | |
472 | myBackgroundImagePath = theFilePath; | |
473 | Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d(); | |
474 | Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath)); | |
475 | aTextureMap->EnableRepeat(); | |
476 | aTextureMap->DisableModulate(); | |
477 | aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL, | |
478 | Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f), | |
479 | Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f)); | |
480 | anAspect->SetTextureMap (aTextureMap); | |
481 | anAspect->SetInteriorStyle (Aspect_IS_SOLID); | |
b6472664 | 482 | anAspect->SetSuppressBackFaces (false); |
c357e426 | 483 | // Enable texture mapping |
484 | if (aTextureMap->IsDone()) | |
2166f0fa | 485 | { |
c357e426 | 486 | anAspect->SetTextureMapOn(); |
2166f0fa SK |
487 | } |
488 | else | |
489 | { | |
c357e426 | 490 | anAspect->SetTextureMapOff(); |
491 | return; | |
492 | } | |
2166f0fa | 493 | |
c357e426 | 494 | // Set texture parameters |
495 | myTextureParams->SetAspect (anAspect); | |
496 | } | |
2166f0fa | 497 | |
c357e426 | 498 | // ======================================================================= |
499 | // function : BackgroundImageStyle | |
500 | // purpose : | |
501 | // ======================================================================= | |
502 | Aspect_FillMethod OpenGl_View::BackgroundImageStyle() const | |
503 | { | |
504 | return myBgTextureArray->TextureFillMethod(); | |
2166f0fa SK |
505 | } |
506 | ||
c357e426 | 507 | // ======================================================================= |
508 | // function : SetBackgroundImageStyle | |
509 | // purpose : | |
510 | // ======================================================================= | |
511 | void OpenGl_View::SetBackgroundImageStyle (const Aspect_FillMethod theFillStyle) | |
512 | { | |
513 | myBgTextureArray->SetTextureFillMethod (theFillStyle); | |
514 | } | |
2166f0fa | 515 | |
c357e426 | 516 | //======================================================================= |
517 | //function : AddZLayer | |
518 | //purpose : | |
519 | //======================================================================= | |
520 | void OpenGl_View::AddZLayer (const Graphic3d_ZLayerId theLayerId) | |
2166f0fa | 521 | { |
c357e426 | 522 | myZLayers.AddLayer (theLayerId); |
2166f0fa SK |
523 | } |
524 | ||
c357e426 | 525 | //======================================================================= |
526 | //function : RemoveZLayer | |
527 | //purpose : | |
528 | //======================================================================= | |
529 | void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId) | |
530 | { | |
531 | myZLayers.RemoveLayer (theLayerId); | |
532 | } | |
2166f0fa | 533 | |
c357e426 | 534 | //======================================================================= |
535 | //function : SetZLayerSettings | |
536 | //purpose : | |
537 | //======================================================================= | |
538 | void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId, | |
539 | const Graphic3d_ZLayerSettings& theSettings) | |
2166f0fa | 540 | { |
c357e426 | 541 | myZLayers.SetLayerSettings (theLayerId, theSettings); |
2166f0fa SK |
542 | } |
543 | ||
50d06d8f | 544 | //======================================================================= |
545 | //function : ZLayerMax | |
546 | //purpose : | |
547 | //======================================================================= | |
548 | Standard_Integer OpenGl_View::ZLayerMax() const | |
549 | { | |
550 | Standard_Integer aLayerMax = Graphic3d_ZLayerId_Default; | |
551 | for (OpenGl_LayerSeqIds::Iterator aMapIt(myZLayers.LayerIDs()); aMapIt.More(); aMapIt.Next()) | |
552 | { | |
553 | aLayerMax = Max (aLayerMax, aMapIt.Value()); | |
554 | } | |
555 | ||
556 | return aLayerMax; | |
557 | } | |
558 | ||
559 | //======================================================================= | |
560 | //function : InvalidateZLayerBoundingBox | |
561 | //purpose : | |
562 | //======================================================================= | |
563 | void OpenGl_View::InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId) const | |
564 | { | |
565 | if (myZLayers.LayerIDs().IsBound (theLayerId)) | |
566 | { | |
567 | myZLayers.Layer (theLayerId).InvalidateBoundingBox(); | |
568 | } | |
569 | else | |
570 | { | |
1475265b | 571 | const Standard_Integer aLayerMax = ZLayerMax(); |
572 | for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId < aLayerMax; ++aLayerId) | |
50d06d8f | 573 | { |
574 | if (myZLayers.LayerIDs().IsBound (aLayerId)) | |
575 | { | |
576 | const OpenGl_Layer& aLayer = myZLayers.Layer (aLayerId); | |
577 | if (aLayer.NbOfTransformPersistenceObjects() > 0) | |
578 | { | |
579 | aLayer.InvalidateBoundingBox(); | |
580 | } | |
581 | } | |
582 | } | |
583 | } | |
584 | } | |
585 | ||
586 | //======================================================================= | |
587 | //function : ZLayerBoundingBox | |
588 | //purpose : | |
589 | //======================================================================= | |
7c3ef2f7 | 590 | Bnd_Box OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId, |
591 | const Handle(Graphic3d_Camera)& theCamera, | |
592 | const Standard_Integer theWindowWidth, | |
593 | const Standard_Integer theWindowHeight, | |
594 | const Standard_Boolean theToIncludeAuxiliary) const | |
50d06d8f | 595 | { |
7c3ef2f7 | 596 | Bnd_Box aBox; |
50d06d8f | 597 | if (myZLayers.LayerIDs().IsBound (theLayerId)) |
598 | { | |
71d8ccc7 | 599 | aBox = myZLayers.Layer (theLayerId).BoundingBox (Identification(), |
50d06d8f | 600 | theCamera, |
601 | theWindowWidth, | |
602 | theWindowHeight, | |
3fe9ce0e | 603 | theToIncludeAuxiliary); |
50d06d8f | 604 | } |
605 | ||
71d8ccc7 | 606 | // add bounding box of gradient/texture background for proper Z-fit |
607 | if (theToIncludeAuxiliary | |
608 | && theLayerId == Graphic3d_ZLayerId_BotOSD | |
609 | && (myBgTextureArray->IsDefined() | |
610 | || myBgGradientArray->IsDefined())) | |
611 | { | |
612 | // Background is drawn using 2D transformation persistence | |
613 | // (e.g. it is actually placed in 3D coordinates within active camera position). | |
614 | // We add here full-screen plane with 2D transformation persistence | |
615 | // for simplicity (myBgTextureArray might define a little bit different options | |
616 | // but it is updated within ::Render()) | |
7c3ef2f7 | 617 | const Graphic3d_Mat4d& aProjectionMat = theCamera->ProjectionMatrix(); |
618 | const Graphic3d_Mat4d& aWorldViewMat = theCamera->OrientationMatrix(); | |
619 | Graphic3d_BndBox3d aBox2d (Graphic3d_Vec3d (0.0, 0.0, 0.0), | |
620 | Graphic3d_Vec3d (double(theWindowWidth), double(theWindowHeight), 0.0)); | |
71d8ccc7 | 621 | |
778cd667 | 622 | Graphic3d_TransformPers aTrsfPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER); |
71d8ccc7 | 623 | aTrsfPers.Apply (theCamera, |
624 | aProjectionMat, | |
625 | aWorldViewMat, | |
626 | theWindowWidth, | |
627 | theWindowHeight, | |
628 | aBox2d); | |
7c3ef2f7 | 629 | aBox.Add (gp_Pnt (aBox2d.CornerMin().x(), aBox2d.CornerMin().y(), aBox2d.CornerMin().z())); |
630 | aBox.Add (gp_Pnt (aBox2d.CornerMax().x(), aBox2d.CornerMax().y(), aBox2d.CornerMax().z())); | |
71d8ccc7 | 631 | } |
632 | ||
633 | return aBox; | |
50d06d8f | 634 | } |
635 | ||
636 | //======================================================================= | |
637 | //function : considerZoomPersistenceObjects | |
638 | //purpose : | |
639 | //======================================================================= | |
640 | Standard_Real OpenGl_View::considerZoomPersistenceObjects (const Graphic3d_ZLayerId theLayerId, | |
641 | const Handle(Graphic3d_Camera)& theCamera, | |
642 | const Standard_Integer theWindowWidth, | |
3fe9ce0e | 643 | const Standard_Integer theWindowHeight) const |
50d06d8f | 644 | { |
1d92133e | 645 | if (myZLayers.LayerIDs().IsBound (theLayerId)) |
50d06d8f | 646 | { |
647 | return myZLayers.Layer (theLayerId).considerZoomPersistenceObjects (Identification(), | |
648 | theCamera, | |
649 | theWindowWidth, | |
3fe9ce0e | 650 | theWindowHeight); |
50d06d8f | 651 | } |
652 | ||
653 | return 1.0; | |
654 | } | |
655 | ||
c357e426 | 656 | //======================================================================= |
657 | //function : FBO | |
658 | //purpose : | |
659 | //======================================================================= | |
b128c892 | 660 | Handle(Standard_Transient) OpenGl_View::FBO() const |
c357e426 | 661 | { |
b128c892 | 662 | return Handle(Standard_Transient)(myFBO); |
c357e426 | 663 | } |
2166f0fa | 664 | |
c357e426 | 665 | //======================================================================= |
666 | //function : SetFBO | |
667 | //purpose : | |
668 | //======================================================================= | |
b128c892 | 669 | void OpenGl_View::SetFBO (const Handle(Standard_Transient)& theFbo) |
2166f0fa | 670 | { |
b128c892 | 671 | myFBO = Handle(OpenGl_FrameBuffer)::DownCast (theFbo); |
2166f0fa SK |
672 | } |
673 | ||
c357e426 | 674 | //======================================================================= |
675 | //function : FBOCreate | |
676 | //purpose : | |
677 | //======================================================================= | |
b128c892 | 678 | Handle(Standard_Transient) OpenGl_View::FBOCreate (const Standard_Integer theWidth, |
679 | const Standard_Integer theHeight) | |
c357e426 | 680 | { |
681 | return myWorkspace->FBOCreate (theWidth, theHeight); | |
682 | } | |
2166f0fa | 683 | |
c357e426 | 684 | //======================================================================= |
685 | //function : FBORelease | |
686 | //purpose : | |
687 | //======================================================================= | |
b128c892 | 688 | void OpenGl_View::FBORelease (Handle(Standard_Transient)& theFbo) |
2166f0fa | 689 | { |
b128c892 | 690 | Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo); |
691 | if (aFrameBuffer.IsNull()) | |
692 | { | |
693 | return; | |
694 | } | |
695 | ||
696 | myWorkspace->FBORelease (aFrameBuffer); | |
697 | theFbo.Nullify(); | |
c357e426 | 698 | } |
699 | ||
700 | //======================================================================= | |
701 | //function : FBOGetDimensions | |
702 | //purpose : | |
703 | //======================================================================= | |
b128c892 | 704 | void OpenGl_View::FBOGetDimensions (const Handle(Standard_Transient)& theFbo, |
c357e426 | 705 | Standard_Integer& theWidth, |
706 | Standard_Integer& theHeight, | |
707 | Standard_Integer& theWidthMax, | |
708 | Standard_Integer& theHeightMax) | |
709 | { | |
b128c892 | 710 | const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo); |
711 | if (aFrameBuffer.IsNull()) | |
712 | { | |
713 | return; | |
714 | } | |
715 | ||
c357e426 | 716 | theWidth = aFrameBuffer->GetVPSizeX(); // current viewport size |
717 | theHeight = aFrameBuffer->GetVPSizeY(); | |
718 | theWidthMax = aFrameBuffer->GetSizeX(); // texture size | |
719 | theHeightMax = aFrameBuffer->GetSizeY(); | |
720 | } | |
721 | ||
722 | //======================================================================= | |
723 | //function : FBOChangeViewport | |
724 | //purpose : | |
725 | //======================================================================= | |
b128c892 | 726 | void OpenGl_View::FBOChangeViewport (const Handle(Standard_Transient)& theFbo, |
c357e426 | 727 | const Standard_Integer theWidth, |
728 | const Standard_Integer theHeight) | |
729 | { | |
b128c892 | 730 | const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo); |
731 | if (aFrameBuffer.IsNull()) | |
732 | { | |
733 | return; | |
734 | } | |
735 | ||
c357e426 | 736 | aFrameBuffer->ChangeViewport (theWidth, theHeight); |
737 | } | |
738 | ||
739 | // ======================================================================= | |
740 | // function : Export | |
741 | // purpose : | |
742 | // ======================================================================= | |
743 | #ifdef HAVE_GL2PS | |
744 | Standard_Boolean OpenGl_View::Export (const Standard_CString theFileName, | |
745 | const Graphic3d_ExportFormat theFormat, | |
746 | const Graphic3d_SortType theSortType) | |
747 | { | |
748 | // gl2psBeginPage() will call OpenGL functions | |
749 | // so we should activate correct GL context before redraw scene call | |
750 | if (!myWorkspace->Activate()) | |
751 | { | |
752 | return Standard_False; | |
753 | } | |
754 | ||
755 | Standard_Integer aFormat = -1; | |
756 | Standard_Integer aSortType = Graphic3d_ST_BSP_Tree; | |
757 | switch (theFormat) | |
758 | { | |
759 | case Graphic3d_EF_PostScript: | |
760 | aFormat = GL2PS_PS; | |
761 | break; | |
762 | case Graphic3d_EF_EnhPostScript: | |
763 | aFormat = GL2PS_EPS; | |
764 | break; | |
765 | case Graphic3d_EF_TEX: | |
766 | aFormat = GL2PS_TEX; | |
767 | break; | |
768 | case Graphic3d_EF_PDF: | |
769 | aFormat = GL2PS_PDF; | |
770 | break; | |
771 | case Graphic3d_EF_SVG: | |
772 | aFormat = GL2PS_SVG; | |
773 | break; | |
774 | case Graphic3d_EF_PGF: | |
775 | aFormat = GL2PS_PGF; | |
776 | break; | |
777 | case Graphic3d_EF_EMF: | |
778 | //aFormat = GL2PS_EMF; | |
779 | aFormat = GL2PS_PGF + 1; // 6 | |
780 | break; | |
781 | default: | |
782 | // unsupported format | |
783 | return Standard_False; | |
784 | } | |
785 | ||
786 | switch (theSortType) | |
787 | { | |
788 | case Graphic3d_ST_Simple: | |
789 | aSortType = GL2PS_SIMPLE_SORT; | |
790 | break; | |
791 | case Graphic3d_ST_BSP_Tree: | |
792 | aSortType = GL2PS_BSP_SORT; | |
793 | break; | |
794 | } | |
795 | ||
796 | GLint aViewport[4]; | |
797 | aViewport[0] = 0; | |
798 | aViewport[1] = 0; | |
799 | aViewport[2] = myWindow->Width(); | |
800 | aViewport[3] = myWindow->Height(); | |
801 | ||
802 | GLint aBufferSize = 1024 * 1024; | |
803 | GLint anErrCode = GL2PS_SUCCESS; | |
804 | ||
805 | // gl2ps uses standard write functions and do not check locale | |
806 | Standard_CLocaleSentry aLocaleSentry; | |
807 | ||
808 | while (aBufferSize > 0) | |
809 | { | |
810 | // current patch for EMF support in gl2ps uses WinAPI functions to create file | |
811 | FILE* aFileH = (theFormat != Graphic3d_EF_EMF) ? fopen (theFileName, "wb") : NULL; | |
812 | anErrCode = gl2psBeginPage ("", "", aViewport, aFormat, aSortType, | |
813 | GL2PS_DRAW_BACKGROUND | GL2PS_OCCLUSION_CULL | GL2PS_BEST_ROOT/* | GL2PS_SIMPLE_LINE_OFFSET*/, | |
814 | GL_RGBA, 0, NULL, | |
815 | 0, 0, 0, aBufferSize, aFileH, theFileName); | |
816 | if (anErrCode != GL2PS_SUCCESS) | |
817 | { | |
818 | // initialization failed | |
819 | if (aFileH != NULL) | |
820 | fclose (aFileH); | |
821 | break; | |
822 | } | |
823 | Redraw(); | |
824 | ||
825 | anErrCode = gl2psEndPage(); | |
826 | if (aFileH != NULL) | |
827 | fclose (aFileH); | |
828 | ||
829 | if (anErrCode == GL2PS_OVERFLOW) | |
830 | aBufferSize *= 2; | |
831 | else | |
832 | break; | |
833 | } | |
834 | return anErrCode == GL2PS_SUCCESS; | |
835 | } | |
836 | #else | |
837 | Standard_Boolean OpenGl_View::Export (const Standard_CString /*theFileName*/, | |
838 | const Graphic3d_ExportFormat /*theFormat*/, | |
839 | const Graphic3d_SortType /*theSortType*/) | |
840 | { | |
841 | return Standard_False; | |
842 | } | |
843 | #endif | |
844 | ||
845 | //======================================================================= | |
846 | //function : displayStructure | |
847 | //purpose : | |
848 | //======================================================================= | |
849 | void OpenGl_View::displayStructure (const Handle(Graphic3d_CStructure)& theStructure, | |
850 | const Standard_Integer thePriority) | |
851 | { | |
852 | const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->()); | |
853 | const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer(); | |
854 | myZLayers.AddStructure (aStruct, aZLayer, thePriority); | |
855 | } | |
856 | ||
857 | //======================================================================= | |
858 | //function : eraseStructure | |
859 | //purpose : | |
860 | //======================================================================= | |
861 | void OpenGl_View::eraseStructure (const Handle(Graphic3d_CStructure)& theStructure) | |
862 | { | |
863 | const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->()); | |
864 | myZLayers.RemoveStructure (aStruct); | |
865 | } | |
866 | ||
867 | //======================================================================= | |
868 | //function : changeZLayer | |
869 | //purpose : | |
870 | //======================================================================= | |
871 | void OpenGl_View::changeZLayer (const Handle(Graphic3d_CStructure)& theStructure, | |
872 | const Graphic3d_ZLayerId theNewLayerId) | |
873 | { | |
874 | const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer(); | |
875 | const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->()); | |
876 | myZLayers.ChangeLayer (aStruct, anOldLayer, theNewLayerId); | |
cfece3ef | 877 | Update (anOldLayer); |
878 | Update (theNewLayerId); | |
c357e426 | 879 | } |
880 | ||
881 | //======================================================================= | |
882 | //function : changePriority | |
883 | //purpose : | |
884 | //======================================================================= | |
885 | void OpenGl_View::changePriority (const Handle(Graphic3d_CStructure)& theStructure, | |
886 | const Standard_Integer theNewPriority) | |
887 | { | |
888 | const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer(); | |
889 | const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->()); | |
890 | myZLayers.ChangePriority (aStruct, aLayerId, theNewPriority); | |
2166f0fa | 891 | } |
26d9c835 | 892 | |
893 | //======================================================================= | |
894 | //function : DiagnosticInformation | |
895 | //purpose : | |
896 | //======================================================================= | |
897 | void OpenGl_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict, | |
898 | Graphic3d_DiagnosticInfo theFlags) const | |
899 | { | |
900 | Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext(); | |
901 | if (!myWorkspace->Activate() | |
902 | || aCtx.IsNull()) | |
903 | { | |
904 | return; | |
905 | } | |
906 | ||
907 | aCtx->DiagnosticInformation (theDict, theFlags); | |
908 | if ((theFlags & Graphic3d_DiagnosticInfo_FrameBuffer) != 0) | |
909 | { | |
910 | TCollection_AsciiString aResRatio (myRenderParams.ResolutionRatio()); | |
911 | theDict.ChangeFromIndex (theDict.Add ("ResolutionRatio", aResRatio)) = aResRatio; | |
912 | } | |
913 | } |