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 myResultFBO = new OpenGl_FrameBuffer();
181 if (!myGlContext->GetResource ("OpenGl_LineAttributes", myLineAttribs))
183 // share and register for release once the resource is no longer used
184 myLineAttribs = new OpenGl_LineAttributes();
185 myGlContext->ShareResource ("OpenGl_LineAttributes", myLineAttribs);
186 myLineAttribs->Init (myGlContext);
189 // General initialization of the context
191 #if !defined(GL_ES_VERSION_2_0)
192 if (myGlContext->core11 != NULL)
194 // Eviter d'avoir les faces mal orientees en noir.
195 // Pourrait etre utiliser pour detecter les problemes d'orientation
196 glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
198 // Optimisation pour le Fog et l'antialiasing
199 glHint (GL_FOG_HINT, GL_FASTEST);
200 glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST);
203 glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST);
204 glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
208 const char* anAaEnv = ::getenv ("CALL_OPENGL_ANTIALIASING_MODE");
212 if (sscanf (anAaEnv, "%d", &v) > 0) myAntiAliasingMode = v;
216 // =======================================================================
217 // function : SetImmediateModeDrawToFront
219 // =======================================================================
220 Standard_Boolean OpenGl_Workspace::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer)
222 const Standard_Boolean aPrevMode = myTransientDrawToFront;
223 myTransientDrawToFront = theDrawToFrontBuffer;
227 // =======================================================================
228 // function : ~OpenGl_Workspace
230 // =======================================================================
231 OpenGl_Workspace::~OpenGl_Workspace()
233 if (!myLineAttribs.IsNull())
235 myLineAttribs.Nullify();
236 myGlContext->ReleaseResource ("OpenGl_LineAttributes", Standard_True);
239 if (!myResultFBO.IsNull())
241 myResultFBO->Release (myGlContext.operator->());
242 myResultFBO.Nullify();
244 if (myFullScreenQuad.IsValid())
246 myFullScreenQuad.Release (myGlContext.operator->());
250 // =======================================================================
251 // function : Activate
253 // =======================================================================
254 Standard_Boolean OpenGl_Workspace::Activate()
256 if (!OpenGl_Window::Activate())
257 return Standard_False;
259 ViewMatrix_applied = &myDefaultMatrix;
260 StructureMatrix_applied = &myDefaultMatrix;
262 ResetAppliedAspect();
264 return Standard_True;
267 //=======================================================================
268 //function : ResetAppliedAspect
269 //purpose : Sets default values of GL parameters in accordance with default aspects
270 //=======================================================================
271 void OpenGl_Workspace::ResetAppliedAspect()
273 myGlContext->BindDefaultVao();
275 NamedStatus = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0;
276 HighlightColor = &THE_WHITE_COLOR;
277 AspectLine_set = &myDefaultAspectLine;
278 AspectLine_applied = NULL;
279 AspectFace_set = &myDefaultAspectFace;
280 AspectFace_applied = NULL;
281 AspectMarker_set = &myDefaultAspectMarker;
282 AspectMarker_applied = NULL;
283 AspectText_set = &myDefaultAspectText;
284 AspectText_applied = NULL;
285 TextParam_set = &myDefaultTextParam;
286 TextParam_applied = NULL;
287 PolygonOffset_applied = THE_DEFAULT_POFFSET;
288 myCullingMode = TelCullUndefined;
290 AspectLine(Standard_True);
291 AspectFace(Standard_True);
292 AspectMarker(Standard_True);
293 AspectText(Standard_True);
296 // =======================================================================
297 // function : DisableTexture
299 // =======================================================================
300 Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
302 if (myTextureBound.IsNull())
304 return myTextureBound;
307 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
308 if (!aSampler.IsNull())
310 aSampler->Unbind (*myGlContext);
313 #if !defined(GL_ES_VERSION_2_0)
314 // reset texture matrix because some code may expect it is identity
315 if (myGlContext->core11 != NULL)
317 GLint aMatrixMode = GL_TEXTURE;
318 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
319 glMatrixMode (GL_TEXTURE);
321 glMatrixMode (aMatrixMode);
325 myTextureBound->Unbind (myGlContext);
326 switch (myTextureBound->GetTarget())
328 #if !defined(GL_ES_VERSION_2_0)
331 if (myGlContext->core11 != NULL)
333 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
335 glDisable (GL_TEXTURE_GEN_S);
337 glDisable (GL_TEXTURE_1D);
344 #if !defined(GL_ES_VERSION_2_0)
345 if (myGlContext->core11 != NULL)
347 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
349 glDisable (GL_TEXTURE_GEN_S);
350 glDisable (GL_TEXTURE_GEN_T);
351 if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE)
353 glDisable (GL_POINT_SPRITE);
356 glDisable (GL_TEXTURE_2D);
364 Handle(OpenGl_Texture) aPrevTexture = myTextureBound;
365 myTextureBound.Nullify();
369 // =======================================================================
370 // function : setTextureParams
372 // =======================================================================
373 void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& theTexture,
374 const Handle(Graphic3d_TextureParams)& theParams)
376 const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams;
377 if (aParams.IsNull())
382 #if !defined(GL_ES_VERSION_2_0)
383 GLint aMatrixMode = GL_TEXTURE;
384 if (myGlContext->core11 != NULL)
386 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
388 // setup texture matrix
389 glMatrixMode (GL_TEXTURE);
390 OpenGl_Mat4 aTextureMat;
391 const Graphic3d_Vec2& aScale = aParams->Scale();
392 const Graphic3d_Vec2& aTrans = aParams->Translation();
393 OpenGl_Utils::Scale (aTextureMat, aScale.x(), aScale.y(), 1.0f);
394 OpenGl_Utils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f);
395 OpenGl_Utils::Rotate (aTextureMat, -aParams->Rotation(), 0.0f, 0.0f, 1.0f);
396 glLoadMatrixf (aTextureMat);
398 GLint anEnvMode = GL_MODULATE; // lighting mode
399 if (!aParams->IsModulate())
401 anEnvMode = GL_DECAL;
402 if (theTexture->GetFormat() == GL_ALPHA
403 || theTexture->GetFormat() == GL_LUMINANCE)
405 anEnvMode = GL_REPLACE;
409 // setup generation of texture coordinates
410 switch (aParams->GenMode())
412 case Graphic3d_TOTM_OBJECT:
414 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
415 glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData());
416 if (theTexture->GetTarget() != GL_TEXTURE_1D)
418 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
419 glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData());
423 case Graphic3d_TOTM_SPHERE:
425 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
426 if (theTexture->GetTarget() != GL_TEXTURE_1D)
428 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
432 case Graphic3d_TOTM_EYE:
434 myGlContext->WorldViewState.Push();
436 myGlContext->WorldViewState.SetIdentity();
437 myGlContext->ApplyWorldViewMatrix();
439 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
440 glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData());
442 if (theTexture->GetTarget() != GL_TEXTURE_1D)
444 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
445 glTexGenfv (GL_T, GL_EYE_PLANE, aParams->GenPlaneT().GetData());
448 myGlContext->WorldViewState.Pop();
452 case Graphic3d_TOTM_SPRITE:
454 if (GetGlContext()->core20fwd != NULL)
456 glEnable (GL_POINT_SPRITE);
457 glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
458 anEnvMode = GL_REPLACE;
459 GetGlContext()->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
463 case Graphic3d_TOTM_MANUAL:
468 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
472 // get active sampler object to override default texture parameters
473 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
475 // setup texture filtering and wrapping
476 //if (theTexture->GetParams() != theParams)
477 const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
478 const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : myGlContext->TextureWrapClamp();
479 switch (theTexture->GetTarget())
481 #if !defined(GL_ES_VERSION_2_0)
484 if (aSampler.IsNull() || !aSampler->IsValid())
486 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
487 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
488 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
492 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
493 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilter);
494 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
502 GLenum aFilterMin = aFilter;
503 if (theTexture->HasMipmaps())
505 aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
506 if (aParams->Filter() == Graphic3d_TOTF_BILINEAR)
508 aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
510 else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR)
512 aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
515 if (myGlContext->extAnis)
517 // setup degree of anisotropy filter
518 const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
520 switch (aParams->AnisoFilter())
522 case Graphic3d_LOTA_QUALITY:
524 aDegree = aMaxDegree;
527 case Graphic3d_LOTA_MIDDLE:
529 aDegree = (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2);
532 case Graphic3d_LOTA_FAST:
537 case Graphic3d_LOTA_OFF:
545 if (aSampler.IsNull() || !aSampler->IsValid())
547 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
551 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
556 if (aSampler.IsNull() || !aSampler->IsValid())
558 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
559 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
560 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
561 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
565 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilterMin);
566 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
567 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
568 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_T, aWrapMode);
576 switch (theTexture->GetTarget())
578 #if !defined(GL_ES_VERSION_2_0)
581 if (myGlContext->core11 != NULL)
583 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
585 glEnable (GL_TEXTURE_GEN_S);
587 glEnable (GL_TEXTURE_1D);
594 #if !defined(GL_ES_VERSION_2_0)
595 if (myGlContext->core11 != NULL)
597 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
599 glEnable (GL_TEXTURE_GEN_S);
600 glEnable (GL_TEXTURE_GEN_T);
602 glEnable (GL_TEXTURE_2D);
610 #if !defined(GL_ES_VERSION_2_0)
611 if (myGlContext->core11 != NULL)
613 glMatrixMode (aMatrixMode); // turn back active matrix
616 theTexture->SetParams (aParams);
619 // =======================================================================
620 // function : EnableTexture
622 // =======================================================================
623 Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture,
624 const Handle(Graphic3d_TextureParams)& theParams)
626 if (theTexture.IsNull() || !theTexture->IsValid())
628 return DisableTexture();
631 if (myTextureBound == theTexture
632 && (theParams.IsNull() || theParams == theTexture->GetParams()))
635 return myTextureBound;
638 Handle(OpenGl_Texture) aPrevTexture = DisableTexture();
639 myTextureBound = theTexture;
640 myTextureBound->Bind (myGlContext);
641 setTextureParams (myTextureBound, theParams);
643 // If custom sampler object is available it will be
644 // used for overriding default texture parameters
645 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
647 if (!aSampler.IsNull() && aSampler->IsValid())
649 aSampler->Bind (*myGlContext);
655 // =======================================================================
658 // =======================================================================
659 void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
660 const Aspect_CLayer2d& theCUnderLayer,
661 const Aspect_CLayer2d& theCOverLayer)
669 myIsCullingEnabled = theCView.IsCullingEnabled;
671 // release pending GL resources
672 myGlContext->ReleaseDelayed();
674 // fetch OpenGl context state
675 myGlContext->FetchState();
677 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theCView.ptrFBO;
678 if (aFrameBuffer != NULL)
680 aFrameBuffer->SetupViewport (myGlContext);
684 myGlContext->core11fwd->glViewport (0, 0, myWidth, myHeight);
686 bool toSwap = myGlContext->IsRender()
687 && !myGlContext->caps->buffersNoSwap
688 && aFrameBuffer == NULL;
690 Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth;
691 Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight;
693 if (!myGlContext->DefaultFrameBuffer().IsNull()
694 && myGlContext->DefaultFrameBuffer()->IsValid())
696 myGlContext->DefaultFrameBuffer()->BindBuffer (myGlContext);
700 && myTransientDrawToFront)
702 if (myResultFBO->GetVPSizeX() != aSizeX
703 || myResultFBO->GetVPSizeY() != aSizeY)
705 // prepare FBOs containing main scene
706 // for further blitting and rendering immediate presentations on top
707 if (myGlContext->core20fwd != NULL)
709 myResultFBO->Init (myGlContext, aSizeX, aSizeY);
713 if (myResultFBO->IsValid())
715 myResultFBO->SetupViewport (myGlContext);
720 myResultFBO->Release (myGlContext.operator->());
721 myResultFBO->ChangeViewport (0, 0);
724 // draw entire frame using normal OpenGL pipeline
725 if (myResultFBO->IsValid())
727 myResultFBO->BindBuffer (myGlContext);
729 else if (aFrameBuffer != NULL)
731 aFrameBuffer->BindBuffer (myGlContext);
734 redraw1 (theCView, theCUnderLayer, theCOverLayer);
735 myBackBufferRestored = Standard_True;
736 myIsImmediateDrawn = Standard_False;
737 if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aFrameBuffer))
742 if (aFrameBuffer != NULL)
744 aFrameBuffer->UnbindBuffer (myGlContext);
745 // move back original viewport
746 myGlContext->core11fwd->glViewport (0, 0, myWidth, myHeight);
749 #if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
750 if (OpenGl_AVIWriter_AllowWriting (theCView.DefWindow.XWindow))
753 glGetIntegerv (GL_VIEWPORT, params);
754 int nWidth = params[2] & ~0x7;
755 int nHeight = params[3] & ~0x7;
757 const int nBitsPerPixel = 24;
758 GLubyte* aDumpData = new GLubyte[nWidth * nHeight * nBitsPerPixel / 8];
760 glPixelStorei (GL_PACK_ALIGNMENT, 1);
761 glReadPixels (0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, aDumpData);
762 OpenGl_AVIWriter_AVIWriter (aDumpData, nWidth, nHeight, nBitsPerPixel);
770 GetGlContext()->SwapBuffers();
771 if (!myResultFBO->IsValid())
773 myBackBufferRestored = Standard_False;
778 myGlContext->core11fwd->glFlush();
781 // reset render mode state
782 myGlContext->FetchState();
785 // =======================================================================
786 // function : redraw1
788 // =======================================================================
789 void OpenGl_Workspace::redraw1 (const Graphic3d_CView& theCView,
790 const Aspect_CLayer2d& theCUnderLayer,
791 const Aspect_CLayer2d& theCOverLayer)
798 // request reset of material
799 NamedStatus |= OPENGL_NS_RESMAT;
801 GLbitfield toClear = GL_COLOR_BUFFER_BIT;
804 glDepthFunc (GL_LEQUAL);
805 glDepthMask (GL_TRUE);
808 glEnable (GL_DEPTH_TEST);
812 glDisable (GL_DEPTH_TEST);
815 #if !defined(GL_ES_VERSION_2_0)
818 glClearDepthf (1.0f);
820 toClear |= GL_DEPTH_BUFFER_BIT;
824 glDisable (GL_DEPTH_TEST);
827 if (NamedStatus & OPENGL_NS_WHITEBACK)
829 // set background to white
830 glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
831 toClear |= GL_DEPTH_BUFFER_BIT;
835 glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.0f);
840 Handle(OpenGl_Workspace) aWS (this);
841 myView->Render (myPrintContext, aWS, theCView, theCUnderLayer, theCOverLayer, Standard_False);
844 // =======================================================================
845 // function : copyBackToFront
847 // =======================================================================
848 void OpenGl_Workspace::copyBackToFront()
850 #if !defined(GL_ES_VERSION_2_0)
852 OpenGl_Mat4 aProjectMat;
853 OpenGl_Utils::Ortho2D<Standard_ShortReal> (aProjectMat,
854 0.f, static_cast<GLfloat> (myWidth), 0.f, static_cast<GLfloat> (myHeight));
856 myGlContext->WorldViewState.Push();
857 myGlContext->ProjectionState.Push();
859 myGlContext->WorldViewState.SetIdentity();
860 myGlContext->ProjectionState.SetCurrent (aProjectMat);
862 myGlContext->ApplyProjectionMatrix();
863 myGlContext->ApplyWorldViewMatrix();
867 glDrawBuffer (GL_FRONT);
868 glReadBuffer (GL_BACK);
870 glRasterPos2i (0, 0);
871 glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_COLOR);
872 //glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_DEPTH);
876 myGlContext->WorldViewState.Pop();
877 myGlContext->ProjectionState.Pop();
878 myGlContext->ApplyProjectionMatrix();
879 glDrawBuffer (GL_BACK);
882 myIsImmediateDrawn = Standard_False;
885 // =======================================================================
886 // function : DisplayCallback
888 // =======================================================================
889 void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& theCView,
890 Standard_Integer theReason)
892 if (theCView.GDisplayCB == NULL)
897 Aspect_GraphicCallbackStruct aCallData;
898 aCallData.reason = theReason;
899 aCallData.glContext = myGlContext;
900 aCallData.wsID = theCView.WsId;
901 aCallData.viewID = theCView.ViewId;
902 aCallData.IsCoreProfile = (myGlContext->core11 == NULL);
903 theCView.GDisplayCB (theCView.DefWindow.XWindow, theCView.GClientData, &aCallData);
906 // =======================================================================
907 // function : RedrawImmediate
909 // =======================================================================
910 void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView,
911 const Aspect_CLayer2d& theCUnderLayer,
912 const Aspect_CLayer2d& theCOverLayer)
914 if (!myTransientDrawToFront
915 || !myBackBufferRestored
916 || (myGlContext->caps->buffersNoSwap && !myResultFBO->IsValid()))
918 Redraw (theCView, theCUnderLayer, theCOverLayer);
921 else if (!Activate())
926 if (!myGlContext->DefaultFrameBuffer().IsNull()
927 && myGlContext->DefaultFrameBuffer()->IsValid())
929 myGlContext->DefaultFrameBuffer()->BindBuffer (myGlContext);
932 if (redrawImmediate (theCView, theCUnderLayer, theCOverLayer, NULL, Standard_True)
933 && !myGlContext->caps->buffersNoSwap)
935 myGlContext->SwapBuffers();
939 myGlContext->core11fwd->glFlush();
940 MakeBackBufCurrent();
944 // =======================================================================
945 // function : redrawImmediate
947 // =======================================================================
948 bool OpenGl_Workspace::redrawImmediate (const Graphic3d_CView& theCView,
949 const Aspect_CLayer2d& theCUnderLayer,
950 const Aspect_CLayer2d& theCOverLayer,
951 OpenGl_FrameBuffer* theTargetFBO,
952 const Standard_Boolean theIsPartialUpdate)
954 GLboolean toCopyBackToFront = GL_FALSE;
955 if (!myTransientDrawToFront)
957 myBackBufferRestored = Standard_False;
959 else if (myResultFBO->IsValid()
960 && myGlContext->IsRender())
962 // clear destination before blitting
963 if (theTargetFBO != NULL)
965 theTargetFBO->BindBuffer (myGlContext);
967 else if (!myGlContext->DefaultFrameBuffer().IsNull()
968 && myGlContext->DefaultFrameBuffer()->IsValid())
970 myGlContext->DefaultFrameBuffer()->BindBuffer (myGlContext);
974 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
976 #if !defined(GL_ES_VERSION_2_0)
977 myGlContext->core20fwd->glClearDepth (1.0);
979 myGlContext->core20fwd->glClearDepthf (1.0f);
981 myGlContext->core20fwd->glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
983 /*#if !defined(GL_ES_VERSION_2_0)
984 if (myGlContext->arbFBOBlit != NULL)
986 myResultFBO->BindReadBuffer (myGlContext);
987 if (theTargetFBO != NULL)
989 theTargetFBO->BindDrawBuffer (myGlContext);
991 else if (!myGlContext->DefaultFrameBuffer().IsNull()
992 && myGlContext->DefaultFrameBuffer()->IsValid())
994 myGlContext->DefaultFrameBuffer()->BindDrawBuffer (myGlContext);
998 myGlContext->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
1000 // we don't copy stencil buffer here... does it matter for performance?
1001 myGlContext->arbFBOBlit->glBlitFramebuffer (0, 0, myResultFBO->GetVPSizeX(), myResultFBO->GetVPSizeY(),
1002 0, 0, myResultFBO->GetVPSizeX(), myResultFBO->GetVPSizeY(),
1003 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
1005 if (theTargetFBO != NULL)
1007 theTargetFBO->BindBuffer (myGlContext);
1009 else if (!myGlContext->DefaultFrameBuffer().IsNull()
1010 && myGlContext->DefaultFrameBuffer()->IsValid())
1012 myGlContext->DefaultFrameBuffer()->BindBuffer (myGlContext);
1016 myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
1022 myGlContext->core20fwd->glDepthFunc (GL_ALWAYS);
1023 myGlContext->core20fwd->glDepthMask (GL_TRUE);
1024 myGlContext->core20fwd->glEnable (GL_DEPTH_TEST);
1027 if (!myFullScreenQuad.IsValid())
1029 OpenGl_Vec4 aQuad[4] =
1031 OpenGl_Vec4( 1.0f, -1.0f, 1.0f, 0.0f),
1032 OpenGl_Vec4( 1.0f, 1.0f, 1.0f, 1.0f),
1033 OpenGl_Vec4(-1.0f, -1.0f, 0.0f, 0.0f),
1034 OpenGl_Vec4(-1.0f, 1.0f, 0.0f, 1.0f)
1036 myFullScreenQuad.Init (myGlContext, 4, 4, aQuad[0].GetData());
1039 const Handle(OpenGl_ShaderManager)& aManager = myGlContext->ShaderManager();
1040 if (myFullScreenQuad.IsValid()
1041 && aManager->BindFboBlitProgram())
1043 myResultFBO->ColorTexture() ->Bind (myGlContext, GL_TEXTURE0 + 0);
1044 myResultFBO->DepthStencilTexture()->Bind (myGlContext, GL_TEXTURE0 + 1);
1045 myFullScreenQuad.BindVertexAttrib (myGlContext, 0);
1047 myGlContext->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
1049 myFullScreenQuad.UnbindVertexAttrib (myGlContext, 0);
1050 myResultFBO->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + 1);
1051 myResultFBO->ColorTexture() ->Unbind (myGlContext, GL_TEXTURE0 + 0);
1055 TCollection_ExtendedString aMsg = TCollection_ExtendedString()
1056 + "Error! FBO blitting has failed";
1057 myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
1058 GL_DEBUG_TYPE_ERROR_ARB,
1060 GL_DEBUG_SEVERITY_HIGH_ARB,
1062 myHasFboBlit = Standard_False;
1063 myResultFBO->Release (myGlContext.operator->());
1068 else if (theTargetFBO == NULL)
1070 #if !defined(GL_ES_VERSION_2_0)
1071 myGlContext->core11fwd->glGetBooleanv (GL_DOUBLEBUFFER, &toCopyBackToFront);
1073 if (toCopyBackToFront)
1075 if (!myView->HasImmediateStructures()
1076 && !theIsPartialUpdate)
1078 // prefer Swap Buffers within Redraw in compatibility mode (without FBO)
1082 MakeFrontBufCurrent();
1086 myBackBufferRestored = Standard_False;
1091 myBackBufferRestored = Standard_False;
1093 myIsImmediateDrawn = Standard_True;
1095 Handle(OpenGl_Workspace) aWS (this);
1099 glDepthFunc (GL_LEQUAL);
1100 glDepthMask (GL_TRUE);
1103 glEnable (GL_DEPTH_TEST);
1107 glDisable (GL_DEPTH_TEST);
1110 #if !defined(GL_ES_VERSION_2_0)
1113 glClearDepthf (1.0f);
1118 glDisable (GL_DEPTH_TEST);
1121 myView->Render (myPrintContext, aWS, theCView, theCUnderLayer, theCOverLayer, Standard_True);
1122 if (!myView->ImmediateStructures().IsEmpty())
1124 glDisable (GL_DEPTH_TEST);
1126 for (OpenGl_SequenceOfStructure::Iterator anIter (myView->ImmediateStructures());
1127 anIter.More(); anIter.Next())
1129 const OpenGl_Structure* aStructure = anIter.Value();
1130 if (!aStructure->IsVisible())
1135 aStructure->Render (aWS);
1138 if (toCopyBackToFront)
1140 MakeBackBufCurrent();
1146 IMPLEMENT_STANDARD_HANDLE (OpenGl_RaytraceFilter, OpenGl_RenderFilter)
1147 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RaytraceFilter, OpenGl_RenderFilter)
1149 // =======================================================================
1150 // function : CanRender
1152 // =======================================================================
1153 Standard_Boolean OpenGl_RaytraceFilter::CanRender (const OpenGl_Element* theElement)
1155 Standard_Boolean aPrevFilterResult = Standard_True;
1156 if (!myPrevRenderFilter.IsNull())
1158 aPrevFilterResult = myPrevRenderFilter->CanRender (theElement);
1160 return aPrevFilterResult &&
1161 !OpenGl_Raytrace::IsRaytracedElement (theElement);