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 myComputeInitStatus (OpenGl_RT_NONE),
150 myIsRaytraceDataValid (Standard_False),
151 myIsRaytraceWarnTextures (Standard_False),
152 myHasFboBlit (Standard_True),
153 myViewModificationStatus (0),
154 myLayersModificationStatus (0),
156 myRaytraceFilter (new OpenGl_RaytraceFilter()),
157 myToRedrawGL (Standard_True),
159 myAntiAliasingMode (3),
160 myTransientDrawToFront (Standard_True),
161 myBackBufferRestored (Standard_False),
162 myIsImmediateDrawn (Standard_False),
163 myUseZBuffer (Standard_False),
164 myUseDepthTest (Standard_True),
165 myUseGLLight (Standard_True),
166 myIsCullingEnabled (Standard_False),
169 AspectLine_set (&myDefaultAspectLine),
170 AspectLine_applied (NULL),
171 AspectFace_set (&myDefaultAspectFace),
172 AspectFace_applied (NULL),
173 AspectMarker_set (&myDefaultAspectMarker),
174 AspectMarker_applied (NULL),
175 AspectText_set (&myDefaultAspectText),
176 AspectText_applied (NULL),
177 TextParam_set (&myDefaultTextParam),
178 TextParam_applied (NULL),
179 ViewMatrix_applied (&myDefaultMatrix),
180 StructureMatrix_applied (&myDefaultMatrix),
181 myCullingMode (TelCullUndefined),
182 myModelViewMatrix (myDefaultMatrix),
183 PolygonOffset_applied (THE_DEFAULT_POFFSET)
185 myGlContext->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
186 myResultFBO = new OpenGl_FrameBuffer();
188 if (!myGlContext->GetResource ("OpenGl_LineAttributes", myLineAttribs))
190 // share and register for release once the resource is no longer used
191 myLineAttribs = new OpenGl_LineAttributes();
192 myGlContext->ShareResource ("OpenGl_LineAttributes", myLineAttribs);
193 myLineAttribs->Init (myGlContext);
196 // General initialization of the context
198 #if !defined(GL_ES_VERSION_2_0)
199 if (myGlContext->core11 != NULL)
201 // Eviter d'avoir les faces mal orientees en noir.
202 // Pourrait etre utiliser pour detecter les problemes d'orientation
203 glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
205 // Optimisation pour le Fog et l'antialiasing
206 glHint (GL_FOG_HINT, GL_FASTEST);
207 glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST);
210 glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST);
211 glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
215 const char* anAaEnv = ::getenv ("CALL_OPENGL_ANTIALIASING_MODE");
219 if (sscanf (anAaEnv, "%d", &v) > 0) myAntiAliasingMode = v;
223 // =======================================================================
224 // function : SetImmediateModeDrawToFront
226 // =======================================================================
227 Standard_Boolean OpenGl_Workspace::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer)
229 const Standard_Boolean aPrevMode = myTransientDrawToFront;
230 myTransientDrawToFront = theDrawToFrontBuffer;
234 // =======================================================================
235 // function : ~OpenGl_Workspace
237 // =======================================================================
238 OpenGl_Workspace::~OpenGl_Workspace()
240 if (!myLineAttribs.IsNull())
242 myLineAttribs.Nullify();
243 myGlContext->ReleaseResource ("OpenGl_LineAttributes", Standard_True);
246 if (!myResultFBO.IsNull())
248 myResultFBO->Release (myGlContext.operator->());
249 myResultFBO.Nullify();
251 if (myFullScreenQuad.IsValid())
253 myFullScreenQuad.Release (myGlContext.operator->());
256 ReleaseRaytraceResources();
259 // =======================================================================
260 // function : Activate
262 // =======================================================================
263 Standard_Boolean OpenGl_Workspace::Activate()
265 if (!OpenGl_Window::Activate())
266 return Standard_False;
268 ViewMatrix_applied = &myDefaultMatrix;
269 StructureMatrix_applied = &myDefaultMatrix;
271 ResetAppliedAspect();
273 return Standard_True;
276 //=======================================================================
277 //function : ResetAppliedAspect
278 //purpose : Sets default values of GL parameters in accordance with default aspects
279 //=======================================================================
280 void OpenGl_Workspace::ResetAppliedAspect()
282 myGlContext->BindDefaultVao();
284 NamedStatus = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0;
285 HighlightColor = &THE_WHITE_COLOR;
286 AspectLine_set = &myDefaultAspectLine;
287 AspectLine_applied = NULL;
288 AspectFace_set = &myDefaultAspectFace;
289 AspectFace_applied = NULL;
290 AspectMarker_set = &myDefaultAspectMarker;
291 AspectMarker_applied = NULL;
292 AspectText_set = &myDefaultAspectText;
293 AspectText_applied = NULL;
294 TextParam_set = &myDefaultTextParam;
295 TextParam_applied = NULL;
296 PolygonOffset_applied = THE_DEFAULT_POFFSET;
297 myCullingMode = TelCullUndefined;
299 AspectLine(Standard_True);
300 AspectFace(Standard_True);
301 AspectMarker(Standard_True);
302 AspectText(Standard_True);
305 // =======================================================================
306 // function : DisableTexture
308 // =======================================================================
309 Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
311 if (myTextureBound.IsNull())
313 return myTextureBound;
316 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
317 if (!aSampler.IsNull())
319 aSampler->Unbind (*myGlContext);
322 #if !defined(GL_ES_VERSION_2_0)
323 // reset texture matrix because some code may expect it is identity
324 if (myGlContext->core11 != NULL)
326 GLint aMatrixMode = GL_TEXTURE;
327 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
328 glMatrixMode (GL_TEXTURE);
330 glMatrixMode (aMatrixMode);
334 myTextureBound->Unbind (myGlContext);
335 switch (myTextureBound->GetTarget())
337 #if !defined(GL_ES_VERSION_2_0)
340 if (myGlContext->core11 != NULL)
342 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
344 glDisable (GL_TEXTURE_GEN_S);
346 glDisable (GL_TEXTURE_1D);
353 #if !defined(GL_ES_VERSION_2_0)
354 if (myGlContext->core11 != NULL)
356 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
358 glDisable (GL_TEXTURE_GEN_S);
359 glDisable (GL_TEXTURE_GEN_T);
360 if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE)
362 glDisable (GL_POINT_SPRITE);
365 glDisable (GL_TEXTURE_2D);
373 Handle(OpenGl_Texture) aPrevTexture = myTextureBound;
374 myTextureBound.Nullify();
378 // =======================================================================
379 // function : setTextureParams
381 // =======================================================================
382 void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& theTexture,
383 const Handle(Graphic3d_TextureParams)& theParams)
385 const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams;
386 if (aParams.IsNull())
391 #if !defined(GL_ES_VERSION_2_0)
392 GLint aMatrixMode = GL_TEXTURE;
393 if (myGlContext->core11 != NULL)
395 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
397 // setup texture matrix
398 glMatrixMode (GL_TEXTURE);
399 OpenGl_Mat4 aTextureMat;
400 const Graphic3d_Vec2& aScale = aParams->Scale();
401 const Graphic3d_Vec2& aTrans = aParams->Translation();
402 OpenGl_Utils::Scale (aTextureMat, aScale.x(), aScale.y(), 1.0f);
403 OpenGl_Utils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f);
404 OpenGl_Utils::Rotate (aTextureMat, -aParams->Rotation(), 0.0f, 0.0f, 1.0f);
405 glLoadMatrixf (aTextureMat);
407 GLint anEnvMode = GL_MODULATE; // lighting mode
408 if (!aParams->IsModulate())
410 anEnvMode = GL_DECAL;
411 if (theTexture->GetFormat() == GL_ALPHA
412 || theTexture->GetFormat() == GL_LUMINANCE)
414 anEnvMode = GL_REPLACE;
418 // setup generation of texture coordinates
419 switch (aParams->GenMode())
421 case Graphic3d_TOTM_OBJECT:
423 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
424 glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData());
425 if (theTexture->GetTarget() != GL_TEXTURE_1D)
427 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
428 glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData());
432 case Graphic3d_TOTM_SPHERE:
434 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
435 if (theTexture->GetTarget() != GL_TEXTURE_1D)
437 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
441 case Graphic3d_TOTM_EYE:
443 myGlContext->WorldViewState.Push();
445 myGlContext->WorldViewState.SetIdentity();
446 myGlContext->ApplyWorldViewMatrix();
448 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
449 glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData());
451 if (theTexture->GetTarget() != GL_TEXTURE_1D)
453 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
454 glTexGenfv (GL_T, GL_EYE_PLANE, aParams->GenPlaneT().GetData());
457 myGlContext->WorldViewState.Pop();
461 case Graphic3d_TOTM_SPRITE:
463 if (GetGlContext()->core20fwd != NULL)
465 glEnable (GL_POINT_SPRITE);
466 glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
467 anEnvMode = GL_REPLACE;
468 GetGlContext()->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
472 case Graphic3d_TOTM_MANUAL:
477 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
481 // get active sampler object to override default texture parameters
482 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
484 // setup texture filtering and wrapping
485 //if (theTexture->GetParams() != theParams)
486 const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
487 const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : myGlContext->TextureWrapClamp();
488 switch (theTexture->GetTarget())
490 #if !defined(GL_ES_VERSION_2_0)
493 if (aSampler.IsNull() || !aSampler->IsValid())
495 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
496 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
497 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
501 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
502 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilter);
503 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
511 GLenum aFilterMin = aFilter;
512 if (theTexture->HasMipmaps())
514 aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
515 if (aParams->Filter() == Graphic3d_TOTF_BILINEAR)
517 aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
519 else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR)
521 aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
524 if (myGlContext->extAnis)
526 // setup degree of anisotropy filter
527 const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
529 switch (aParams->AnisoFilter())
531 case Graphic3d_LOTA_QUALITY:
533 aDegree = aMaxDegree;
536 case Graphic3d_LOTA_MIDDLE:
538 aDegree = (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2);
541 case Graphic3d_LOTA_FAST:
546 case Graphic3d_LOTA_OFF:
554 if (aSampler.IsNull() || !aSampler->IsValid())
556 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
560 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
565 if (aSampler.IsNull() || !aSampler->IsValid())
567 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
568 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
569 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
570 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
574 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilterMin);
575 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
576 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
577 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_T, aWrapMode);
585 switch (theTexture->GetTarget())
587 #if !defined(GL_ES_VERSION_2_0)
590 if (myGlContext->core11 != NULL)
592 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
594 glEnable (GL_TEXTURE_GEN_S);
596 glEnable (GL_TEXTURE_1D);
603 #if !defined(GL_ES_VERSION_2_0)
604 if (myGlContext->core11 != NULL)
606 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
608 glEnable (GL_TEXTURE_GEN_S);
609 glEnable (GL_TEXTURE_GEN_T);
611 glEnable (GL_TEXTURE_2D);
619 #if !defined(GL_ES_VERSION_2_0)
620 if (myGlContext->core11 != NULL)
622 glMatrixMode (aMatrixMode); // turn back active matrix
625 theTexture->SetParams (aParams);
628 // =======================================================================
629 // function : EnableTexture
631 // =======================================================================
632 Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture,
633 const Handle(Graphic3d_TextureParams)& theParams)
635 if (theTexture.IsNull() || !theTexture->IsValid())
637 return DisableTexture();
640 if (myTextureBound == theTexture
641 && (theParams.IsNull() || theParams == theTexture->GetParams()))
644 return myTextureBound;
647 Handle(OpenGl_Texture) aPrevTexture = DisableTexture();
648 myTextureBound = theTexture;
649 myTextureBound->Bind (myGlContext);
650 setTextureParams (myTextureBound, theParams);
652 // If custom sampler object is available it will be
653 // used for overriding default texture parameters
654 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
656 if (!aSampler.IsNull() && aSampler->IsValid())
658 aSampler->Bind (*myGlContext);
664 // =======================================================================
667 // =======================================================================
668 void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
669 const Aspect_CLayer2d& theCUnderLayer,
670 const Aspect_CLayer2d& theCOverLayer)
678 myIsCullingEnabled = theCView.IsCullingEnabled;
680 // release pending GL resources
681 myGlContext->ReleaseDelayed();
683 // fetch OpenGl context state
684 myGlContext->FetchState();
686 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theCView.ptrFBO;
687 if (aFrameBuffer != NULL)
689 aFrameBuffer->SetupViewport (myGlContext);
693 myGlContext->core11fwd->glViewport (0, 0, myWidth, myHeight);
695 bool toSwap = myGlContext->IsRender()
696 && !myGlContext->caps->buffersNoSwap
697 && aFrameBuffer == NULL;
699 Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth;
700 Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight;
703 && myTransientDrawToFront)
705 if (myResultFBO->GetVPSizeX() != aSizeX
706 || myResultFBO->GetVPSizeY() != aSizeY)
708 // prepare FBOs containing main scene
709 // for further blitting and rendering immediate presentations on top
710 if (myGlContext->core20fwd != NULL)
712 myResultFBO->Init (myGlContext, aSizeX, aSizeY);
716 if (myResultFBO->IsValid())
718 myResultFBO->SetupViewport (myGlContext);
723 myResultFBO->Release (myGlContext.operator->());
726 myToRedrawGL = Standard_True;
727 if (theCView.RenderParams.Method == Graphic3d_RM_RAYTRACING
728 && myComputeInitStatus != OpenGl_RT_FAIL)
730 if (InitRaytraceResources (theCView) && UpdateRaytraceGeometry (OpenGl_GUM_CHECK) && myIsRaytraceDataValid)
732 myToRedrawGL = Standard_False;
734 // Only non-raytracable structures should be rendered in OpenGL mode.
735 Handle(OpenGl_RenderFilter) aRenderFilter = GetRenderFilter();
736 myRaytraceFilter->SetPrevRenderFilter (aRenderFilter);
737 SetRenderFilter (myRaytraceFilter);
739 if (myOpenGlFBO.IsNull())
741 myOpenGlFBO = new OpenGl_FrameBuffer();
743 if (myOpenGlFBO->GetVPSizeX() != aSizeX
744 || myOpenGlFBO->GetVPSizeY() != aSizeY)
746 myOpenGlFBO->Init (myGlContext, aSizeX, aSizeY);
749 // OverLayer and UnderLayer shouldn't be drawn by OpenGL.
750 // They will be drawn during ray-tracing.
751 Aspect_CLayer2d anEmptyCLayer;
752 anEmptyCLayer.ptrLayer = NULL;
754 myOpenGlFBO->BindBuffer (myGlContext);
755 redraw1 (theCView, anEmptyCLayer, anEmptyCLayer);
756 myOpenGlFBO->UnbindBuffer (myGlContext);
758 Raytrace (theCView, aSizeX, aSizeY,
759 theCOverLayer, theCUnderLayer,
760 myResultFBO->IsValid() ? myResultFBO.operator->() : aFrameBuffer);
761 myBackBufferRestored = Standard_True;
762 myIsImmediateDrawn = Standard_False;
763 if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aFrameBuffer))
768 SetRenderFilter (aRenderFilter);
770 theCView.WasRedrawnGL = Standard_False;
776 // draw entire frame using normal OpenGL pipeline
777 if (myResultFBO->IsValid())
779 myResultFBO->BindBuffer (myGlContext);
781 else if (aFrameBuffer != NULL)
783 aFrameBuffer->BindBuffer (myGlContext);
786 redraw1 (theCView, theCUnderLayer, theCOverLayer);
787 myBackBufferRestored = Standard_True;
788 myIsImmediateDrawn = Standard_False;
789 if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aFrameBuffer))
794 theCView.WasRedrawnGL = Standard_True;
797 if (aFrameBuffer != NULL)
799 aFrameBuffer->UnbindBuffer (myGlContext);
800 // move back original viewport
801 myGlContext->core11fwd->glViewport (0, 0, myWidth, myHeight);
804 #if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
805 if (OpenGl_AVIWriter_AllowWriting (theCView.DefWindow.XWindow))
808 glGetIntegerv (GL_VIEWPORT, params);
809 int nWidth = params[2] & ~0x7;
810 int nHeight = params[3] & ~0x7;
812 const int nBitsPerPixel = 24;
813 GLubyte* aDumpData = new GLubyte[nWidth * nHeight * nBitsPerPixel / 8];
815 glPixelStorei (GL_PACK_ALIGNMENT, 1);
816 glReadPixels (0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, aDumpData);
817 OpenGl_AVIWriter_AVIWriter (aDumpData, nWidth, nHeight, nBitsPerPixel);
825 GetGlContext()->SwapBuffers();
826 if (!myResultFBO->IsValid())
828 myBackBufferRestored = Standard_False;
833 myGlContext->core11fwd->glFlush();
836 // reset render mode state
837 myGlContext->FetchState();
840 // =======================================================================
841 // function : redraw1
843 // =======================================================================
844 void OpenGl_Workspace::redraw1 (const Graphic3d_CView& theCView,
845 const Aspect_CLayer2d& theCUnderLayer,
846 const Aspect_CLayer2d& theCOverLayer)
853 // request reset of material
854 NamedStatus |= OPENGL_NS_RESMAT;
856 GLbitfield toClear = GL_COLOR_BUFFER_BIT;
859 glDepthFunc (GL_LEQUAL);
860 glDepthMask (GL_TRUE);
863 glEnable (GL_DEPTH_TEST);
867 glDisable (GL_DEPTH_TEST);
870 #if !defined(GL_ES_VERSION_2_0)
873 glClearDepthf (1.0f);
875 toClear |= GL_DEPTH_BUFFER_BIT;
879 glDisable (GL_DEPTH_TEST);
884 // set background to black
885 glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
886 toClear |= GL_DEPTH_BUFFER_BIT; //
890 if (NamedStatus & OPENGL_NS_WHITEBACK)
892 // set background to white
893 glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
894 toClear |= GL_DEPTH_BUFFER_BIT;
898 glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.0f);
903 Handle(OpenGl_Workspace) aWS (this);
904 myView->Render (myPrintContext, aWS, theCView, theCUnderLayer, theCOverLayer, Standard_False);
907 // =======================================================================
908 // function : copyBackToFront
910 // =======================================================================
911 void OpenGl_Workspace::copyBackToFront()
913 #if !defined(GL_ES_VERSION_2_0)
915 OpenGl_Mat4 aProjectMat;
916 OpenGl_Utils::Ortho2D<Standard_ShortReal> (aProjectMat,
917 0.f, static_cast<GLfloat> (myWidth), 0.f, static_cast<GLfloat> (myHeight));
919 myGlContext->WorldViewState.Push();
920 myGlContext->ProjectionState.Push();
922 myGlContext->WorldViewState.SetIdentity();
923 myGlContext->ProjectionState.SetCurrent (aProjectMat);
925 myGlContext->ApplyProjectionMatrix();
926 myGlContext->ApplyWorldViewMatrix();
930 glDrawBuffer (GL_FRONT);
931 glReadBuffer (GL_BACK);
933 glRasterPos2i (0, 0);
934 glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_COLOR);
935 //glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_DEPTH);
939 myGlContext->WorldViewState.Pop();
940 myGlContext->ProjectionState.Pop();
941 myGlContext->ApplyProjectionMatrix();
942 glDrawBuffer (GL_BACK);
945 myIsImmediateDrawn = Standard_False;
948 // =======================================================================
949 // function : DisplayCallback
951 // =======================================================================
952 void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& theCView,
953 Standard_Integer theReason)
955 if (theCView.GDisplayCB == NULL)
960 Aspect_GraphicCallbackStruct aCallData;
961 aCallData.reason = theReason;
962 aCallData.glContext = myGlContext;
963 aCallData.wsID = theCView.WsId;
964 aCallData.viewID = theCView.ViewId;
965 aCallData.IsCoreProfile = (myGlContext->core11 == NULL);
966 theCView.GDisplayCB (theCView.DefWindow.XWindow, theCView.GClientData, &aCallData);
969 // =======================================================================
970 // function : RedrawImmediate
972 // =======================================================================
973 void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView,
974 const Aspect_CLayer2d& theCUnderLayer,
975 const Aspect_CLayer2d& theCOverLayer)
977 if (!myTransientDrawToFront
978 || !myBackBufferRestored
979 || (myGlContext->caps->buffersNoSwap && !myResultFBO->IsValid()))
981 Redraw (theCView, theCUnderLayer, theCOverLayer);
984 else if (!Activate())
989 if (redrawImmediate (theCView, theCUnderLayer, theCOverLayer, NULL, Standard_True)
990 && !myGlContext->caps->buffersNoSwap)
992 myGlContext->SwapBuffers();
996 myGlContext->core11fwd->glFlush();
997 MakeBackBufCurrent();
1001 // =======================================================================
1002 // function : redrawImmediate
1004 // =======================================================================
1005 bool OpenGl_Workspace::redrawImmediate (const Graphic3d_CView& theCView,
1006 const Aspect_CLayer2d& theCUnderLayer,
1007 const Aspect_CLayer2d& theCOverLayer,
1008 OpenGl_FrameBuffer* theTargetFBO,
1009 const Standard_Boolean theIsPartialUpdate)
1011 GLboolean toCopyBackToFront = GL_FALSE;
1012 if (!myTransientDrawToFront)
1014 myBackBufferRestored = Standard_False;
1016 else if (myResultFBO->IsValid()
1017 && myGlContext->IsRender())
1019 // clear destination before blitting
1020 if (theTargetFBO != NULL)
1022 theTargetFBO->BindBuffer (myGlContext);
1026 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
1028 #if !defined(GL_ES_VERSION_2_0)
1029 myGlContext->core20fwd->glClearDepth (1.0);
1031 myGlContext->core20fwd->glClearDepthf (1.0f);
1033 myGlContext->core20fwd->glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1035 /*#if !defined(GL_ES_VERSION_2_0)
1036 if (myGlContext->arbFBOBlit != NULL)
1038 myResultFBO->BindReadBuffer (myGlContext);
1039 if (theTargetFBO != NULL)
1041 theTargetFBO->BindDrawBuffer (myGlContext);
1045 myGlContext->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
1047 // we don't copy stencil buffer here... does it matter for performance?
1048 myGlContext->arbFBOBlit->glBlitFramebuffer (0, 0, myResultFBO->GetVPSizeX(), myResultFBO->GetVPSizeY(),
1049 0, 0, myResultFBO->GetVPSizeX(), myResultFBO->GetVPSizeY(),
1050 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
1052 if (theTargetFBO != NULL)
1054 theTargetFBO->BindBuffer (myGlContext);
1058 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
1064 myGlContext->core20fwd->glDepthFunc (GL_ALWAYS);
1065 myGlContext->core20fwd->glDepthMask (GL_TRUE);
1066 myGlContext->core20fwd->glEnable (GL_DEPTH_TEST);
1069 if (!myFullScreenQuad.IsValid())
1071 OpenGl_Vec4 aQuad[4] =
1073 OpenGl_Vec4( 1.0f, -1.0f, 1.0f, 0.0f),
1074 OpenGl_Vec4( 1.0f, 1.0f, 1.0f, 1.0f),
1075 OpenGl_Vec4(-1.0f, -1.0f, 0.0f, 0.0f),
1076 OpenGl_Vec4(-1.0f, 1.0f, 0.0f, 1.0f)
1078 myFullScreenQuad.Init (myGlContext, 4, 4, aQuad[0].GetData());
1081 const Handle(OpenGl_ShaderManager)& aManager = myGlContext->ShaderManager();
1082 if (myFullScreenQuad.IsValid()
1083 && aManager->BindFboBlitProgram())
1085 myResultFBO->ColorTexture() ->Bind (myGlContext, GL_TEXTURE0 + 0);
1086 myResultFBO->DepthStencilTexture()->Bind (myGlContext, GL_TEXTURE0 + 1);
1087 myFullScreenQuad.BindVertexAttrib (myGlContext, 0);
1089 myGlContext->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
1091 myFullScreenQuad.UnbindVertexAttrib (myGlContext, 0);
1092 myResultFBO->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + 1);
1093 myResultFBO->ColorTexture() ->Unbind (myGlContext, GL_TEXTURE0 + 0);
1097 TCollection_ExtendedString aMsg = TCollection_ExtendedString()
1098 + "Error! FBO blitting has failed";
1099 myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
1100 GL_DEBUG_TYPE_ERROR_ARB,
1102 GL_DEBUG_SEVERITY_HIGH_ARB,
1104 myHasFboBlit = Standard_False;
1105 myResultFBO->Release (myGlContext.operator->());
1110 else if (theTargetFBO == NULL)
1112 #if !defined(GL_ES_VERSION_2_0)
1113 myGlContext->core11fwd->glGetBooleanv (GL_DOUBLEBUFFER, &toCopyBackToFront);
1115 if (toCopyBackToFront)
1117 if (!myView->HasImmediateStructures()
1118 && !theIsPartialUpdate)
1120 // prefer Swap Buffers within Redraw in compatibility mode (without FBO)
1124 MakeFrontBufCurrent();
1128 myBackBufferRestored = Standard_False;
1133 myBackBufferRestored = Standard_False;
1135 myIsImmediateDrawn = Standard_True;
1137 Handle(OpenGl_Workspace) aWS (this);
1141 glDepthFunc (GL_LEQUAL);
1142 glDepthMask (GL_TRUE);
1145 glEnable (GL_DEPTH_TEST);
1149 glDisable (GL_DEPTH_TEST);
1152 #if !defined(GL_ES_VERSION_2_0)
1155 glClearDepthf (1.0f);
1160 glDisable (GL_DEPTH_TEST);
1163 myView->Render (myPrintContext, aWS, theCView, theCUnderLayer, theCOverLayer, Standard_True);
1164 if (!myView->ImmediateStructures().IsEmpty())
1166 glDisable (GL_DEPTH_TEST);
1168 for (OpenGl_SequenceOfStructure::Iterator anIter (myView->ImmediateStructures());
1169 anIter.More(); anIter.Next())
1171 const OpenGl_Structure* aStructure = anIter.Value();
1172 if (!aStructure->IsVisible())
1177 aStructure->Render (aWS);
1180 if (toCopyBackToFront)
1182 MakeBackBufCurrent();