1 // Created on: 2011-09-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OpenGl_GlCore15.hxx>
17 #include <OpenGl_ArbFBO.hxx>
19 #include <InterfaceGraphic.hxx>
21 #include <OpenGl_AspectLine.hxx>
22 #include <OpenGl_AspectFace.hxx>
23 #include <OpenGl_AspectMarker.hxx>
24 #include <OpenGl_AspectText.hxx>
25 #include <OpenGl_Context.hxx>
26 #include <OpenGl_Element.hxx>
27 #include <OpenGl_FrameBuffer.hxx>
28 #include <OpenGl_Structure.hxx>
29 #include <OpenGl_Sampler.hxx>
30 #include <OpenGl_ShaderManager.hxx>
31 #include <OpenGl_Texture.hxx>
32 #include <OpenGl_Utils.hxx>
33 #include <OpenGl_View.hxx>
34 #include <OpenGl_Workspace.hxx>
36 #include <Graphic3d_TextureParams.hxx>
38 #if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
39 #include <OpenGl_AVIWriter.hxx>
42 IMPLEMENT_STANDARD_HANDLE(OpenGl_Workspace,OpenGl_Window)
43 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Workspace,OpenGl_Window)
47 static const TEL_COLOUR THE_WHITE_COLOR = { { 1.0f, 1.0f, 1.0f, 1.0f } };
48 static const OpenGl_Vec4 THE_BLACK_COLOR (0.0f, 0.0f, 0.0f, 1.0f);
50 static const OpenGl_AspectLine myDefaultAspectLine;
51 static const OpenGl_AspectFace myDefaultAspectFace;
52 static const OpenGl_AspectMarker myDefaultAspectMarker;
53 static const OpenGl_AspectText myDefaultAspectText;
55 static const OpenGl_TextParam myDefaultTextParam =
57 16, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM
60 static const OpenGl_Matrix myDefaultMatrix =
62 {{ 1.0F, 0.0F, 0.0F, 0.0F },
63 { 0.0F, 1.0F, 0.0F, 0.0F },
64 { 0.0F, 0.0F, 1.0F, 0.0F },
65 { 0.0F, 0.0F, 0.0F, 1.0F }}
70 // =======================================================================
73 // =======================================================================
74 void OpenGl_Material::Init (const OPENGL_SURF_PROP& theProp)
77 if (theProp.color_mask & OPENGL_AMBIENT_MASK)
79 const float* aSrcAmb = theProp.isphysic ? theProp.ambcol.rgb : theProp.matcol.rgb;
80 Ambient = OpenGl_Vec4 (aSrcAmb[0] * theProp.amb,
81 aSrcAmb[1] * theProp.amb,
82 aSrcAmb[2] * theProp.amb,
87 Ambient = THE_BLACK_COLOR;
90 // diffusion component
91 if (theProp.color_mask & OPENGL_DIFFUSE_MASK)
93 const float* aSrcDif = theProp.isphysic ? theProp.difcol.rgb : theProp.matcol.rgb;
94 Diffuse = OpenGl_Vec4 (aSrcDif[0] * theProp.diff,
95 aSrcDif[1] * theProp.diff,
96 aSrcDif[2] * theProp.diff,
101 Diffuse = THE_BLACK_COLOR;
104 // specular component
105 if (theProp.color_mask & OPENGL_SPECULAR_MASK)
107 const float* aSrcSpe = theProp.isphysic ? theProp.speccol.rgb : THE_WHITE_COLOR.rgb;
108 Specular = OpenGl_Vec4 (aSrcSpe[0] * theProp.spec,
109 aSrcSpe[1] * theProp.spec,
110 aSrcSpe[2] * theProp.spec,
115 Specular = THE_BLACK_COLOR;
118 // emission component
119 if (theProp.color_mask & OPENGL_EMISSIVE_MASK)
121 const float* aSrcEms = theProp.isphysic ? theProp.emscol.rgb : theProp.matcol.rgb;
122 Emission = OpenGl_Vec4 (aSrcEms[0] * theProp.emsv,
123 aSrcEms[1] * theProp.emsv,
124 aSrcEms[2] * theProp.emsv,
129 Emission = THE_BLACK_COLOR;
132 ChangeShine() = theProp.shine;
133 ChangeTransparency() = theProp.trans;
136 // =======================================================================
137 // function : OpenGl_Workspace
139 // =======================================================================
140 OpenGl_Workspace::OpenGl_Workspace (const Handle(OpenGl_GraphicDriver)& theDriver,
141 const CALL_DEF_WINDOW& theCWindow,
142 Aspect_RenderingContext theGContext,
143 const Handle(OpenGl_Caps)& theCaps,
144 const Handle(OpenGl_Context)& theShareCtx)
145 : OpenGl_Window (theDriver, theCWindow, theGContext, theCaps, theShareCtx),
147 HighlightColor (&THE_WHITE_COLOR),
149 myHasFboBlit (Standard_True),
152 myAntiAliasingMode (3),
153 myTransientDrawToFront (Standard_True),
154 myBackBufferRestored (Standard_False),
155 myIsImmediateDrawn (Standard_False),
156 myUseZBuffer (Standard_False),
157 myUseDepthTest (Standard_True),
158 myUseGLLight (Standard_True),
159 myIsCullingEnabled (Standard_False),
162 AspectLine_set (&myDefaultAspectLine),
163 AspectLine_applied (NULL),
164 AspectFace_set (&myDefaultAspectFace),
165 AspectFace_applied (NULL),
166 AspectMarker_set (&myDefaultAspectMarker),
167 AspectMarker_applied (NULL),
168 AspectText_set (&myDefaultAspectText),
169 AspectText_applied (NULL),
170 TextParam_set (&myDefaultTextParam),
171 TextParam_applied (NULL),
172 ViewMatrix_applied (&myDefaultMatrix),
173 StructureMatrix_applied (&myDefaultMatrix),
174 myCullingMode (TelCullUndefined),
175 myModelViewMatrix (myDefaultMatrix),
176 PolygonOffset_applied (THE_DEFAULT_POFFSET)
178 myGlContext->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
179 myMainSceneFbos[0] = new OpenGl_FrameBuffer();
180 myMainSceneFbos[1] = new OpenGl_FrameBuffer();
181 myImmediateSceneFbos[0] = new OpenGl_FrameBuffer();
182 myImmediateSceneFbos[1] = new OpenGl_FrameBuffer();
184 if (!myGlContext->GetResource ("OpenGl_LineAttributes", myLineAttribs))
186 // share and register for release once the resource is no longer used
187 myLineAttribs = new OpenGl_LineAttributes();
188 myGlContext->ShareResource ("OpenGl_LineAttributes", myLineAttribs);
189 myLineAttribs->Init (myGlContext);
192 // General initialization of the context
194 #if !defined(GL_ES_VERSION_2_0)
195 if (myGlContext->core11 != NULL)
197 // Eviter d'avoir les faces mal orientees en noir.
198 // Pourrait etre utiliser pour detecter les problemes d'orientation
199 glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
201 // Optimisation pour le Fog et l'antialiasing
202 glHint (GL_FOG_HINT, GL_FASTEST);
203 glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST);
206 glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST);
207 glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
211 const char* anAaEnv = ::getenv ("CALL_OPENGL_ANTIALIASING_MODE");
215 if (sscanf (anAaEnv, "%d", &v) > 0) myAntiAliasingMode = v;
219 // =======================================================================
220 // function : SetImmediateModeDrawToFront
222 // =======================================================================
223 Standard_Boolean OpenGl_Workspace::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer)
225 const Standard_Boolean aPrevMode = myTransientDrawToFront;
226 myTransientDrawToFront = theDrawToFrontBuffer;
230 inline void nullifyGlResource (Handle(OpenGl_Resource)& theResource,
231 const Handle(OpenGl_Context)& theCtx)
233 if (!theResource.IsNull())
235 theResource->Release (theCtx.operator->());
236 theResource.Nullify();
240 // =======================================================================
241 // function : ~OpenGl_Workspace
243 // =======================================================================
244 OpenGl_Workspace::~OpenGl_Workspace()
246 if (!myLineAttribs.IsNull())
248 myLineAttribs.Nullify();
249 myGlContext->ReleaseResource ("OpenGl_LineAttributes", Standard_True);
252 nullifyGlResource (myMainSceneFbos[0], myGlContext);
253 nullifyGlResource (myMainSceneFbos[1], myGlContext);
254 nullifyGlResource (myImmediateSceneFbos[0], myGlContext);
255 nullifyGlResource (myImmediateSceneFbos[1], myGlContext);
257 myFullScreenQuad.Release (myGlContext.operator->());
260 // =======================================================================
261 // function : Activate
263 // =======================================================================
264 Standard_Boolean OpenGl_Workspace::Activate()
266 if (!OpenGl_Window::Activate())
267 return Standard_False;
269 ViewMatrix_applied = &myDefaultMatrix;
270 StructureMatrix_applied = &myDefaultMatrix;
272 ResetAppliedAspect();
274 return Standard_True;
277 //=======================================================================
278 //function : ResetAppliedAspect
279 //purpose : Sets default values of GL parameters in accordance with default aspects
280 //=======================================================================
281 void OpenGl_Workspace::ResetAppliedAspect()
283 myGlContext->BindDefaultVao();
285 NamedStatus = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0;
286 HighlightColor = &THE_WHITE_COLOR;
287 AspectLine_set = &myDefaultAspectLine;
288 AspectLine_applied = NULL;
289 AspectFace_set = &myDefaultAspectFace;
290 AspectFace_applied = NULL;
291 AspectMarker_set = &myDefaultAspectMarker;
292 AspectMarker_applied = NULL;
293 AspectText_set = &myDefaultAspectText;
294 AspectText_applied = NULL;
295 TextParam_set = &myDefaultTextParam;
296 TextParam_applied = NULL;
297 PolygonOffset_applied = THE_DEFAULT_POFFSET;
298 myCullingMode = TelCullUndefined;
300 AspectLine(Standard_True);
301 AspectFace(Standard_True);
302 AspectMarker(Standard_True);
303 AspectText(Standard_True);
306 // =======================================================================
307 // function : DisableTexture
309 // =======================================================================
310 Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
312 if (myTextureBound.IsNull())
314 return myTextureBound;
317 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
318 if (!aSampler.IsNull())
320 aSampler->Unbind (*myGlContext);
323 #if !defined(GL_ES_VERSION_2_0)
324 // reset texture matrix because some code may expect it is identity
325 if (myGlContext->core11 != NULL)
327 GLint aMatrixMode = GL_TEXTURE;
328 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
329 glMatrixMode (GL_TEXTURE);
331 glMatrixMode (aMatrixMode);
335 myTextureBound->Unbind (myGlContext);
336 switch (myTextureBound->GetTarget())
338 #if !defined(GL_ES_VERSION_2_0)
341 if (myGlContext->core11 != NULL)
343 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
345 glDisable (GL_TEXTURE_GEN_S);
347 glDisable (GL_TEXTURE_1D);
354 #if !defined(GL_ES_VERSION_2_0)
355 if (myGlContext->core11 != NULL)
357 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
359 glDisable (GL_TEXTURE_GEN_S);
360 glDisable (GL_TEXTURE_GEN_T);
361 if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE)
363 glDisable (GL_POINT_SPRITE);
366 glDisable (GL_TEXTURE_2D);
374 Handle(OpenGl_Texture) aPrevTexture = myTextureBound;
375 myTextureBound.Nullify();
379 // =======================================================================
380 // function : setTextureParams
382 // =======================================================================
383 void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& theTexture,
384 const Handle(Graphic3d_TextureParams)& theParams)
386 const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams;
387 if (aParams.IsNull())
392 #if !defined(GL_ES_VERSION_2_0)
393 GLint aMatrixMode = GL_TEXTURE;
394 if (myGlContext->core11 != NULL)
396 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
398 // setup texture matrix
399 glMatrixMode (GL_TEXTURE);
400 OpenGl_Mat4 aTextureMat;
401 const Graphic3d_Vec2& aScale = aParams->Scale();
402 const Graphic3d_Vec2& aTrans = aParams->Translation();
403 OpenGl_Utils::Scale (aTextureMat, aScale.x(), aScale.y(), 1.0f);
404 OpenGl_Utils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f);
405 OpenGl_Utils::Rotate (aTextureMat, -aParams->Rotation(), 0.0f, 0.0f, 1.0f);
406 glLoadMatrixf (aTextureMat);
408 GLint anEnvMode = GL_MODULATE; // lighting mode
409 if (!aParams->IsModulate())
411 anEnvMode = GL_DECAL;
412 if (theTexture->GetFormat() == GL_ALPHA
413 || theTexture->GetFormat() == GL_LUMINANCE)
415 anEnvMode = GL_REPLACE;
419 // setup generation of texture coordinates
420 switch (aParams->GenMode())
422 case Graphic3d_TOTM_OBJECT:
424 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
425 glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData());
426 if (theTexture->GetTarget() != GL_TEXTURE_1D)
428 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
429 glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData());
433 case Graphic3d_TOTM_SPHERE:
435 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
436 if (theTexture->GetTarget() != GL_TEXTURE_1D)
438 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
442 case Graphic3d_TOTM_EYE:
444 myGlContext->WorldViewState.Push();
446 myGlContext->WorldViewState.SetIdentity();
447 myGlContext->ApplyWorldViewMatrix();
449 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
450 glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData());
452 if (theTexture->GetTarget() != GL_TEXTURE_1D)
454 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
455 glTexGenfv (GL_T, GL_EYE_PLANE, aParams->GenPlaneT().GetData());
458 myGlContext->WorldViewState.Pop();
462 case Graphic3d_TOTM_SPRITE:
464 if (GetGlContext()->core20fwd != NULL)
466 glEnable (GL_POINT_SPRITE);
467 glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
468 anEnvMode = GL_REPLACE;
469 GetGlContext()->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
473 case Graphic3d_TOTM_MANUAL:
478 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
482 // get active sampler object to override default texture parameters
483 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
485 // setup texture filtering and wrapping
486 //if (theTexture->GetParams() != theParams)
487 const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
488 const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : myGlContext->TextureWrapClamp();
489 switch (theTexture->GetTarget())
491 #if !defined(GL_ES_VERSION_2_0)
494 if (aSampler.IsNull() || !aSampler->IsValid())
496 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
497 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
498 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
502 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
503 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilter);
504 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
512 GLenum aFilterMin = aFilter;
513 if (theTexture->HasMipmaps())
515 aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
516 if (aParams->Filter() == Graphic3d_TOTF_BILINEAR)
518 aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
520 else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR)
522 aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
525 if (myGlContext->extAnis)
527 // setup degree of anisotropy filter
528 const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
530 switch (aParams->AnisoFilter())
532 case Graphic3d_LOTA_QUALITY:
534 aDegree = aMaxDegree;
537 case Graphic3d_LOTA_MIDDLE:
539 aDegree = (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2);
542 case Graphic3d_LOTA_FAST:
547 case Graphic3d_LOTA_OFF:
555 if (aSampler.IsNull() || !aSampler->IsValid())
557 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
561 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
566 if (aSampler.IsNull() || !aSampler->IsValid())
568 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
569 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
570 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
571 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
575 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilterMin);
576 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
577 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
578 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_T, aWrapMode);
586 switch (theTexture->GetTarget())
588 #if !defined(GL_ES_VERSION_2_0)
591 if (myGlContext->core11 != NULL)
593 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
595 glEnable (GL_TEXTURE_GEN_S);
597 glEnable (GL_TEXTURE_1D);
604 #if !defined(GL_ES_VERSION_2_0)
605 if (myGlContext->core11 != NULL)
607 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
609 glEnable (GL_TEXTURE_GEN_S);
610 glEnable (GL_TEXTURE_GEN_T);
612 glEnable (GL_TEXTURE_2D);
620 #if !defined(GL_ES_VERSION_2_0)
621 if (myGlContext->core11 != NULL)
623 glMatrixMode (aMatrixMode); // turn back active matrix
626 theTexture->SetParams (aParams);
629 // =======================================================================
630 // function : EnableTexture
632 // =======================================================================
633 Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture,
634 const Handle(Graphic3d_TextureParams)& theParams)
636 if (theTexture.IsNull() || !theTexture->IsValid())
638 return DisableTexture();
641 if (myTextureBound == theTexture
642 && (theParams.IsNull() || theParams == theTexture->GetParams()))
645 return myTextureBound;
648 Handle(OpenGl_Texture) aPrevTexture = DisableTexture();
649 myTextureBound = theTexture;
650 myTextureBound->Bind (myGlContext);
651 setTextureParams (myTextureBound, theParams);
653 // If custom sampler object is available it will be
654 // used for overriding default texture parameters
655 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
657 if (!aSampler.IsNull() && aSampler->IsValid())
659 aSampler->Bind (*myGlContext);
665 // =======================================================================
666 // function : bindDefaultFbo
668 // =======================================================================
669 void OpenGl_Workspace::bindDefaultFbo (OpenGl_FrameBuffer* theCustomFbo)
671 OpenGl_FrameBuffer* anFbo = (theCustomFbo != NULL && theCustomFbo->IsValid())
673 : (!myGlContext->DefaultFrameBuffer().IsNull()
674 && myGlContext->DefaultFrameBuffer()->IsValid()
675 ? myGlContext->DefaultFrameBuffer().operator->()
679 anFbo->BindBuffer (myGlContext);
683 #if !defined(GL_ES_VERSION_2_0)
684 myGlContext->SetReadDrawBuffer (GL_BACK);
686 if (myGlContext->arbFBO != NULL)
688 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
692 myGlContext->core11fwd->glViewport (0, 0, myWidth, myHeight);
695 // =======================================================================
696 // function : blitBuffers
698 // =======================================================================
699 bool OpenGl_Workspace::blitBuffers (OpenGl_FrameBuffer* theReadFbo,
700 OpenGl_FrameBuffer* theDrawFbo)
702 if (theReadFbo == NULL)
707 // clear destination before blitting
708 if (theDrawFbo != NULL
709 && theDrawFbo->IsValid())
711 theDrawFbo->BindBuffer (myGlContext);
715 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
717 #if !defined(GL_ES_VERSION_2_0)
718 myGlContext->core20fwd->glClearDepth (1.0);
720 myGlContext->core20fwd->glClearDepthf (1.0f);
722 myGlContext->core20fwd->glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
724 /*#if !defined(GL_ES_VERSION_2_0)
725 if (myGlContext->arbFBOBlit != NULL)
727 theReadFbo->BindReadBuffer (myGlContext);
728 if (theDrawFbo != NULL
729 && theDrawFbo->IsValid())
731 theDrawFbo->BindDrawBuffer (myGlContext);
735 myGlContext->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
737 // we don't copy stencil buffer here... does it matter for performance?
738 myGlContext->arbFBOBlit->glBlitFramebuffer (0, 0, theReadFbo->GetVPSizeX(), theReadFbo->GetVPSizeY(),
739 0, 0, theReadFbo->GetVPSizeX(), theReadFbo->GetVPSizeY(),
740 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
742 if (theDrawFbo != NULL
743 && theDrawFbo->IsValid())
745 theDrawFbo->BindBuffer (myGlContext);
749 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
755 myGlContext->core20fwd->glDepthFunc (GL_ALWAYS);
756 myGlContext->core20fwd->glDepthMask (GL_TRUE);
757 myGlContext->core20fwd->glEnable (GL_DEPTH_TEST);
760 if (!myFullScreenQuad.IsValid())
762 OpenGl_Vec4 aQuad[4] =
764 OpenGl_Vec4( 1.0f, -1.0f, 1.0f, 0.0f),
765 OpenGl_Vec4( 1.0f, 1.0f, 1.0f, 1.0f),
766 OpenGl_Vec4(-1.0f, -1.0f, 0.0f, 0.0f),
767 OpenGl_Vec4(-1.0f, 1.0f, 0.0f, 1.0f)
769 myFullScreenQuad.Init (myGlContext, 4, 4, aQuad[0].GetData());
772 const Handle(OpenGl_ShaderManager)& aManager = myGlContext->ShaderManager();
773 if (myFullScreenQuad.IsValid()
774 && aManager->BindFboBlitProgram())
776 theReadFbo->ColorTexture() ->Bind (myGlContext, GL_TEXTURE0 + 0);
777 theReadFbo->DepthStencilTexture()->Bind (myGlContext, GL_TEXTURE0 + 1);
778 myFullScreenQuad.BindVertexAttrib (myGlContext, Graphic3d_TOA_POS);
780 myGlContext->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
782 myFullScreenQuad.UnbindVertexAttrib (myGlContext, Graphic3d_TOA_POS);
783 theReadFbo->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + 1);
784 theReadFbo->ColorTexture() ->Unbind (myGlContext, GL_TEXTURE0 + 0);
788 TCollection_ExtendedString aMsg = TCollection_ExtendedString()
789 + "Error! FBO blitting has failed";
790 myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
791 GL_DEBUG_TYPE_ERROR_ARB,
793 GL_DEBUG_SEVERITY_HIGH_ARB,
795 myHasFboBlit = Standard_False;
796 theReadFbo->Release (myGlContext.operator->());
803 // =======================================================================
804 // function : drawStereoPair
806 // =======================================================================
807 void OpenGl_Workspace::drawStereoPair()
809 OpenGl_FrameBuffer* aPair[2] =
811 myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL,
812 myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL
817 aPair[0] = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL;
818 aPair[1] = myMainSceneFbos[1]->IsValid() ? myMainSceneFbos[1].operator->() : NULL;
827 myGlContext->core20fwd->glDepthFunc (GL_ALWAYS);
828 myGlContext->core20fwd->glDepthMask (GL_TRUE);
829 myGlContext->core20fwd->glEnable (GL_DEPTH_TEST);
832 if (!myFullScreenQuad.IsValid())
834 OpenGl_Vec4 aQuad[4] =
836 OpenGl_Vec4( 1.0f, -1.0f, 1.0f, 0.0f),
837 OpenGl_Vec4( 1.0f, 1.0f, 1.0f, 1.0f),
838 OpenGl_Vec4(-1.0f, -1.0f, 0.0f, 0.0f),
839 OpenGl_Vec4(-1.0f, 1.0f, 0.0f, 1.0f)
841 myFullScreenQuad.Init (myGlContext, 4, 4, aQuad[0].GetData());
844 const Handle(OpenGl_ShaderManager)& aManager = myGlContext->ShaderManager();
845 if (myFullScreenQuad.IsValid()
846 && aManager->BindAnaglyphProgram())
848 aPair[0]->ColorTexture()->Bind (myGlContext, GL_TEXTURE0 + 0);
849 aPair[1]->ColorTexture()->Bind (myGlContext, GL_TEXTURE0 + 1);
850 myFullScreenQuad.BindVertexAttrib (myGlContext, 0);
852 myGlContext->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
854 myFullScreenQuad.UnbindVertexAttrib (myGlContext, 0);
855 aPair[1]->ColorTexture()->Unbind (myGlContext, GL_TEXTURE0 + 1);
856 aPair[0]->ColorTexture()->Unbind (myGlContext, GL_TEXTURE0 + 0);
860 TCollection_ExtendedString aMsg = TCollection_ExtendedString()
861 + "Error! Anaglyph has failed";
862 myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
863 GL_DEBUG_TYPE_ERROR_ARB,
865 GL_DEBUG_SEVERITY_HIGH_ARB,
870 // =======================================================================
873 // =======================================================================
874 void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
875 const Aspect_CLayer2d& theCUnderLayer,
876 const Aspect_CLayer2d& theCOverLayer)
884 myIsCullingEnabled = theCView.IsCullingEnabled;
886 // release pending GL resources
887 myGlContext->ReleaseDelayed();
889 // fetch OpenGl context state
890 myGlContext->FetchState();
892 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theCView.ptrFBO;
893 bool toSwap = myGlContext->IsRender()
894 && !myGlContext->caps->buffersNoSwap
895 && aFrameBuffer == NULL;
897 Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth;
898 Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight;
900 if ( aFrameBuffer == NULL
901 && !myGlContext->DefaultFrameBuffer().IsNull()
902 && myGlContext->DefaultFrameBuffer()->IsValid())
904 aFrameBuffer = myGlContext->DefaultFrameBuffer().operator->();
908 && myTransientDrawToFront)
910 if (myMainSceneFbos[0]->GetVPSizeX() != aSizeX
911 || myMainSceneFbos[0]->GetVPSizeY() != aSizeY)
913 // prepare FBOs containing main scene
914 // for further blitting and rendering immediate presentations on top
915 if (myGlContext->core20fwd != NULL)
917 myMainSceneFbos[0]->Init (myGlContext, aSizeX, aSizeY);
923 myMainSceneFbos [0]->Release (myGlContext.operator->());
924 myMainSceneFbos [1]->Release (myGlContext.operator->());
925 myImmediateSceneFbos[0]->Release (myGlContext.operator->());
926 myImmediateSceneFbos[1]->Release (myGlContext.operator->());
927 myMainSceneFbos [0]->ChangeViewport (0, 0);
928 myMainSceneFbos [1]->ChangeViewport (0, 0);
929 myImmediateSceneFbos[0]->ChangeViewport (0, 0);
930 myImmediateSceneFbos[1]->ChangeViewport (0, 0);
933 // draw entire frame using normal OpenGL pipeline
934 const Handle(Graphic3d_Camera)& aCamera = myView->Camera();
935 Graphic3d_Camera::Projection aProjectType = aCamera->ProjectionType();
936 if (aProjectType == Graphic3d_Camera::Projection_Stereo)
938 if (aFrameBuffer != NULL
939 || !myGlContext->IsRender())
941 // implicitly switch to mono camera for image dump
942 aProjectType = Graphic3d_Camera::Projection_Perspective;
944 else if (myMainSceneFbos[0]->IsValid())
946 myMainSceneFbos[1]->InitLazy (myGlContext, aSizeX, aSizeY);
947 if (!myMainSceneFbos[1]->IsValid())
950 aProjectType = Graphic3d_Camera::Projection_Perspective;
952 else if (!myGlContext->HasStereoBuffers())
954 myImmediateSceneFbos[0]->InitLazy (myGlContext, aSizeX, aSizeY);
955 myImmediateSceneFbos[1]->InitLazy (myGlContext, aSizeX, aSizeY);
956 if (!myImmediateSceneFbos[0]->IsValid()
957 || !myImmediateSceneFbos[1]->IsValid())
959 aProjectType = Graphic3d_Camera::Projection_Perspective;
965 if (aProjectType == Graphic3d_Camera::Projection_Stereo)
967 OpenGl_FrameBuffer* aMainFbos[2] =
969 myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL,
970 myMainSceneFbos[1]->IsValid() ? myMainSceneFbos[1].operator->() : NULL
972 OpenGl_FrameBuffer* anImmFbos[2] =
974 myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL,
975 myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL
978 #if !defined(GL_ES_VERSION_2_0)
979 myGlContext->SetReadDrawBuffer (GL_BACK_LEFT);
981 redraw1 (theCView, theCUnderLayer, theCOverLayer,
982 aMainFbos[0], Graphic3d_Camera::Projection_MonoLeftEye);
983 myBackBufferRestored = Standard_True;
984 myIsImmediateDrawn = Standard_False;
985 #if !defined(GL_ES_VERSION_2_0)
986 myGlContext->SetReadDrawBuffer (GL_BACK_LEFT);
988 if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aMainFbos[0], aProjectType, anImmFbos[0]))
993 #if !defined(GL_ES_VERSION_2_0)
994 myGlContext->SetReadDrawBuffer (GL_BACK_RIGHT);
996 redraw1 (theCView, theCUnderLayer, theCOverLayer,
997 aMainFbos[1], Graphic3d_Camera::Projection_MonoRightEye);
998 myBackBufferRestored = Standard_True;
999 myIsImmediateDrawn = Standard_False;
1000 if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aMainFbos[1], aProjectType, anImmFbos[1]))
1005 if (anImmFbos[0] != NULL)
1007 bindDefaultFbo (aFrameBuffer);
1013 OpenGl_FrameBuffer* aMainFbo = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL;
1014 #if !defined(GL_ES_VERSION_2_0)
1015 if (aMainFbo == NULL
1016 && aFrameBuffer == NULL)
1018 myGlContext->SetReadDrawBuffer (GL_BACK);
1021 redraw1 (theCView, theCUnderLayer, theCOverLayer,
1022 aMainFbo != NULL ? aMainFbo : aFrameBuffer, aProjectType);
1023 myBackBufferRestored = Standard_True;
1024 myIsImmediateDrawn = Standard_False;
1025 if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aMainFbo, aProjectType, aFrameBuffer))
1031 #if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
1032 if (OpenGl_AVIWriter_AllowWriting (theCView.DefWindow.XWindow))
1035 glGetIntegerv (GL_VIEWPORT, params);
1036 int nWidth = params[2] & ~0x7;
1037 int nHeight = params[3] & ~0x7;
1039 const int nBitsPerPixel = 24;
1040 GLubyte* aDumpData = new GLubyte[nWidth * nHeight * nBitsPerPixel / 8];
1042 glPixelStorei (GL_PACK_ALIGNMENT, 1);
1043 glReadPixels (0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, aDumpData);
1044 OpenGl_AVIWriter_AVIWriter (aDumpData, nWidth, nHeight, nBitsPerPixel);
1055 GetGlContext()->SwapBuffers();
1056 if (!myMainSceneFbos[0]->IsValid())
1058 myBackBufferRestored = Standard_False;
1063 myGlContext->core11fwd->glFlush();
1066 // reset render mode state
1067 myGlContext->FetchState();
1070 // =======================================================================
1071 // function : redraw1
1073 // =======================================================================
1074 void OpenGl_Workspace::redraw1 (const Graphic3d_CView& theCView,
1075 const Aspect_CLayer2d& theCUnderLayer,
1076 const Aspect_CLayer2d& theCOverLayer,
1077 OpenGl_FrameBuffer* theReadDrawFbo,
1078 const Graphic3d_Camera::Projection theProjection)
1080 if (myView.IsNull())
1085 if (theReadDrawFbo != NULL)
1087 theReadDrawFbo->BindBuffer (myGlContext);
1088 theReadDrawFbo->SetupViewport (myGlContext);
1092 myGlContext->core11fwd->glViewport (0, 0, myWidth, myHeight);
1095 // request reset of material
1096 NamedStatus |= OPENGL_NS_RESMAT;
1098 GLbitfield toClear = GL_COLOR_BUFFER_BIT;
1101 glDepthFunc (GL_LEQUAL);
1102 glDepthMask (GL_TRUE);
1105 glEnable (GL_DEPTH_TEST);
1109 glDisable (GL_DEPTH_TEST);
1112 #if !defined(GL_ES_VERSION_2_0)
1115 glClearDepthf (1.0f);
1117 toClear |= GL_DEPTH_BUFFER_BIT;
1121 glDisable (GL_DEPTH_TEST);
1124 if (NamedStatus & OPENGL_NS_WHITEBACK)
1126 // set background to white
1127 glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
1128 toClear |= GL_DEPTH_BUFFER_BIT;
1132 glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.0f);
1137 Handle(OpenGl_Workspace) aWS (this);
1138 myView->Render (myPrintContext, aWS, theReadDrawFbo, theProjection, theCView, theCUnderLayer, theCOverLayer, Standard_False);
1141 // =======================================================================
1142 // function : copyBackToFront
1144 // =======================================================================
1145 void OpenGl_Workspace::copyBackToFront()
1147 #if !defined(GL_ES_VERSION_2_0)
1149 OpenGl_Mat4 aProjectMat;
1150 OpenGl_Utils::Ortho2D<Standard_ShortReal> (aProjectMat,
1151 0.f, static_cast<GLfloat> (myWidth), 0.f, static_cast<GLfloat> (myHeight));
1153 myGlContext->WorldViewState.Push();
1154 myGlContext->ProjectionState.Push();
1156 myGlContext->WorldViewState.SetIdentity();
1157 myGlContext->ProjectionState.SetCurrent (aProjectMat);
1159 myGlContext->ApplyProjectionMatrix();
1160 myGlContext->ApplyWorldViewMatrix();
1164 switch (myGlContext->DrawBuffer())
1168 myGlContext->SetReadBuffer (GL_BACK_LEFT);
1169 myGlContext->SetDrawBuffer (GL_FRONT_LEFT);
1174 myGlContext->SetReadBuffer (GL_BACK_RIGHT);
1175 myGlContext->SetDrawBuffer (GL_FRONT_RIGHT);
1180 myGlContext->SetReadBuffer (GL_BACK);
1181 myGlContext->SetDrawBuffer (GL_FRONT);
1186 glRasterPos2i (0, 0);
1187 glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_COLOR);
1188 //glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_DEPTH);
1192 myGlContext->WorldViewState.Pop();
1193 myGlContext->ProjectionState.Pop();
1194 myGlContext->ApplyProjectionMatrix();
1196 // read/write from front buffer now
1197 myGlContext->SetReadBuffer (myGlContext->DrawBuffer());
1199 myIsImmediateDrawn = Standard_False;
1202 // =======================================================================
1203 // function : DisplayCallback
1205 // =======================================================================
1206 void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& theCView,
1207 Standard_Integer theReason)
1209 if (theCView.GDisplayCB == NULL)
1214 Aspect_GraphicCallbackStruct aCallData;
1215 aCallData.reason = theReason;
1216 aCallData.glContext = myGlContext;
1217 aCallData.wsID = theCView.WsId;
1218 aCallData.viewID = theCView.ViewId;
1219 aCallData.IsCoreProfile = (myGlContext->core11 == NULL);
1220 theCView.GDisplayCB (theCView.DefWindow.XWindow, theCView.GClientData, &aCallData);
1223 // =======================================================================
1224 // function : RedrawImmediate
1226 // =======================================================================
1227 void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView,
1228 const Aspect_CLayer2d& theCUnderLayer,
1229 const Aspect_CLayer2d& theCOverLayer)
1231 const Handle(Graphic3d_Camera)& aCamera = myView->Camera();
1232 Graphic3d_Camera::Projection aProjectType = aCamera->ProjectionType();
1233 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theCView.ptrFBO;
1234 if ( aFrameBuffer == NULL
1235 && !myGlContext->DefaultFrameBuffer().IsNull()
1236 && myGlContext->DefaultFrameBuffer()->IsValid())
1238 aFrameBuffer = myGlContext->DefaultFrameBuffer().operator->();
1241 if (aProjectType == Graphic3d_Camera::Projection_Stereo)
1243 if (aFrameBuffer != NULL)
1245 // implicitly switch to mono camera for image dump
1246 aProjectType = Graphic3d_Camera::Projection_Perspective;
1248 else if (myMainSceneFbos[0]->IsValid()
1249 && !myMainSceneFbos[1]->IsValid())
1251 aProjectType = Graphic3d_Camera::Projection_Perspective;
1255 if (!myTransientDrawToFront
1256 || !myBackBufferRestored
1257 || (myGlContext->caps->buffersNoSwap && !myMainSceneFbos[0]->IsValid()))
1259 Redraw (theCView, theCUnderLayer, theCOverLayer);
1262 else if (!Activate())
1267 bool toSwap = false;
1268 if (aProjectType == Graphic3d_Camera::Projection_Stereo)
1270 OpenGl_FrameBuffer* aMainFbos[2] =
1272 myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL,
1273 myMainSceneFbos[1]->IsValid() ? myMainSceneFbos[1].operator->() : NULL
1275 OpenGl_FrameBuffer* anImmFbos[2] =
1277 myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL,
1278 myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL
1281 if (myGlContext->arbFBO != NULL)
1283 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
1285 #if !defined(GL_ES_VERSION_2_0)
1286 if (anImmFbos[0] == NULL)
1288 myGlContext->SetReadDrawBuffer (GL_BACK_LEFT);
1291 toSwap = redrawImmediate (theCView, theCUnderLayer, theCOverLayer,
1293 Graphic3d_Camera::Projection_MonoLeftEye,
1295 Standard_True) || toSwap;
1297 if (myGlContext->arbFBO != NULL)
1299 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
1301 #if !defined(GL_ES_VERSION_2_0)
1302 if (anImmFbos[1] == NULL)
1304 myGlContext->SetReadDrawBuffer (GL_BACK_RIGHT);
1307 toSwap = redrawImmediate (theCView, theCUnderLayer, theCOverLayer,
1309 Graphic3d_Camera::Projection_MonoRightEye,
1311 Standard_True) || toSwap;
1312 if (anImmFbos[0] != NULL)
1314 bindDefaultFbo (aFrameBuffer);
1320 OpenGl_FrameBuffer* aMainFbo = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL;
1321 #if !defined(GL_ES_VERSION_2_0)
1322 if (aMainFbo == NULL)
1324 myGlContext->SetReadDrawBuffer (GL_BACK);
1327 toSwap = redrawImmediate (theCView, theCUnderLayer, theCOverLayer,
1331 Standard_True) || toSwap;
1338 && !myGlContext->caps->buffersNoSwap)
1340 myGlContext->SwapBuffers();
1344 myGlContext->core11fwd->glFlush();
1348 // =======================================================================
1349 // function : redrawImmediate
1351 // =======================================================================
1352 bool OpenGl_Workspace::redrawImmediate (const Graphic3d_CView& theCView,
1353 const Aspect_CLayer2d& theCUnderLayer,
1354 const Aspect_CLayer2d& theCOverLayer,
1355 OpenGl_FrameBuffer* theReadFbo,
1356 const Graphic3d_Camera::Projection theProjection,
1357 OpenGl_FrameBuffer* theDrawFbo,
1358 const Standard_Boolean theIsPartialUpdate)
1360 GLboolean toCopyBackToFront = GL_FALSE;
1361 if (!myTransientDrawToFront)
1363 myBackBufferRestored = Standard_False;
1365 else if (theReadFbo != NULL
1366 && theReadFbo->IsValid()
1367 && myGlContext->IsRender())
1369 if (!blitBuffers (theReadFbo, theDrawFbo))
1374 else if (theDrawFbo == NULL)
1376 #if !defined(GL_ES_VERSION_2_0)
1377 myGlContext->core11fwd->glGetBooleanv (GL_DOUBLEBUFFER, &toCopyBackToFront);
1379 if (toCopyBackToFront)
1381 if (!myView->HasImmediateStructures()
1382 && !theIsPartialUpdate)
1384 // prefer Swap Buffers within Redraw in compatibility mode (without FBO)
1391 myBackBufferRestored = Standard_False;
1396 myBackBufferRestored = Standard_False;
1398 myIsImmediateDrawn = Standard_True;
1400 Handle(OpenGl_Workspace) aWS (this);
1404 glDepthFunc (GL_LEQUAL);
1405 glDepthMask (GL_TRUE);
1408 glEnable (GL_DEPTH_TEST);
1412 glDisable (GL_DEPTH_TEST);
1415 #if !defined(GL_ES_VERSION_2_0)
1418 glClearDepthf (1.0f);
1423 glDisable (GL_DEPTH_TEST);
1426 myView->Render (myPrintContext, aWS, theDrawFbo, theProjection,
1427 theCView, theCUnderLayer, theCOverLayer, Standard_True);
1428 if (!myView->ImmediateStructures().IsEmpty())
1430 glDisable (GL_DEPTH_TEST);
1432 for (OpenGl_IndexedMapOfStructure::Iterator anIter (myView->ImmediateStructures()); anIter.More(); anIter.Next())
1434 const OpenGl_Structure* aStructure = anIter.Value();
1435 if (!aStructure->IsVisible())
1440 aStructure->Render (aWS);
1443 return !toCopyBackToFront;
1446 IMPLEMENT_STANDARD_HANDLE (OpenGl_RaytraceFilter, OpenGl_RenderFilter)
1447 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RaytraceFilter, OpenGl_RenderFilter)
1449 // =======================================================================
1450 // function : CanRender
1452 // =======================================================================
1453 Standard_Boolean OpenGl_RaytraceFilter::CanRender (const OpenGl_Element* theElement)
1455 Standard_Boolean aPrevFilterResult = Standard_True;
1456 if (!myPrevRenderFilter.IsNull())
1458 aPrevFilterResult = myPrevRenderFilter->CanRender (theElement);
1460 return aPrevFilterResult &&
1461 !OpenGl_Raytrace::IsRaytracedElement (theElement);