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> | |
cfb54c0c | 20 | #include <Aspect_XRSession.hxx> |
c357e426 | 21 | #include <Graphic3d_AspectFillArea3d.hxx> |
22 | #include <Graphic3d_Texture2Dmanual.hxx> | |
23 | #include <Graphic3d_TextureEnv.hxx> | |
24 | #include <Graphic3d_Mat4d.hxx> | |
cfb54c0c | 25 | #include <Image_AlienPixMap.hxx> |
26 | #include <OpenGl_ArbFBO.hxx> | |
1220d98e | 27 | #include <OpenGl_BackgroundArray.hxx> |
bf75be98 | 28 | #include <OpenGl_Context.hxx> |
78c4e836 | 29 | #include <OpenGl_DepthPeeling.hxx> |
c357e426 | 30 | #include <OpenGl_FrameBuffer.hxx> |
30f0ad28 | 31 | #include <OpenGl_GlCore11.hxx> |
32 | #include <OpenGl_GraduatedTrihedron.hxx> | |
392ac980 | 33 | #include <OpenGl_GraphicDriver.hxx> |
30f0ad28 | 34 | #include <OpenGl_ShaderManager.hxx> |
d84e8669 | 35 | #include <OpenGl_ShadowMap.hxx> |
bf75be98 | 36 | #include <OpenGl_Texture.hxx> |
c357e426 | 37 | #include <OpenGl_Window.hxx> |
30f0ad28 | 38 | #include <OpenGl_Workspace.hxx> |
f5b72419 | 39 | #include <OSD_Parallel.hxx> |
c357e426 | 40 | #include <Standard_CLocaleSentry.hxx> |
2166f0fa | 41 | |
f5b72419 | 42 | #include "../Graphic3d/Graphic3d_Structure.pxx" |
cfb54c0c | 43 | #include "../Textures/Textures_EnvLUT.pxx" |
44 | ||
45 | namespace | |
46 | { | |
47 | //! Format Frame Buffer format for logging messages. | |
48 | static TCollection_AsciiString printFboFormat (const Handle(OpenGl_FrameBuffer)& theFbo) | |
49 | { | |
50 | return TCollection_AsciiString() + theFbo->GetInitVPSizeX() + "x" + theFbo->GetInitVPSizeY() + "@" + theFbo->NbSamples(); | |
51 | } | |
52 | ||
53 | //! Return TRUE if Frame Buffer initialized has failed with the same parameters. | |
54 | static bool checkWasFailedFbo (const Handle(OpenGl_FrameBuffer)& theFboToCheck, | |
55 | Standard_Integer theSizeX, | |
56 | Standard_Integer theSizeY, | |
57 | Standard_Integer theNbSamples) | |
58 | { | |
59 | return !theFboToCheck->IsValid() | |
60 | && theFboToCheck->GetInitVPSizeX() == theSizeX | |
61 | && theFboToCheck->GetInitVPSizeY() == theSizeY | |
62 | && theFboToCheck->NbSamples() == theNbSamples; | |
63 | } | |
64 | ||
65 | //! Return TRUE if Frame Buffer initialized has failed with the same parameters. | |
66 | static bool checkWasFailedFbo (const Handle(OpenGl_FrameBuffer)& theFboToCheck, | |
67 | const Handle(OpenGl_FrameBuffer)& theFboRef) | |
68 | { | |
69 | return checkWasFailedFbo (theFboToCheck, theFboRef->GetVPSizeX(), theFboRef->GetVPSizeY(), theFboRef->NbSamples()); | |
70 | } | |
1220d98e | 71 | |
72 | //! Chooses compatible internal color format for OIT frame buffer. | |
73 | static bool chooseOitColorConfiguration (const Handle(OpenGl_Context)& theGlContext, | |
74 | const Standard_Integer theConfigIndex, | |
75 | OpenGl_ColorFormats& theFormats) | |
76 | { | |
77 | theFormats.Clear(); | |
78 | switch (theConfigIndex) | |
79 | { | |
80 | case 0: // choose best applicable color format combination | |
81 | { | |
82 | theFormats.Append (theGlContext->hasHalfFloatBuffer != OpenGl_FeatureNotAvailable ? GL_RGBA16F : GL_RGBA32F); | |
83 | theFormats.Append (theGlContext->hasHalfFloatBuffer != OpenGl_FeatureNotAvailable ? GL_R16F : GL_R32F); | |
84 | return true; | |
85 | } | |
86 | case 1: // choose non-optimal applicable color format combination | |
87 | { | |
88 | theFormats.Append (theGlContext->hasHalfFloatBuffer != OpenGl_FeatureNotAvailable ? GL_RGBA16F : GL_RGBA32F); | |
89 | theFormats.Append (theGlContext->hasHalfFloatBuffer != OpenGl_FeatureNotAvailable ? GL_RGBA16F : GL_RGBA32F); | |
90 | return true; | |
91 | } | |
92 | } | |
93 | return false; // color combination does not exist | |
94 | } | |
cfb54c0c | 95 | } |
f5b72419 | 96 | |
92efcf78 | 97 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,Graphic3d_CView) |
98 | ||
c357e426 | 99 | // ======================================================================= |
100 | // function : Constructor | |
101 | // purpose : | |
102 | // ======================================================================= | |
103 | OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr, | |
104 | const Handle(OpenGl_GraphicDriver)& theDriver, | |
105 | const Handle(OpenGl_Caps)& theCaps, | |
c357e426 | 106 | OpenGl_StateCounter* theCounter) |
107 | : Graphic3d_CView (theMgr), | |
108 | myDriver (theDriver.operator->()), | |
109 | myCaps (theCaps), | |
c357e426 | 110 | myWasRedrawnGL (Standard_False), |
c357e426 | 111 | myToShowGradTrihedron (false), |
f5b72419 | 112 | myZLayers (Structure_MAX_PRIORITY - Structure_MIN_PRIORITY + 1), |
c357e426 | 113 | myStateCounter (theCounter), |
992ed6b3 | 114 | myCurrLightSourceState (theCounter->Increment()), |
115 | myLightsRevision (0), | |
0b0320e7 | 116 | myLastLightSourceState (0, 0), |
ba00aab7 | 117 | mySRgbState (-1), |
118 | myFboColorFormat (GL_SRGB8_ALPHA8), // note that GL_SRGB8 is not required to be renderable, unlike GL_RGB8, GL_RGBA8, GL_SRGB8_ALPHA8 | |
3c4b62a4 | 119 | myFboDepthFormat (GL_DEPTH24_STENCIL8), |
120 | myToFlipOutput (Standard_False), | |
b40cdc2b | 121 | // |
c357e426 | 122 | myFrameCounter (0), |
123 | myHasFboBlit (Standard_True), | |
a1073ae2 | 124 | myToDisableOIT (Standard_False), |
125 | myToDisableOITMSAA (Standard_False), | |
7ccf8676 | 126 | myToDisableMSAA (Standard_False), |
c357e426 | 127 | myTransientDrawToFront (Standard_True), |
128 | myBackBufferRestored (Standard_False), | |
129 | myIsImmediateDrawn (Standard_False), | |
bf5f0ca2 | 130 | myTextureParams (new OpenGl_Aspects()), |
077a220c | 131 | myCubeMapParams (new OpenGl_Aspects()), |
132 | myBackgroundType (Graphic3d_TOB_NONE), | |
67312b79 | 133 | myPBREnvState (OpenGl_PBREnvState_NONEXISTENT), |
134 | myPBREnvRequest (OpenGl_PBREnvRequest_NONE), | |
91c60b57 | 135 | // ray-tracing fields initialization |
c357e426 | 136 | myRaytraceInitStatus (OpenGl_RT_NONE), |
137 | myIsRaytraceDataValid (Standard_False), | |
91c60b57 | 138 | myIsRaytraceWarnTextures (Standard_False), |
f5b72419 | 139 | myRaytraceBVHBuilder (new BVH_BinnedBuilder<Standard_ShortReal, 3, BVH_Constants_NbBinsBest> (BVH_Constants_LeafNodeSizeAverage, |
140 | BVH_Constants_MaxTreeDepth, | |
141 | Standard_False, | |
142 | OSD_Parallel::NbLogicalProcessors() + 1)), | |
143 | myRaytraceSceneRadius (0.0f), | |
144 | myRaytraceSceneEpsilon (1.0e-6f), | |
91c60b57 | 145 | myToUpdateEnvironmentMap (Standard_False), |
b27ab03d | 146 | myRaytraceLayerListState (0), |
147 | myPrevCameraApertureRadius(0.f), | |
148 | myPrevCameraFocalPlaneDist(0.f) | |
2166f0fa | 149 | { |
077a220c | 150 | for (int i = 0; i < Graphic3d_TypeOfBackground_NB; ++i) |
151 | { | |
152 | myBackgrounds[i] = new OpenGl_BackgroundArray(Graphic3d_TypeOfBackground(i)); | |
153 | } | |
154 | ||
c357e426 | 155 | myWorkspace = new OpenGl_Workspace (this, NULL); |
2166f0fa | 156 | |
06d40093 | 157 | Handle(Graphic3d_CLight) aLight = new Graphic3d_CLight (Graphic3d_TypeOfLightSource_Ambient); |
992ed6b3 | 158 | aLight->SetColor (Quantity_NOC_WHITE); |
8445efca | 159 | myLights = new Graphic3d_LightSet(); |
992ed6b3 | 160 | myNoShadingLight = new Graphic3d_LightSet(); |
161 | myNoShadingLight->Add (aLight); | |
016e5959 | 162 | |
a1073ae2 | 163 | myMainSceneFbos[0] = new OpenGl_FrameBuffer(); |
164 | myMainSceneFbos[1] = new OpenGl_FrameBuffer(); | |
165 | myMainSceneFbosOit[0] = new OpenGl_FrameBuffer(); | |
166 | myMainSceneFbosOit[1] = new OpenGl_FrameBuffer(); | |
167 | myImmediateSceneFbos[0] = new OpenGl_FrameBuffer(); | |
168 | myImmediateSceneFbos[1] = new OpenGl_FrameBuffer(); | |
169 | myImmediateSceneFbosOit[0] = new OpenGl_FrameBuffer(); | |
170 | myImmediateSceneFbosOit[1] = new OpenGl_FrameBuffer(); | |
b40cdc2b | 171 | myXrSceneFbo = new OpenGl_FrameBuffer(); |
a1073ae2 | 172 | myOpenGlFBO = new OpenGl_FrameBuffer(); |
173 | myOpenGlFBO2 = new OpenGl_FrameBuffer(); | |
174 | myRaytraceFBO1[0] = new OpenGl_FrameBuffer(); | |
175 | myRaytraceFBO1[1] = new OpenGl_FrameBuffer(); | |
176 | myRaytraceFBO2[0] = new OpenGl_FrameBuffer(); | |
177 | myRaytraceFBO2[1] = new OpenGl_FrameBuffer(); | |
78c4e836 | 178 | myDepthPeelingFbos = new OpenGl_DepthPeeling(); |
d84e8669 | 179 | myShadowMaps = new OpenGl_ShadowMapArray(); |
c357e426 | 180 | } |
181 | ||
182 | // ======================================================================= | |
183 | // function : Destructor | |
184 | // purpose : | |
185 | // ======================================================================= | |
0b0320e7 | 186 | OpenGl_View::~OpenGl_View() |
2166f0fa | 187 | { |
bf75be98 | 188 | ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context |
077a220c | 189 | for (int i = 0; i < Graphic3d_TypeOfBackground_NB; ++i) |
190 | { | |
191 | OpenGl_Element::Destroy(NULL, myBackgrounds[i]); | |
192 | } | |
193 | ||
0b0320e7 | 194 | OpenGl_Element::Destroy (NULL, myTextureParams); |
077a220c | 195 | OpenGl_Element::Destroy (NULL, myCubeMapParams); |
bf75be98 | 196 | } |
197 | ||
c357e426 | 198 | // ======================================================================= |
ba00aab7 | 199 | // function : releaseSrgbResources |
c357e426 | 200 | // purpose : |
201 | // ======================================================================= | |
ba00aab7 | 202 | void OpenGl_View::releaseSrgbResources (const Handle(OpenGl_Context)& theCtx) |
bf75be98 | 203 | { |
ba00aab7 | 204 | myRenderParams.RebuildRayTracingShaders = true; |
30f0ad28 | 205 | |
bf75be98 | 206 | if (!myTextureEnv.IsNull()) |
207 | { | |
ad67e367 | 208 | if (!theCtx.IsNull()) |
cc8cbabe | 209 | { |
ad67e367 | 210 | for (OpenGl_TextureSet::Iterator aTextureIter (myTextureEnv); aTextureIter.More(); aTextureIter.Next()) |
211 | { | |
212 | theCtx->DelayedRelease (aTextureIter.ChangeValue()); | |
213 | aTextureIter.ChangeValue().Nullify(); | |
214 | } | |
cc8cbabe | 215 | } |
bf75be98 | 216 | myTextureEnv.Nullify(); |
217 | } | |
0b0320e7 | 218 | |
219 | if (myTextureParams != NULL) | |
220 | { | |
ad67e367 | 221 | myTextureParams->Release (theCtx.get()); |
0b0320e7 | 222 | } |
077a220c | 223 | |
224 | if (myCubeMapParams != NULL) | |
0b0320e7 | 225 | { |
077a220c | 226 | myCubeMapParams->Release (theCtx.get()); |
0b0320e7 | 227 | } |
077a220c | 228 | |
229 | for (int i = 0; i < Graphic3d_TypeOfBackground_NB; ++i) | |
bf75be98 | 230 | { |
077a220c | 231 | if (myBackgrounds[i] != NULL) |
232 | { | |
233 | myBackgrounds[i]->Release (theCtx.get()); | |
234 | } | |
bf75be98 | 235 | } |
91c60b57 | 236 | |
ad67e367 | 237 | myMainSceneFbos[0] ->Release (theCtx.get()); |
238 | myMainSceneFbos[1] ->Release (theCtx.get()); | |
239 | myMainSceneFbosOit[0] ->Release (theCtx.get()); | |
240 | myMainSceneFbosOit[1] ->Release (theCtx.get()); | |
241 | myImmediateSceneFbos[0] ->Release (theCtx.get()); | |
242 | myImmediateSceneFbos[1] ->Release (theCtx.get()); | |
243 | myImmediateSceneFbosOit[0]->Release (theCtx.get()); | |
244 | myImmediateSceneFbosOit[1]->Release (theCtx.get()); | |
b40cdc2b | 245 | myXrSceneFbo ->Release (theCtx.get()); |
78c4e836 | 246 | myDepthPeelingFbos ->Release (theCtx.get()); |
ad67e367 | 247 | myOpenGlFBO ->Release (theCtx.get()); |
248 | myOpenGlFBO2 ->Release (theCtx.get()); | |
249 | myFullScreenQuad .Release (theCtx.get()); | |
250 | myFullScreenQuadFlip .Release (theCtx.get()); | |
d84e8669 | 251 | myShadowMaps->Release (theCtx.get()); |
c357e426 | 252 | |
ba00aab7 | 253 | // Technically we should also re-initialize all sRGB/RGB8 color textures. |
254 | // But for now consider this sRGB disabling/enabling to be done at application start-up | |
255 | // and re-create dynamically only frame buffers. | |
256 | } | |
257 | ||
258 | // ======================================================================= | |
259 | // function : ReleaseGlResources | |
260 | // purpose : | |
261 | // ======================================================================= | |
262 | void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx) | |
263 | { | |
264 | myGraduatedTrihedron.Release (theCtx.get()); | |
265 | myFrameStatsPrs.Release (theCtx.get()); | |
266 | ||
267 | releaseSrgbResources (theCtx); | |
268 | ||
91c60b57 | 269 | releaseRaytraceResources (theCtx); |
67312b79 | 270 | |
271 | if (!myPBREnvironment.IsNull()) | |
272 | { | |
273 | myPBREnvironment->Release (theCtx.get()); | |
274 | } | |
b40cdc2b | 275 | ReleaseXR(); |
bf75be98 | 276 | } |
2166f0fa | 277 | |
c357e426 | 278 | // ======================================================================= |
279 | // function : Remove | |
280 | // purpose : | |
281 | // ======================================================================= | |
282 | void OpenGl_View::Remove() | |
bf75be98 | 283 | { |
c357e426 | 284 | if (IsRemoved()) |
bf75be98 | 285 | { |
c357e426 | 286 | return; |
bf75be98 | 287 | } |
288 | ||
c357e426 | 289 | myDriver->RemoveView (this); |
290 | myWindow.Nullify(); | |
291 | ||
292 | Graphic3d_CView::Remove(); | |
293 | } | |
294 | ||
7c3ef2f7 | 295 | // ======================================================================= |
296 | // function : SetLocalOrigin | |
297 | // purpose : | |
298 | // ======================================================================= | |
299 | void OpenGl_View::SetLocalOrigin (const gp_XYZ& theOrigin) | |
300 | { | |
301 | myLocalOrigin = theOrigin; | |
302 | const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext(); | |
303 | if (!aCtx.IsNull()) | |
304 | { | |
305 | aCtx->ShaderManager()->SetLocalOrigin (theOrigin); | |
306 | } | |
307 | } | |
308 | ||
c357e426 | 309 | // ======================================================================= |
310 | // function : SetTextureEnv | |
311 | // purpose : | |
312 | // ======================================================================= | |
313 | void OpenGl_View::SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTextureEnv) | |
314 | { | |
315 | Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext(); | |
316 | if (!aCtx.IsNull() && !myTextureEnv.IsNull()) | |
317 | { | |
cc8cbabe | 318 | for (OpenGl_TextureSet::Iterator aTextureIter (myTextureEnv); aTextureIter.More(); aTextureIter.Next()) |
319 | { | |
320 | aCtx->DelayedRelease (aTextureIter.ChangeValue()); | |
321 | aTextureIter.ChangeValue().Nullify(); | |
322 | } | |
c357e426 | 323 | } |
324 | ||
325 | myToUpdateEnvironmentMap = Standard_True; | |
326 | myTextureEnvData = theTextureEnv; | |
327 | myTextureEnv.Nullify(); | |
328 | initTextureEnv (aCtx); | |
329 | } | |
330 | ||
331 | // ======================================================================= | |
332 | // function : initTextureEnv | |
333 | // purpose : | |
334 | // ======================================================================= | |
335 | void OpenGl_View::initTextureEnv (const Handle(OpenGl_Context)& theContext) | |
336 | { | |
337 | if (myTextureEnvData.IsNull() | |
338 | || theContext.IsNull() | |
339 | || !theContext->MakeCurrent()) | |
bf75be98 | 340 | { |
341 | return; | |
342 | } | |
343 | ||
72f6dc61 | 344 | Handle(OpenGl_Texture) aTextureEnv = new OpenGl_Texture (myTextureEnvData->GetId(), myTextureEnvData->GetParams()); |
faff3767 | 345 | if (Handle(Image_PixMap) anImage = myTextureEnvData->GetImage (theContext->SupportedTextureFormats())) |
c357e426 | 346 | { |
ba00aab7 | 347 | aTextureEnv->Init (theContext, *anImage, myTextureEnvData->Type(), true); |
c357e426 | 348 | } |
72f6dc61 | 349 | myTextureEnv = new OpenGl_TextureSet (aTextureEnv); |
350 | myTextureEnv->ChangeTextureSetBits() = Graphic3d_TextureSetBits_BaseColor; | |
c357e426 | 351 | } |
e276548b | 352 | |
c357e426 | 353 | // ======================================================================= |
354 | // function : SetImmediateModeDrawToFront | |
355 | // purpose : | |
356 | // ======================================================================= | |
357 | Standard_Boolean OpenGl_View::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer) | |
358 | { | |
359 | const Standard_Boolean aPrevMode = myTransientDrawToFront; | |
360 | myTransientDrawToFront = theDrawToFrontBuffer; | |
361 | return aPrevMode; | |
e276548b | 362 | } |
363 | ||
1220d98e | 364 | // ======================================================================= |
365 | // function : Window | |
366 | // purpose : | |
367 | // ======================================================================= | |
368 | Handle(Aspect_Window) OpenGl_View::Window() const | |
369 | { | |
370 | return myWindow->PlatformWindow(); | |
371 | } | |
372 | ||
c357e426 | 373 | // ======================================================================= |
374 | // function : SetWindow | |
375 | // purpose : | |
376 | // ======================================================================= | |
377 | void OpenGl_View::SetWindow (const Handle(Aspect_Window)& theWindow, | |
a521d90d | 378 | const Aspect_RenderingContext theContext) |
e276548b | 379 | { |
c357e426 | 380 | myWindow = myDriver->CreateRenderWindow (theWindow, theContext); |
381 | Standard_ASSERT_RAISE (!myWindow.IsNull(), | |
382 | "OpenGl_View::SetWindow, " | |
383 | "Failed to create OpenGl window."); | |
e276548b | 384 | |
c357e426 | 385 | myWorkspace = new OpenGl_Workspace (this, myWindow); |
386 | myWorldViewProjState.Reset(); | |
91c60b57 | 387 | myToUpdateEnvironmentMap = Standard_True; |
c357e426 | 388 | myHasFboBlit = Standard_True; |
389 | Invalidate(); | |
390 | ||
391 | // Environment texture resource does not support lazy initialization. | |
392 | initTextureEnv (myWorkspace->GetGlContext()); | |
393 | } | |
394 | ||
395 | // ======================================================================= | |
396 | // function : Resized | |
397 | // purpose : | |
398 | // ======================================================================= | |
399 | void OpenGl_View::Resized() | |
400 | { | |
401 | if (myWindow.IsNull()) | |
402 | return; | |
403 | ||
404 | myWindow->Resize(); | |
405 | } | |
406 | ||
c357e426 | 407 | // ======================================================================= |
408 | // function : SetMinMaxValuesCallback | |
409 | // purpose : | |
410 | // ======================================================================= | |
411 | static void SetMinMaxValuesCallback (Graphic3d_CView* theView) | |
412 | { | |
413 | OpenGl_View* aView = dynamic_cast<OpenGl_View*>(theView); | |
414 | if (aView == NULL) | |
415 | return; | |
416 | ||
417 | Bnd_Box aBox = theView->MinMaxValues(); | |
418 | if (!aBox.IsVoid()) | |
2166f0fa | 419 | { |
c357e426 | 420 | gp_Pnt aMin = aBox.CornerMin(); |
421 | gp_Pnt aMax = aBox.CornerMax(); | |
422 | ||
423 | Graphic3d_Vec3 aMinVec ((Standard_ShortReal )aMin.X(), (Standard_ShortReal )aMin.Y(), (Standard_ShortReal )aMin.Z()); | |
424 | Graphic3d_Vec3 aMaxVec ((Standard_ShortReal )aMax.X(), (Standard_ShortReal )aMax.Y(), (Standard_ShortReal )aMax.Z()); | |
425 | aView->GraduatedTrihedronMinMaxValues (aMinVec, aMaxVec); | |
2166f0fa SK |
426 | } |
427 | } | |
428 | ||
c357e426 | 429 | // ======================================================================= |
430 | // function : GraduatedTrihedronDisplay | |
431 | // purpose : | |
432 | // ======================================================================= | |
433 | void OpenGl_View::GraduatedTrihedronDisplay (const Graphic3d_GraduatedTrihedron& theTrihedronData) | |
434 | { | |
435 | myGTrihedronData = theTrihedronData; | |
436 | myGTrihedronData.PtrView = this; | |
437 | myGTrihedronData.CubicAxesCallback = SetMinMaxValuesCallback; | |
438 | myGraduatedTrihedron.SetValues (myGTrihedronData); | |
439 | myToShowGradTrihedron = true; | |
440 | } | |
2166f0fa | 441 | |
c357e426 | 442 | // ======================================================================= |
443 | // function : GraduatedTrihedronErase | |
444 | // purpose : | |
445 | // ======================================================================= | |
446 | void OpenGl_View::GraduatedTrihedronErase() | |
2166f0fa | 447 | { |
c357e426 | 448 | myGTrihedronData.PtrView = NULL; |
449 | myGraduatedTrihedron.Release (myWorkspace->GetGlContext().operator->()); | |
450 | myToShowGradTrihedron = false; | |
2166f0fa SK |
451 | } |
452 | ||
c357e426 | 453 | // ======================================================================= |
454 | // function : GraduatedTrihedronMinMaxValues | |
455 | // purpose : | |
456 | // ======================================================================= | |
457 | void OpenGl_View::GraduatedTrihedronMinMaxValues (const Graphic3d_Vec3 theMin, const Graphic3d_Vec3 theMax) | |
458 | { | |
459 | myGraduatedTrihedron.SetMinMax (theMin, theMax); | |
460 | } | |
2166f0fa | 461 | |
c357e426 | 462 | // ======================================================================= |
463 | // function : BufferDump | |
464 | // purpose : | |
465 | // ======================================================================= | |
466 | Standard_Boolean OpenGl_View::BufferDump (Image_PixMap& theImage, const Graphic3d_BufferType& theBufferType) | |
467 | { | |
38d90bb3 | 468 | if (theBufferType != Graphic3d_BT_RGB_RayTraceHdrLeft) |
469 | { | |
470 | return myWorkspace->BufferDump(myFBO, theImage, theBufferType); | |
471 | } | |
472 | ||
473 | if (!myRaytraceParameters.AdaptiveScreenSampling) | |
474 | { | |
475 | return myWorkspace->BufferDump(myAccumFrames % 2 ? myRaytraceFBO2[0] : myRaytraceFBO1[0], theImage, theBufferType); | |
476 | } | |
477 | ||
478 | #if defined(GL_ES_VERSION_2_0) | |
479 | return false; | |
480 | #else | |
481 | if (theImage.Format() != Image_Format_RGBF) | |
482 | { | |
483 | return false; | |
484 | } | |
485 | ||
486 | const GLuint aW = myRaytraceOutputTexture[0]->SizeX(); | |
487 | const GLuint aH = myRaytraceOutputTexture[0]->SizeY(); | |
488 | if (aW / 3 != theImage.SizeX() || aH / 2 != theImage.SizeY()) | |
489 | { | |
490 | return false; | |
491 | } | |
492 | ||
493 | std::vector<GLfloat> aValues; | |
494 | try | |
495 | { | |
496 | aValues.resize (aW * aH); | |
497 | } | |
498 | catch (const std::bad_alloc&) | |
499 | { | |
500 | return false; | |
501 | } | |
502 | ||
503 | glBindTexture (GL_TEXTURE_RECTANGLE, myRaytraceOutputTexture[0]->TextureId()); | |
504 | glGetTexImage (GL_TEXTURE_RECTANGLE, 0, OpenGl_TextureFormat::Create<GLfloat, 1>().Format(), GL_FLOAT, &aValues[0]); | |
505 | glBindTexture (GL_TEXTURE_RECTANGLE, 0); | |
506 | for (unsigned int aRow = 0; aRow < aH; aRow += 2) | |
507 | { | |
508 | for (unsigned int aCol = 0; aCol < aW; aCol += 3) | |
509 | { | |
510 | float* anImageValue = theImage.ChangeValue<float[3]> ((aH - aRow) / 2 - 1, aCol / 3); | |
511 | float aInvNbSamples = 1.f / aValues[aRow * aW + aCol + aW]; | |
512 | anImageValue[0] = aValues[aRow * aW + aCol] * aInvNbSamples; | |
513 | anImageValue[1] = aValues[aRow * aW + aCol + 1] * aInvNbSamples; | |
514 | anImageValue[2] = aValues[aRow * aW + aCol + 1 + aW] * aInvNbSamples; | |
515 | } | |
516 | } | |
517 | ||
518 | return true; | |
519 | #endif | |
c357e426 | 520 | } |
521 | ||
c357e426 | 522 | // ======================================================================= |
523 | // function : GradientBackground | |
524 | // purpose : | |
525 | // ======================================================================= | |
526 | Aspect_GradientBackground OpenGl_View::GradientBackground() const | |
527 | { | |
528 | Quantity_Color aColor1, aColor2; | |
077a220c | 529 | aColor1.SetValues (myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (0).r(), |
530 | myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (0).g(), | |
531 | myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (0).b(), Quantity_TOC_RGB); | |
532 | aColor2.SetValues (myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (1).r(), | |
533 | myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (1).g(), | |
534 | myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (1).b(), Quantity_TOC_RGB); | |
535 | return Aspect_GradientBackground (aColor1, aColor2, myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientFillMethod()); | |
c357e426 | 536 | } |
2166f0fa | 537 | |
c357e426 | 538 | // ======================================================================= |
539 | // function : SetGradientBackground | |
540 | // purpose : | |
541 | // ======================================================================= | |
542 | void OpenGl_View::SetGradientBackground (const Aspect_GradientBackground& theBackground) | |
2166f0fa | 543 | { |
c357e426 | 544 | Quantity_Color aColor1, aColor2; |
545 | theBackground.Colors (aColor1, aColor2); | |
077a220c | 546 | myBackgrounds[Graphic3d_TOB_GRADIENT]->SetGradientParameters (aColor1, aColor2, theBackground.BgGradientFillMethod()); |
547 | ||
548 | myBackgroundType = Graphic3d_TOB_GRADIENT; | |
c357e426 | 549 | } |
550 | ||
551 | // ======================================================================= | |
552 | // function : SetBackgroundImage | |
553 | // purpose : | |
554 | // ======================================================================= | |
99289bed | 555 | void OpenGl_View::SetBackgroundImage (const Handle(Graphic3d_TextureMap)& theTextureMap, |
556 | Standard_Boolean theToUpdatePBREnv) | |
c357e426 | 557 | { |
99289bed | 558 | if (theTextureMap.IsNull() |
559 | || !theTextureMap->IsDone()) | |
560 | { | |
561 | if (myBackgroundType == Graphic3d_TOB_TEXTURE | |
562 | || myBackgroundType == Graphic3d_TOB_CUBEMAP) | |
563 | { | |
564 | myBackgroundType = Graphic3d_TOB_NONE; | |
565 | if (theToUpdatePBREnv) | |
566 | { | |
567 | myPBREnvRequest = OpenGl_PBREnvRequest_CLEAR; | |
568 | } | |
569 | } | |
570 | return; | |
571 | } | |
572 | ||
c357e426 | 573 | Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d(); |
99289bed | 574 | Handle(Graphic3d_TextureSet) aTextureSet = new Graphic3d_TextureSet (theTextureMap); |
c357e426 | 575 | anAspect->SetInteriorStyle (Aspect_IS_SOLID); |
7fd4958d | 576 | anAspect->SetFaceCulling (Graphic3d_TypeOfBackfacingModel_DoubleSided); |
99289bed | 577 | anAspect->SetShadingModel (Graphic3d_TOSM_UNLIT); |
578 | anAspect->SetTextureSet (aTextureSet); | |
579 | anAspect->SetTextureMapOn (true); | |
580 | ||
581 | if (Handle(Graphic3d_Texture2D) aTextureMap = Handle(Graphic3d_Texture2D)::DownCast (theTextureMap)) | |
2166f0fa | 582 | { |
99289bed | 583 | if (theToUpdatePBREnv && myBackgroundType == Graphic3d_TOB_CUBEMAP) |
584 | { | |
585 | myPBREnvRequest = OpenGl_PBREnvRequest_CLEAR; | |
586 | } | |
587 | ||
588 | myTextureParams->SetAspect (anAspect); | |
589 | myBackgroundType = Graphic3d_TOB_TEXTURE; | |
590 | myBackgroundImage = aTextureMap; | |
591 | return; | |
2166f0fa | 592 | } |
99289bed | 593 | |
594 | if (Handle(Graphic3d_CubeMap) aCubeMap = Handle(Graphic3d_CubeMap)::DownCast (theTextureMap)) | |
2166f0fa | 595 | { |
99289bed | 596 | if (theToUpdatePBREnv) |
597 | { | |
598 | myPBREnvRequest = OpenGl_PBREnvRequest_BAKE; | |
599 | } | |
600 | ||
601 | aCubeMap->SetMipmapsGeneration (Standard_True); | |
602 | if (const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext()) | |
603 | { | |
604 | anAspect->SetShaderProgram (aCtx->ShaderManager()->GetBgCubeMapProgram()); | |
605 | } | |
606 | ||
607 | myCubeMapParams->SetAspect (anAspect); | |
608 | ||
609 | const OpenGl_Aspects* anAspectsBackup = myWorkspace->SetAspects (myCubeMapParams); | |
610 | myWorkspace->ApplyAspects(); | |
611 | myWorkspace->SetAspects (anAspectsBackup); | |
612 | myWorkspace->ApplyAspects(); | |
613 | ||
614 | myBackgroundType = Graphic3d_TOB_CUBEMAP; | |
615 | myBackgroundCubeMap = aCubeMap; | |
c357e426 | 616 | return; |
617 | } | |
2166f0fa | 618 | |
99289bed | 619 | throw Standard_ProgramError ("OpenGl_View::SetBackgroundImage() - invalid texture map set for background"); |
c357e426 | 620 | } |
2166f0fa | 621 | |
c357e426 | 622 | // ======================================================================= |
623 | // function : BackgroundImageStyle | |
624 | // purpose : | |
625 | // ======================================================================= | |
626 | Aspect_FillMethod OpenGl_View::BackgroundImageStyle() const | |
627 | { | |
077a220c | 628 | return myBackgrounds[Graphic3d_TOB_TEXTURE]->TextureFillMethod(); |
2166f0fa SK |
629 | } |
630 | ||
c357e426 | 631 | // ======================================================================= |
632 | // function : SetBackgroundImageStyle | |
633 | // purpose : | |
634 | // ======================================================================= | |
635 | void OpenGl_View::SetBackgroundImageStyle (const Aspect_FillMethod theFillStyle) | |
636 | { | |
077a220c | 637 | myBackgrounds[Graphic3d_TOB_TEXTURE]->SetTextureFillMethod (theFillStyle); |
638 | } | |
639 | ||
640 | // ======================================================================= | |
641 | // function : BackgroundCubeMap | |
642 | // purpose : | |
643 | // ======================================================================= | |
644 | Handle(Graphic3d_CubeMap) OpenGl_View::BackgroundCubeMap() const | |
645 | { | |
646 | return myBackgroundCubeMap; | |
647 | } | |
67312b79 | 648 | |
649 | // ======================================================================= | |
650 | // function : SpecIBLMapLevels | |
651 | // purpose : | |
652 | // ======================================================================= | |
653 | unsigned int OpenGl_View::SpecIBLMapLevels() const | |
654 | { | |
655 | return myPBREnvironment.IsNull() ? 0 : myPBREnvironment->SpecMapLevelsNumber(); | |
656 | } | |
2166f0fa | 657 | |
c357e426 | 658 | //======================================================================= |
1c728f2d | 659 | //function : InsertLayerBefore |
c357e426 | 660 | //purpose : |
661 | //======================================================================= | |
1c728f2d | 662 | void OpenGl_View::InsertLayerBefore (const Graphic3d_ZLayerId theLayerId, |
077a220c | 663 | const Graphic3d_ZLayerSettings& theSettings, |
664 | const Graphic3d_ZLayerId theLayerAfter) | |
2166f0fa | 665 | { |
1c728f2d | 666 | myZLayers.InsertLayerBefore (theLayerId, theSettings, theLayerAfter); |
667 | } | |
668 | ||
669 | //======================================================================= | |
670 | //function : InsertLayerAfter | |
671 | //purpose : | |
672 | //======================================================================= | |
673 | void OpenGl_View::InsertLayerAfter (const Graphic3d_ZLayerId theLayerId, | |
077a220c | 674 | const Graphic3d_ZLayerSettings& theSettings, |
675 | const Graphic3d_ZLayerId theLayerBefore) | |
1c728f2d | 676 | { |
677 | myZLayers.InsertLayerAfter (theLayerId, theSettings, theLayerBefore); | |
2166f0fa SK |
678 | } |
679 | ||
c357e426 | 680 | //======================================================================= |
681 | //function : RemoveZLayer | |
682 | //purpose : | |
683 | //======================================================================= | |
684 | void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId) | |
685 | { | |
686 | myZLayers.RemoveLayer (theLayerId); | |
687 | } | |
2166f0fa | 688 | |
c357e426 | 689 | //======================================================================= |
690 | //function : SetZLayerSettings | |
691 | //purpose : | |
692 | //======================================================================= | |
693 | void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId, | |
694 | const Graphic3d_ZLayerSettings& theSettings) | |
2166f0fa | 695 | { |
c357e426 | 696 | myZLayers.SetLayerSettings (theLayerId, theSettings); |
2166f0fa SK |
697 | } |
698 | ||
50d06d8f | 699 | //======================================================================= |
700 | //function : ZLayerMax | |
701 | //purpose : | |
702 | //======================================================================= | |
703 | Standard_Integer OpenGl_View::ZLayerMax() const | |
704 | { | |
705 | Standard_Integer aLayerMax = Graphic3d_ZLayerId_Default; | |
1c728f2d | 706 | for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myZLayers.Layers()); aLayerIter.More(); aLayerIter.Next()) |
50d06d8f | 707 | { |
1c728f2d | 708 | aLayerMax = Max (aLayerMax, aLayerIter.Value()->LayerId()); |
50d06d8f | 709 | } |
50d06d8f | 710 | return aLayerMax; |
711 | } | |
712 | ||
713 | //======================================================================= | |
1c728f2d | 714 | //function : Layers |
715 | //purpose : | |
716 | //======================================================================= | |
717 | const NCollection_List<Handle(Graphic3d_Layer)>& OpenGl_View::Layers() const | |
718 | { | |
719 | return myZLayers.Layers(); | |
720 | } | |
721 | ||
722 | //======================================================================= | |
723 | //function : Layer | |
50d06d8f | 724 | //purpose : |
725 | //======================================================================= | |
1c728f2d | 726 | Handle(Graphic3d_Layer) OpenGl_View::Layer (const Graphic3d_ZLayerId theLayerId) const |
50d06d8f | 727 | { |
1c728f2d | 728 | Handle(Graphic3d_Layer) aLayer; |
729 | if (theLayerId != Graphic3d_ZLayerId_UNKNOWN) | |
50d06d8f | 730 | { |
1c728f2d | 731 | myZLayers.LayerIDs().Find (theLayerId, aLayer); |
50d06d8f | 732 | } |
1c728f2d | 733 | return aLayer; |
50d06d8f | 734 | } |
735 | ||
736 | //======================================================================= | |
1c728f2d | 737 | //function : MinMaxValues |
50d06d8f | 738 | //purpose : |
739 | //======================================================================= | |
1c728f2d | 740 | Bnd_Box OpenGl_View::MinMaxValues (const Standard_Boolean theToIncludeAuxiliary) const |
50d06d8f | 741 | { |
1c728f2d | 742 | if (!IsDefined()) |
50d06d8f | 743 | { |
1c728f2d | 744 | return Bnd_Box(); |
50d06d8f | 745 | } |
746 | ||
1c728f2d | 747 | Bnd_Box aBox = base_type::MinMaxValues (theToIncludeAuxiliary); |
748 | ||
71d8ccc7 | 749 | return aBox; |
50d06d8f | 750 | } |
751 | ||
752 | //======================================================================= | |
c357e426 | 753 | //function : FBO |
754 | //purpose : | |
755 | //======================================================================= | |
b128c892 | 756 | Handle(Standard_Transient) OpenGl_View::FBO() const |
c357e426 | 757 | { |
b128c892 | 758 | return Handle(Standard_Transient)(myFBO); |
c357e426 | 759 | } |
2166f0fa | 760 | |
c357e426 | 761 | //======================================================================= |
762 | //function : SetFBO | |
763 | //purpose : | |
764 | //======================================================================= | |
b128c892 | 765 | void OpenGl_View::SetFBO (const Handle(Standard_Transient)& theFbo) |
2166f0fa | 766 | { |
b128c892 | 767 | myFBO = Handle(OpenGl_FrameBuffer)::DownCast (theFbo); |
2166f0fa SK |
768 | } |
769 | ||
c357e426 | 770 | //======================================================================= |
771 | //function : FBOCreate | |
772 | //purpose : | |
773 | //======================================================================= | |
b128c892 | 774 | Handle(Standard_Transient) OpenGl_View::FBOCreate (const Standard_Integer theWidth, |
775 | const Standard_Integer theHeight) | |
c357e426 | 776 | { |
777 | return myWorkspace->FBOCreate (theWidth, theHeight); | |
778 | } | |
2166f0fa | 779 | |
c357e426 | 780 | //======================================================================= |
781 | //function : FBORelease | |
782 | //purpose : | |
783 | //======================================================================= | |
b128c892 | 784 | void OpenGl_View::FBORelease (Handle(Standard_Transient)& theFbo) |
2166f0fa | 785 | { |
b128c892 | 786 | Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo); |
787 | if (aFrameBuffer.IsNull()) | |
788 | { | |
789 | return; | |
790 | } | |
791 | ||
792 | myWorkspace->FBORelease (aFrameBuffer); | |
793 | theFbo.Nullify(); | |
c357e426 | 794 | } |
795 | ||
796 | //======================================================================= | |
797 | //function : FBOGetDimensions | |
798 | //purpose : | |
799 | //======================================================================= | |
b128c892 | 800 | void OpenGl_View::FBOGetDimensions (const Handle(Standard_Transient)& theFbo, |
c357e426 | 801 | Standard_Integer& theWidth, |
802 | Standard_Integer& theHeight, | |
803 | Standard_Integer& theWidthMax, | |
804 | Standard_Integer& theHeightMax) | |
805 | { | |
b128c892 | 806 | const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo); |
807 | if (aFrameBuffer.IsNull()) | |
808 | { | |
809 | return; | |
810 | } | |
811 | ||
c357e426 | 812 | theWidth = aFrameBuffer->GetVPSizeX(); // current viewport size |
813 | theHeight = aFrameBuffer->GetVPSizeY(); | |
814 | theWidthMax = aFrameBuffer->GetSizeX(); // texture size | |
815 | theHeightMax = aFrameBuffer->GetSizeY(); | |
816 | } | |
817 | ||
818 | //======================================================================= | |
819 | //function : FBOChangeViewport | |
820 | //purpose : | |
821 | //======================================================================= | |
b128c892 | 822 | void OpenGl_View::FBOChangeViewport (const Handle(Standard_Transient)& theFbo, |
c357e426 | 823 | const Standard_Integer theWidth, |
824 | const Standard_Integer theHeight) | |
825 | { | |
b128c892 | 826 | const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo); |
827 | if (aFrameBuffer.IsNull()) | |
828 | { | |
829 | return; | |
830 | } | |
831 | ||
c357e426 | 832 | aFrameBuffer->ChangeViewport (theWidth, theHeight); |
833 | } | |
834 | ||
c357e426 | 835 | //======================================================================= |
836 | //function : displayStructure | |
837 | //purpose : | |
838 | //======================================================================= | |
839 | void OpenGl_View::displayStructure (const Handle(Graphic3d_CStructure)& theStructure, | |
840 | const Standard_Integer thePriority) | |
841 | { | |
7d47ebdb | 842 | const OpenGl_Structure* aStruct = static_cast<const OpenGl_Structure*> (theStructure.get()); |
c357e426 | 843 | const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer(); |
844 | myZLayers.AddStructure (aStruct, aZLayer, thePriority); | |
845 | } | |
846 | ||
847 | //======================================================================= | |
848 | //function : eraseStructure | |
849 | //purpose : | |
850 | //======================================================================= | |
851 | void OpenGl_View::eraseStructure (const Handle(Graphic3d_CStructure)& theStructure) | |
852 | { | |
7d47ebdb | 853 | const OpenGl_Structure* aStruct = static_cast<const OpenGl_Structure*> (theStructure.get()); |
c357e426 | 854 | myZLayers.RemoveStructure (aStruct); |
855 | } | |
856 | ||
857 | //======================================================================= | |
858 | //function : changeZLayer | |
859 | //purpose : | |
860 | //======================================================================= | |
861 | void OpenGl_View::changeZLayer (const Handle(Graphic3d_CStructure)& theStructure, | |
862 | const Graphic3d_ZLayerId theNewLayerId) | |
863 | { | |
864 | const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer(); | |
7d47ebdb | 865 | const OpenGl_Structure* aStruct = static_cast<const OpenGl_Structure*> (theStructure.get()); |
c357e426 | 866 | myZLayers.ChangeLayer (aStruct, anOldLayer, theNewLayerId); |
cfece3ef | 867 | Update (anOldLayer); |
868 | Update (theNewLayerId); | |
c357e426 | 869 | } |
870 | ||
871 | //======================================================================= | |
872 | //function : changePriority | |
873 | //purpose : | |
874 | //======================================================================= | |
875 | void OpenGl_View::changePriority (const Handle(Graphic3d_CStructure)& theStructure, | |
876 | const Standard_Integer theNewPriority) | |
877 | { | |
878 | const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer(); | |
7d47ebdb | 879 | const OpenGl_Structure* aStruct = static_cast<const OpenGl_Structure*> (theStructure.get()); |
c357e426 | 880 | myZLayers.ChangePriority (aStruct, aLayerId, theNewPriority); |
2166f0fa | 881 | } |
26d9c835 | 882 | |
883 | //======================================================================= | |
884 | //function : DiagnosticInformation | |
885 | //purpose : | |
886 | //======================================================================= | |
887 | void OpenGl_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict, | |
888 | Graphic3d_DiagnosticInfo theFlags) const | |
889 | { | |
b40cdc2b | 890 | base_type::DiagnosticInformation (theDict, theFlags); |
26d9c835 | 891 | Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext(); |
892 | if (!myWorkspace->Activate() | |
893 | || aCtx.IsNull()) | |
894 | { | |
895 | return; | |
896 | } | |
897 | ||
898 | aCtx->DiagnosticInformation (theDict, theFlags); | |
899 | if ((theFlags & Graphic3d_DiagnosticInfo_FrameBuffer) != 0) | |
900 | { | |
901 | TCollection_AsciiString aResRatio (myRenderParams.ResolutionRatio()); | |
902 | theDict.ChangeFromIndex (theDict.Add ("ResolutionRatio", aResRatio)) = aResRatio; | |
903 | } | |
904 | } | |
79b544e6 | 905 | |
906 | //======================================================================= | |
907 | //function : StatisticInformation | |
908 | //purpose : | |
909 | //======================================================================= | |
910 | void OpenGl_View::StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const | |
911 | { | |
912 | if (const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext()) | |
913 | { | |
914 | const Handle(OpenGl_FrameStats)& aStats = aCtx->FrameStats(); | |
915 | const Graphic3d_RenderingParams& aRendParams = myWorkspace->View()->RenderingParams(); | |
916 | aStats->FormatStats (theDict, aRendParams.CollectedStats); | |
917 | } | |
918 | } | |
919 | ||
920 | //======================================================================= | |
921 | //function : StatisticInformation | |
922 | //purpose : | |
923 | //======================================================================= | |
924 | TCollection_AsciiString OpenGl_View::StatisticInformation() const | |
925 | { | |
926 | if (const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext()) | |
927 | { | |
928 | const Handle(OpenGl_FrameStats)& aStats = aCtx->FrameStats(); | |
929 | const Graphic3d_RenderingParams& aRendParams = myWorkspace->View()->RenderingParams(); | |
930 | return aStats->FormatStats (aRendParams.CollectedStats); | |
931 | } | |
932 | return TCollection_AsciiString(); | |
933 | } | |
cfb54c0c | 934 | |
935 | //======================================================================= | |
936 | //function : drawBackground | |
937 | //purpose : | |
938 | //======================================================================= | |
939 | void OpenGl_View::drawBackground (const Handle(OpenGl_Workspace)& theWorkspace, | |
940 | Graphic3d_Camera::Projection theProjection) | |
941 | { | |
942 | const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); | |
4b52faa5 | 943 | const bool wasUsedZBuffer = theWorkspace->SetUseZBuffer (false); |
cfb54c0c | 944 | if (wasUsedZBuffer) |
945 | { | |
946 | aCtx->core11fwd->glDisable (GL_DEPTH_TEST); | |
947 | } | |
948 | ||
4b52faa5 | 949 | #ifdef GL_DEPTH_CLAMP |
950 | const bool wasDepthClamped = aCtx->arbDepthClamp && glIsEnabled (GL_DEPTH_CLAMP); | |
951 | if (aCtx->arbDepthClamp && !wasDepthClamped) | |
952 | { | |
953 | // make sure background is always drawn (workaround skybox rendering on some hardware) | |
954 | aCtx->core11fwd->glEnable (GL_DEPTH_CLAMP); | |
955 | } | |
956 | #endif | |
957 | ||
cfb54c0c | 958 | if (myBackgroundType == Graphic3d_TOB_CUBEMAP) |
959 | { | |
960 | myCubeMapParams->Aspect()->ShaderProgram()->PushVariableInt ("uZCoeff", myBackgroundCubeMap->ZIsInverted() ? -1 : 1); | |
961 | myCubeMapParams->Aspect()->ShaderProgram()->PushVariableInt ("uYCoeff", myBackgroundCubeMap->IsTopDown() ? 1 : -1); | |
962 | const OpenGl_Aspects* anOldAspectFace = theWorkspace->SetAspects (myCubeMapParams); | |
963 | ||
964 | myBackgrounds[Graphic3d_TOB_CUBEMAP]->Render (theWorkspace, theProjection); | |
965 | ||
966 | theWorkspace->SetAspects (anOldAspectFace); | |
967 | } | |
968 | else if (myBackgroundType == Graphic3d_TOB_GRADIENT | |
969 | || myBackgroundType == Graphic3d_TOB_TEXTURE) | |
970 | { | |
971 | // Drawing background gradient if: | |
972 | // - gradient fill type is not Aspect_GFM_NONE and | |
973 | // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode | |
974 | if (myBackgrounds[Graphic3d_TOB_GRADIENT]->IsDefined() | |
975 | && (!myTextureParams->Aspect()->ToMapTexture() | |
976 | || myBackgrounds[Graphic3d_TOB_TEXTURE]->TextureFillMethod() == Aspect_FM_CENTERED | |
977 | || myBackgrounds[Graphic3d_TOB_TEXTURE]->TextureFillMethod() == Aspect_FM_NONE)) | |
978 | { | |
979 | myBackgrounds[Graphic3d_TOB_GRADIENT]->Render(theWorkspace, theProjection); | |
980 | } | |
981 | ||
982 | // Drawing background image if it is defined | |
983 | // (texture is defined and fill type is not Aspect_FM_NONE) | |
984 | if (myBackgrounds[Graphic3d_TOB_TEXTURE]->IsDefined() | |
985 | && myTextureParams->Aspect()->ToMapTexture()) | |
986 | { | |
987 | aCtx->core11fwd->glDisable (GL_BLEND); | |
988 | ||
989 | const OpenGl_Aspects* anOldAspectFace = theWorkspace->SetAspects (myTextureParams); | |
990 | myBackgrounds[Graphic3d_TOB_TEXTURE]->Render (theWorkspace, theProjection); | |
991 | theWorkspace->SetAspects (anOldAspectFace); | |
992 | } | |
993 | } | |
994 | ||
995 | if (wasUsedZBuffer) | |
996 | { | |
997 | theWorkspace->SetUseZBuffer (Standard_True); | |
998 | aCtx->core11fwd->glEnable (GL_DEPTH_TEST); | |
999 | } | |
4b52faa5 | 1000 | #ifdef GL_DEPTH_CLAMP |
1001 | if (aCtx->arbDepthClamp && !wasDepthClamped) | |
1002 | { | |
1003 | aCtx->core11fwd->glDisable (GL_DEPTH_CLAMP); | |
1004 | } | |
1005 | #endif | |
cfb54c0c | 1006 | } |
1007 | ||
1008 | //======================================================================= | |
1009 | //function : prepareFrameBuffers | |
1010 | //purpose : | |
1011 | //======================================================================= | |
1012 | bool OpenGl_View::prepareFrameBuffers (Graphic3d_Camera::Projection& theProj) | |
1013 | { | |
1014 | theProj = myCamera->ProjectionType(); | |
1015 | const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext(); | |
1016 | ||
1017 | Standard_Integer aSizeX = 0, aSizeY = 0; | |
1018 | OpenGl_FrameBuffer* aFrameBuffer = myFBO.get(); | |
1019 | if (aFrameBuffer != NULL) | |
1020 | { | |
1021 | aSizeX = aFrameBuffer->GetVPSizeX(); | |
1022 | aSizeY = aFrameBuffer->GetVPSizeY(); | |
1023 | } | |
1024 | else if (IsActiveXR()) | |
1025 | { | |
1026 | aSizeX = myXRSession->RecommendedViewport().x(); | |
1027 | aSizeY = myXRSession->RecommendedViewport().y(); | |
1028 | } | |
1029 | else | |
1030 | { | |
1031 | aSizeX = myWindow->Width(); | |
1032 | aSizeY = myWindow->Height(); | |
1033 | } | |
1034 | ||
1220d98e | 1035 | const Graphic3d_Vec2i aRendSize (Standard_Integer(myRenderParams.RenderResolutionScale * aSizeX + 0.5f), |
1036 | Standard_Integer(myRenderParams.RenderResolutionScale * aSizeY + 0.5f)); | |
cfb54c0c | 1037 | if (aSizeX < 1 |
1038 | || aSizeY < 1 | |
1220d98e | 1039 | || aRendSize.x() < 1 |
1040 | || aRendSize.y() < 1) | |
cfb54c0c | 1041 | { |
1042 | myBackBufferRestored = Standard_False; | |
1043 | myIsImmediateDrawn = Standard_False; | |
1044 | return false; | |
1045 | } | |
1046 | ||
1047 | // determine multisampling parameters | |
1220d98e | 1048 | Standard_Integer aNbSamples = !myToDisableMSAA && aSizeX == aRendSize.x() |
cfb54c0c | 1049 | ? Max (Min (myRenderParams.NbMsaaSamples, aCtx->MaxMsaaSamples()), 0) |
1050 | : 0; | |
1051 | if (aNbSamples != 0) | |
1052 | { | |
1053 | aNbSamples = OpenGl_Context::GetPowerOfTwo (aNbSamples, aCtx->MaxMsaaSamples()); | |
1054 | } | |
1055 | ||
78c4e836 | 1056 | bool toUseOit = myRenderParams.TransparencyMethod != Graphic3d_RTM_BLEND_UNORDERED |
cfb54c0c | 1057 | && checkOitCompatibility (aCtx, aNbSamples > 0); |
1058 | ||
1059 | const bool toInitImmediateFbo = myTransientDrawToFront | |
1060 | && (!aCtx->caps->useSystemBuffer || (toUseOit && HasImmediateStructures())); | |
1061 | ||
1062 | if ( aFrameBuffer == NULL | |
1063 | && !aCtx->DefaultFrameBuffer().IsNull() | |
1064 | && aCtx->DefaultFrameBuffer()->IsValid()) | |
1065 | { | |
1066 | aFrameBuffer = aCtx->DefaultFrameBuffer().operator->(); | |
1067 | } | |
1068 | ||
1069 | if (myHasFboBlit | |
1070 | && (myTransientDrawToFront | |
1071 | || theProj == Graphic3d_Camera::Projection_Stereo | |
1072 | || aNbSamples != 0 | |
1073 | || toUseOit | |
1220d98e | 1074 | || aSizeX != aRendSize.x())) |
cfb54c0c | 1075 | { |
1220d98e | 1076 | if (myMainSceneFbos[0]->GetVPSize() != aRendSize |
1077 | || myMainSceneFbos[0]->NbSamples() != aNbSamples) | |
cfb54c0c | 1078 | { |
1079 | if (!myTransientDrawToFront) | |
1080 | { | |
1081 | myImmediateSceneFbos[0]->Release (aCtx.operator->()); | |
1082 | myImmediateSceneFbos[1]->Release (aCtx.operator->()); | |
1083 | myImmediateSceneFbos[0]->ChangeViewport (0, 0); | |
1084 | myImmediateSceneFbos[1]->ChangeViewport (0, 0); | |
1085 | } | |
1086 | ||
1087 | // prepare FBOs containing main scene | |
1088 | // for further blitting and rendering immediate presentations on top | |
1089 | if (aCtx->core20fwd != NULL) | |
1090 | { | |
1220d98e | 1091 | const bool wasFailedMain0 = checkWasFailedFbo (myMainSceneFbos[0], aRendSize.x(), aRendSize.y(), aNbSamples); |
1092 | if (!myMainSceneFbos[0]->Init (aCtx, aRendSize, myFboColorFormat, myFboDepthFormat, aNbSamples) | |
cfb54c0c | 1093 | && !wasFailedMain0) |
1094 | { | |
1095 | TCollection_ExtendedString aMsg = TCollection_ExtendedString() + "Error! Main FBO " | |
1096 | + printFboFormat (myMainSceneFbos[0]) + " initialization has failed"; | |
1097 | aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg); | |
1098 | } | |
1099 | } | |
1100 | } | |
78c4e836 | 1101 | |
cfb54c0c | 1102 | if (myMainSceneFbos[0]->IsValid() && (toInitImmediateFbo || myImmediateSceneFbos[0]->IsValid())) |
1103 | { | |
1104 | const bool wasFailedImm0 = checkWasFailedFbo (myImmediateSceneFbos[0], myMainSceneFbos[0]); | |
1105 | if (!myImmediateSceneFbos[0]->InitLazy (aCtx, *myMainSceneFbos[0]) | |
1106 | && !wasFailedImm0) | |
1107 | { | |
1108 | TCollection_ExtendedString aMsg = TCollection_ExtendedString() + "Error! Immediate FBO " | |
1109 | + printFboFormat (myImmediateSceneFbos[0]) + " initialization has failed"; | |
1110 | aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg); | |
1111 | } | |
1112 | } | |
1113 | } | |
1114 | else | |
1115 | { | |
1116 | myMainSceneFbos [0]->Release (aCtx.operator->()); | |
1117 | myMainSceneFbos [1]->Release (aCtx.operator->()); | |
1118 | myImmediateSceneFbos[0]->Release (aCtx.operator->()); | |
1119 | myImmediateSceneFbos[1]->Release (aCtx.operator->()); | |
1120 | myXrSceneFbo ->Release (aCtx.operator->()); | |
1121 | myMainSceneFbos [0]->ChangeViewport (0, 0); | |
1122 | myMainSceneFbos [1]->ChangeViewport (0, 0); | |
1123 | myImmediateSceneFbos[0]->ChangeViewport (0, 0); | |
1124 | myImmediateSceneFbos[1]->ChangeViewport (0, 0); | |
1125 | myXrSceneFbo ->ChangeViewport (0, 0); | |
1126 | } | |
1127 | ||
1128 | bool hasXRBlitFbo = false; | |
1129 | if (theProj == Graphic3d_Camera::Projection_Stereo | |
1130 | && IsActiveXR() | |
1131 | && myMainSceneFbos[0]->IsValid()) | |
1132 | { | |
1133 | if (aNbSamples != 0 | |
1220d98e | 1134 | || aSizeX != aRendSize.x()) |
cfb54c0c | 1135 | { |
1220d98e | 1136 | hasXRBlitFbo = myXrSceneFbo->InitLazy (aCtx, Graphic3d_Vec2i (aSizeX, aSizeY), myFboColorFormat, myFboDepthFormat, 0); |
cfb54c0c | 1137 | if (!hasXRBlitFbo) |
1138 | { | |
1139 | TCollection_ExtendedString aMsg = TCollection_ExtendedString() + "Error! VR FBO " | |
1140 | + printFboFormat (myXrSceneFbo) + " initialization has failed"; | |
1141 | aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg); | |
1142 | } | |
1143 | } | |
1144 | } | |
1145 | else if (theProj == Graphic3d_Camera::Projection_Stereo | |
1146 | && myMainSceneFbos[0]->IsValid()) | |
1147 | { | |
1148 | const bool wasFailedMain1 = checkWasFailedFbo (myMainSceneFbos[1], myMainSceneFbos[0]); | |
1149 | if (!myMainSceneFbos[1]->InitLazy (aCtx, *myMainSceneFbos[0]) | |
1150 | && !wasFailedMain1) | |
1151 | { | |
1152 | TCollection_ExtendedString aMsg = TCollection_ExtendedString() + "Error! Main FBO (second) " | |
1153 | + printFboFormat (myMainSceneFbos[1]) + " initialization has failed"; | |
1154 | aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg); | |
1155 | } | |
1156 | if (!myMainSceneFbos[1]->IsValid()) | |
1157 | { | |
1158 | // no enough memory? | |
1159 | theProj = Graphic3d_Camera::Projection_Perspective; | |
1160 | } | |
1161 | else if (!myTransientDrawToFront) | |
1162 | { | |
1163 | // | |
1164 | } | |
1165 | else if (!aCtx->HasStereoBuffers() | |
1166 | || myRenderParams.StereoMode != Graphic3d_StereoMode_QuadBuffer) | |
1167 | { | |
1168 | const bool wasFailedImm0 = checkWasFailedFbo (myImmediateSceneFbos[0], myMainSceneFbos[0]); | |
1169 | const bool wasFailedImm1 = checkWasFailedFbo (myImmediateSceneFbos[1], myMainSceneFbos[0]); | |
1170 | if (!myImmediateSceneFbos[0]->InitLazy (aCtx, *myMainSceneFbos[0]) | |
1171 | && !wasFailedImm0) | |
1172 | { | |
1173 | TCollection_ExtendedString aMsg = TCollection_ExtendedString() + "Error! Immediate FBO (first) " | |
1174 | + printFboFormat (myImmediateSceneFbos[0]) + " initialization has failed"; | |
1175 | aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg); | |
1176 | } | |
1177 | if (!myImmediateSceneFbos[1]->InitLazy (aCtx, *myMainSceneFbos[0]) | |
1178 | && !wasFailedImm1) | |
1179 | { | |
1180 | TCollection_ExtendedString aMsg = TCollection_ExtendedString() + "Error! Immediate FBO (first) " | |
1181 | + printFboFormat (myImmediateSceneFbos[1]) + " initialization has failed"; | |
1182 | aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg); | |
1183 | } | |
1184 | if (!myImmediateSceneFbos[0]->IsValid() | |
1185 | || !myImmediateSceneFbos[1]->IsValid()) | |
1186 | { | |
1187 | theProj = Graphic3d_Camera::Projection_Perspective; | |
1188 | } | |
1189 | } | |
1190 | } | |
1191 | if (!hasXRBlitFbo) | |
1192 | { | |
1193 | myXrSceneFbo->Release (aCtx.get()); | |
1194 | myXrSceneFbo->ChangeViewport (0, 0); | |
1195 | } | |
1196 | ||
1197 | // process PBR environment | |
114db5a5 | 1198 | if (myRenderParams.ShadingModel == Graphic3d_TOSM_PBR |
1199 | || myRenderParams.ShadingModel == Graphic3d_TOSM_PBR_FACET) | |
cfb54c0c | 1200 | { |
1201 | if (!myPBREnvironment.IsNull() | |
1202 | && myPBREnvironment->SizesAreDifferent (myRenderParams.PbrEnvPow2Size, | |
1203 | myRenderParams.PbrEnvSpecMapNbLevels)) | |
1204 | { | |
1205 | myPBREnvironment->Release (aCtx.get()); | |
1206 | myPBREnvironment.Nullify(); | |
1207 | myPBREnvState = OpenGl_PBREnvState_NONEXISTENT; | |
1208 | myPBREnvRequest = OpenGl_PBREnvRequest_BAKE; | |
1209 | ++myLightsRevision; | |
1210 | } | |
1211 | ||
1212 | if (myPBREnvState == OpenGl_PBREnvState_NONEXISTENT | |
1213 | && aCtx->HasPBR()) | |
1214 | { | |
1215 | myPBREnvironment = OpenGl_PBREnvironment::Create (aCtx, myRenderParams.PbrEnvPow2Size, myRenderParams.PbrEnvSpecMapNbLevels); | |
1216 | myPBREnvState = myPBREnvironment.IsNull() ? OpenGl_PBREnvState_UNAVAILABLE : OpenGl_PBREnvState_CREATED; | |
1217 | if (myPBREnvState == OpenGl_PBREnvState_CREATED) | |
1218 | { | |
1219 | Handle(OpenGl_Texture) anEnvLUT; | |
1220 | static const TCollection_AsciiString THE_SHARED_ENV_LUT_KEY("EnvLUT"); | |
1221 | if (!aCtx->GetResource (THE_SHARED_ENV_LUT_KEY, anEnvLUT)) | |
1222 | { | |
1ac837b2 | 1223 | bool toConvertHalfFloat = false; |
1224 | #if defined(GL_ES_VERSION_2_0) | |
1225 | // GL_RG32F is not texture-filterable format in OpenGL ES without OES_texture_float_linear extension. | |
1226 | // GL_RG16F is texture-filterable since OpenGL ES 3.0 or OpenGL ES 2.0 + OES_texture_half_float_linear. | |
1227 | // OpenGL ES 3.0 allows initialization of GL_RG16F from 32-bit float data, but OpenGL ES 2.0 + OES_texture_half_float does not. | |
1228 | // Note that it is expected that GL_RG16F has enough precision for this table, so that it can be used also on desktop OpenGL. | |
1229 | const bool hasHalfFloat = aCtx->IsGlGreaterEqual (3, 0) || aCtx->CheckExtension ("GL_OES_texture_half_float_linear"); | |
1230 | toConvertHalfFloat = !aCtx->IsGlGreaterEqual (3, 0) && hasHalfFloat; | |
1231 | #endif | |
1232 | Image_Format anImgFormat = Image_Format_UNKNOWN; | |
8f8fe4a9 | 1233 | if (aCtx->arbTexRG) |
1ac837b2 | 1234 | { |
1235 | anImgFormat = toConvertHalfFloat ? Image_Format_RGF_half : Image_Format_RGF; | |
1236 | } | |
1237 | else | |
1238 | { | |
1239 | anImgFormat = toConvertHalfFloat ? Image_Format_RGBAF_half : Image_Format_RGBAF; | |
1240 | } | |
1241 | ||
1242 | Handle(Image_PixMap) aPixMap = new Image_PixMap(); | |
1243 | if (anImgFormat == Image_Format_RGF) | |
8f8fe4a9 | 1244 | { |
1245 | aPixMap->InitWrapper (Image_Format_RGF, (Standard_Byte*)Textures_EnvLUT, Textures_EnvLUTSize, Textures_EnvLUTSize); | |
1246 | } | |
1247 | else | |
1248 | { | |
1ac837b2 | 1249 | aPixMap->InitZero (anImgFormat, Textures_EnvLUTSize, Textures_EnvLUTSize); |
8f8fe4a9 | 1250 | Image_PixMap aPixMapRG; |
1251 | aPixMapRG.InitWrapper (Image_Format_RGF, (Standard_Byte*)Textures_EnvLUT, Textures_EnvLUTSize, Textures_EnvLUTSize); | |
8f8fe4a9 | 1252 | for (Standard_Size aRowIter = 0; aRowIter < aPixMapRG.SizeY(); ++aRowIter) |
1253 | { | |
1254 | for (Standard_Size aColIter = 0; aColIter < aPixMapRG.SizeX(); ++aColIter) | |
1255 | { | |
1256 | const Image_ColorRGF& aPixelRG = aPixMapRG.Value<Image_ColorRGF> (aRowIter, aColIter); | |
1ac837b2 | 1257 | if (toConvertHalfFloat) |
1258 | { | |
1259 | NCollection_Vec2<uint16_t>& aPixelRGBA = aPixMap->ChangeValue<NCollection_Vec2<uint16_t>> (aRowIter, aColIter); | |
1260 | aPixelRGBA.x() = Image_PixMap::ConvertToHalfFloat (aPixelRG.r()); | |
1261 | aPixelRGBA.y() = Image_PixMap::ConvertToHalfFloat (aPixelRG.g()); | |
1262 | } | |
1263 | else | |
1264 | { | |
1265 | Image_ColorRGBAF& aPixelRGBA = aPixMap->ChangeValue<Image_ColorRGBAF> (aRowIter, aColIter); | |
1266 | aPixelRGBA.r() = aPixelRG.r(); | |
1267 | aPixelRGBA.g() = aPixelRG.g(); | |
1268 | } | |
8f8fe4a9 | 1269 | } |
1270 | } | |
1271 | } | |
1272 | ||
cfb54c0c | 1273 | OpenGl_TextureFormat aTexFormat = OpenGl_TextureFormat::FindFormat (aCtx, aPixMap->Format(), false); |
1274 | #if defined(GL_ES_VERSION_2_0) | |
1ac837b2 | 1275 | if (aTexFormat.IsValid() |
1276 | && hasHalfFloat) | |
1277 | { | |
1278 | aTexFormat.SetInternalFormat (aCtx->arbTexRG ? GL_RG16F : GL_RGBA16F); | |
1279 | } | |
cfb54c0c | 1280 | #endif |
1ac837b2 | 1281 | |
1282 | Handle(Graphic3d_TextureParams) aParams = new Graphic3d_TextureParams(); | |
1283 | aParams->SetFilter (Graphic3d_TOTF_BILINEAR); | |
1284 | aParams->SetRepeat (Standard_False); | |
1285 | aParams->SetTextureUnit (aCtx->PBREnvLUTTexUnit()); | |
1286 | anEnvLUT = new OpenGl_Texture(THE_SHARED_ENV_LUT_KEY, aParams); | |
cfb54c0c | 1287 | if (!aTexFormat.IsValid() |
1288 | || !anEnvLUT->Init (aCtx, aTexFormat, Graphic3d_Vec2i((Standard_Integer)Textures_EnvLUTSize), Graphic3d_TOT_2D, aPixMap.get())) | |
1289 | { | |
1290 | aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, "Failed allocation of LUT for PBR"); | |
1291 | anEnvLUT.Nullify(); | |
1292 | } | |
1293 | aCtx->ShareResource (THE_SHARED_ENV_LUT_KEY, anEnvLUT); | |
1294 | } | |
1295 | if (!anEnvLUT.IsNull()) | |
1296 | { | |
1297 | anEnvLUT->Bind (aCtx); | |
1298 | } | |
1299 | myWorkspace->ApplyAspects(); | |
1300 | } | |
1301 | } | |
1302 | processPBREnvRequest (aCtx); | |
1303 | } | |
1304 | ||
1305 | // create color and coverage accumulation buffers required for OIT algorithm | |
78c4e836 | 1306 | if (toUseOit |
1307 | && myRenderParams.TransparencyMethod == Graphic3d_RTM_DEPTH_PEELING_OIT) | |
1308 | { | |
1220d98e | 1309 | if (myDepthPeelingFbos->BlendBackFboOit()->GetSize() != aRendSize) |
78c4e836 | 1310 | { |
1220d98e | 1311 | if (myDepthPeelingFbos->BlendBackFboOit()->Init (aCtx, aRendSize, GL_RGBA16F, 0)) |
78c4e836 | 1312 | { |
1313 | for (int aPairIter = 0; aPairIter < 2; ++aPairIter) | |
1314 | { | |
1315 | OpenGl_ColorFormats aColorFormats; | |
1316 | aColorFormats.Append (GL_RG32F); | |
1317 | aColorFormats.Append (GL_RGBA16F); | |
1318 | aColorFormats.Append (GL_RGBA16F); | |
1220d98e | 1319 | myDepthPeelingFbos->DepthPeelFbosOit()[aPairIter]->Init (aCtx, aRendSize, aColorFormats, 0); |
78c4e836 | 1320 | |
1321 | NCollection_Sequence<Handle(OpenGl_Texture)> anAttachments; | |
1322 | anAttachments.Append (myDepthPeelingFbos->DepthPeelFbosOit()[aPairIter]->ColorTexture (1)); | |
1323 | anAttachments.Append (myDepthPeelingFbos->DepthPeelFbosOit()[aPairIter]->ColorTexture (2)); | |
1324 | myDepthPeelingFbos->FrontBackColorFbosOit()[aPairIter]->InitWrapper (aCtx, anAttachments); | |
1325 | } | |
1326 | } | |
1327 | else | |
1328 | { | |
1329 | toUseOit = false; | |
1330 | aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, | |
1331 | "Initialization of float texture framebuffer for use with\n" | |
1332 | " Depth-Peeling order-independent transparency rendering algorithm has failed."); | |
1333 | } | |
1334 | } | |
1335 | } | |
1336 | if (!toUseOit) | |
1337 | { | |
1338 | myDepthPeelingFbos->Release (aCtx.operator->()); | |
1339 | } | |
1340 | ||
1341 | if (toUseOit | |
1342 | && myRenderParams.TransparencyMethod == Graphic3d_RTM_BLEND_OIT) | |
cfb54c0c | 1343 | { |
1344 | Standard_Integer anFboIt = 0; | |
1345 | for (; anFboIt < 2; ++anFboIt) | |
1346 | { | |
1347 | Handle(OpenGl_FrameBuffer)& aMainSceneFbo = myMainSceneFbos [anFboIt]; | |
1348 | Handle(OpenGl_FrameBuffer)& aMainSceneFboOit = myMainSceneFbosOit [anFboIt]; | |
1349 | Handle(OpenGl_FrameBuffer)& anImmediateSceneFbo = myImmediateSceneFbos [anFboIt]; | |
1350 | Handle(OpenGl_FrameBuffer)& anImmediateSceneFboOit = myImmediateSceneFbosOit[anFboIt]; | |
1351 | if (aMainSceneFbo->IsValid() | |
1220d98e | 1352 | && (aMainSceneFboOit->GetVPSize() != aRendSize |
1353 | || aMainSceneFboOit->NbSamples() != aNbSamples)) | |
cfb54c0c | 1354 | { |
1355 | Standard_Integer aColorConfig = 0; | |
1356 | for (;;) // seemly responding to driver limitation (GL_FRAMEBUFFER_UNSUPPORTED) | |
1357 | { | |
1358 | if (myFboOitColorConfig.IsEmpty()) | |
1359 | { | |
1360 | if (!chooseOitColorConfiguration (aCtx, aColorConfig++, myFboOitColorConfig)) | |
1361 | { | |
1362 | break; | |
1363 | } | |
1364 | } | |
1220d98e | 1365 | if (aMainSceneFboOit->Init (aCtx, aRendSize, myFboOitColorConfig, aMainSceneFbo->DepthStencilTexture(), aNbSamples)) |
cfb54c0c | 1366 | { |
1367 | break; | |
1368 | } | |
1369 | myFboOitColorConfig.Clear(); | |
1370 | } | |
1371 | if (!aMainSceneFboOit->IsValid()) | |
1372 | { | |
1373 | break; | |
1374 | } | |
1375 | } | |
1376 | else if (!aMainSceneFbo->IsValid()) | |
1377 | { | |
1378 | aMainSceneFboOit->Release (aCtx.operator->()); | |
1379 | aMainSceneFboOit->ChangeViewport (0, 0); | |
1380 | } | |
1381 | ||
1382 | if (anImmediateSceneFbo->IsValid() | |
1220d98e | 1383 | && (anImmediateSceneFboOit->GetVPSize() != aRendSize |
1384 | || anImmediateSceneFboOit->NbSamples() != aNbSamples)) | |
cfb54c0c | 1385 | { |
1220d98e | 1386 | if (!anImmediateSceneFboOit->Init (aCtx, aRendSize, myFboOitColorConfig, |
cfb54c0c | 1387 | anImmediateSceneFbo->DepthStencilTexture(), aNbSamples)) |
1388 | { | |
1389 | break; | |
1390 | } | |
1391 | } | |
1392 | else if (!anImmediateSceneFbo->IsValid()) | |
1393 | { | |
1394 | anImmediateSceneFboOit->Release (aCtx.operator->()); | |
1395 | anImmediateSceneFboOit->ChangeViewport (0, 0); | |
1396 | } | |
1397 | } | |
1398 | if (anFboIt == 0) // only the first OIT framebuffer is mandatory | |
1399 | { | |
1400 | aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, | |
1401 | "Initialization of float texture framebuffer for use with\n" | |
1402 | " blended order-independent transparency rendering algorithm has failed.\n" | |
1403 | " Blended order-independent transparency will not be available.\n"); | |
1404 | if (aNbSamples > 0) | |
1405 | { | |
1406 | myToDisableOITMSAA = Standard_True; | |
1407 | } | |
1408 | else | |
1409 | { | |
1410 | myToDisableOIT = Standard_True; | |
1411 | } | |
1412 | toUseOit = false; | |
1413 | } | |
1414 | } | |
1415 | if (!toUseOit && myMainSceneFbosOit[0]->IsValid()) | |
1416 | { | |
78c4e836 | 1417 | myDepthPeelingFbos->Release (aCtx.operator->()); |
cfb54c0c | 1418 | myMainSceneFbosOit [0]->Release (aCtx.operator->()); |
1419 | myMainSceneFbosOit [1]->Release (aCtx.operator->()); | |
1420 | myImmediateSceneFbosOit[0]->Release (aCtx.operator->()); | |
1421 | myImmediateSceneFbosOit[1]->Release (aCtx.operator->()); | |
1422 | myMainSceneFbosOit [0]->ChangeViewport (0, 0); | |
1423 | myMainSceneFbosOit [1]->ChangeViewport (0, 0); | |
1424 | myImmediateSceneFbosOit[0]->ChangeViewport (0, 0); | |
1425 | myImmediateSceneFbosOit[1]->ChangeViewport (0, 0); | |
1426 | } | |
1427 | ||
d84e8669 | 1428 | // allocate shadow maps |
114db5a5 | 1429 | const Handle(Graphic3d_LightSet)& aLights = myRenderParams.ShadingModel == Graphic3d_TOSM_UNLIT ? myNoShadingLight : myLights; |
d84e8669 | 1430 | if (!aLights.IsNull()) |
1431 | { | |
1432 | aLights->UpdateRevision(); | |
1433 | } | |
1434 | bool toUseShadowMap = myRenderParams.IsShadowEnabled | |
1435 | && myRenderParams.ShadowMapResolution > 0 | |
1436 | && !myLights.IsNull() | |
1437 | && myLights->NbCastShadows() > 0 | |
1438 | && myRenderParams.Method != Graphic3d_RM_RAYTRACING; | |
1439 | if (toUseShadowMap) | |
1440 | { | |
1441 | if (myShadowMaps->Size() != myLights->NbCastShadows()) | |
1442 | { | |
1443 | myShadowMaps->Release (aCtx.get()); | |
1444 | myShadowMaps->Resize (0, myLights->NbCastShadows() - 1, true); | |
1445 | } | |
1446 | ||
1447 | const GLint aSamplFrom = GLint(aCtx->ShadowMapTexUnit()) - myLights->NbCastShadows() + 1; | |
1448 | for (Standard_Integer aShadowIter = 0; aShadowIter < myShadowMaps->Size(); ++aShadowIter) | |
1449 | { | |
1450 | Handle(OpenGl_ShadowMap)& aShadow = myShadowMaps->ChangeValue (aShadowIter); | |
1451 | if (aShadow.IsNull()) | |
1452 | { | |
1453 | aShadow = new OpenGl_ShadowMap(); | |
1454 | } | |
1455 | aShadow->SetShadowMapBias (myRenderParams.ShadowMapBias); | |
1456 | aShadow->Texture()->Sampler()->Parameters()->SetTextureUnit ((Graphic3d_TextureUnit )(aSamplFrom + aShadowIter)); | |
1457 | ||
1458 | const Handle(OpenGl_FrameBuffer)& aShadowFbo = aShadow->FrameBuffer(); | |
1459 | if (aShadowFbo->GetVPSizeX() != myRenderParams.ShadowMapResolution | |
1460 | && toUseShadowMap) | |
1461 | { | |
1462 | OpenGl_ColorFormats aDummy; | |
1220d98e | 1463 | if (!aShadowFbo->Init (aCtx, Graphic3d_Vec2i (myRenderParams.ShadowMapResolution), aDummy, myFboDepthFormat, 0)) |
d84e8669 | 1464 | { |
1465 | toUseShadowMap = false; | |
1466 | } | |
1467 | } | |
1468 | } | |
1469 | } | |
1470 | if (!toUseShadowMap && myShadowMaps->IsValid()) | |
1471 | { | |
1472 | myShadowMaps->Release (aCtx.get()); | |
1473 | } | |
1474 | ||
cfb54c0c | 1475 | return true; |
1476 | } | |
1477 | ||
1478 | //======================================================================= | |
1479 | //function : Redraw | |
1480 | //purpose : | |
1481 | //======================================================================= | |
1482 | void OpenGl_View::Redraw() | |
1483 | { | |
1484 | const Standard_Boolean wasDisabledMSAA = myToDisableMSAA; | |
1485 | const Standard_Boolean hadFboBlit = myHasFboBlit; | |
1486 | if (myRenderParams.Method == Graphic3d_RM_RAYTRACING | |
1487 | && !myCaps->vboDisable | |
1488 | && !myCaps->keepArrayData) | |
1489 | { | |
1490 | // caps are shared across all views, thus we need to invalidate all of them | |
1491 | // if (myWasRedrawnGL) { myStructureManager->SetDeviceLost(); } | |
1492 | myDriver->setDeviceLost(); | |
1493 | myCaps->keepArrayData = Standard_True; | |
1494 | } | |
1495 | ||
1496 | if (!myWorkspace->Activate()) | |
1497 | { | |
1498 | return; | |
1499 | } | |
1500 | ||
1501 | // implicitly disable VSync when using HMD composer (can be mirrored in window for debugging) | |
1502 | myWindow->SetSwapInterval (IsActiveXR()); | |
1503 | ||
1504 | ++myFrameCounter; | |
1505 | const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext(); | |
1506 | aCtx->FrameStats()->FrameStart (myWorkspace->View(), false); | |
1507 | aCtx->SetLineFeather (myRenderParams.LineFeather); | |
1508 | ||
1509 | const Standard_Integer anSRgbState = aCtx->ToRenderSRGB() ? 1 : 0; | |
1510 | if (mySRgbState != -1 | |
1511 | && mySRgbState != anSRgbState) | |
1512 | { | |
1513 | releaseSrgbResources (aCtx); | |
1514 | initTextureEnv (aCtx); | |
1515 | } | |
1516 | mySRgbState = anSRgbState; | |
1517 | aCtx->ShaderManager()->UpdateSRgbState(); | |
1518 | ||
1519 | // release pending GL resources | |
1520 | aCtx->ReleaseDelayed(); | |
1521 | ||
1522 | // fetch OpenGl context state | |
1523 | aCtx->FetchState(); | |
1524 | ||
1525 | const Graphic3d_StereoMode aStereoMode = myRenderParams.StereoMode; | |
1526 | Graphic3d_Camera::Projection aProjectType = myCamera->ProjectionType(); | |
1527 | if (!prepareFrameBuffers (aProjectType)) | |
1528 | { | |
1529 | myBackBufferRestored = Standard_False; | |
1530 | myIsImmediateDrawn = Standard_False; | |
1531 | return; | |
1532 | } | |
1533 | ||
d84e8669 | 1534 | // draw shadow maps |
1535 | if (myShadowMaps->IsValid()) | |
1536 | { | |
1537 | Standard_Integer aShadowIndex = myShadowMaps->Lower(); | |
1538 | for (Graphic3d_LightSet::Iterator aLightIter (myLights, Graphic3d_LightSet::IterationFilter_ActiveShadowCasters); | |
1539 | aLightIter.More(); aLightIter.Next()) | |
1540 | { | |
1541 | const Handle(Graphic3d_CLight)& aLight = aLightIter.Value(); | |
1542 | if (aLight->ToCastShadows()) | |
1543 | { | |
1544 | const Handle(OpenGl_ShadowMap)& aShadowMap = myShadowMaps->ChangeValue (aShadowIndex); | |
1545 | aShadowMap->SetLightSource (aLight); | |
1546 | renderShadowMap (aShadowMap); | |
1547 | ++aShadowIndex; | |
1548 | } | |
1549 | } | |
1550 | for (; aShadowIndex <= myShadowMaps->Upper(); ++aShadowIndex) | |
1551 | { | |
1552 | myShadowMaps->ChangeValue (aShadowIndex)->SetLightSource (Handle(Graphic3d_CLight)()); | |
1553 | } | |
1554 | } | |
1555 | ||
cfb54c0c | 1556 | OpenGl_FrameBuffer* aFrameBuffer = myFBO.get(); |
1557 | bool toSwap = aCtx->IsRender() | |
1558 | && !aCtx->caps->buffersNoSwap | |
1559 | && aFrameBuffer == NULL | |
1560 | && (!IsActiveXR() || myRenderParams.ToMirrorComposer); | |
1561 | if ( aFrameBuffer == NULL | |
1562 | && !aCtx->DefaultFrameBuffer().IsNull() | |
1563 | && aCtx->DefaultFrameBuffer()->IsValid()) | |
1564 | { | |
1565 | aFrameBuffer = aCtx->DefaultFrameBuffer().operator->(); | |
1566 | } | |
1567 | ||
1568 | if (aProjectType == Graphic3d_Camera::Projection_Stereo) | |
1569 | { | |
1570 | OpenGl_FrameBuffer* aMainFbos[2] = | |
1571 | { | |
1572 | myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL, | |
1573 | myMainSceneFbos[1]->IsValid() ? myMainSceneFbos[1].operator->() : NULL | |
1574 | }; | |
1575 | OpenGl_FrameBuffer* aMainFbosOit[2] = | |
1576 | { | |
1577 | myMainSceneFbosOit[0]->IsValid() ? myMainSceneFbosOit[0].operator->() : NULL, | |
1578 | myMainSceneFbosOit[1]->IsValid() ? myMainSceneFbosOit[1].operator->() : | |
1579 | myMainSceneFbosOit[0]->IsValid() ? myMainSceneFbosOit[0].operator->() : NULL | |
1580 | }; | |
1581 | ||
1582 | OpenGl_FrameBuffer* anImmFbos[2] = | |
1583 | { | |
1584 | myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL, | |
1585 | myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL | |
1586 | }; | |
1587 | OpenGl_FrameBuffer* anImmFbosOit[2] = | |
1588 | { | |
1589 | myImmediateSceneFbosOit[0]->IsValid() ? myImmediateSceneFbosOit[0].operator->() : NULL, | |
1590 | myImmediateSceneFbosOit[1]->IsValid() ? myImmediateSceneFbosOit[1].operator->() : | |
1591 | myImmediateSceneFbosOit[0]->IsValid() ? myImmediateSceneFbosOit[0].operator->() : NULL | |
1592 | }; | |
1593 | ||
1594 | if (IsActiveXR()) | |
1595 | { | |
1596 | // use single frame for both views - caching main scene content makes no sense | |
1597 | // when head position is expected to be updated each frame redraw with high accuracy | |
1598 | aMainFbos[1] = aMainFbos[0]; | |
1599 | aMainFbosOit[1] = aMainFbosOit[0]; | |
1600 | anImmFbos[0] = aMainFbos[0]; | |
1601 | anImmFbos[1] = aMainFbos[1]; | |
1602 | anImmFbosOit[0] = aMainFbosOit[0]; | |
1603 | anImmFbosOit[1] = aMainFbosOit[1]; | |
1604 | } | |
1605 | else if (!myTransientDrawToFront) | |
1606 | { | |
1607 | anImmFbos [0] = aMainFbos [0]; | |
1608 | anImmFbos [1] = aMainFbos [1]; | |
1609 | anImmFbosOit[0] = aMainFbosOit[0]; | |
1610 | anImmFbosOit[1] = aMainFbosOit[1]; | |
1611 | } | |
1612 | else if (aStereoMode == Graphic3d_StereoMode_SoftPageFlip | |
1613 | || aStereoMode == Graphic3d_StereoMode_QuadBuffer) | |
1614 | { | |
1615 | anImmFbos [0] = NULL; | |
1616 | anImmFbos [1] = NULL; | |
1617 | anImmFbosOit[0] = NULL; | |
1618 | anImmFbosOit[1] = NULL; | |
1619 | } | |
1620 | ||
1621 | #if !defined(GL_ES_VERSION_2_0) | |
1622 | aCtx->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_LEFT : GL_BACK); | |
1623 | #endif | |
1624 | aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(), | |
1625 | aMainFbos[0] != NULL ? myRenderParams.RenderResolutionScale : 1.0f); | |
1626 | ||
1627 | redraw (Graphic3d_Camera::Projection_MonoLeftEye, aMainFbos[0], aMainFbosOit[0]); | |
1628 | myBackBufferRestored = Standard_True; | |
1629 | myIsImmediateDrawn = Standard_False; | |
1630 | #if !defined(GL_ES_VERSION_2_0) | |
1631 | aCtx->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_LEFT : GL_BACK); | |
1632 | #endif | |
1633 | aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(), | |
1634 | anImmFbos[0] != NULL ? myRenderParams.RenderResolutionScale : 1.0f); | |
1635 | if (!redrawImmediate (Graphic3d_Camera::Projection_MonoLeftEye, aMainFbos[0], anImmFbos[0], anImmFbosOit[0])) | |
1636 | { | |
1637 | toSwap = false; | |
1638 | } | |
1639 | else if (aStereoMode == Graphic3d_StereoMode_SoftPageFlip && toSwap) | |
1640 | { | |
1641 | aCtx->SwapBuffers(); | |
1642 | } | |
1643 | ||
1644 | if (IsActiveXR()) | |
1645 | { | |
1646 | // push Left frame to HMD display composer | |
1647 | OpenGl_FrameBuffer* anXRFbo = myXrSceneFbo->IsValid() ? myXrSceneFbo.get() : aMainFbos[0]; | |
1648 | if (anXRFbo != aMainFbos[0]) | |
1649 | { | |
1650 | blitBuffers (aMainFbos[0], anXRFbo); // resize or resolve MSAA samples | |
1651 | } | |
1652 | #if !defined(GL_ES_VERSION_2_0) | |
1653 | const Aspect_GraphicsLibrary aGraphicsLib = Aspect_GraphicsLibrary_OpenGL; | |
1654 | #else | |
1655 | const Aspect_GraphicsLibrary aGraphicsLib = Aspect_GraphicsLibrary_OpenGLES; | |
1656 | #endif | |
1657 | myXRSession->SubmitEye ((void* )(size_t )anXRFbo->ColorTexture()->TextureId(), | |
1658 | aGraphicsLib, Aspect_ColorSpace_sRGB, Aspect_Eye_Left); | |
1659 | } | |
1660 | ||
1661 | #if !defined(GL_ES_VERSION_2_0) | |
1662 | aCtx->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_RIGHT : GL_BACK); | |
1663 | #endif | |
1664 | aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(), | |
1665 | aMainFbos[1] != NULL ? myRenderParams.RenderResolutionScale : 1.0f); | |
1666 | ||
1667 | redraw (Graphic3d_Camera::Projection_MonoRightEye, aMainFbos[1], aMainFbosOit[1]); | |
1668 | myBackBufferRestored = Standard_True; | |
1669 | myIsImmediateDrawn = Standard_False; | |
1670 | aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(), | |
1671 | anImmFbos[1] != NULL ? myRenderParams.RenderResolutionScale : 1.0f); | |
1672 | if (!redrawImmediate (Graphic3d_Camera::Projection_MonoRightEye, aMainFbos[1], anImmFbos[1], anImmFbosOit[1])) | |
1673 | { | |
1674 | toSwap = false; | |
1675 | } | |
1676 | ||
1677 | if (IsActiveXR()) | |
1678 | { | |
1679 | // push Right frame to HMD display composer | |
1680 | OpenGl_FrameBuffer* anXRFbo = myXrSceneFbo->IsValid() ? myXrSceneFbo.get() : aMainFbos[1]; | |
1681 | if (anXRFbo != aMainFbos[1]) | |
1682 | { | |
1683 | blitBuffers (aMainFbos[1], anXRFbo); // resize or resolve MSAA samples | |
1684 | } | |
1685 | #if !defined(GL_ES_VERSION_2_0) | |
1686 | const Aspect_GraphicsLibrary aGraphicsLib = Aspect_GraphicsLibrary_OpenGL; | |
1687 | #else | |
1688 | const Aspect_GraphicsLibrary aGraphicsLib = Aspect_GraphicsLibrary_OpenGLES; | |
1689 | #endif | |
1690 | myXRSession->SubmitEye ((void* )(size_t )anXRFbo->ColorTexture()->TextureId(), | |
1691 | aGraphicsLib, Aspect_ColorSpace_sRGB, Aspect_Eye_Right); | |
43eddb47 | 1692 | aCtx->core11fwd->glFinish(); |
cfb54c0c | 1693 | |
1694 | if (myRenderParams.ToMirrorComposer) | |
1695 | { | |
1696 | blitBuffers (anXRFbo, aFrameBuffer, myToFlipOutput); | |
1697 | } | |
1698 | } | |
1699 | else if (anImmFbos[0] != NULL) | |
1700 | { | |
1701 | aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(), 1.0f); | |
1702 | drawStereoPair (aFrameBuffer); | |
1703 | } | |
1704 | } | |
1705 | else | |
1706 | { | |
1707 | OpenGl_FrameBuffer* aMainFbo = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : aFrameBuffer; | |
1708 | OpenGl_FrameBuffer* aMainFboOit = myMainSceneFbosOit[0]->IsValid() ? myMainSceneFbosOit[0].operator->() : NULL; | |
1709 | OpenGl_FrameBuffer* anImmFbo = aFrameBuffer; | |
1710 | OpenGl_FrameBuffer* anImmFboOit = NULL; | |
1711 | if (!myTransientDrawToFront) | |
1712 | { | |
1713 | anImmFbo = aMainFbo; | |
1714 | anImmFboOit = aMainFboOit; | |
1715 | } | |
1716 | else if (myImmediateSceneFbos[0]->IsValid()) | |
1717 | { | |
1718 | anImmFbo = myImmediateSceneFbos[0].operator->(); | |
1719 | anImmFboOit = myImmediateSceneFbosOit[0]->IsValid() ? myImmediateSceneFbosOit[0].operator->() : NULL; | |
1720 | } | |
1721 | ||
1722 | #if !defined(GL_ES_VERSION_2_0) | |
1723 | if (aMainFbo == NULL) | |
1724 | { | |
1725 | aCtx->SetReadDrawBuffer (GL_BACK); | |
1726 | } | |
1727 | #endif | |
1728 | aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(), | |
1729 | aMainFbo != aFrameBuffer ? myRenderParams.RenderResolutionScale : 1.0f); | |
1730 | ||
1731 | redraw (aProjectType, aMainFbo, aMainFboOit); | |
1732 | myBackBufferRestored = Standard_True; | |
1733 | myIsImmediateDrawn = Standard_False; | |
1734 | aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(), | |
1735 | anImmFbo != aFrameBuffer ? myRenderParams.RenderResolutionScale : 1.0f); | |
1736 | if (!redrawImmediate (aProjectType, aMainFbo, anImmFbo, anImmFboOit)) | |
1737 | { | |
1738 | toSwap = false; | |
1739 | } | |
1740 | ||
1741 | if (anImmFbo != NULL | |
1742 | && anImmFbo != aFrameBuffer) | |
1743 | { | |
1744 | blitBuffers (anImmFbo, aFrameBuffer, myToFlipOutput); | |
1745 | } | |
1746 | } | |
1747 | ||
1748 | if (myRenderParams.Method == Graphic3d_RM_RAYTRACING | |
1749 | && myRenderParams.IsGlobalIlluminationEnabled) | |
1750 | { | |
1751 | myAccumFrames++; | |
1752 | } | |
1753 | ||
1754 | // bind default FBO | |
1755 | bindDefaultFbo(); | |
1756 | ||
1757 | if (wasDisabledMSAA != myToDisableMSAA | |
1758 | || hadFboBlit != myHasFboBlit) | |
1759 | { | |
1760 | // retry on error | |
1761 | Redraw(); | |
1762 | } | |
1763 | ||
1764 | // reset state for safety | |
1765 | aCtx->BindProgram (Handle(OpenGl_ShaderProgram)()); | |
1766 | if (aCtx->caps->ffpEnable) | |
1767 | { | |
1768 | aCtx->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)()); | |
1769 | } | |
1770 | ||
1771 | // Swap the buffers | |
1772 | if (toSwap) | |
1773 | { | |
1774 | aCtx->SwapBuffers(); | |
1775 | if (!myMainSceneFbos[0]->IsValid()) | |
1776 | { | |
1777 | myBackBufferRestored = Standard_False; | |
1778 | } | |
1779 | } | |
1780 | else | |
1781 | { | |
1782 | aCtx->core11fwd->glFlush(); | |
1783 | } | |
1784 | ||
1785 | // reset render mode state | |
1786 | aCtx->FetchState(); | |
1787 | aCtx->FrameStats()->FrameEnd (myWorkspace->View(), false); | |
1788 | ||
1789 | myWasRedrawnGL = Standard_True; | |
1790 | } | |
1791 | ||
1792 | // ======================================================================= | |
1793 | // function : RedrawImmediate | |
1794 | // purpose : | |
1795 | // ======================================================================= | |
1796 | void OpenGl_View::RedrawImmediate() | |
1797 | { | |
1798 | if (!myWorkspace->Activate()) | |
1799 | return; | |
1800 | ||
1801 | // no special handling of HMD display, since it will force full Redraw() due to no frame caching (myBackBufferRestored) | |
1802 | Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext(); | |
1803 | if (!myTransientDrawToFront | |
1804 | || !myBackBufferRestored | |
1805 | || (aCtx->caps->buffersNoSwap && !myMainSceneFbos[0]->IsValid())) | |
1806 | { | |
1807 | Redraw(); | |
1808 | return; | |
1809 | } | |
1810 | ||
1811 | const Graphic3d_StereoMode aStereoMode = myRenderParams.StereoMode; | |
1812 | Graphic3d_Camera::Projection aProjectType = myCamera->ProjectionType(); | |
1813 | OpenGl_FrameBuffer* aFrameBuffer = myFBO.get(); | |
1814 | aCtx->FrameStats()->FrameStart (myWorkspace->View(), true); | |
1815 | ||
1816 | if ( aFrameBuffer == NULL | |
1817 | && !aCtx->DefaultFrameBuffer().IsNull() | |
1818 | && aCtx->DefaultFrameBuffer()->IsValid()) | |
1819 | { | |
1820 | aFrameBuffer = aCtx->DefaultFrameBuffer().operator->(); | |
1821 | } | |
1822 | ||
1823 | if (aProjectType == Graphic3d_Camera::Projection_Stereo) | |
1824 | { | |
1825 | if (myMainSceneFbos[0]->IsValid() | |
1826 | && !myMainSceneFbos[1]->IsValid()) | |
1827 | { | |
1828 | aProjectType = Graphic3d_Camera::Projection_Perspective; | |
1829 | } | |
1830 | } | |
1831 | ||
1832 | bool toSwap = false; | |
1833 | if (aProjectType == Graphic3d_Camera::Projection_Stereo) | |
1834 | { | |
1835 | OpenGl_FrameBuffer* aMainFbos[2] = | |
1836 | { | |
1837 | myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL, | |
1838 | myMainSceneFbos[1]->IsValid() ? myMainSceneFbos[1].operator->() : NULL | |
1839 | }; | |
1840 | OpenGl_FrameBuffer* anImmFbos[2] = | |
1841 | { | |
1842 | myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL, | |
1843 | myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL | |
1844 | }; | |
1845 | OpenGl_FrameBuffer* anImmFbosOit[2] = | |
1846 | { | |
1847 | myImmediateSceneFbosOit[0]->IsValid() ? myImmediateSceneFbosOit[0].operator->() : NULL, | |
1848 | myImmediateSceneFbosOit[1]->IsValid() ? myImmediateSceneFbosOit[1].operator->() : | |
1849 | myImmediateSceneFbosOit[0]->IsValid() ? myImmediateSceneFbosOit[0].operator->() : NULL | |
1850 | }; | |
1851 | if (aStereoMode == Graphic3d_StereoMode_SoftPageFlip | |
1852 | || aStereoMode == Graphic3d_StereoMode_QuadBuffer) | |
1853 | { | |
1854 | anImmFbos[0] = NULL; | |
1855 | anImmFbos[1] = NULL; | |
1856 | anImmFbosOit[0] = NULL; | |
1857 | anImmFbosOit[1] = NULL; | |
1858 | } | |
1859 | ||
1860 | if (aCtx->arbFBO != NULL) | |
1861 | { | |
1862 | aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER); | |
1863 | } | |
1864 | #if !defined(GL_ES_VERSION_2_0) | |
1865 | if (anImmFbos[0] == NULL) | |
1866 | { | |
1867 | aCtx->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_LEFT : GL_BACK); | |
1868 | } | |
1869 | #endif | |
1870 | ||
1871 | aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(), | |
1872 | anImmFbos[0] != NULL ? myRenderParams.RenderResolutionScale : 1.0f); | |
1873 | toSwap = redrawImmediate (Graphic3d_Camera::Projection_MonoLeftEye, | |
1874 | aMainFbos[0], | |
1875 | anImmFbos[0], | |
1876 | anImmFbosOit[0], | |
1877 | Standard_True) || toSwap; | |
1878 | if (aStereoMode == Graphic3d_StereoMode_SoftPageFlip | |
1879 | && toSwap | |
655e883c | 1880 | && myFBO.get() == NULL |
cfb54c0c | 1881 | && !aCtx->caps->buffersNoSwap) |
1882 | { | |
1883 | aCtx->SwapBuffers(); | |
1884 | } | |
1885 | ||
1886 | if (aCtx->arbFBO != NULL) | |
1887 | { | |
1888 | aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER); | |
1889 | } | |
1890 | #if !defined(GL_ES_VERSION_2_0) | |
1891 | if (anImmFbos[1] == NULL) | |
1892 | { | |
1893 | aCtx->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_RIGHT : GL_BACK); | |
1894 | } | |
1895 | #endif | |
1896 | aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(), | |
1897 | anImmFbos[1] != NULL ? myRenderParams.RenderResolutionScale : 1.0f); | |
1898 | toSwap = redrawImmediate (Graphic3d_Camera::Projection_MonoRightEye, | |
1899 | aMainFbos[1], | |
1900 | anImmFbos[1], | |
1901 | anImmFbosOit[1], | |
1902 | Standard_True) || toSwap; | |
1903 | if (anImmFbos[0] != NULL) | |
1904 | { | |
1905 | drawStereoPair (aFrameBuffer); | |
1906 | } | |
1907 | } | |
1908 | else | |
1909 | { | |
1910 | OpenGl_FrameBuffer* aMainFbo = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL; | |
1911 | OpenGl_FrameBuffer* anImmFbo = aFrameBuffer; | |
1912 | OpenGl_FrameBuffer* anImmFboOit = NULL; | |
1913 | if (myImmediateSceneFbos[0]->IsValid()) | |
1914 | { | |
1915 | anImmFbo = myImmediateSceneFbos[0].operator->(); | |
1916 | anImmFboOit = myImmediateSceneFbosOit[0]->IsValid() ? myImmediateSceneFbosOit[0].operator->() : NULL; | |
1917 | } | |
1918 | #if !defined(GL_ES_VERSION_2_0) | |
1919 | if (aMainFbo == NULL) | |
1920 | { | |
1921 | aCtx->SetReadDrawBuffer (GL_BACK); | |
1922 | } | |
1923 | #endif | |
1924 | aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(), | |
1925 | anImmFbo != aFrameBuffer ? myRenderParams.RenderResolutionScale : 1.0f); | |
1926 | toSwap = redrawImmediate (aProjectType, | |
1927 | aMainFbo, | |
1928 | anImmFbo, | |
1929 | anImmFboOit, | |
1930 | Standard_True) || toSwap; | |
1931 | if (anImmFbo != NULL | |
1932 | && anImmFbo != aFrameBuffer) | |
1933 | { | |
1934 | blitBuffers (anImmFbo, aFrameBuffer, myToFlipOutput); | |
1935 | } | |
1936 | } | |
1937 | ||
1938 | // bind default FBO | |
1939 | bindDefaultFbo(); | |
1940 | ||
1941 | // reset state for safety | |
1942 | aCtx->BindProgram (Handle(OpenGl_ShaderProgram)()); | |
1943 | if (aCtx->caps->ffpEnable) | |
1944 | { | |
1945 | aCtx->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)()); | |
1946 | } | |
1947 | ||
655e883c | 1948 | if (toSwap |
1949 | && myFBO.get() == NULL | |
1950 | && !aCtx->caps->buffersNoSwap) | |
cfb54c0c | 1951 | { |
1952 | aCtx->SwapBuffers(); | |
1953 | } | |
1954 | else | |
1955 | { | |
1956 | aCtx->core11fwd->glFlush(); | |
1957 | } | |
1958 | aCtx->FrameStats()->FrameEnd (myWorkspace->View(), true); | |
1959 | ||
1960 | myWasRedrawnGL = Standard_True; | |
1961 | } | |
1962 | ||
1963 | // ======================================================================= | |
1964 | // function : redraw | |
1965 | // purpose : | |
1966 | // ======================================================================= | |
1967 | void OpenGl_View::redraw (const Graphic3d_Camera::Projection theProjection, | |
1968 | OpenGl_FrameBuffer* theReadDrawFbo, | |
1969 | OpenGl_FrameBuffer* theOitAccumFbo) | |
1970 | { | |
1971 | Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext(); | |
1972 | if (theReadDrawFbo != NULL) | |
1973 | { | |
1974 | theReadDrawFbo->BindBuffer (aCtx); | |
1975 | theReadDrawFbo->SetupViewport (aCtx); | |
1976 | } | |
1977 | else | |
1978 | { | |
1979 | const Standard_Integer aViewport[4] = { 0, 0, myWindow->Width(), myWindow->Height() }; | |
1980 | aCtx->ResizeViewport (aViewport); | |
1981 | } | |
1982 | ||
1983 | // request reset of material | |
1984 | aCtx->ShaderManager()->UpdateMaterialState(); | |
1985 | ||
1986 | myWorkspace->UseZBuffer() = Standard_True; | |
1987 | myWorkspace->UseDepthWrite() = Standard_True; | |
1988 | GLbitfield toClear = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT; | |
1989 | aCtx->core11fwd->glDepthFunc (GL_LEQUAL); | |
1990 | aCtx->core11fwd->glDepthMask (GL_TRUE); | |
1991 | aCtx->core11fwd->glEnable (GL_DEPTH_TEST); | |
1992 | ||
1993 | aCtx->core11fwd->glClearDepth (1.0); | |
1994 | ||
1995 | const OpenGl_Vec4 aBgColor = aCtx->Vec4FromQuantityColor (myBgColor); | |
1996 | aCtx->SetColorMaskRGBA (NCollection_Vec4<bool> (true)); // force writes into all components, including alpha | |
1997 | aCtx->core11fwd->glClearColor (aBgColor.r(), aBgColor.g(), aBgColor.b(), aCtx->caps->buffersOpaqueAlpha ? 1.0f : 0.0f); | |
1998 | aCtx->core11fwd->glClear (toClear); | |
1999 | aCtx->SetColorMask (true); // restore default alpha component write state | |
2000 | ||
2001 | render (theProjection, theReadDrawFbo, theOitAccumFbo, Standard_False); | |
2002 | } | |
2003 | ||
2004 | // ======================================================================= | |
d84e8669 | 2005 | // function : redrawImmediate |
cfb54c0c | 2006 | // purpose : |
2007 | // ======================================================================= | |
2008 | bool OpenGl_View::redrawImmediate (const Graphic3d_Camera::Projection theProjection, | |
2009 | OpenGl_FrameBuffer* theReadFbo, | |
2010 | OpenGl_FrameBuffer* theDrawFbo, | |
2011 | OpenGl_FrameBuffer* theOitAccumFbo, | |
2012 | const Standard_Boolean theIsPartialUpdate) | |
2013 | { | |
2014 | const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext(); | |
2015 | GLboolean toCopyBackToFront = GL_FALSE; | |
2016 | if (theDrawFbo == theReadFbo | |
2017 | && theDrawFbo != NULL | |
2018 | && theDrawFbo->IsValid()) | |
2019 | { | |
2020 | myBackBufferRestored = Standard_False; | |
2021 | theDrawFbo->BindBuffer (aCtx); | |
2022 | } | |
2023 | else if (theReadFbo != NULL | |
2024 | && theReadFbo->IsValid() | |
2025 | && aCtx->IsRender()) | |
2026 | { | |
2027 | if (!blitBuffers (theReadFbo, theDrawFbo)) | |
2028 | { | |
2029 | return true; | |
2030 | } | |
2031 | } | |
2032 | else if (theDrawFbo == NULL) | |
2033 | { | |
2034 | #if !defined(GL_ES_VERSION_2_0) | |
2035 | aCtx->core11fwd->glGetBooleanv (GL_DOUBLEBUFFER, &toCopyBackToFront); | |
2036 | #endif | |
2037 | if (toCopyBackToFront | |
2038 | && myTransientDrawToFront) | |
2039 | { | |
2040 | if (!HasImmediateStructures() | |
2041 | && !theIsPartialUpdate) | |
2042 | { | |
2043 | // prefer Swap Buffers within Redraw in compatibility mode (without FBO) | |
2044 | return true; | |
2045 | } | |
2046 | if (!copyBackToFront()) | |
2047 | { | |
2048 | toCopyBackToFront = GL_FALSE; | |
2049 | myBackBufferRestored = Standard_False; | |
2050 | } | |
2051 | } | |
2052 | else | |
2053 | { | |
2054 | toCopyBackToFront = GL_FALSE; | |
2055 | myBackBufferRestored = Standard_False; | |
2056 | } | |
2057 | } | |
2058 | else | |
2059 | { | |
2060 | myBackBufferRestored = Standard_False; | |
2061 | } | |
2062 | myIsImmediateDrawn = Standard_True; | |
2063 | ||
2064 | myWorkspace->UseZBuffer() = Standard_True; | |
2065 | myWorkspace->UseDepthWrite() = Standard_True; | |
43eddb47 | 2066 | aCtx->core11fwd->glDepthFunc (GL_LEQUAL); |
2067 | aCtx->core11fwd->glDepthMask (GL_TRUE); | |
2068 | aCtx->core11fwd->glEnable (GL_DEPTH_TEST); | |
2069 | aCtx->core11fwd->glClearDepth (1.0); | |
cfb54c0c | 2070 | |
2071 | render (theProjection, theDrawFbo, theOitAccumFbo, Standard_True); | |
2072 | ||
2073 | return !toCopyBackToFront; | |
2074 | } | |
2075 | ||
d84e8669 | 2076 | //======================================================================= |
2077 | //function : renderShadowMap | |
2078 | //purpose : | |
2079 | //======================================================================= | |
2080 | void OpenGl_View::renderShadowMap (const Handle(OpenGl_ShadowMap)& theShadowMap) | |
2081 | { | |
2082 | const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext(); | |
2083 | if (!theShadowMap->UpdateCamera (*this)) | |
2084 | { | |
2085 | return; | |
2086 | } | |
2087 | ||
2088 | myBVHSelector.SetViewVolume (theShadowMap->Camera()); | |
2089 | myBVHSelector.SetViewportSize (myWindow->Width(), myWindow->Height(), myRenderParams.ResolutionRatio()); | |
2090 | myBVHSelector.CacheClipPtsProjections(); | |
2091 | ||
2092 | myLocalOrigin.SetCoord (0.0, 0.0, 0.0); | |
2093 | aCtx->SetCamera (theShadowMap->Camera()); | |
2094 | aCtx->ProjectionState.SetCurrent (theShadowMap->Camera()->ProjectionMatrixF()); | |
2095 | aCtx->ApplyProjectionMatrix(); | |
2096 | ||
2097 | aCtx->ShaderManager()->UpdateMaterialState(); | |
2098 | aCtx->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4()); | |
2099 | aCtx->ShaderManager()->SetShadingModel (Graphic3d_TOSM_UNLIT); | |
2100 | ||
2101 | const Handle(OpenGl_FrameBuffer)& aShadowBuffer = theShadowMap->FrameBuffer(); | |
2102 | aShadowBuffer->BindBuffer (aCtx); | |
2103 | aShadowBuffer->SetupViewport (aCtx); | |
2104 | ||
2105 | aCtx->SetColorMask (false); | |
2106 | aCtx->SetAllowSampleAlphaToCoverage (false); | |
2107 | aCtx->SetSampleAlphaToCoverage (false); | |
2108 | ||
2109 | myWorkspace->UseZBuffer() = true; | |
2110 | myWorkspace->UseDepthWrite() = true; | |
2111 | aCtx->core11fwd->glDepthFunc (GL_LEQUAL); | |
2112 | aCtx->core11fwd->glDepthMask (GL_TRUE); | |
2113 | aCtx->core11fwd->glEnable (GL_DEPTH_TEST); | |
2114 | aCtx->core11fwd->glClearDepth (1.0); | |
2115 | aCtx->core11fwd->glClear (GL_DEPTH_BUFFER_BIT); | |
2116 | ||
2117 | renderScene (Graphic3d_Camera::Projection_Orthographic, aShadowBuffer.get(), NULL, false); | |
2118 | ||
2119 | aCtx->SetColorMask (true); | |
2120 | myWorkspace->ResetAppliedAspect(); | |
2121 | aCtx->BindProgram (Handle(OpenGl_ShaderProgram)()); | |
2122 | ||
2123 | //Image_AlienPixMap anImage; anImage.InitZero (Image_Format_Gray, aShadowBuffer->GetVPSizeX(), aShadowBuffer->GetVPSizeY()); | |
2124 | //OpenGl_FrameBuffer::BufferDump (aCtx, aShadowBuffer, anImage, Graphic3d_BT_Depth); | |
2125 | //anImage.Save (TCollection_AsciiString ("shadow") + theShadowMap->Texture()->Sampler()->Parameters()->TextureUnit() + ".png"); | |
2126 | ||
2127 | bindDefaultFbo(); | |
2128 | } | |
2129 | ||
cfb54c0c | 2130 | //======================================================================= |
2131 | //function : Render | |
2132 | //purpose : | |
2133 | //======================================================================= | |
2134 | void OpenGl_View::render (Graphic3d_Camera::Projection theProjection, | |
2135 | OpenGl_FrameBuffer* theOutputFBO, | |
2136 | OpenGl_FrameBuffer* theOitAccumFbo, | |
2137 | const Standard_Boolean theToDrawImmediate) | |
2138 | { | |
2139 | // ================================== | |
2140 | // Step 1: Prepare for render | |
2141 | // ================================== | |
2142 | ||
2143 | const Handle(OpenGl_Context)& aContext = myWorkspace->GetGlContext(); | |
2144 | aContext->SetAllowSampleAlphaToCoverage (myRenderParams.ToEnableAlphaToCoverage | |
2145 | && theOutputFBO != NULL | |
2146 | && theOutputFBO->NbSamples() != 0); | |
2147 | ||
2148 | #if !defined(GL_ES_VERSION_2_0) | |
2149 | // Disable current clipping planes | |
43eddb47 | 2150 | if (aContext->core11ffp != NULL) |
cfb54c0c | 2151 | { |
2152 | const Standard_Integer aMaxPlanes = aContext->MaxClipPlanes(); | |
2153 | for (Standard_Integer aClipPlaneId = GL_CLIP_PLANE0; aClipPlaneId < GL_CLIP_PLANE0 + aMaxPlanes; ++aClipPlaneId) | |
2154 | { | |
2155 | aContext->core11fwd->glDisable (aClipPlaneId); | |
2156 | } | |
2157 | } | |
2158 | #endif | |
2159 | ||
2160 | // update states of OpenGl_BVHTreeSelector (frustum culling algorithm); | |
2161 | // note that we pass here window dimensions ignoring Graphic3d_RenderingParams::RenderResolutionScale | |
2162 | myBVHSelector.SetViewVolume (myCamera); | |
2163 | myBVHSelector.SetViewportSize (myWindow->Width(), myWindow->Height(), myRenderParams.ResolutionRatio()); | |
2164 | myBVHSelector.CacheClipPtsProjections(); | |
2165 | ||
2166 | const Handle(OpenGl_ShaderManager)& aManager = aContext->ShaderManager(); | |
114db5a5 | 2167 | const Handle(Graphic3d_LightSet)& aLights = myRenderParams.ShadingModel == Graphic3d_TOSM_UNLIT ? myNoShadingLight : myLights; |
cfb54c0c | 2168 | Standard_Size aLightsRevision = 0; |
2169 | if (!aLights.IsNull()) | |
2170 | { | |
2171 | aLightsRevision = aLights->UpdateRevision(); | |
2172 | } | |
2173 | if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState | |
2174 | || aLightsRevision != myLightsRevision) | |
2175 | { | |
2176 | myLightsRevision = aLightsRevision; | |
d84e8669 | 2177 | aManager->UpdateLightSourceStateTo (aLights, SpecIBLMapLevels(), myShadowMaps->IsValid() ? myShadowMaps : Handle(OpenGl_ShadowMapArray)()); |
cfb54c0c | 2178 | myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()); |
2179 | } | |
2180 | ||
2181 | // Update matrices if camera has changed. | |
2182 | Graphic3d_WorldViewProjState aWVPState = myCamera->WorldViewProjState(); | |
2183 | if (myWorldViewProjState != aWVPState) | |
2184 | { | |
2185 | myAccumFrames = 0; | |
2186 | myWorldViewProjState = aWVPState; | |
2187 | } | |
2188 | ||
2189 | myLocalOrigin.SetCoord (0.0, 0.0, 0.0); | |
2190 | aContext->SetCamera (myCamera); | |
2191 | if (aManager->ModelWorldState().Index() == 0) | |
2192 | { | |
2193 | aContext->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4()); | |
2194 | } | |
2195 | ||
2196 | // ==================================== | |
2197 | // Step 2: Redraw background | |
2198 | // ==================================== | |
2199 | ||
2200 | // Render background | |
2201 | if (!theToDrawImmediate) | |
2202 | { | |
2203 | drawBackground (myWorkspace, theProjection); | |
2204 | } | |
2205 | ||
2206 | #if !defined(GL_ES_VERSION_2_0) | |
2207 | // Switch off lighting by default | |
43eddb47 | 2208 | if (aContext->core11ffp != NULL |
cfb54c0c | 2209 | && aContext->caps->ffpEnable) |
2210 | { | |
43eddb47 | 2211 | aContext->core11fwd->glDisable (GL_LIGHTING); |
cfb54c0c | 2212 | } |
2213 | #endif | |
2214 | ||
2215 | // ================================= | |
2216 | // Step 3: Redraw main plane | |
2217 | // ================================= | |
2218 | ||
cfb54c0c | 2219 | #if !defined(GL_ES_VERSION_2_0) |
2220 | // if the view is scaled normal vectors are scaled to unit | |
2221 | // length for correct displaying of shaded objects | |
2222 | const gp_Pnt anAxialScale = aContext->Camera()->AxialScale(); | |
2223 | if (anAxialScale.X() != 1.F || | |
2224 | anAxialScale.Y() != 1.F || | |
2225 | anAxialScale.Z() != 1.F) | |
2226 | { | |
2227 | aContext->SetGlNormalizeEnabled (Standard_True); | |
2228 | } | |
2229 | else | |
2230 | { | |
2231 | aContext->SetGlNormalizeEnabled (Standard_False); | |
2232 | } | |
2233 | #endif | |
2234 | ||
114db5a5 | 2235 | aManager->SetShadingModel (OpenGl_ShaderManager::PBRShadingModelFallback (myRenderParams.ShadingModel, checkPBRAvailability())); |
cfb54c0c | 2236 | |
2237 | // Redraw 3d scene | |
2238 | if (theProjection == Graphic3d_Camera::Projection_MonoLeftEye) | |
2239 | { | |
2240 | aContext->ProjectionState.SetCurrent (aContext->Camera()->ProjectionStereoLeftF()); | |
2241 | aContext->ApplyProjectionMatrix(); | |
2242 | } | |
2243 | else if (theProjection == Graphic3d_Camera::Projection_MonoRightEye) | |
2244 | { | |
2245 | aContext->ProjectionState.SetCurrent (aContext->Camera()->ProjectionStereoRightF()); | |
2246 | aContext->ApplyProjectionMatrix(); | |
2247 | } | |
2248 | ||
2249 | myWorkspace->SetEnvironmentTexture (myTextureEnv); | |
2250 | ||
d84e8669 | 2251 | const bool hasShadowMap = aContext->ShaderManager()->LightSourceState().HasShadowMaps(); |
2252 | if (hasShadowMap) | |
2253 | { | |
2254 | for (Standard_Integer aShadowIter = myShadowMaps->Lower(); aShadowIter <= myShadowMaps->Upper(); ++aShadowIter) | |
2255 | { | |
2256 | const Handle(OpenGl_ShadowMap)& aShadow = myShadowMaps->Value (aShadowIter); | |
2257 | aShadow->Texture()->Bind (aContext); | |
2258 | } | |
2259 | } | |
2260 | ||
cfb54c0c | 2261 | renderScene (theProjection, theOutputFBO, theOitAccumFbo, theToDrawImmediate); |
2262 | ||
d84e8669 | 2263 | if (hasShadowMap) |
2264 | { | |
2265 | for (Standard_Integer aShadowIter = myShadowMaps->Lower(); aShadowIter <= myShadowMaps->Upper(); ++aShadowIter) | |
2266 | { | |
2267 | const Handle(OpenGl_ShadowMap)& aShadow = myShadowMaps->Value (aShadowIter); | |
2268 | aShadow->Texture()->Unbind (aContext); | |
2269 | } | |
2270 | if (aContext->core15fwd != NULL) | |
2271 | { | |
2272 | aContext->core15fwd->glActiveTexture (GL_TEXTURE0); | |
2273 | } | |
2274 | } | |
2275 | ||
cfb54c0c | 2276 | myWorkspace->SetEnvironmentTexture (Handle(OpenGl_TextureSet)()); |
2277 | ||
2278 | // =============================== | |
2279 | // Step 4: Trihedron | |
2280 | // =============================== | |
2281 | ||
2282 | // Resetting GL parameters according to the default aspects | |
2283 | // in order to synchronize GL state with the graphic driver state | |
2284 | // before drawing auxiliary stuff (trihedrons, overlayer) | |
2285 | myWorkspace->ResetAppliedAspect(); | |
2286 | ||
2287 | // Render trihedron | |
2288 | if (!theToDrawImmediate) | |
2289 | { | |
2290 | renderTrihedron (myWorkspace); | |
cfb54c0c | 2291 | } |
2292 | else | |
2293 | { | |
2294 | renderFrameStats(); | |
2295 | } | |
2296 | ||
2297 | myWorkspace->ResetAppliedAspect(); | |
2298 | aContext->SetAllowSampleAlphaToCoverage (false); | |
2299 | aContext->SetSampleAlphaToCoverage (false); | |
2300 | ||
2301 | // reset FFP state for safety | |
2302 | aContext->BindProgram (Handle(OpenGl_ShaderProgram)()); | |
2303 | if (aContext->caps->ffpEnable) | |
2304 | { | |
2305 | aContext->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)()); | |
2306 | } | |
cfb54c0c | 2307 | } |
2308 | ||
2309 | // ======================================================================= | |
2310 | // function : InvalidateBVHData | |
2311 | // purpose : | |
2312 | // ======================================================================= | |
2313 | void OpenGl_View::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId) | |
2314 | { | |
2315 | myZLayers.InvalidateBVHData (theLayerId); | |
2316 | } | |
2317 | ||
2318 | //======================================================================= | |
2319 | //function : renderStructs | |
2320 | //purpose : | |
2321 | //======================================================================= | |
2322 | void OpenGl_View::renderStructs (Graphic3d_Camera::Projection theProjection, | |
2323 | OpenGl_FrameBuffer* theReadDrawFbo, | |
2324 | OpenGl_FrameBuffer* theOitAccumFbo, | |
2325 | const Standard_Boolean theToDrawImmediate) | |
2326 | { | |
2327 | myZLayers.UpdateCulling (myWorkspace, theToDrawImmediate); | |
2328 | if ( myZLayers.NbStructures() <= 0 ) | |
2329 | return; | |
2330 | ||
2331 | Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext(); | |
2332 | Standard_Boolean toRenderGL = theToDrawImmediate || | |
2333 | myRenderParams.Method != Graphic3d_RM_RAYTRACING || | |
2334 | myRaytraceInitStatus == OpenGl_RT_FAIL || | |
2335 | aCtx->IsFeedback(); | |
2336 | ||
2337 | if (!toRenderGL) | |
2338 | { | |
1220d98e | 2339 | const Graphic3d_Vec2i aSizeXY = theReadDrawFbo != NULL |
2340 | ? theReadDrawFbo->GetVPSize() | |
2341 | : Graphic3d_Vec2i (myWindow->Width(), myWindow->Height()); | |
cfb54c0c | 2342 | |
1220d98e | 2343 | toRenderGL = !initRaytraceResources (aSizeXY.x(), aSizeXY.y(), aCtx) |
cfb54c0c | 2344 | || !updateRaytraceGeometry (OpenGl_GUM_CHECK, myId, aCtx); |
2345 | ||
2346 | toRenderGL |= !myIsRaytraceDataValid; // if no ray-trace data use OpenGL | |
2347 | ||
2348 | if (!toRenderGL) | |
2349 | { | |
1220d98e | 2350 | myOpenGlFBO ->InitLazy (aCtx, aSizeXY, myFboColorFormat, myFboDepthFormat, 0); |
cfb54c0c | 2351 | if (theReadDrawFbo != NULL) |
1220d98e | 2352 | { |
cfb54c0c | 2353 | theReadDrawFbo->UnbindBuffer (aCtx); |
1220d98e | 2354 | } |
cfb54c0c | 2355 | |
2356 | // Prepare preliminary OpenGL output | |
2357 | if (aCtx->arbFBOBlit != NULL) | |
2358 | { | |
2359 | // Render bottom OSD layer | |
2360 | myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Bottom, theReadDrawFbo, theOitAccumFbo); | |
2361 | ||
2362 | const Standard_Integer aPrevFilter = myWorkspace->RenderFilter() & ~(Standard_Integer )(OpenGl_RenderFilter_NonRaytraceableOnly); | |
2363 | myWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_NonRaytraceableOnly); | |
2364 | { | |
2365 | if (theReadDrawFbo != NULL) | |
2366 | { | |
2367 | theReadDrawFbo->BindDrawBuffer (aCtx); | |
2368 | } | |
2369 | else | |
2370 | { | |
2371 | aCtx->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, 0); | |
2372 | aCtx->SetFrameBufferSRGB (false); | |
2373 | } | |
2374 | ||
2375 | // Render non-polygonal elements in default layer | |
2376 | myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_RayTracable, theReadDrawFbo, theOitAccumFbo); | |
2377 | } | |
2378 | myWorkspace->SetRenderFilter (aPrevFilter); | |
2379 | } | |
2380 | ||
2381 | if (theReadDrawFbo != NULL) | |
2382 | { | |
2383 | theReadDrawFbo->BindBuffer (aCtx); | |
2384 | } | |
2385 | else | |
2386 | { | |
2387 | aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, 0); | |
2388 | aCtx->SetFrameBufferSRGB (false); | |
2389 | } | |
2390 | ||
2391 | // Reset OpenGl aspects state to default to avoid enabling of | |
2392 | // backface culling which is not supported in ray-tracing. | |
2393 | myWorkspace->ResetAppliedAspect(); | |
2394 | ||
2395 | // Ray-tracing polygonal primitive arrays | |
1220d98e | 2396 | raytrace (aSizeXY.x(), aSizeXY.y(), theProjection, theReadDrawFbo, aCtx); |
cfb54c0c | 2397 | |
2398 | // Render upper (top and topmost) OpenGL layers | |
2399 | myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Upper, theReadDrawFbo, theOitAccumFbo); | |
2400 | } | |
2401 | } | |
2402 | ||
2403 | // Redraw 3D scene using OpenGL in standard | |
2404 | // mode or in case of ray-tracing failure | |
2405 | if (toRenderGL) | |
2406 | { | |
2407 | myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_All, theReadDrawFbo, theOitAccumFbo); | |
2408 | ||
2409 | // Set flag that scene was redrawn by standard pipeline | |
2410 | myWasRedrawnGL = Standard_True; | |
2411 | } | |
2412 | } | |
2413 | ||
2414 | //======================================================================= | |
2415 | //function : renderTrihedron | |
2416 | //purpose : | |
2417 | //======================================================================= | |
2418 | void OpenGl_View::renderTrihedron (const Handle(OpenGl_Workspace) &theWorkspace) | |
2419 | { | |
2420 | if (myToShowGradTrihedron) | |
2421 | { | |
2422 | myGraduatedTrihedron.Render (theWorkspace); | |
2423 | } | |
2424 | } | |
2425 | ||
2426 | //======================================================================= | |
2427 | //function : renderFrameStats | |
2428 | //purpose : | |
2429 | //======================================================================= | |
2430 | void OpenGl_View::renderFrameStats() | |
2431 | { | |
2432 | if (myRenderParams.ToShowStats | |
2433 | && myRenderParams.CollectedStats != Graphic3d_RenderingParams::PerfCounters_NONE) | |
2434 | { | |
2435 | myFrameStatsPrs.Update (myWorkspace); | |
2436 | myFrameStatsPrs.Render (myWorkspace); | |
2437 | } | |
2438 | } | |
2439 | ||
2440 | // ======================================================================= | |
2441 | // function : Invalidate | |
2442 | // purpose : | |
2443 | // ======================================================================= | |
2444 | void OpenGl_View::Invalidate() | |
2445 | { | |
2446 | myBackBufferRestored = Standard_False; | |
2447 | } | |
2448 | ||
2449 | //======================================================================= | |
2450 | //function : renderScene | |
2451 | //purpose : | |
2452 | //======================================================================= | |
2453 | void OpenGl_View::renderScene (Graphic3d_Camera::Projection theProjection, | |
2454 | OpenGl_FrameBuffer* theReadDrawFbo, | |
2455 | OpenGl_FrameBuffer* theOitAccumFbo, | |
2456 | const Standard_Boolean theToDrawImmediate) | |
2457 | { | |
2458 | const Handle(OpenGl_Context)& aContext = myWorkspace->GetGlContext(); | |
2459 | ||
2460 | // Specify clipping planes in view transformation space | |
2461 | aContext->ChangeClipping().Reset (myClipPlanes); | |
2462 | if (!myClipPlanes.IsNull() | |
2463 | && !myClipPlanes->IsEmpty()) | |
2464 | { | |
2465 | aContext->ShaderManager()->UpdateClippingState(); | |
2466 | } | |
2467 | ||
2468 | renderStructs (theProjection, theReadDrawFbo, theOitAccumFbo, theToDrawImmediate); | |
2469 | aContext->BindTextures (Handle(OpenGl_TextureSet)(), Handle(OpenGl_ShaderProgram)()); | |
2470 | ||
2471 | // Apply restored view matrix. | |
2472 | aContext->ApplyWorldViewMatrix(); | |
2473 | ||
2474 | aContext->ChangeClipping().Reset (Handle(Graphic3d_SequenceOfHClipPlane)()); | |
2475 | if (!myClipPlanes.IsNull() | |
2476 | && !myClipPlanes->IsEmpty()) | |
2477 | { | |
2478 | aContext->ShaderManager()->RevertClippingState(); | |
2479 | } | |
2480 | } | |
2481 | ||
2482 | // ======================================================================= | |
2483 | // function : bindDefaultFbo | |
2484 | // purpose : | |
2485 | // ======================================================================= | |
2486 | void OpenGl_View::bindDefaultFbo (OpenGl_FrameBuffer* theCustomFbo) | |
2487 | { | |
2488 | Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext(); | |
2489 | OpenGl_FrameBuffer* anFbo = (theCustomFbo != NULL && theCustomFbo->IsValid()) | |
2490 | ? theCustomFbo | |
2491 | : (!aCtx->DefaultFrameBuffer().IsNull() | |
2492 | && aCtx->DefaultFrameBuffer()->IsValid() | |
2493 | ? aCtx->DefaultFrameBuffer().operator->() | |
2494 | : NULL); | |
2495 | if (anFbo != NULL) | |
2496 | { | |
2497 | anFbo->BindBuffer (aCtx); | |
2498 | anFbo->SetupViewport (aCtx); | |
2499 | } | |
2500 | else | |
2501 | { | |
2502 | #if !defined(GL_ES_VERSION_2_0) | |
2503 | aCtx->SetReadDrawBuffer (GL_BACK); | |
2504 | #else | |
2505 | if (aCtx->arbFBO != NULL) | |
2506 | { | |
2507 | aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER); | |
2508 | } | |
2509 | #endif | |
2510 | const Standard_Integer aViewport[4] = { 0, 0, myWindow->Width(), myWindow->Height() }; | |
2511 | aCtx->ResizeViewport (aViewport); | |
2512 | } | |
2513 | } | |
2514 | ||
2515 | // ======================================================================= | |
2516 | // function : initBlitQuad | |
2517 | // purpose : | |
2518 | // ======================================================================= | |
2519 | OpenGl_VertexBuffer* OpenGl_View::initBlitQuad (const Standard_Boolean theToFlip) | |
2520 | { | |
2521 | OpenGl_VertexBuffer* aVerts = NULL; | |
2522 | if (!theToFlip) | |
2523 | { | |
2524 | aVerts = &myFullScreenQuad; | |
2525 | if (!aVerts->IsValid()) | |
2526 | { | |
2527 | OpenGl_Vec4 aQuad[4] = | |
2528 | { | |
2529 | OpenGl_Vec4( 1.0f, -1.0f, 1.0f, 0.0f), | |
2530 | OpenGl_Vec4( 1.0f, 1.0f, 1.0f, 1.0f), | |
2531 | OpenGl_Vec4(-1.0f, -1.0f, 0.0f, 0.0f), | |
2532 | OpenGl_Vec4(-1.0f, 1.0f, 0.0f, 1.0f) | |
2533 | }; | |
2534 | aVerts->Init (myWorkspace->GetGlContext(), 4, 4, aQuad[0].GetData()); | |
2535 | } | |
2536 | } | |
2537 | else | |
2538 | { | |
2539 | aVerts = &myFullScreenQuadFlip; | |
2540 | if (!aVerts->IsValid()) | |
2541 | { | |
2542 | OpenGl_Vec4 aQuad[4] = | |
2543 | { | |
2544 | OpenGl_Vec4( 1.0f, -1.0f, 1.0f, 1.0f), | |
2545 | OpenGl_Vec4( 1.0f, 1.0f, 1.0f, 0.0f), | |
2546 | OpenGl_Vec4(-1.0f, -1.0f, 0.0f, 1.0f), | |
2547 | OpenGl_Vec4(-1.0f, 1.0f, 0.0f, 0.0f) | |
2548 | }; | |
2549 | aVerts->Init (myWorkspace->GetGlContext(), 4, 4, aQuad[0].GetData()); | |
2550 | } | |
2551 | } | |
2552 | return aVerts; | |
2553 | } | |
2554 | ||
2555 | // ======================================================================= | |
2556 | // function : blitBuffers | |
2557 | // purpose : | |
2558 | // ======================================================================= | |
2559 | bool OpenGl_View::blitBuffers (OpenGl_FrameBuffer* theReadFbo, | |
2560 | OpenGl_FrameBuffer* theDrawFbo, | |
2561 | const Standard_Boolean theToFlip) | |
2562 | { | |
2563 | Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext(); | |
2564 | const Standard_Integer aReadSizeX = theReadFbo != NULL ? theReadFbo->GetVPSizeX() : myWindow->Width(); | |
2565 | const Standard_Integer aReadSizeY = theReadFbo != NULL ? theReadFbo->GetVPSizeY() : myWindow->Height(); | |
2566 | const Standard_Integer aDrawSizeX = theDrawFbo != NULL ? theDrawFbo->GetVPSizeX() : myWindow->Width(); | |
2567 | const Standard_Integer aDrawSizeY = theDrawFbo != NULL ? theDrawFbo->GetVPSizeY() : myWindow->Height(); | |
2568 | if (theReadFbo == NULL || aCtx->IsFeedback()) | |
2569 | { | |
2570 | return false; | |
2571 | } | |
2572 | else if (theReadFbo == theDrawFbo) | |
2573 | { | |
2574 | return true; | |
2575 | } | |
2576 | ||
2577 | // clear destination before blitting | |
2578 | if (theDrawFbo != NULL | |
2579 | && theDrawFbo->IsValid()) | |
2580 | { | |
2581 | theDrawFbo->BindBuffer (aCtx); | |
2582 | } | |
2583 | else | |
2584 | { | |
2585 | aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER); | |
2586 | aCtx->SetFrameBufferSRGB (false); | |
2587 | } | |
2588 | const Standard_Integer aViewport[4] = { 0, 0, aDrawSizeX, aDrawSizeY }; | |
2589 | aCtx->ResizeViewport (aViewport); | |
2590 | ||
2591 | aCtx->SetColorMaskRGBA (NCollection_Vec4<bool> (true)); // force writes into all components, including alpha | |
2592 | aCtx->core20fwd->glClearDepth (1.0); | |
57357010 | 2593 | aCtx->core20fwd->glClearColor (0.0f, 0.0f, 0.0f, aCtx->caps->buffersOpaqueAlpha ? 1.0f : 0.0f); |
cfb54c0c | 2594 | aCtx->core20fwd->glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
2595 | aCtx->SetColorMask (true); // restore default alpha component write state | |
2596 | ||
2597 | const bool toApplyGamma = aCtx->ToRenderSRGB() != aCtx->IsFrameBufferSRGB(); | |
2598 | if (aCtx->arbFBOBlit != NULL | |
2599 | && !toApplyGamma | |
2600 | && theReadFbo->NbSamples() != 0) | |
2601 | { | |
2602 | GLbitfield aCopyMask = 0; | |
2603 | theReadFbo->BindReadBuffer (aCtx); | |
2604 | if (theDrawFbo != NULL | |
2605 | && theDrawFbo->IsValid()) | |
2606 | { | |
2607 | theDrawFbo->BindDrawBuffer (aCtx); | |
2608 | if (theDrawFbo->HasColor() | |
2609 | && theReadFbo->HasColor()) | |
2610 | { | |
2611 | aCopyMask |= GL_COLOR_BUFFER_BIT; | |
2612 | } | |
2613 | if (theDrawFbo->HasDepth() | |
2614 | && theReadFbo->HasDepth()) | |
2615 | { | |
2616 | aCopyMask |= GL_DEPTH_BUFFER_BIT; | |
2617 | } | |
2618 | } | |
2619 | else | |
2620 | { | |
2621 | if (theReadFbo->HasColor()) | |
2622 | { | |
2623 | aCopyMask |= GL_COLOR_BUFFER_BIT; | |
2624 | } | |
2625 | if (theReadFbo->HasDepth()) | |
2626 | { | |
2627 | aCopyMask |= GL_DEPTH_BUFFER_BIT; | |
2628 | } | |
2629 | aCtx->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER); | |
2630 | aCtx->SetFrameBufferSRGB (false); | |
2631 | } | |
2632 | ||
2633 | // we don't copy stencil buffer here... does it matter for performance? | |
2634 | aCtx->arbFBOBlit->glBlitFramebuffer (0, 0, aReadSizeX, aReadSizeY, | |
2635 | 0, 0, aDrawSizeX, aDrawSizeY, | |
2636 | aCopyMask, GL_NEAREST); | |
a46ab511 | 2637 | const int anErr = aCtx->core11fwd->glGetError(); |
cfb54c0c | 2638 | if (anErr != GL_NO_ERROR) |
2639 | { | |
2640 | // glBlitFramebuffer() might fail in several cases: | |
2641 | // - Both FBOs have MSAA and they are samples number does not match. | |
2642 | // OCCT checks that this does not happen, | |
2643 | // however some graphics drivers provide an option for overriding MSAA. | |
2644 | // In this case window MSAA might be non-zero (and application can not check it) | |
2645 | // and might not match MSAA of our offscreen FBOs. | |
2646 | // - Pixel formats of FBOs do not match. | |
2647 | // This also might happen with window has pixel format, | |
2648 | // e.g. Mesa fails blitting RGBA8 -> RGB8 while other drivers support this conversion. | |
a46ab511 | 2649 | TCollection_ExtendedString aMsg = TCollection_ExtendedString() + "FBO blitting has failed [Error " + OpenGl_Context::FormatGlError (anErr) + "]\n" |
cfb54c0c | 2650 | + " Please check your graphics driver settings or try updating driver."; |
2651 | if (theReadFbo->NbSamples() != 0) | |
2652 | { | |
2653 | myToDisableMSAA = true; | |
2654 | aMsg += "\n MSAA settings should not be overridden by driver!"; | |
2655 | } | |
a46ab511 | 2656 | aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg); |
cfb54c0c | 2657 | } |
2658 | ||
2659 | if (theDrawFbo != NULL | |
2660 | && theDrawFbo->IsValid()) | |
2661 | { | |
2662 | theDrawFbo->BindBuffer (aCtx); | |
2663 | } | |
2664 | else | |
2665 | { | |
2666 | aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER); | |
2667 | aCtx->SetFrameBufferSRGB (false); | |
2668 | } | |
2669 | } | |
2670 | else | |
2671 | { | |
2672 | aCtx->core20fwd->glDepthFunc (GL_ALWAYS); | |
2673 | aCtx->core20fwd->glDepthMask (GL_TRUE); | |
2674 | aCtx->core20fwd->glEnable (GL_DEPTH_TEST); | |
2675 | #if defined(GL_ES_VERSION_2_0) | |
2676 | if (!aCtx->IsGlGreaterEqual (3, 0) | |
2677 | && !aCtx->extFragDepth) | |
2678 | { | |
2679 | aCtx->core20fwd->glDisable (GL_DEPTH_TEST); | |
2680 | } | |
2681 | #endif | |
2682 | ||
2683 | aCtx->BindTextures (Handle(OpenGl_TextureSet)(), Handle(OpenGl_ShaderProgram)()); | |
2684 | ||
2685 | const Graphic3d_TypeOfTextureFilter aFilter = (aDrawSizeX == aReadSizeX && aDrawSizeY == aReadSizeY) ? Graphic3d_TOTF_NEAREST : Graphic3d_TOTF_BILINEAR; | |
2686 | const GLint aFilterGl = aFilter == Graphic3d_TOTF_NEAREST ? GL_NEAREST : GL_LINEAR; | |
2687 | ||
2688 | OpenGl_VertexBuffer* aVerts = initBlitQuad (theToFlip); | |
2689 | const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager(); | |
2690 | if (aVerts->IsValid() | |
2691 | && aManager->BindFboBlitProgram (theReadFbo != NULL ? theReadFbo->NbSamples() : 0, toApplyGamma)) | |
2692 | { | |
2693 | aCtx->SetSampleAlphaToCoverage (false); | |
2694 | theReadFbo->ColorTexture()->Bind (aCtx, Graphic3d_TextureUnit_0); | |
2695 | if (theReadFbo->ColorTexture()->Sampler()->Parameters()->Filter() != aFilter) | |
2696 | { | |
2697 | theReadFbo->ColorTexture()->Sampler()->Parameters()->SetFilter (aFilter); | |
2698 | aCtx->core20fwd->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterGl); | |
2699 | aCtx->core20fwd->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilterGl); | |
2700 | } | |
2701 | ||
2702 | theReadFbo->DepthStencilTexture()->Bind (aCtx, Graphic3d_TextureUnit_1); | |
2703 | if (theReadFbo->DepthStencilTexture()->Sampler()->Parameters()->Filter() != aFilter) | |
2704 | { | |
2705 | theReadFbo->DepthStencilTexture()->Sampler()->Parameters()->SetFilter (aFilter); | |
2706 | aCtx->core20fwd->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterGl); | |
2707 | aCtx->core20fwd->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilterGl); | |
2708 | } | |
2709 | ||
2710 | aVerts->BindVertexAttrib (aCtx, Graphic3d_TOA_POS); | |
2711 | ||
2712 | aCtx->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); | |
2713 | ||
2714 | aVerts->UnbindVertexAttrib (aCtx, Graphic3d_TOA_POS); | |
2715 | theReadFbo->DepthStencilTexture()->Unbind (aCtx, Graphic3d_TextureUnit_1); | |
2716 | theReadFbo->ColorTexture() ->Unbind (aCtx, Graphic3d_TextureUnit_0); | |
2717 | aCtx->BindProgram (NULL); | |
2718 | } | |
2719 | else | |
2720 | { | |
2721 | TCollection_ExtendedString aMsg = TCollection_ExtendedString() | |
2722 | + "Error! FBO blitting has failed"; | |
2723 | aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, | |
2724 | GL_DEBUG_TYPE_ERROR, | |
2725 | 0, | |
2726 | GL_DEBUG_SEVERITY_HIGH, | |
2727 | aMsg); | |
2728 | myHasFboBlit = Standard_False; | |
2729 | theReadFbo->Release (aCtx.operator->()); | |
2730 | return true; | |
2731 | } | |
2732 | } | |
2733 | return true; | |
2734 | } | |
2735 | ||
2736 | // ======================================================================= | |
2737 | // function : drawStereoPair | |
2738 | // purpose : | |
2739 | // ======================================================================= | |
2740 | void OpenGl_View::drawStereoPair (OpenGl_FrameBuffer* theDrawFbo) | |
2741 | { | |
2742 | const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext(); | |
2743 | bindDefaultFbo (theDrawFbo); | |
2744 | OpenGl_FrameBuffer* aPair[2] = | |
2745 | { | |
2746 | myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL, | |
2747 | myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL | |
2748 | }; | |
2749 | if (aPair[0] == NULL | |
2750 | || aPair[1] == NULL | |
2751 | || !myTransientDrawToFront) | |
2752 | { | |
2753 | aPair[0] = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL; | |
2754 | aPair[1] = myMainSceneFbos[1]->IsValid() ? myMainSceneFbos[1].operator->() : NULL; | |
2755 | } | |
2756 | ||
2757 | if (aPair[0] == NULL | |
2758 | || aPair[1] == NULL) | |
2759 | { | |
2760 | return; | |
2761 | } | |
2762 | ||
2763 | if (aPair[0]->NbSamples() != 0) | |
2764 | { | |
2765 | // resolve MSAA buffers before drawing | |
1220d98e | 2766 | if (!myOpenGlFBO ->InitLazy (aCtx, aPair[0]->GetVPSize(), myFboColorFormat, myFboDepthFormat, 0) |
2767 | || !myOpenGlFBO2->InitLazy (aCtx, aPair[0]->GetVPSize(), myFboColorFormat, 0, 0)) | |
cfb54c0c | 2768 | { |
2769 | aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, | |
2770 | GL_DEBUG_TYPE_ERROR, | |
2771 | 0, | |
2772 | GL_DEBUG_SEVERITY_HIGH, | |
2773 | "Error! Unable to allocate FBO for blitting stereo pair"); | |
2774 | bindDefaultFbo (theDrawFbo); | |
2775 | return; | |
2776 | } | |
2777 | ||
2778 | if (!blitBuffers (aPair[0], myOpenGlFBO .operator->(), Standard_False) | |
2779 | || !blitBuffers (aPair[1], myOpenGlFBO2.operator->(), Standard_False)) | |
2780 | { | |
2781 | bindDefaultFbo (theDrawFbo); | |
2782 | return; | |
2783 | } | |
2784 | ||
2785 | aPair[0] = myOpenGlFBO .operator->(); | |
2786 | aPair[1] = myOpenGlFBO2.operator->(); | |
2787 | bindDefaultFbo (theDrawFbo); | |
2788 | } | |
2789 | ||
2790 | struct | |
2791 | { | |
2792 | Standard_Integer left; | |
2793 | Standard_Integer top; | |
2794 | Standard_Integer right; | |
2795 | Standard_Integer bottom; | |
2796 | Standard_Integer dx() { return right - left; } | |
2797 | Standard_Integer dy() { return bottom - top; } | |
2798 | } aGeom; | |
2799 | ||
2800 | myWindow->PlatformWindow()->Position (aGeom.left, aGeom.top, aGeom.right, aGeom.bottom); | |
2801 | ||
2802 | Standard_Boolean toReverse = myRenderParams.ToReverseStereo; | |
2803 | const Standard_Boolean isOddY = (aGeom.top + aGeom.dy()) % 2 == 1; | |
2804 | const Standard_Boolean isOddX = aGeom.left % 2 == 1; | |
2805 | if (isOddY | |
2806 | && (myRenderParams.StereoMode == Graphic3d_StereoMode_RowInterlaced | |
2807 | || myRenderParams.StereoMode == Graphic3d_StereoMode_ChessBoard)) | |
2808 | { | |
2809 | toReverse = !toReverse; | |
2810 | } | |
2811 | if (isOddX | |
2812 | && (myRenderParams.StereoMode == Graphic3d_StereoMode_ColumnInterlaced | |
2813 | || myRenderParams.StereoMode == Graphic3d_StereoMode_ChessBoard)) | |
2814 | { | |
2815 | toReverse = !toReverse; | |
2816 | } | |
2817 | ||
2818 | if (toReverse) | |
2819 | { | |
2820 | std::swap (aPair[0], aPair[1]); | |
2821 | } | |
2822 | ||
2823 | aCtx->core20fwd->glDepthFunc (GL_ALWAYS); | |
2824 | aCtx->core20fwd->glDepthMask (GL_TRUE); | |
2825 | aCtx->core20fwd->glEnable (GL_DEPTH_TEST); | |
2826 | ||
2827 | aCtx->BindTextures (Handle(OpenGl_TextureSet)(), Handle(OpenGl_ShaderProgram)()); | |
2828 | OpenGl_VertexBuffer* aVerts = initBlitQuad (myToFlipOutput); | |
2829 | ||
2830 | const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager(); | |
2831 | if (aVerts->IsValid() | |
2832 | && aManager->BindStereoProgram (myRenderParams.StereoMode)) | |
2833 | { | |
2834 | if (myRenderParams.StereoMode == Graphic3d_StereoMode_Anaglyph) | |
2835 | { | |
2836 | OpenGl_Mat4 aFilterL, aFilterR; | |
2837 | aFilterL.SetDiagonal (Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f)); | |
2838 | aFilterR.SetDiagonal (Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f)); | |
2839 | switch (myRenderParams.AnaglyphFilter) | |
2840 | { | |
2841 | case Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple: | |
2842 | { | |
2843 | aFilterL.SetRow (0, Graphic3d_Vec4 (1.0f, 0.0f, 0.0f, 0.0f)); | |
2844 | aFilterR.SetRow (1, Graphic3d_Vec4 (0.0f, 1.0f, 0.0f, 0.0f)); | |
2845 | aFilterR.SetRow (2, Graphic3d_Vec4 (0.0f, 0.0f, 1.0f, 0.0f)); | |
2846 | break; | |
2847 | } | |
2848 | case Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized: | |
2849 | { | |
2850 | aFilterL.SetRow (0, Graphic3d_Vec4 ( 0.4154f, 0.4710f, 0.16666667f, 0.0f)); | |
2851 | aFilterL.SetRow (1, Graphic3d_Vec4 (-0.0458f, -0.0484f, -0.0257f, 0.0f)); | |
2852 | aFilterL.SetRow (2, Graphic3d_Vec4 (-0.0547f, -0.0615f, 0.0128f, 0.0f)); | |
2853 | aFilterL.SetRow (3, Graphic3d_Vec4 ( 0.0f, 0.0f, 0.0f, 0.0f)); | |
2854 | aFilterR.SetRow (0, Graphic3d_Vec4 (-0.01090909f, -0.03636364f, -0.00606061f, 0.0f)); | |
2855 | aFilterR.SetRow (1, Graphic3d_Vec4 ( 0.37560000f, 0.73333333f, 0.01111111f, 0.0f)); | |
2856 | aFilterR.SetRow (2, Graphic3d_Vec4 (-0.06510000f, -0.12870000f, 1.29710000f, 0.0f)); | |
2857 | aFilterR.SetRow (3, Graphic3d_Vec4 ( 0.0f, 0.0f, 0.0f, 0.0f)); | |
2858 | break; | |
2859 | } | |
2860 | case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple: | |
2861 | { | |
2862 | aFilterL.SetRow (0, Graphic3d_Vec4 (1.0f, 0.0f, 0.0f, 0.0f)); | |
2863 | aFilterL.SetRow (1, Graphic3d_Vec4 (0.0f, 1.0f, 0.0f, 0.0f)); | |
2864 | aFilterR.SetRow (2, Graphic3d_Vec4 (0.0f, 0.0f, 1.0f, 0.0f)); | |
2865 | break; | |
2866 | } | |
2867 | case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized: | |
2868 | { | |
2869 | aFilterL.SetRow (0, Graphic3d_Vec4 ( 1.062f, -0.205f, 0.299f, 0.0f)); | |
2870 | aFilterL.SetRow (1, Graphic3d_Vec4 (-0.026f, 0.908f, 0.068f, 0.0f)); | |
2871 | aFilterL.SetRow (2, Graphic3d_Vec4 (-0.038f, -0.173f, 0.022f, 0.0f)); | |
2872 | aFilterL.SetRow (3, Graphic3d_Vec4 ( 0.0f, 0.0f, 0.0f, 0.0f)); | |
2873 | aFilterR.SetRow (0, Graphic3d_Vec4 (-0.016f, -0.123f, -0.017f, 0.0f)); | |
2874 | aFilterR.SetRow (1, Graphic3d_Vec4 ( 0.006f, 0.062f, -0.017f, 0.0f)); | |
2875 | aFilterR.SetRow (2, Graphic3d_Vec4 ( 0.094f, 0.185f, 0.911f, 0.0f)); | |
2876 | aFilterR.SetRow (3, Graphic3d_Vec4 ( 0.0f, 0.0f, 0.0f, 0.0f)); | |
2877 | break; | |
2878 | } | |
2879 | case Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple: | |
2880 | { | |
2881 | aFilterR.SetRow (0, Graphic3d_Vec4 (1.0f, 0.0f, 0.0f, 0.0f)); | |
2882 | aFilterL.SetRow (1, Graphic3d_Vec4 (0.0f, 1.0f, 0.0f, 0.0f)); | |
2883 | aFilterR.SetRow (2, Graphic3d_Vec4 (0.0f, 0.0f, 1.0f, 0.0f)); | |
2884 | break; | |
2885 | } | |
2886 | case Graphic3d_RenderingParams::Anaglyph_UserDefined: | |
2887 | { | |
2888 | aFilterL = myRenderParams.AnaglyphLeft; | |
2889 | aFilterR = myRenderParams.AnaglyphRight; | |
2890 | break; | |
2891 | } | |
2892 | } | |
2893 | aCtx->ActiveProgram()->SetUniform (aCtx, "uMultL", aFilterL); | |
2894 | aCtx->ActiveProgram()->SetUniform (aCtx, "uMultR", aFilterR); | |
2895 | } | |
2896 | ||
2897 | aPair[0]->ColorTexture()->Bind (aCtx, Graphic3d_TextureUnit_0); | |
2898 | aPair[1]->ColorTexture()->Bind (aCtx, Graphic3d_TextureUnit_1); | |
2899 | aVerts->BindVertexAttrib (aCtx, 0); | |
2900 | ||
2901 | aCtx->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); | |
2902 | ||
2903 | aVerts->UnbindVertexAttrib (aCtx, 0); | |
2904 | aPair[1]->ColorTexture()->Unbind (aCtx, Graphic3d_TextureUnit_1); | |
2905 | aPair[0]->ColorTexture()->Unbind (aCtx, Graphic3d_TextureUnit_0); | |
2906 | } | |
2907 | else | |
2908 | { | |
2909 | TCollection_ExtendedString aMsg = TCollection_ExtendedString() | |
2910 | + "Error! Anaglyph has failed"; | |
2911 | aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, | |
2912 | GL_DEBUG_TYPE_ERROR, | |
2913 | 0, | |
2914 | GL_DEBUG_SEVERITY_HIGH, | |
2915 | aMsg); | |
2916 | } | |
2917 | } | |
2918 | ||
2919 | // ======================================================================= | |
2920 | // function : copyBackToFront | |
2921 | // purpose : | |
2922 | // ======================================================================= | |
2923 | bool OpenGl_View::copyBackToFront() | |
2924 | { | |
2925 | myIsImmediateDrawn = Standard_False; | |
2926 | #if !defined(GL_ES_VERSION_2_0) | |
2927 | const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext(); | |
43eddb47 | 2928 | if (aCtx->core11ffp == NULL) |
cfb54c0c | 2929 | { |
2930 | return false; | |
2931 | } | |
2932 | ||
2933 | OpenGl_Mat4 aProjectMat; | |
2934 | Graphic3d_TransformUtils::Ortho2D (aProjectMat, | |
2935 | 0.0f, static_cast<GLfloat> (myWindow->Width()), | |
2936 | 0.0f, static_cast<GLfloat> (myWindow->Height())); | |
2937 | ||
2938 | aCtx->WorldViewState.Push(); | |
2939 | aCtx->ProjectionState.Push(); | |
2940 | ||
2941 | aCtx->WorldViewState.SetIdentity(); | |
2942 | aCtx->ProjectionState.SetCurrent (aProjectMat); | |
2943 | ||
2944 | aCtx->ApplyProjectionMatrix(); | |
2945 | aCtx->ApplyWorldViewMatrix(); | |
2946 | ||
2947 | // synchronize FFP state before copying pixels | |
2948 | aCtx->BindProgram (Handle(OpenGl_ShaderProgram)()); | |
2949 | aCtx->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)()); | |
2950 | aCtx->DisableFeatures(); | |
2951 | ||
2952 | switch (aCtx->DrawBuffer()) | |
2953 | { | |
2954 | case GL_BACK_LEFT: | |
2955 | { | |
2956 | aCtx->SetReadBuffer (GL_BACK_LEFT); | |
2957 | aCtx->SetDrawBuffer (GL_FRONT_LEFT); | |
2958 | break; | |
2959 | } | |
2960 | case GL_BACK_RIGHT: | |
2961 | { | |
2962 | aCtx->SetReadBuffer (GL_BACK_RIGHT); | |
2963 | aCtx->SetDrawBuffer (GL_FRONT_RIGHT); | |
2964 | break; | |
2965 | } | |
2966 | default: | |
2967 | { | |
2968 | aCtx->SetReadBuffer (GL_BACK); | |
2969 | aCtx->SetDrawBuffer (GL_FRONT); | |
2970 | break; | |
2971 | } | |
2972 | } | |
2973 | ||
43eddb47 | 2974 | aCtx->core11ffp->glRasterPos2i (0, 0); |
2975 | aCtx->core11ffp->glCopyPixels (0, 0, myWindow->Width() + 1, myWindow->Height() + 1, GL_COLOR); | |
2976 | //aCtx->core11ffp->glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_DEPTH); | |
cfb54c0c | 2977 | |
2978 | aCtx->EnableFeatures(); | |
2979 | ||
2980 | aCtx->WorldViewState.Pop(); | |
2981 | aCtx->ProjectionState.Pop(); | |
2982 | aCtx->ApplyProjectionMatrix(); | |
2983 | ||
2984 | // read/write from front buffer now | |
2985 | aCtx->SetReadBuffer (aCtx->DrawBuffer()); | |
2986 | return true; | |
2987 | #else | |
2988 | return false; | |
2989 | #endif | |
2990 | } | |
2991 | ||
2992 | // ======================================================================= | |
2993 | // function : checkOitCompatibility | |
2994 | // purpose : | |
2995 | // ======================================================================= | |
2996 | Standard_Boolean OpenGl_View::checkOitCompatibility (const Handle(OpenGl_Context)& theGlContext, | |
2997 | const Standard_Boolean theMSAA) | |
2998 | { | |
2999 | // determine if OIT is supported by current OpenGl context | |
3000 | Standard_Boolean& aToDisableOIT = theMSAA ? myToDisableMSAA : myToDisableOIT; | |
3001 | if (aToDisableOIT) | |
3002 | { | |
3003 | return Standard_False; | |
3004 | } | |
3005 | ||
3006 | TCollection_ExtendedString aCompatibilityMsg; | |
3007 | if (theGlContext->hasFloatBuffer == OpenGl_FeatureNotAvailable | |
3008 | && theGlContext->hasHalfFloatBuffer == OpenGl_FeatureNotAvailable) | |
3009 | { | |
3010 | aCompatibilityMsg += "OpenGL context does not support floating-point RGBA color buffer format.\n"; | |
3011 | } | |
3012 | if (theMSAA && theGlContext->hasSampleVariables == OpenGl_FeatureNotAvailable) | |
3013 | { | |
3014 | aCompatibilityMsg += "Current version of GLSL does not support built-in sample variables.\n"; | |
3015 | } | |
3016 | if (theGlContext->hasDrawBuffers == OpenGl_FeatureNotAvailable) | |
3017 | { | |
3018 | aCompatibilityMsg += "OpenGL context does not support multiple draw buffers.\n"; | |
3019 | } | |
3020 | if (aCompatibilityMsg.IsEmpty()) | |
3021 | { | |
3022 | return Standard_True; | |
3023 | } | |
3024 | ||
3025 | aCompatibilityMsg += " Blended order-independent transparency will not be available.\n"; | |
3026 | theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, | |
3027 | GL_DEBUG_TYPE_ERROR, | |
3028 | 0, | |
3029 | GL_DEBUG_SEVERITY_HIGH, | |
3030 | aCompatibilityMsg); | |
3031 | ||
3032 | aToDisableOIT = Standard_True; | |
3033 | return Standard_False; | |
3034 | } | |
3035 | ||
cfb54c0c | 3036 | // ======================================================================= |
3037 | // function : checkPBRAvailability | |
3038 | // purpose : | |
3039 | // ======================================================================= | |
3040 | Standard_Boolean OpenGl_View::checkPBRAvailability() const | |
3041 | { | |
3042 | return myWorkspace->GetGlContext()->HasPBR() | |
3043 | && !myPBREnvironment.IsNull(); | |
3044 | } | |
3045 | ||
3046 | // ======================================================================= | |
3047 | // function : bakePBREnvironment | |
3048 | // purpose : | |
3049 | // ======================================================================= | |
3050 | void OpenGl_View::bakePBREnvironment (const Handle(OpenGl_Context)& theCtx) | |
3051 | { | |
3052 | const Handle(OpenGl_TextureSet)& aTextureSet = myCubeMapParams->TextureSet (theCtx); | |
3053 | if (!aTextureSet.IsNull() | |
3054 | && !aTextureSet->IsEmpty()) | |
3055 | { | |
3056 | myPBREnvironment->Bake (theCtx, | |
3057 | aTextureSet->First(), | |
3058 | myBackgroundCubeMap->ZIsInverted(), | |
3059 | myBackgroundCubeMap->IsTopDown(), | |
3060 | myRenderParams.PbrEnvBakingDiffNbSamples, | |
3061 | myRenderParams.PbrEnvBakingSpecNbSamples, | |
3062 | myRenderParams.PbrEnvBakingProbability); | |
3063 | } | |
3064 | else | |
3065 | { | |
3066 | myPBREnvironment->Clear (theCtx); | |
3067 | } | |
3068 | } | |
3069 | ||
3070 | // ======================================================================= | |
3071 | // function : clearPBREnvironment | |
3072 | // purpose : | |
3073 | // ======================================================================= | |
3074 | void OpenGl_View::clearPBREnvironment (const Handle(OpenGl_Context)& theCtx) | |
3075 | { | |
3076 | myPBREnvironment->Clear (theCtx); | |
3077 | } | |
3078 | ||
3079 | // ======================================================================= | |
3080 | // function : clearPBREnvironment | |
3081 | // purpose : | |
3082 | // ======================================================================= | |
3083 | void OpenGl_View::processPBREnvRequest (const Handle(OpenGl_Context)& theCtx) | |
3084 | { | |
3085 | if (myPBREnvState == OpenGl_PBREnvState_CREATED) | |
3086 | { | |
3087 | switch (myPBREnvRequest) | |
3088 | { | |
3089 | case OpenGl_PBREnvRequest_NONE: return; | |
3090 | case OpenGl_PBREnvRequest_BAKE: bakePBREnvironment (theCtx); break; | |
3091 | case OpenGl_PBREnvRequest_CLEAR: clearPBREnvironment (theCtx); break; | |
3092 | } | |
3093 | } | |
3094 | myPBREnvRequest = OpenGl_PBREnvRequest_NONE; | |
3095 | } |