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_True),
157 myUseDepthWrite (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);
305 myGlContext->SetTypeOfLine (myDefaultAspectLine.Type());
306 myGlContext->SetLineWidth (myDefaultAspectLine.Width());
309 // =======================================================================
310 // function : DisableTexture
312 // =======================================================================
313 Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
315 if (myTextureBound.IsNull())
317 return myTextureBound;
320 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
321 if (!aSampler.IsNull())
323 aSampler->Unbind (*myGlContext);
326 #if !defined(GL_ES_VERSION_2_0)
327 // reset texture matrix because some code may expect it is identity
328 if (myGlContext->core11 != NULL)
330 GLint aMatrixMode = GL_TEXTURE;
331 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
332 glMatrixMode (GL_TEXTURE);
334 glMatrixMode (aMatrixMode);
338 myTextureBound->Unbind (myGlContext);
339 switch (myTextureBound->GetTarget())
341 #if !defined(GL_ES_VERSION_2_0)
344 if (myGlContext->core11 != NULL)
346 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
348 glDisable (GL_TEXTURE_GEN_S);
350 glDisable (GL_TEXTURE_1D);
357 #if !defined(GL_ES_VERSION_2_0)
358 if (myGlContext->core11 != NULL)
360 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
362 glDisable (GL_TEXTURE_GEN_S);
363 glDisable (GL_TEXTURE_GEN_T);
364 if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE)
366 glDisable (GL_POINT_SPRITE);
369 glDisable (GL_TEXTURE_2D);
377 Handle(OpenGl_Texture) aPrevTexture = myTextureBound;
378 myTextureBound.Nullify();
382 // =======================================================================
383 // function : setTextureParams
385 // =======================================================================
386 void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& theTexture,
387 const Handle(Graphic3d_TextureParams)& theParams)
389 const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams;
390 if (aParams.IsNull())
395 #if !defined(GL_ES_VERSION_2_0)
396 GLint aMatrixMode = GL_TEXTURE;
397 if (myGlContext->core11 != NULL)
399 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
401 // setup texture matrix
402 glMatrixMode (GL_TEXTURE);
403 OpenGl_Mat4 aTextureMat;
404 const Graphic3d_Vec2& aScale = aParams->Scale();
405 const Graphic3d_Vec2& aTrans = aParams->Translation();
406 OpenGl_Utils::Scale (aTextureMat, aScale.x(), aScale.y(), 1.0f);
407 OpenGl_Utils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f);
408 OpenGl_Utils::Rotate (aTextureMat, -aParams->Rotation(), 0.0f, 0.0f, 1.0f);
409 glLoadMatrixf (aTextureMat);
411 GLint anEnvMode = GL_MODULATE; // lighting mode
412 if (!aParams->IsModulate())
414 anEnvMode = GL_DECAL;
415 if (theTexture->GetFormat() == GL_ALPHA
416 || theTexture->GetFormat() == GL_LUMINANCE)
418 anEnvMode = GL_REPLACE;
422 // setup generation of texture coordinates
423 switch (aParams->GenMode())
425 case Graphic3d_TOTM_OBJECT:
427 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
428 glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData());
429 if (theTexture->GetTarget() != GL_TEXTURE_1D)
431 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
432 glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData());
436 case Graphic3d_TOTM_SPHERE:
438 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
439 if (theTexture->GetTarget() != GL_TEXTURE_1D)
441 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
445 case Graphic3d_TOTM_EYE:
447 myGlContext->WorldViewState.Push();
449 myGlContext->WorldViewState.SetIdentity();
450 myGlContext->ApplyWorldViewMatrix();
452 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
453 glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData());
455 if (theTexture->GetTarget() != GL_TEXTURE_1D)
457 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
458 glTexGenfv (GL_T, GL_EYE_PLANE, aParams->GenPlaneT().GetData());
461 myGlContext->WorldViewState.Pop();
465 case Graphic3d_TOTM_SPRITE:
467 if (GetGlContext()->core20fwd != NULL)
469 glEnable (GL_POINT_SPRITE);
470 glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
471 anEnvMode = GL_REPLACE;
472 GetGlContext()->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
476 case Graphic3d_TOTM_MANUAL:
481 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
485 // get active sampler object to override default texture parameters
486 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
488 // setup texture filtering and wrapping
489 //if (theTexture->GetParams() != theParams)
490 const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
491 const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : myGlContext->TextureWrapClamp();
492 switch (theTexture->GetTarget())
494 #if !defined(GL_ES_VERSION_2_0)
497 if (aSampler.IsNull() || !aSampler->IsValid())
499 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
500 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
501 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
505 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
506 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilter);
507 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
515 GLenum aFilterMin = aFilter;
516 if (theTexture->HasMipmaps())
518 aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
519 if (aParams->Filter() == Graphic3d_TOTF_BILINEAR)
521 aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
523 else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR)
525 aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
528 if (myGlContext->extAnis)
530 // setup degree of anisotropy filter
531 const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
533 switch (aParams->AnisoFilter())
535 case Graphic3d_LOTA_QUALITY:
537 aDegree = aMaxDegree;
540 case Graphic3d_LOTA_MIDDLE:
542 aDegree = (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2);
545 case Graphic3d_LOTA_FAST:
550 case Graphic3d_LOTA_OFF:
558 if (aSampler.IsNull() || !aSampler->IsValid())
560 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
564 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
569 if (aSampler.IsNull() || !aSampler->IsValid())
571 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
572 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
573 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
574 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
578 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilterMin);
579 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
580 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
581 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_T, aWrapMode);
589 switch (theTexture->GetTarget())
591 #if !defined(GL_ES_VERSION_2_0)
594 if (myGlContext->core11 != NULL)
596 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
598 glEnable (GL_TEXTURE_GEN_S);
600 glEnable (GL_TEXTURE_1D);
607 #if !defined(GL_ES_VERSION_2_0)
608 if (myGlContext->core11 != NULL)
610 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
612 glEnable (GL_TEXTURE_GEN_S);
613 glEnable (GL_TEXTURE_GEN_T);
615 glEnable (GL_TEXTURE_2D);
623 #if !defined(GL_ES_VERSION_2_0)
624 if (myGlContext->core11 != NULL)
626 glMatrixMode (aMatrixMode); // turn back active matrix
629 theTexture->SetParams (aParams);
632 // =======================================================================
633 // function : EnableTexture
635 // =======================================================================
636 Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture,
637 const Handle(Graphic3d_TextureParams)& theParams)
639 if (theTexture.IsNull() || !theTexture->IsValid())
641 return DisableTexture();
644 if (myTextureBound == theTexture
645 && (theParams.IsNull() || theParams == theTexture->GetParams()))
648 return myTextureBound;
651 Handle(OpenGl_Texture) aPrevTexture = DisableTexture();
652 myTextureBound = theTexture;
653 myTextureBound->Bind (myGlContext);
654 setTextureParams (myTextureBound, theParams);
656 // If custom sampler object is available it will be
657 // used for overriding default texture parameters
658 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
660 if (!aSampler.IsNull() && aSampler->IsValid())
662 aSampler->Bind (*myGlContext);
668 // =======================================================================
669 // function : bindDefaultFbo
671 // =======================================================================
672 void OpenGl_Workspace::bindDefaultFbo (OpenGl_FrameBuffer* theCustomFbo)
674 OpenGl_FrameBuffer* anFbo = (theCustomFbo != NULL && theCustomFbo->IsValid())
676 : (!myGlContext->DefaultFrameBuffer().IsNull()
677 && myGlContext->DefaultFrameBuffer()->IsValid()
678 ? myGlContext->DefaultFrameBuffer().operator->()
682 anFbo->BindBuffer (myGlContext);
686 #if !defined(GL_ES_VERSION_2_0)
687 myGlContext->SetReadDrawBuffer (GL_BACK);
689 if (myGlContext->arbFBO != NULL)
691 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
695 myGlContext->core11fwd->glViewport (0, 0, myWidth, myHeight);
698 // =======================================================================
699 // function : blitBuffers
701 // =======================================================================
702 bool OpenGl_Workspace::blitBuffers (OpenGl_FrameBuffer* theReadFbo,
703 OpenGl_FrameBuffer* theDrawFbo)
705 if (theReadFbo == NULL)
710 // clear destination before blitting
711 if (theDrawFbo != NULL
712 && theDrawFbo->IsValid())
714 theDrawFbo->BindBuffer (myGlContext);
718 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
720 #if !defined(GL_ES_VERSION_2_0)
721 myGlContext->core20fwd->glClearDepth (1.0);
723 myGlContext->core20fwd->glClearDepthf (1.0f);
725 myGlContext->core20fwd->glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
727 /*#if !defined(GL_ES_VERSION_2_0)
728 if (myGlContext->arbFBOBlit != NULL)
730 theReadFbo->BindReadBuffer (myGlContext);
731 if (theDrawFbo != NULL
732 && theDrawFbo->IsValid())
734 theDrawFbo->BindDrawBuffer (myGlContext);
738 myGlContext->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
740 // we don't copy stencil buffer here... does it matter for performance?
741 myGlContext->arbFBOBlit->glBlitFramebuffer (0, 0, theReadFbo->GetVPSizeX(), theReadFbo->GetVPSizeY(),
742 0, 0, theReadFbo->GetVPSizeX(), theReadFbo->GetVPSizeY(),
743 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
745 if (theDrawFbo != NULL
746 && theDrawFbo->IsValid())
748 theDrawFbo->BindBuffer (myGlContext);
752 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
758 myGlContext->core20fwd->glDepthFunc (GL_ALWAYS);
759 myGlContext->core20fwd->glDepthMask (GL_TRUE);
760 myGlContext->core20fwd->glEnable (GL_DEPTH_TEST);
763 if (!myFullScreenQuad.IsValid())
765 OpenGl_Vec4 aQuad[4] =
767 OpenGl_Vec4( 1.0f, -1.0f, 1.0f, 0.0f),
768 OpenGl_Vec4( 1.0f, 1.0f, 1.0f, 1.0f),
769 OpenGl_Vec4(-1.0f, -1.0f, 0.0f, 0.0f),
770 OpenGl_Vec4(-1.0f, 1.0f, 0.0f, 1.0f)
772 myFullScreenQuad.Init (myGlContext, 4, 4, aQuad[0].GetData());
775 const Handle(OpenGl_ShaderManager)& aManager = myGlContext->ShaderManager();
776 if (myFullScreenQuad.IsValid()
777 && aManager->BindFboBlitProgram())
779 theReadFbo->ColorTexture() ->Bind (myGlContext, GL_TEXTURE0 + 0);
780 theReadFbo->DepthStencilTexture()->Bind (myGlContext, GL_TEXTURE0 + 1);
781 myFullScreenQuad.BindVertexAttrib (myGlContext, Graphic3d_TOA_POS);
783 myGlContext->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
785 myFullScreenQuad.UnbindVertexAttrib (myGlContext, Graphic3d_TOA_POS);
786 theReadFbo->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + 1);
787 theReadFbo->ColorTexture() ->Unbind (myGlContext, GL_TEXTURE0 + 0);
791 TCollection_ExtendedString aMsg = TCollection_ExtendedString()
792 + "Error! FBO blitting has failed";
793 myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
794 GL_DEBUG_TYPE_ERROR_ARB,
796 GL_DEBUG_SEVERITY_HIGH_ARB,
798 myHasFboBlit = Standard_False;
799 theReadFbo->Release (myGlContext.operator->());
806 // =======================================================================
807 // function : drawStereoPair
809 // =======================================================================
810 void OpenGl_Workspace::drawStereoPair()
812 OpenGl_FrameBuffer* aPair[2] =
814 myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL,
815 myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL
820 aPair[0] = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL;
821 aPair[1] = myMainSceneFbos[1]->IsValid() ? myMainSceneFbos[1].operator->() : NULL;
830 myGlContext->core20fwd->glDepthFunc (GL_ALWAYS);
831 myGlContext->core20fwd->glDepthMask (GL_TRUE);
832 myGlContext->core20fwd->glEnable (GL_DEPTH_TEST);
835 if (!myFullScreenQuad.IsValid())
837 OpenGl_Vec4 aQuad[4] =
839 OpenGl_Vec4( 1.0f, -1.0f, 1.0f, 0.0f),
840 OpenGl_Vec4( 1.0f, 1.0f, 1.0f, 1.0f),
841 OpenGl_Vec4(-1.0f, -1.0f, 0.0f, 0.0f),
842 OpenGl_Vec4(-1.0f, 1.0f, 0.0f, 1.0f)
844 myFullScreenQuad.Init (myGlContext, 4, 4, aQuad[0].GetData());
847 const Handle(OpenGl_ShaderManager)& aManager = myGlContext->ShaderManager();
848 if (myFullScreenQuad.IsValid()
849 && aManager->BindAnaglyphProgram())
851 aPair[0]->ColorTexture()->Bind (myGlContext, GL_TEXTURE0 + 0);
852 aPair[1]->ColorTexture()->Bind (myGlContext, GL_TEXTURE0 + 1);
853 myFullScreenQuad.BindVertexAttrib (myGlContext, 0);
855 myGlContext->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
857 myFullScreenQuad.UnbindVertexAttrib (myGlContext, 0);
858 aPair[1]->ColorTexture()->Unbind (myGlContext, GL_TEXTURE0 + 1);
859 aPair[0]->ColorTexture()->Unbind (myGlContext, GL_TEXTURE0 + 0);
863 TCollection_ExtendedString aMsg = TCollection_ExtendedString()
864 + "Error! Anaglyph has failed";
865 myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
866 GL_DEBUG_TYPE_ERROR_ARB,
868 GL_DEBUG_SEVERITY_HIGH_ARB,
873 // =======================================================================
876 // =======================================================================
877 void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
878 const Aspect_CLayer2d& theCUnderLayer,
879 const Aspect_CLayer2d& theCOverLayer)
887 myIsCullingEnabled = theCView.IsCullingEnabled;
889 // release pending GL resources
890 myGlContext->ReleaseDelayed();
892 // fetch OpenGl context state
893 myGlContext->FetchState();
895 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theCView.ptrFBO;
896 bool toSwap = myGlContext->IsRender()
897 && !myGlContext->caps->buffersNoSwap
898 && aFrameBuffer == NULL;
900 Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth;
901 Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight;
903 if ( aFrameBuffer == NULL
904 && !myGlContext->DefaultFrameBuffer().IsNull()
905 && myGlContext->DefaultFrameBuffer()->IsValid())
907 aFrameBuffer = myGlContext->DefaultFrameBuffer().operator->();
911 && myTransientDrawToFront)
913 if (myMainSceneFbos[0]->GetVPSizeX() != aSizeX
914 || myMainSceneFbos[0]->GetVPSizeY() != aSizeY)
916 // prepare FBOs containing main scene
917 // for further blitting and rendering immediate presentations on top
918 if (myGlContext->core20fwd != NULL)
920 myMainSceneFbos[0]->Init (myGlContext, aSizeX, aSizeY);
926 myMainSceneFbos [0]->Release (myGlContext.operator->());
927 myMainSceneFbos [1]->Release (myGlContext.operator->());
928 myImmediateSceneFbos[0]->Release (myGlContext.operator->());
929 myImmediateSceneFbos[1]->Release (myGlContext.operator->());
930 myMainSceneFbos [0]->ChangeViewport (0, 0);
931 myMainSceneFbos [1]->ChangeViewport (0, 0);
932 myImmediateSceneFbos[0]->ChangeViewport (0, 0);
933 myImmediateSceneFbos[1]->ChangeViewport (0, 0);
936 // draw entire frame using normal OpenGL pipeline
937 const Handle(Graphic3d_Camera)& aCamera = myView->Camera();
938 Graphic3d_Camera::Projection aProjectType = aCamera->ProjectionType();
939 if (aProjectType == Graphic3d_Camera::Projection_Stereo)
941 if (aFrameBuffer != NULL
942 || !myGlContext->IsRender())
944 // implicitly switch to mono camera for image dump
945 aProjectType = Graphic3d_Camera::Projection_Perspective;
947 else if (myMainSceneFbos[0]->IsValid())
949 myMainSceneFbos[1]->InitLazy (myGlContext, aSizeX, aSizeY);
950 if (!myMainSceneFbos[1]->IsValid())
953 aProjectType = Graphic3d_Camera::Projection_Perspective;
955 else if (!myGlContext->HasStereoBuffers())
957 myImmediateSceneFbos[0]->InitLazy (myGlContext, aSizeX, aSizeY);
958 myImmediateSceneFbos[1]->InitLazy (myGlContext, aSizeX, aSizeY);
959 if (!myImmediateSceneFbos[0]->IsValid()
960 || !myImmediateSceneFbos[1]->IsValid())
962 aProjectType = Graphic3d_Camera::Projection_Perspective;
968 if (aProjectType == Graphic3d_Camera::Projection_Stereo)
970 OpenGl_FrameBuffer* aMainFbos[2] =
972 myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL,
973 myMainSceneFbos[1]->IsValid() ? myMainSceneFbos[1].operator->() : NULL
975 OpenGl_FrameBuffer* anImmFbos[2] =
977 myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL,
978 myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL
981 #if !defined(GL_ES_VERSION_2_0)
982 myGlContext->SetReadDrawBuffer (GL_BACK_LEFT);
984 redraw1 (theCView, theCUnderLayer, theCOverLayer,
985 aMainFbos[0], Graphic3d_Camera::Projection_MonoLeftEye);
986 myBackBufferRestored = Standard_True;
987 myIsImmediateDrawn = Standard_False;
988 #if !defined(GL_ES_VERSION_2_0)
989 myGlContext->SetReadDrawBuffer (GL_BACK_LEFT);
991 if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aMainFbos[0], aProjectType, anImmFbos[0]))
996 #if !defined(GL_ES_VERSION_2_0)
997 myGlContext->SetReadDrawBuffer (GL_BACK_RIGHT);
999 redraw1 (theCView, theCUnderLayer, theCOverLayer,
1000 aMainFbos[1], Graphic3d_Camera::Projection_MonoRightEye);
1001 myBackBufferRestored = Standard_True;
1002 myIsImmediateDrawn = Standard_False;
1003 if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aMainFbos[1], aProjectType, anImmFbos[1]))
1008 if (anImmFbos[0] != NULL)
1010 bindDefaultFbo (aFrameBuffer);
1016 OpenGl_FrameBuffer* aMainFbo = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL;
1017 #if !defined(GL_ES_VERSION_2_0)
1018 if (aMainFbo == NULL
1019 && aFrameBuffer == NULL)
1021 myGlContext->SetReadDrawBuffer (GL_BACK);
1024 redraw1 (theCView, theCUnderLayer, theCOverLayer,
1025 aMainFbo != NULL ? aMainFbo : aFrameBuffer, aProjectType);
1026 myBackBufferRestored = Standard_True;
1027 myIsImmediateDrawn = Standard_False;
1028 if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aMainFbo, aProjectType, aFrameBuffer))
1034 #if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
1035 if (OpenGl_AVIWriter_AllowWriting (theCView.DefWindow.XWindow))
1038 glGetIntegerv (GL_VIEWPORT, params);
1039 int nWidth = params[2] & ~0x7;
1040 int nHeight = params[3] & ~0x7;
1042 const int nBitsPerPixel = 24;
1043 GLubyte* aDumpData = new GLubyte[nWidth * nHeight * nBitsPerPixel / 8];
1045 glPixelStorei (GL_PACK_ALIGNMENT, 1);
1046 glReadPixels (0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, aDumpData);
1047 OpenGl_AVIWriter_AVIWriter (aDumpData, nWidth, nHeight, nBitsPerPixel);
1058 GetGlContext()->SwapBuffers();
1059 if (!myMainSceneFbos[0]->IsValid())
1061 myBackBufferRestored = Standard_False;
1066 myGlContext->core11fwd->glFlush();
1069 // reset render mode state
1070 myGlContext->FetchState();
1073 // =======================================================================
1074 // function : redraw1
1076 // =======================================================================
1077 void OpenGl_Workspace::redraw1 (const Graphic3d_CView& theCView,
1078 const Aspect_CLayer2d& theCUnderLayer,
1079 const Aspect_CLayer2d& theCOverLayer,
1080 OpenGl_FrameBuffer* theReadDrawFbo,
1081 const Graphic3d_Camera::Projection theProjection)
1083 if (myView.IsNull())
1088 if (theReadDrawFbo != NULL)
1090 theReadDrawFbo->BindBuffer (myGlContext);
1091 theReadDrawFbo->SetupViewport (myGlContext);
1095 myGlContext->core11fwd->glViewport (0, 0, myWidth, myHeight);
1098 // request reset of material
1099 NamedStatus |= OPENGL_NS_RESMAT;
1101 myUseZBuffer = Standard_True;
1102 myUseDepthWrite = Standard_True;
1103 GLbitfield toClear = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
1104 glDepthFunc (GL_LEQUAL);
1105 glDepthMask (GL_TRUE);
1106 glEnable (GL_DEPTH_TEST);
1108 #if !defined(GL_ES_VERSION_2_0)
1111 glClearDepthf (1.0f);
1114 if (NamedStatus & OPENGL_NS_WHITEBACK)
1116 // set background to white
1117 glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
1121 glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.0f);
1126 Handle(OpenGl_Workspace) aWS (this);
1127 myView->Render (myPrintContext, aWS, theReadDrawFbo, theProjection, theCView, theCUnderLayer, theCOverLayer, Standard_False);
1130 // =======================================================================
1131 // function : copyBackToFront
1133 // =======================================================================
1134 void OpenGl_Workspace::copyBackToFront()
1136 #if !defined(GL_ES_VERSION_2_0)
1138 OpenGl_Mat4 aProjectMat;
1139 OpenGl_Utils::Ortho2D<Standard_ShortReal> (aProjectMat,
1140 0.f, static_cast<GLfloat> (myWidth), 0.f, static_cast<GLfloat> (myHeight));
1142 myGlContext->WorldViewState.Push();
1143 myGlContext->ProjectionState.Push();
1145 myGlContext->WorldViewState.SetIdentity();
1146 myGlContext->ProjectionState.SetCurrent (aProjectMat);
1148 myGlContext->ApplyProjectionMatrix();
1149 myGlContext->ApplyWorldViewMatrix();
1153 switch (myGlContext->DrawBuffer())
1157 myGlContext->SetReadBuffer (GL_BACK_LEFT);
1158 myGlContext->SetDrawBuffer (GL_FRONT_LEFT);
1163 myGlContext->SetReadBuffer (GL_BACK_RIGHT);
1164 myGlContext->SetDrawBuffer (GL_FRONT_RIGHT);
1169 myGlContext->SetReadBuffer (GL_BACK);
1170 myGlContext->SetDrawBuffer (GL_FRONT);
1175 glRasterPos2i (0, 0);
1176 glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_COLOR);
1177 //glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_DEPTH);
1181 myGlContext->WorldViewState.Pop();
1182 myGlContext->ProjectionState.Pop();
1183 myGlContext->ApplyProjectionMatrix();
1185 // read/write from front buffer now
1186 myGlContext->SetReadBuffer (myGlContext->DrawBuffer());
1188 myIsImmediateDrawn = Standard_False;
1191 // =======================================================================
1192 // function : DisplayCallback
1194 // =======================================================================
1195 void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& theCView,
1196 Standard_Integer theReason)
1198 if (theCView.GDisplayCB == NULL)
1203 Aspect_GraphicCallbackStruct aCallData;
1204 aCallData.reason = theReason;
1205 aCallData.glContext = myGlContext;
1206 aCallData.wsID = theCView.WsId;
1207 aCallData.viewID = theCView.ViewId;
1208 aCallData.IsCoreProfile = (myGlContext->core11 == NULL);
1209 theCView.GDisplayCB (theCView.DefWindow.XWindow, theCView.GClientData, &aCallData);
1212 // =======================================================================
1213 // function : RedrawImmediate
1215 // =======================================================================
1216 void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView,
1217 const Aspect_CLayer2d& theCUnderLayer,
1218 const Aspect_CLayer2d& theCOverLayer)
1220 const Handle(Graphic3d_Camera)& aCamera = myView->Camera();
1221 Graphic3d_Camera::Projection aProjectType = aCamera->ProjectionType();
1222 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theCView.ptrFBO;
1223 if ( aFrameBuffer == NULL
1224 && !myGlContext->DefaultFrameBuffer().IsNull()
1225 && myGlContext->DefaultFrameBuffer()->IsValid())
1227 aFrameBuffer = myGlContext->DefaultFrameBuffer().operator->();
1230 if (aProjectType == Graphic3d_Camera::Projection_Stereo)
1232 if (aFrameBuffer != NULL)
1234 // implicitly switch to mono camera for image dump
1235 aProjectType = Graphic3d_Camera::Projection_Perspective;
1237 else if (myMainSceneFbos[0]->IsValid()
1238 && !myMainSceneFbos[1]->IsValid())
1240 aProjectType = Graphic3d_Camera::Projection_Perspective;
1244 if (!myTransientDrawToFront
1245 || !myBackBufferRestored
1246 || (myGlContext->caps->buffersNoSwap && !myMainSceneFbos[0]->IsValid()))
1248 Redraw (theCView, theCUnderLayer, theCOverLayer);
1251 else if (!Activate())
1256 bool toSwap = false;
1257 if (aProjectType == Graphic3d_Camera::Projection_Stereo)
1259 OpenGl_FrameBuffer* aMainFbos[2] =
1261 myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL,
1262 myMainSceneFbos[1]->IsValid() ? myMainSceneFbos[1].operator->() : NULL
1264 OpenGl_FrameBuffer* anImmFbos[2] =
1266 myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL,
1267 myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL
1270 if (myGlContext->arbFBO != NULL)
1272 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
1274 #if !defined(GL_ES_VERSION_2_0)
1275 if (anImmFbos[0] == NULL)
1277 myGlContext->SetReadDrawBuffer (GL_BACK_LEFT);
1280 toSwap = redrawImmediate (theCView, theCUnderLayer, theCOverLayer,
1282 Graphic3d_Camera::Projection_MonoLeftEye,
1284 Standard_True) || toSwap;
1286 if (myGlContext->arbFBO != NULL)
1288 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
1290 #if !defined(GL_ES_VERSION_2_0)
1291 if (anImmFbos[1] == NULL)
1293 myGlContext->SetReadDrawBuffer (GL_BACK_RIGHT);
1296 toSwap = redrawImmediate (theCView, theCUnderLayer, theCOverLayer,
1298 Graphic3d_Camera::Projection_MonoRightEye,
1300 Standard_True) || toSwap;
1301 if (anImmFbos[0] != NULL)
1303 bindDefaultFbo (aFrameBuffer);
1309 OpenGl_FrameBuffer* aMainFbo = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL;
1310 #if !defined(GL_ES_VERSION_2_0)
1311 if (aMainFbo == NULL)
1313 myGlContext->SetReadDrawBuffer (GL_BACK);
1316 toSwap = redrawImmediate (theCView, theCUnderLayer, theCOverLayer,
1320 Standard_True) || toSwap;
1327 && !myGlContext->caps->buffersNoSwap)
1329 myGlContext->SwapBuffers();
1333 myGlContext->core11fwd->glFlush();
1337 // =======================================================================
1338 // function : redrawImmediate
1340 // =======================================================================
1341 bool OpenGl_Workspace::redrawImmediate (const Graphic3d_CView& theCView,
1342 const Aspect_CLayer2d& theCUnderLayer,
1343 const Aspect_CLayer2d& theCOverLayer,
1344 OpenGl_FrameBuffer* theReadFbo,
1345 const Graphic3d_Camera::Projection theProjection,
1346 OpenGl_FrameBuffer* theDrawFbo,
1347 const Standard_Boolean theIsPartialUpdate)
1349 GLboolean toCopyBackToFront = GL_FALSE;
1350 if (!myTransientDrawToFront)
1352 myBackBufferRestored = Standard_False;
1354 else if (theReadFbo != NULL
1355 && theReadFbo->IsValid()
1356 && myGlContext->IsRender())
1358 if (!blitBuffers (theReadFbo, theDrawFbo))
1363 else if (theDrawFbo == NULL)
1365 #if !defined(GL_ES_VERSION_2_0)
1366 myGlContext->core11fwd->glGetBooleanv (GL_DOUBLEBUFFER, &toCopyBackToFront);
1368 if (toCopyBackToFront)
1370 if (!myView->HasImmediateStructures()
1371 && !theIsPartialUpdate)
1373 // prefer Swap Buffers within Redraw in compatibility mode (without FBO)
1380 myBackBufferRestored = Standard_False;
1385 myBackBufferRestored = Standard_False;
1387 myIsImmediateDrawn = Standard_True;
1389 Handle(OpenGl_Workspace) aWS (this);
1391 myUseZBuffer = Standard_True;
1392 myUseDepthWrite = Standard_True;
1393 glDepthFunc (GL_LEQUAL);
1394 glDepthMask (GL_TRUE);
1395 glEnable (GL_DEPTH_TEST);
1396 #if !defined(GL_ES_VERSION_2_0)
1399 glClearDepthf (1.0f);
1402 myView->Render (myPrintContext, aWS, theDrawFbo, theProjection,
1403 theCView, theCUnderLayer, theCOverLayer, Standard_True);
1404 if (!myView->ImmediateStructures().IsEmpty())
1406 myUseZBuffer = Standard_False;
1407 glDisable (GL_DEPTH_TEST);
1409 for (OpenGl_IndexedMapOfStructure::Iterator anIter (myView->ImmediateStructures()); anIter.More(); anIter.Next())
1411 const OpenGl_Structure* aStructure = anIter.Value();
1412 if (!aStructure->IsVisible())
1417 aStructure->Render (aWS);
1420 return !toCopyBackToFront;
1423 IMPLEMENT_STANDARD_HANDLE (OpenGl_RaytraceFilter, OpenGl_RenderFilter)
1424 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RaytraceFilter, OpenGl_RenderFilter)
1426 // =======================================================================
1427 // function : CanRender
1429 // =======================================================================
1430 Standard_Boolean OpenGl_RaytraceFilter::CanRender (const OpenGl_Element* theElement)
1432 Standard_Boolean aPrevFilterResult = Standard_True;
1433 if (!myPrevRenderFilter.IsNull())
1435 aPrevFilterResult = myPrevRenderFilter->CanRender (theElement);
1437 return aPrevFilterResult &&
1438 !OpenGl_Raytrace::IsRaytracedElement (theElement);