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_Workspace.hxx>
18 #include <OpenGl_ArbFBO.hxx>
19 #include <OpenGl_AspectLine.hxx>
20 #include <OpenGl_AspectFace.hxx>
21 #include <OpenGl_AspectMarker.hxx>
22 #include <OpenGl_AspectText.hxx>
23 #include <OpenGl_Context.hxx>
24 #include <OpenGl_Element.hxx>
25 #include <OpenGl_FrameBuffer.hxx>
26 #include <OpenGl_GlCore15.hxx>
27 #include <OpenGl_SceneGeometry.hxx>
28 #include <OpenGl_Structure.hxx>
29 #include <OpenGl_Sampler.hxx>
30 #include <OpenGl_ShaderManager.hxx>
31 #include <OpenGl_Texture.hxx>
32 #include <OpenGl_View.hxx>
33 #include <OpenGl_Window.hxx>
35 #include <Graphic3d_TextureParams.hxx>
36 #include <Graphic3d_TransformUtils.hxx>
37 #include <NCollection_AlignedAllocator.hxx>
39 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Workspace,Standard_Transient)
40 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RaytraceFilter,OpenGl_RenderFilter)
44 /* OCC22216 NOTE: linker dependency can be switched off by undefining macro.
45 Pragma comment for gl2ps.lib is defined only here. */
47 #pragma comment( lib, "gl2ps.lib" )
53 static const OpenGl_Vec4 THE_WHITE_COLOR (1.0f, 1.0f, 1.0f, 1.0f);
54 static const OpenGl_Vec4 THE_BLACK_COLOR (0.0f, 0.0f, 0.0f, 1.0f);
56 static const OpenGl_AspectLine myDefaultAspectLine;
57 static const OpenGl_AspectFace myDefaultAspectFace;
58 static const OpenGl_AspectMarker myDefaultAspectMarker;
59 static const OpenGl_AspectText myDefaultAspectText;
61 static const OpenGl_Matrix myDefaultMatrix =
63 {{ 1.0F, 0.0F, 0.0F, 0.0F },
64 { 0.0F, 1.0F, 0.0F, 0.0F },
65 { 0.0F, 0.0F, 1.0F, 0.0F },
66 { 0.0F, 0.0F, 0.0F, 1.0F }}
71 // =======================================================================
74 // =======================================================================
75 void OpenGl_Material::Init (const Graphic3d_MaterialAspect& theMat,
76 const Quantity_Color& theInteriorColor)
78 const bool isPhysic = theMat.MaterialType (Graphic3d_MATERIAL_PHYSIC);
79 ChangeShine() = 128.0f * theMat.Shininess();
80 ChangeTransparency() = theMat.Alpha();
83 if (theMat.ReflectionMode (Graphic3d_TOR_AMBIENT))
85 const OpenGl_Vec3& aSrcAmb = isPhysic ? theMat.AmbientColor() : theInteriorColor;
86 Ambient = OpenGl_Vec4 (aSrcAmb * theMat.Ambient(), 1.0f);
90 Ambient = THE_BLACK_COLOR;
93 // diffusion component
94 if (theMat.ReflectionMode (Graphic3d_TOR_DIFFUSE))
96 const OpenGl_Vec3& aSrcDif = isPhysic ? theMat.DiffuseColor() : theInteriorColor;
97 Diffuse = OpenGl_Vec4 (aSrcDif * theMat.Diffuse(), 1.0f);
101 Diffuse = THE_BLACK_COLOR;
104 // specular component
105 if (theMat.ReflectionMode (Graphic3d_TOR_SPECULAR))
107 const OpenGl_Vec3& aSrcSpe = isPhysic ? (const OpenGl_Vec3& )theMat.SpecularColor() : THE_WHITE_COLOR.rgb();
108 Specular = OpenGl_Vec4 (aSrcSpe * theMat.Specular(), 1.0f);
112 Specular = THE_BLACK_COLOR;
115 // emission component
116 if (theMat.ReflectionMode (Graphic3d_TOR_EMISSION))
118 const OpenGl_Vec3& aSrcEms = isPhysic ? theMat.EmissiveColor() : theInteriorColor;
119 Emission = OpenGl_Vec4 (aSrcEms * theMat.Emissive(), 1.0f);
123 Emission = THE_BLACK_COLOR;
127 // =======================================================================
128 // function : OpenGl_Workspace
130 // =======================================================================
131 OpenGl_Workspace::OpenGl_Workspace (OpenGl_View* theView, const Handle(OpenGl_Window)& theWindow)
133 myWindow (theWindow),
134 myGlContext (!theWindow.IsNull() ? theWindow->GetGlContext() : NULL),
135 myUseZBuffer (Standard_True),
136 myUseDepthWrite (Standard_True),
138 myAspectLineSet (&myDefaultAspectLine),
139 myAspectFaceSet (&myDefaultAspectFace),
140 myAspectMarkerSet (&myDefaultAspectMarker),
141 myAspectTextSet (&myDefaultAspectText),
143 ViewMatrix_applied (&myDefaultMatrix),
144 StructureMatrix_applied (&myDefaultMatrix),
145 myToAllowFaceCulling (false),
146 myModelViewMatrix (myDefaultMatrix)
148 if (!myGlContext.IsNull() && myGlContext->MakeCurrent())
150 myGlContext->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
152 // General initialization of the context
153 #if !defined(GL_ES_VERSION_2_0)
154 if (myGlContext->core11 != NULL)
156 // Eviter d'avoir les faces mal orientees en noir.
157 // Pourrait etre utiliser pour detecter les problemes d'orientation
158 glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
160 // Optimisation pour le Fog et l'antialiasing
161 glHint (GL_FOG_HINT, GL_FASTEST);
162 glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST);
165 glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST);
166 glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
170 myDefaultCappingAlgoFilter = new OpenGl_CappingAlgoFilter();
172 myNoneCulling .Aspect()->SetSuppressBackFaces (false);
173 myNoneCulling .Aspect()->SetDrawEdges (false);
174 myFrontCulling.Aspect()->SetSuppressBackFaces (true);
175 myFrontCulling.Aspect()->SetDrawEdges (false);
178 // =======================================================================
179 // function : Activate
181 // =======================================================================
182 Standard_Boolean OpenGl_Workspace::Activate()
184 if (myWindow.IsNull() || !myWindow->Activate())
186 return Standard_False;
189 ViewMatrix_applied = &myDefaultMatrix;
190 StructureMatrix_applied = &myDefaultMatrix;
192 ResetAppliedAspect();
194 // reset state for safety
195 myGlContext->BindProgram (Handle(OpenGl_ShaderProgram)());
196 if (myGlContext->core20fwd != NULL)
198 myGlContext->core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
200 myGlContext->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
201 return Standard_True;
204 //=======================================================================
205 //function : ResetAppliedAspect
206 //purpose : Sets default values of GL parameters in accordance with default aspects
207 //=======================================================================
208 void OpenGl_Workspace::ResetAppliedAspect()
210 myGlContext->BindDefaultVao();
212 myHighlightStyle.Nullify();
213 myToAllowFaceCulling = false;
214 myAspectLineSet = &myDefaultAspectLine;
215 myAspectFaceSet = &myDefaultAspectFace;
216 myAspectFaceApplied.Nullify();
217 myAspectMarkerSet = &myDefaultAspectMarker;
218 myAspectMarkerApplied.Nullify();
219 myAspectTextSet = &myDefaultAspectText;
220 myPolygonOffsetApplied= Graphic3d_PolygonOffset();
227 myGlContext->SetTypeOfLine (myDefaultAspectLine.Aspect()->Type());
228 myGlContext->SetLineWidth (myDefaultAspectLine.Aspect()->Width());
231 // =======================================================================
232 // function : DisableTexture
234 // =======================================================================
235 Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
237 if (myTextureBound.IsNull())
239 return myTextureBound;
242 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
243 if (!aSampler.IsNull())
245 aSampler->Unbind (*myGlContext);
248 #if !defined(GL_ES_VERSION_2_0)
249 // reset texture matrix because some code may expect it is identity
250 if (myGlContext->core11 != NULL)
252 GLint aMatrixMode = GL_TEXTURE;
253 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
254 glMatrixMode (GL_TEXTURE);
256 glMatrixMode (aMatrixMode);
260 myTextureBound->Unbind (myGlContext);
261 switch (myTextureBound->GetTarget())
263 #if !defined(GL_ES_VERSION_2_0)
266 if (myGlContext->core11 != NULL)
268 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
270 glDisable (GL_TEXTURE_GEN_S);
272 glDisable (GL_TEXTURE_1D);
279 #if !defined(GL_ES_VERSION_2_0)
280 if (myGlContext->core11 != NULL)
282 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
284 glDisable (GL_TEXTURE_GEN_S);
285 glDisable (GL_TEXTURE_GEN_T);
286 if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE)
288 glDisable (GL_POINT_SPRITE);
291 glDisable (GL_TEXTURE_2D);
299 Handle(OpenGl_Texture) aPrevTexture = myTextureBound;
300 myTextureBound.Nullify();
304 // =======================================================================
305 // function : setTextureParams
307 // =======================================================================
308 void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& theTexture,
309 const Handle(Graphic3d_TextureParams)& theParams)
311 const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams;
312 if (aParams.IsNull())
317 #if !defined(GL_ES_VERSION_2_0)
318 if (myGlContext->core11 != NULL)
320 GLint anEnvMode = GL_MODULATE; // lighting mode
321 if (!aParams->IsModulate())
323 anEnvMode = GL_DECAL;
324 if (theTexture->GetFormat() == GL_ALPHA
325 || theTexture->GetFormat() == GL_LUMINANCE)
327 anEnvMode = GL_REPLACE;
331 // setup generation of texture coordinates
332 switch (aParams->GenMode())
334 case Graphic3d_TOTM_OBJECT:
336 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
337 glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData());
338 if (theTexture->GetTarget() != GL_TEXTURE_1D)
340 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
341 glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData());
345 case Graphic3d_TOTM_SPHERE:
347 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
348 if (theTexture->GetTarget() != GL_TEXTURE_1D)
350 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
354 case Graphic3d_TOTM_EYE:
356 myGlContext->WorldViewState.Push();
358 myGlContext->WorldViewState.SetIdentity();
359 myGlContext->ApplyWorldViewMatrix();
361 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
362 glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData());
364 if (theTexture->GetTarget() != GL_TEXTURE_1D)
366 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
367 glTexGenfv (GL_T, GL_EYE_PLANE, aParams->GenPlaneT().GetData());
370 myGlContext->WorldViewState.Pop();
374 case Graphic3d_TOTM_SPRITE:
376 if (myGlContext->core20fwd != NULL)
378 glEnable (GL_POINT_SPRITE);
379 glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
380 anEnvMode = GL_REPLACE;
384 case Graphic3d_TOTM_MANUAL:
389 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
393 // get active sampler object to override default texture parameters
394 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
396 // setup texture filtering and wrapping
397 //if (theTexture->GetParams() != theParams)
398 const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
399 const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : myGlContext->TextureWrapClamp();
400 switch (theTexture->GetTarget())
402 #if !defined(GL_ES_VERSION_2_0)
405 if (aSampler.IsNull() || !aSampler->IsValid())
407 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
408 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
409 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
413 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
414 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilter);
415 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
423 GLenum aFilterMin = aFilter;
424 if (theTexture->HasMipmaps())
426 aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
427 if (aParams->Filter() == Graphic3d_TOTF_BILINEAR)
429 aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
431 else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR)
433 aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
436 if (myGlContext->extAnis)
438 // setup degree of anisotropy filter
439 const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
441 switch (aParams->AnisoFilter())
443 case Graphic3d_LOTA_QUALITY:
445 aDegree = aMaxDegree;
448 case Graphic3d_LOTA_MIDDLE:
450 aDegree = (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2);
453 case Graphic3d_LOTA_FAST:
458 case Graphic3d_LOTA_OFF:
466 if (aSampler.IsNull() || !aSampler->IsValid())
468 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
472 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
477 if (aSampler.IsNull() || !aSampler->IsValid())
479 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
480 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
481 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
482 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
486 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilterMin);
487 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
488 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
489 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_T, aWrapMode);
497 switch (theTexture->GetTarget())
499 #if !defined(GL_ES_VERSION_2_0)
502 if (myGlContext->core11 != NULL)
504 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
506 glEnable (GL_TEXTURE_GEN_S);
508 glEnable (GL_TEXTURE_1D);
515 #if !defined(GL_ES_VERSION_2_0)
516 if (myGlContext->core11 != NULL)
518 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
520 glEnable (GL_TEXTURE_GEN_S);
521 glEnable (GL_TEXTURE_GEN_T);
523 glEnable (GL_TEXTURE_2D);
531 theTexture->SetParams (aParams);
534 // =======================================================================
535 // function : EnableTexture
537 // =======================================================================
538 Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture,
539 const Handle(Graphic3d_TextureParams)& theParams)
541 if (theTexture.IsNull() || !theTexture->IsValid())
543 return DisableTexture();
546 if (myTextureBound == theTexture
547 && (theParams.IsNull() || theParams == theTexture->GetParams()))
550 return myTextureBound;
553 Handle(OpenGl_Texture) aPrevTexture = DisableTexture();
554 myTextureBound = theTexture;
555 myTextureBound->Bind (myGlContext);
556 setTextureParams (myTextureBound, theParams);
558 // If custom sampler object is available it will be
559 // used for overriding default texture parameters
560 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
562 if (!aSampler.IsNull() && aSampler->IsValid())
564 aSampler->Bind (*myGlContext);
570 // =======================================================================
571 // function : SetAspectLine
573 // =======================================================================
574 const OpenGl_AspectLine* OpenGl_Workspace::SetAspectLine (const OpenGl_AspectLine* theAspect)
576 const OpenGl_AspectLine* aPrevAspectLine = myAspectLineSet;
577 myAspectLineSet = theAspect;
578 return aPrevAspectLine;
581 // =======================================================================
582 // function : SetAspectFace
584 // =======================================================================
585 const OpenGl_AspectFace * OpenGl_Workspace::SetAspectFace (const OpenGl_AspectFace* theAspect)
587 const OpenGl_AspectFace* aPrevAspectFace = myAspectFaceSet;
588 myAspectFaceSet = theAspect;
589 return aPrevAspectFace;
592 // =======================================================================
593 // function : SetAspectMarker
595 // =======================================================================
596 const OpenGl_AspectMarker* OpenGl_Workspace::SetAspectMarker (const OpenGl_AspectMarker* theAspect)
598 const OpenGl_AspectMarker* aPrevAspectMarker = myAspectMarkerSet;
599 myAspectMarkerSet = theAspect;
600 return aPrevAspectMarker;
603 // =======================================================================
604 // function : SetAspectText
606 // =======================================================================
607 const OpenGl_AspectText * OpenGl_Workspace::SetAspectText (const OpenGl_AspectText* theAspect)
609 const OpenGl_AspectText* aPrevAspectText = myAspectTextSet;
610 myAspectTextSet = theAspect;
611 return aPrevAspectText;
614 // =======================================================================
615 // function : ApplyAspectFace
617 // =======================================================================
618 const OpenGl_AspectFace* OpenGl_Workspace::ApplyAspectFace()
620 if (myView->BackfacingModel() == Graphic3d_TOBM_AUTOMATIC)
622 // manage back face culling mode, disable culling when clipping is enabled
623 bool toSuppressBackFaces = myToAllowFaceCulling
624 && myAspectFaceSet->Aspect()->ToSuppressBackFaces();
625 if (toSuppressBackFaces)
627 if (myGlContext->Clipping().IsClippingOrCappingOn()
628 || myAspectFaceSet->Aspect()->InteriorStyle() == Aspect_IS_HATCH)
630 toSuppressBackFaces = false;
633 if (toSuppressBackFaces)
635 if ((float )myAspectFaceSet->Aspect()->FrontMaterial().Transparency() != 0.0f)
637 // disable culling in case of translucent shading aspect
638 toSuppressBackFaces = false;
641 myGlContext->SetCullBackFaces (toSuppressBackFaces);
644 if (myAspectFaceSet->Aspect() == myAspectFaceApplied
645 && myHighlightStyle == myAspectFaceAppliedWithHL)
647 return myAspectFaceSet;
649 myAspectFaceAppliedWithHL = myHighlightStyle;
651 #if !defined(GL_ES_VERSION_2_0)
652 const Aspect_InteriorStyle anIntstyle = myAspectFaceSet->Aspect()->InteriorStyle();
653 if (myAspectFaceApplied.IsNull()
654 || myAspectFaceApplied->InteriorStyle() != anIntstyle)
658 case Aspect_IS_EMPTY:
659 case Aspect_IS_HOLLOW:
661 myGlContext->SetPolygonMode (GL_LINE);
664 case Aspect_IS_HATCH:
666 myGlContext->SetPolygonMode (GL_FILL);
667 myGlContext->SetPolygonHatchEnabled (true);
670 case Aspect_IS_SOLID:
671 case Aspect_IS_HIDDENLINE:
673 myGlContext->SetPolygonMode (GL_FILL);
674 myGlContext->SetPolygonHatchEnabled (false);
677 case Aspect_IS_POINT:
679 myGlContext->SetPolygonMode (GL_POINT);
685 if (anIntstyle == Aspect_IS_HATCH)
687 myGlContext->SetPolygonHatchStyle (myAspectFaceSet->Aspect()->HatchStyle());
691 // Aspect_POM_None means: do not change current settings
692 if ((myAspectFaceSet->Aspect()->PolygonOffset().Mode & Aspect_POM_None) != Aspect_POM_None)
694 if (myPolygonOffsetApplied.Mode != myAspectFaceSet->Aspect()->PolygonOffset().Mode
695 || myPolygonOffsetApplied.Factor != myAspectFaceSet->Aspect()->PolygonOffset().Factor
696 || myPolygonOffsetApplied.Units != myAspectFaceSet->Aspect()->PolygonOffset().Units)
698 SetPolygonOffset (myAspectFaceSet->Aspect()->PolygonOffset());
702 // Case of hidden line
703 if (myAspectFaceSet->Aspect()->InteriorStyle() == Aspect_IS_HIDDENLINE)
705 // copy all values including line edge aspect
706 *myAspectFaceHl.Aspect().operator->() = *myAspectFaceSet->Aspect();
707 myAspectFaceHl.SetAspectEdge (myAspectFaceSet->AspectEdge());
708 myAspectFaceHl.Aspect()->SetInteriorColor (myView->BackgroundColor().GetRGB());
709 myAspectFaceHl.SetNoLighting (true);
710 myAspectFaceSet = &myAspectFaceHl;
714 myGlContext->SetShadingMaterial (myAspectFaceSet, myHighlightStyle);
717 if (myAspectFaceSet->Aspect()->ToMapTexture())
719 EnableTexture (myAspectFaceSet->TextureRes (myGlContext),
720 myAspectFaceSet->TextureParams());
724 if (!myEnvironmentTexture.IsNull())
726 EnableTexture (myEnvironmentTexture,
727 myEnvironmentTexture->GetParams());
735 myAspectFaceApplied = myAspectFaceSet->Aspect();
736 return myAspectFaceSet;
739 //=======================================================================
740 //function : SetPolygonOffset
742 //=======================================================================
743 void OpenGl_Workspace::SetPolygonOffset (const Graphic3d_PolygonOffset& theParams)
745 myPolygonOffsetApplied = theParams;
747 if ((theParams.Mode & Aspect_POM_Fill) == Aspect_POM_Fill)
749 glEnable (GL_POLYGON_OFFSET_FILL);
753 glDisable (GL_POLYGON_OFFSET_FILL);
756 #if !defined(GL_ES_VERSION_2_0)
757 if ((theParams.Mode & Aspect_POM_Line) == Aspect_POM_Line)
759 glEnable (GL_POLYGON_OFFSET_LINE);
763 glDisable (GL_POLYGON_OFFSET_LINE);
766 if ((theParams.Mode & Aspect_POM_Point) == Aspect_POM_Point)
768 glEnable (GL_POLYGON_OFFSET_POINT);
772 glDisable (GL_POLYGON_OFFSET_POINT);
775 glPolygonOffset (theParams.Factor, theParams.Units);
778 // =======================================================================
779 // function : ApplyAspectMarker
781 // =======================================================================
782 const OpenGl_AspectMarker* OpenGl_Workspace::ApplyAspectMarker()
784 if (myAspectMarkerSet->Aspect() != myAspectMarkerApplied)
786 if (myAspectMarkerApplied.IsNull()
787 || (myAspectMarkerSet->Aspect()->Scale() != myAspectMarkerApplied->Scale()))
789 #if !defined(GL_ES_VERSION_2_0)
790 glPointSize (myAspectMarkerSet->Aspect()->Scale());
792 gl2psPointSize (myAspectMarkerSet->Aspect()->Scale());
796 myAspectMarkerApplied = myAspectMarkerSet->Aspect();
798 return myAspectMarkerSet;
801 // =======================================================================
804 // =======================================================================
805 Standard_Integer OpenGl_Workspace::Width() const
807 return !myView->GlWindow().IsNull() ? myView->GlWindow()->Width() : 0;
810 // =======================================================================
813 // =======================================================================
814 Standard_Integer OpenGl_Workspace::Height() const
816 return !myView->GlWindow().IsNull() ? myView->GlWindow()->Height() : 0;
819 // =======================================================================
820 // function : IsCullingEnabled
822 // =======================================================================
823 Standard_Boolean OpenGl_Workspace::IsCullingEnabled() const
825 return myView->IsCullingEnabled();
828 // =======================================================================
829 // function : FBOCreate
831 // =======================================================================
832 Handle(OpenGl_FrameBuffer) OpenGl_Workspace::FBOCreate (const Standard_Integer theWidth,
833 const Standard_Integer theHeight)
835 // activate OpenGL context
837 return Handle(OpenGl_FrameBuffer)();
842 const Handle(OpenGl_Context)& aCtx = GetGlContext();
843 Handle(OpenGl_FrameBuffer) aFrameBuffer = new OpenGl_FrameBuffer();
844 if (!aFrameBuffer->Init (aCtx, theWidth, theHeight, GL_RGBA8, GL_DEPTH24_STENCIL8, 0))
846 aFrameBuffer->Release (aCtx.operator->());
847 return Handle(OpenGl_FrameBuffer)();
852 // =======================================================================
853 // function : FBORelease
855 // =======================================================================
856 void OpenGl_Workspace::FBORelease (Handle(OpenGl_FrameBuffer)& theFbo)
858 // activate OpenGL context
865 theFbo->Release (GetGlContext().operator->());
869 // =======================================================================
870 // function : getAligned
872 // =======================================================================
873 inline Standard_Size getAligned (const Standard_Size theNumber,
874 const Standard_Size theAlignment)
876 return theNumber + theAlignment - 1 - (theNumber - 1) % theAlignment;
880 inline void convertRowFromRgba (T* theRgbRow,
881 const Image_ColorRGBA* theRgbaRow,
882 const Standard_Size theWidth)
884 for (Standard_Size aCol = 0; aCol < theWidth; ++aCol)
886 const Image_ColorRGBA& anRgba = theRgbaRow[aCol];
887 T& anRgb = theRgbRow[aCol];
888 anRgb.r() = anRgba.r();
889 anRgb.g() = anRgba.g();
890 anRgb.b() = anRgba.b();
894 // =======================================================================
895 // function : BufferDump
897 // =======================================================================
898 Standard_Boolean OpenGl_Workspace::BufferDump (const Handle(OpenGl_FrameBuffer)& theFbo,
899 Image_PixMap& theImage,
900 const Graphic3d_BufferType& theBufferType)
902 if (theImage.IsEmpty()
905 return Standard_False;
910 bool toSwapRgbaBgra = false;
911 bool toConvRgba2Rgb = false;
912 switch (theImage.Format())
914 #if !defined(GL_ES_VERSION_2_0)
915 case Image_Format_Gray:
916 aFormat = GL_DEPTH_COMPONENT;
917 aType = GL_UNSIGNED_BYTE;
919 case Image_Format_GrayF:
920 aFormat = GL_DEPTH_COMPONENT;
923 case Image_Format_RGB:
925 aType = GL_UNSIGNED_BYTE;
927 case Image_Format_BGR:
929 aType = GL_UNSIGNED_BYTE;
931 case Image_Format_BGRA:
932 case Image_Format_BGR32:
934 aType = GL_UNSIGNED_BYTE;
936 case Image_Format_BGRF:
940 case Image_Format_BGRAF:
945 case Image_Format_Gray:
946 case Image_Format_GrayF:
947 case Image_Format_BGRF:
948 case Image_Format_BGRAF:
949 return Standard_False;
950 case Image_Format_BGRA:
951 case Image_Format_BGR32:
953 aType = GL_UNSIGNED_BYTE;
954 toSwapRgbaBgra = true;
956 case Image_Format_BGR:
957 case Image_Format_RGB:
959 aType = GL_UNSIGNED_BYTE;
960 toConvRgba2Rgb = true;
963 case Image_Format_RGBA:
964 case Image_Format_RGB32:
966 aType = GL_UNSIGNED_BYTE;
968 case Image_Format_RGBF:
972 case Image_Format_RGBAF:
976 case Image_Format_Alpha:
977 case Image_Format_AlphaF:
978 return Standard_False; // GL_ALPHA is no more supported in core context
979 case Image_Format_UNKNOWN:
980 return Standard_False;
985 return Standard_False;
988 #if !defined(GL_ES_VERSION_2_0)
989 GLint aReadBufferPrev = GL_BACK;
990 if (theBufferType == Graphic3d_BT_Depth
991 && aFormat != GL_DEPTH_COMPONENT)
993 return Standard_False;
996 (void )theBufferType;
1000 if (!theFbo.IsNull() && theFbo->IsValid())
1002 theFbo->BindBuffer (GetGlContext());
1006 #if !defined(GL_ES_VERSION_2_0)
1007 glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev);
1008 GLint aDrawBufferPrev = GL_BACK;
1009 glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev);
1010 glReadBuffer (aDrawBufferPrev);
1015 const GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL
1016 glPixelStorei (GL_PACK_ALIGNMENT, anAligment);
1017 bool isBatchCopy = !theImage.IsTopDown();
1019 const GLint anExtraBytes = GLint(theImage.RowExtraBytes());
1020 GLint aPixelsWidth = GLint(theImage.SizeRowBytes() / theImage.SizePixelBytes());
1021 Standard_Size aSizeRowBytesEstim = getAligned (theImage.SizePixelBytes() * aPixelsWidth, anAligment);
1022 if (anExtraBytes < anAligment)
1026 else if (aSizeRowBytesEstim != theImage.SizeRowBytes())
1029 isBatchCopy = false;
1031 #if !defined(GL_ES_VERSION_2_0)
1032 glPixelStorei (GL_PACK_ROW_LENGTH, aPixelsWidth);
1034 if (aPixelsWidth != 0)
1036 isBatchCopy = false;
1041 Handle(NCollection_BaseAllocator) anAlloc = new NCollection_AlignedAllocator (16);
1042 const Standard_Size aRowSize = theImage.SizeX() * 4;
1043 NCollection_Buffer aRowBuffer (anAlloc);
1044 if (!aRowBuffer.Allocate (aRowSize))
1046 return Standard_False;
1049 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
1051 // Image_PixMap rows indexation always starts from the upper corner
1052 // while order in memory depends on the flag and processed by ChangeRow() method
1053 glReadPixels (0, GLint(theImage.SizeY() - aRow - 1), GLsizei (theImage.SizeX()), 1, aFormat, aType, aRowBuffer.ChangeData());
1054 const Image_ColorRGBA* aRowDataRgba = (const Image_ColorRGBA* )aRowBuffer.Data();
1055 if (theImage.Format() == Image_Format_BGR)
1057 convertRowFromRgba ((Image_ColorBGR* )theImage.ChangeRow (aRow), aRowDataRgba, theImage.SizeX());
1061 convertRowFromRgba ((Image_ColorRGB* )theImage.ChangeRow (aRow), aRowDataRgba, theImage.SizeX());
1065 else if (!isBatchCopy)
1068 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
1070 // Image_PixMap rows indexation always starts from the upper corner
1071 // while order in memory depends on the flag and processed by ChangeRow() method
1072 glReadPixels (0, GLint(theImage.SizeY() - aRow - 1), GLsizei (theImage.SizeX()), 1, aFormat, aType, theImage.ChangeRow (aRow));
1077 glReadPixels (0, 0, GLsizei (theImage.SizeX()), GLsizei (theImage.SizeY()), aFormat, aType, theImage.ChangeData());
1079 const bool hasErrors = myGlContext->ResetErrors (true);
1081 glPixelStorei (GL_PACK_ALIGNMENT, 1);
1082 #if !defined(GL_ES_VERSION_2_0)
1083 glPixelStorei (GL_PACK_ROW_LENGTH, 0);
1086 if (!theFbo.IsNull() && theFbo->IsValid())
1088 theFbo->UnbindBuffer (GetGlContext());
1092 #if !defined(GL_ES_VERSION_2_0)
1093 glReadBuffer (aReadBufferPrev);
1099 Image_PixMap::SwapRgbaBgra (theImage);
1105 // =======================================================================
1106 // function : ShouldRender
1108 // =======================================================================
1109 Standard_Boolean OpenGl_RaytraceFilter::ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace,
1110 const OpenGl_Element* theElement)
1112 Standard_Boolean aPrevFilterResult = Standard_True;
1113 if (!myPrevRenderFilter.IsNull())
1115 aPrevFilterResult = myPrevRenderFilter->ShouldRender (theWorkspace, theElement);
1117 return aPrevFilterResult &&
1118 !OpenGl_Raytrace::IsRaytracedElement (theElement);