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);
81 if (theMat.ReflectionMode (Graphic3d_TOR_AMBIENT))
83 const OpenGl_Vec3& aSrcAmb = isPhysic ? theMat.AmbientColor() : theInteriorColor;
84 Ambient = OpenGl_Vec4 (aSrcAmb * theMat.Ambient(), 1.0f);
88 Ambient = THE_BLACK_COLOR;
91 // diffusion component
92 if (theMat.ReflectionMode (Graphic3d_TOR_DIFFUSE))
94 const OpenGl_Vec3& aSrcDif = isPhysic ? theMat.DiffuseColor() : theInteriorColor;
95 Diffuse = OpenGl_Vec4 (aSrcDif * theMat.Diffuse(), 1.0f);
99 Diffuse = THE_BLACK_COLOR;
102 // specular component
103 if (theMat.ReflectionMode (Graphic3d_TOR_SPECULAR))
105 const OpenGl_Vec3& aSrcSpe = isPhysic ? (const OpenGl_Vec3& )theMat.SpecularColor() : THE_WHITE_COLOR.rgb();
106 Specular = OpenGl_Vec4 (aSrcSpe * theMat.Specular(), 1.0f);
110 Specular = THE_BLACK_COLOR;
113 // emission component
114 if (theMat.ReflectionMode (Graphic3d_TOR_EMISSION))
116 const OpenGl_Vec3& aSrcEms = isPhysic ? theMat.EmissiveColor() : theInteriorColor;
117 Emission = OpenGl_Vec4 (aSrcEms * theMat.Emissive(), 1.0f);
121 Emission = THE_BLACK_COLOR;
124 ChangeShine() = 128.0f * theMat.Shininess();
125 ChangeTransparency() = 1.0f - theMat.Transparency();
128 // =======================================================================
129 // function : OpenGl_Workspace
131 // =======================================================================
132 OpenGl_Workspace::OpenGl_Workspace (OpenGl_View* theView, const Handle(OpenGl_Window)& theWindow)
134 myWindow (theWindow),
135 myGlContext (!theWindow.IsNull() ? theWindow->GetGlContext() : NULL),
136 myUseZBuffer (Standard_True),
137 myUseDepthWrite (Standard_True),
139 myAspectLineSet (&myDefaultAspectLine),
140 myAspectFaceSet (&myDefaultAspectFace),
141 myAspectMarkerSet (&myDefaultAspectMarker),
142 myAspectTextSet (&myDefaultAspectText),
144 ViewMatrix_applied (&myDefaultMatrix),
145 StructureMatrix_applied (&myDefaultMatrix),
146 myToAllowFaceCulling (false),
147 myModelViewMatrix (myDefaultMatrix)
149 if (!myGlContext.IsNull() && myGlContext->MakeCurrent())
151 myGlContext->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
153 // General initialization of the context
154 #if !defined(GL_ES_VERSION_2_0)
155 if (myGlContext->core11 != NULL)
157 // Eviter d'avoir les faces mal orientees en noir.
158 // Pourrait etre utiliser pour detecter les problemes d'orientation
159 glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
161 // Optimisation pour le Fog et l'antialiasing
162 glHint (GL_FOG_HINT, GL_FASTEST);
163 glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST);
166 glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST);
167 glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
171 myDefaultCappingAlgoFilter = new OpenGl_CappingAlgoFilter();
173 myNoneCulling .Aspect()->SetSuppressBackFaces (false);
174 myNoneCulling .Aspect()->SetDrawEdges (false);
175 myFrontCulling.Aspect()->SetSuppressBackFaces (true);
176 myFrontCulling.Aspect()->SetDrawEdges (false);
179 // =======================================================================
180 // function : Activate
182 // =======================================================================
183 Standard_Boolean OpenGl_Workspace::Activate()
185 if (myWindow.IsNull() || !myWindow->Activate())
187 return Standard_False;
190 ViewMatrix_applied = &myDefaultMatrix;
191 StructureMatrix_applied = &myDefaultMatrix;
193 ResetAppliedAspect();
195 // reset state for safety
196 myGlContext->BindProgram (Handle(OpenGl_ShaderProgram)());
197 if (myGlContext->core20fwd != NULL)
199 myGlContext->core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
201 myGlContext->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
202 return Standard_True;
205 //=======================================================================
206 //function : ResetAppliedAspect
207 //purpose : Sets default values of GL parameters in accordance with default aspects
208 //=======================================================================
209 void OpenGl_Workspace::ResetAppliedAspect()
211 myGlContext->BindDefaultVao();
213 myHighlightStyle.Nullify();
214 myToAllowFaceCulling = false;
215 myAspectLineSet = &myDefaultAspectLine;
216 myAspectFaceSet = &myDefaultAspectFace;
217 myAspectFaceApplied.Nullify();
218 myAspectMarkerSet = &myDefaultAspectMarker;
219 myAspectMarkerApplied.Nullify();
220 myAspectTextSet = &myDefaultAspectText;
221 myPolygonOffsetApplied= Graphic3d_PolygonOffset();
228 myGlContext->SetTypeOfLine (myDefaultAspectLine.Aspect()->Type());
229 myGlContext->SetLineWidth (myDefaultAspectLine.Aspect()->Width());
232 // =======================================================================
233 // function : DisableTexture
235 // =======================================================================
236 Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
238 if (myTextureBound.IsNull())
240 return myTextureBound;
243 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
244 if (!aSampler.IsNull())
246 aSampler->Unbind (*myGlContext);
249 #if !defined(GL_ES_VERSION_2_0)
250 // reset texture matrix because some code may expect it is identity
251 if (myGlContext->core11 != NULL)
253 GLint aMatrixMode = GL_TEXTURE;
254 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
255 glMatrixMode (GL_TEXTURE);
257 glMatrixMode (aMatrixMode);
261 myTextureBound->Unbind (myGlContext);
262 switch (myTextureBound->GetTarget())
264 #if !defined(GL_ES_VERSION_2_0)
267 if (myGlContext->core11 != NULL)
269 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
271 glDisable (GL_TEXTURE_GEN_S);
273 glDisable (GL_TEXTURE_1D);
280 #if !defined(GL_ES_VERSION_2_0)
281 if (myGlContext->core11 != NULL)
283 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
285 glDisable (GL_TEXTURE_GEN_S);
286 glDisable (GL_TEXTURE_GEN_T);
287 if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE)
289 glDisable (GL_POINT_SPRITE);
292 glDisable (GL_TEXTURE_2D);
300 Handle(OpenGl_Texture) aPrevTexture = myTextureBound;
301 myTextureBound.Nullify();
305 // =======================================================================
306 // function : setTextureParams
308 // =======================================================================
309 void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& theTexture,
310 const Handle(Graphic3d_TextureParams)& theParams)
312 const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams;
313 if (aParams.IsNull())
318 #if !defined(GL_ES_VERSION_2_0)
319 if (myGlContext->core11 != NULL)
321 GLint anEnvMode = GL_MODULATE; // lighting mode
322 if (!aParams->IsModulate())
324 anEnvMode = GL_DECAL;
325 if (theTexture->GetFormat() == GL_ALPHA
326 || theTexture->GetFormat() == GL_LUMINANCE)
328 anEnvMode = GL_REPLACE;
332 // setup generation of texture coordinates
333 switch (aParams->GenMode())
335 case Graphic3d_TOTM_OBJECT:
337 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
338 glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData());
339 if (theTexture->GetTarget() != GL_TEXTURE_1D)
341 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
342 glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData());
346 case Graphic3d_TOTM_SPHERE:
348 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
349 if (theTexture->GetTarget() != GL_TEXTURE_1D)
351 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
355 case Graphic3d_TOTM_EYE:
357 myGlContext->WorldViewState.Push();
359 myGlContext->WorldViewState.SetIdentity();
360 myGlContext->ApplyWorldViewMatrix();
362 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
363 glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData());
365 if (theTexture->GetTarget() != GL_TEXTURE_1D)
367 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
368 glTexGenfv (GL_T, GL_EYE_PLANE, aParams->GenPlaneT().GetData());
371 myGlContext->WorldViewState.Pop();
375 case Graphic3d_TOTM_SPRITE:
377 if (myGlContext->core20fwd != NULL)
379 glEnable (GL_POINT_SPRITE);
380 glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
381 anEnvMode = GL_REPLACE;
385 case Graphic3d_TOTM_MANUAL:
390 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
394 // get active sampler object to override default texture parameters
395 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
397 // setup texture filtering and wrapping
398 //if (theTexture->GetParams() != theParams)
399 const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
400 const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : myGlContext->TextureWrapClamp();
401 switch (theTexture->GetTarget())
403 #if !defined(GL_ES_VERSION_2_0)
406 if (aSampler.IsNull() || !aSampler->IsValid())
408 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
409 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
410 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
414 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
415 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilter);
416 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
424 GLenum aFilterMin = aFilter;
425 if (theTexture->HasMipmaps())
427 aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
428 if (aParams->Filter() == Graphic3d_TOTF_BILINEAR)
430 aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
432 else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR)
434 aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
437 if (myGlContext->extAnis)
439 // setup degree of anisotropy filter
440 const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
442 switch (aParams->AnisoFilter())
444 case Graphic3d_LOTA_QUALITY:
446 aDegree = aMaxDegree;
449 case Graphic3d_LOTA_MIDDLE:
451 aDegree = (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2);
454 case Graphic3d_LOTA_FAST:
459 case Graphic3d_LOTA_OFF:
467 if (aSampler.IsNull() || !aSampler->IsValid())
469 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
473 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
478 if (aSampler.IsNull() || !aSampler->IsValid())
480 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
481 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
482 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
483 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
487 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilterMin);
488 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
489 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
490 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_T, aWrapMode);
498 switch (theTexture->GetTarget())
500 #if !defined(GL_ES_VERSION_2_0)
503 if (myGlContext->core11 != NULL)
505 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
507 glEnable (GL_TEXTURE_GEN_S);
509 glEnable (GL_TEXTURE_1D);
516 #if !defined(GL_ES_VERSION_2_0)
517 if (myGlContext->core11 != NULL)
519 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
521 glEnable (GL_TEXTURE_GEN_S);
522 glEnable (GL_TEXTURE_GEN_T);
524 glEnable (GL_TEXTURE_2D);
532 theTexture->SetParams (aParams);
535 // =======================================================================
536 // function : EnableTexture
538 // =======================================================================
539 Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture,
540 const Handle(Graphic3d_TextureParams)& theParams)
542 if (theTexture.IsNull() || !theTexture->IsValid())
544 return DisableTexture();
547 if (myTextureBound == theTexture
548 && (theParams.IsNull() || theParams == theTexture->GetParams()))
551 return myTextureBound;
554 Handle(OpenGl_Texture) aPrevTexture = DisableTexture();
555 myTextureBound = theTexture;
556 myTextureBound->Bind (myGlContext);
557 setTextureParams (myTextureBound, theParams);
559 // If custom sampler object is available it will be
560 // used for overriding default texture parameters
561 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
563 if (!aSampler.IsNull() && aSampler->IsValid())
565 aSampler->Bind (*myGlContext);
571 // =======================================================================
572 // function : SetAspectLine
574 // =======================================================================
575 const OpenGl_AspectLine* OpenGl_Workspace::SetAspectLine (const OpenGl_AspectLine* theAspect)
577 const OpenGl_AspectLine* aPrevAspectLine = myAspectLineSet;
578 myAspectLineSet = theAspect;
579 return aPrevAspectLine;
582 // =======================================================================
583 // function : SetAspectFace
585 // =======================================================================
586 const OpenGl_AspectFace * OpenGl_Workspace::SetAspectFace (const OpenGl_AspectFace* theAspect)
588 const OpenGl_AspectFace* aPrevAspectFace = myAspectFaceSet;
589 myAspectFaceSet = theAspect;
590 return aPrevAspectFace;
593 // =======================================================================
594 // function : SetAspectMarker
596 // =======================================================================
597 const OpenGl_AspectMarker* OpenGl_Workspace::SetAspectMarker (const OpenGl_AspectMarker* theAspect)
599 const OpenGl_AspectMarker* aPrevAspectMarker = myAspectMarkerSet;
600 myAspectMarkerSet = theAspect;
601 return aPrevAspectMarker;
604 // =======================================================================
605 // function : SetAspectText
607 // =======================================================================
608 const OpenGl_AspectText * OpenGl_Workspace::SetAspectText (const OpenGl_AspectText* theAspect)
610 const OpenGl_AspectText* aPrevAspectText = myAspectTextSet;
611 myAspectTextSet = theAspect;
612 return aPrevAspectText;
615 // =======================================================================
616 // function : ApplyAspectFace
618 // =======================================================================
619 const OpenGl_AspectFace* OpenGl_Workspace::ApplyAspectFace()
621 if (myView->BackfacingModel() == Graphic3d_TOBM_AUTOMATIC)
623 // manage back face culling mode, disable culling when clipping is enabled
624 bool toSuppressBackFaces = myToAllowFaceCulling
625 && myAspectFaceSet->Aspect()->ToSuppressBackFaces();
626 if (toSuppressBackFaces)
628 if (myGlContext->Clipping().IsClippingOrCappingOn()
629 || myAspectFaceSet->Aspect()->InteriorStyle() == Aspect_IS_HATCH)
631 toSuppressBackFaces = false;
634 if (toSuppressBackFaces)
636 if ((float )myAspectFaceSet->Aspect()->FrontMaterial().Transparency() != 0.0f)
638 // disable culling in case of translucent shading aspect
639 toSuppressBackFaces = false;
642 myGlContext->SetCullBackFaces (toSuppressBackFaces);
645 if (myAspectFaceSet->Aspect() == myAspectFaceApplied
646 && myHighlightStyle == myAspectFaceAppliedWithHL)
648 return myAspectFaceSet;
650 myAspectFaceAppliedWithHL = myHighlightStyle;
652 #if !defined(GL_ES_VERSION_2_0)
653 const Aspect_InteriorStyle anIntstyle = myAspectFaceSet->Aspect()->InteriorStyle();
654 if (myAspectFaceApplied.IsNull()
655 || myAspectFaceApplied->InteriorStyle() != anIntstyle)
659 case Aspect_IS_EMPTY:
660 case Aspect_IS_HOLLOW:
662 myGlContext->SetPolygonMode (GL_LINE);
665 case Aspect_IS_HATCH:
667 myGlContext->SetPolygonMode (GL_FILL);
668 myGlContext->SetPolygonHatchEnabled (true);
671 case Aspect_IS_SOLID:
672 case Aspect_IS_HIDDENLINE:
674 myGlContext->SetPolygonMode (GL_FILL);
675 myGlContext->SetPolygonHatchEnabled (false);
678 case Aspect_IS_POINT:
680 myGlContext->SetPolygonMode (GL_POINT);
686 if (anIntstyle == Aspect_IS_HATCH)
688 myGlContext->SetPolygonHatchStyle (myAspectFaceSet->Aspect()->HatchStyle());
692 // Aspect_POM_None means: do not change current settings
693 if ((myAspectFaceSet->Aspect()->PolygonOffset().Mode & Aspect_POM_None) != Aspect_POM_None)
695 if (myPolygonOffsetApplied.Mode != myAspectFaceSet->Aspect()->PolygonOffset().Mode
696 || myPolygonOffsetApplied.Factor != myAspectFaceSet->Aspect()->PolygonOffset().Factor
697 || myPolygonOffsetApplied.Units != myAspectFaceSet->Aspect()->PolygonOffset().Units)
699 SetPolygonOffset (myAspectFaceSet->Aspect()->PolygonOffset());
703 // Case of hidden line
704 if (myAspectFaceSet->Aspect()->InteriorStyle() == Aspect_IS_HIDDENLINE)
706 // copy all values including line edge aspect
707 *myAspectFaceHl.Aspect().operator->() = *myAspectFaceSet->Aspect();
708 myAspectFaceHl.SetAspectEdge (myAspectFaceSet->AspectEdge());
709 myAspectFaceHl.Aspect()->SetInteriorColor (myView->BackgroundColor().GetRGB());
710 myAspectFaceHl.SetNoLighting (true);
711 myAspectFaceSet = &myAspectFaceHl;
715 myGlContext->SetShadingMaterial (myAspectFaceSet, myHighlightStyle);
718 if (myAspectFaceSet->Aspect()->ToMapTexture())
720 EnableTexture (myAspectFaceSet->TextureRes (myGlContext),
721 myAspectFaceSet->TextureParams());
725 if (!myEnvironmentTexture.IsNull())
727 EnableTexture (myEnvironmentTexture,
728 myEnvironmentTexture->GetParams());
736 myAspectFaceApplied = myAspectFaceSet->Aspect();
737 return myAspectFaceSet;
740 //=======================================================================
741 //function : SetPolygonOffset
743 //=======================================================================
744 void OpenGl_Workspace::SetPolygonOffset (const Graphic3d_PolygonOffset& theParams)
746 myPolygonOffsetApplied = theParams;
748 if ((theParams.Mode & Aspect_POM_Fill) == Aspect_POM_Fill)
750 glEnable (GL_POLYGON_OFFSET_FILL);
754 glDisable (GL_POLYGON_OFFSET_FILL);
757 #if !defined(GL_ES_VERSION_2_0)
758 if ((theParams.Mode & Aspect_POM_Line) == Aspect_POM_Line)
760 glEnable (GL_POLYGON_OFFSET_LINE);
764 glDisable (GL_POLYGON_OFFSET_LINE);
767 if ((theParams.Mode & Aspect_POM_Point) == Aspect_POM_Point)
769 glEnable (GL_POLYGON_OFFSET_POINT);
773 glDisable (GL_POLYGON_OFFSET_POINT);
776 glPolygonOffset (theParams.Factor, theParams.Units);
779 // =======================================================================
780 // function : ApplyAspectMarker
782 // =======================================================================
783 const OpenGl_AspectMarker* OpenGl_Workspace::ApplyAspectMarker()
785 if (myAspectMarkerSet->Aspect() != myAspectMarkerApplied)
787 if (myAspectMarkerApplied.IsNull()
788 || (myAspectMarkerSet->Aspect()->Scale() != myAspectMarkerApplied->Scale()))
790 #if !defined(GL_ES_VERSION_2_0)
791 glPointSize (myAspectMarkerSet->Aspect()->Scale());
793 gl2psPointSize (myAspectMarkerSet->Aspect()->Scale());
797 myAspectMarkerApplied = myAspectMarkerSet->Aspect();
799 return myAspectMarkerSet;
802 // =======================================================================
805 // =======================================================================
806 Standard_Integer OpenGl_Workspace::Width() const
808 return !myView->GlWindow().IsNull() ? myView->GlWindow()->Width() : 0;
811 // =======================================================================
814 // =======================================================================
815 Standard_Integer OpenGl_Workspace::Height() const
817 return !myView->GlWindow().IsNull() ? myView->GlWindow()->Height() : 0;
820 // =======================================================================
821 // function : IsCullingEnabled
823 // =======================================================================
824 Standard_Boolean OpenGl_Workspace::IsCullingEnabled() const
826 return myView->IsCullingEnabled();
829 // =======================================================================
830 // function : FBOCreate
832 // =======================================================================
833 Handle(OpenGl_FrameBuffer) OpenGl_Workspace::FBOCreate (const Standard_Integer theWidth,
834 const Standard_Integer theHeight)
836 // activate OpenGL context
838 return Handle(OpenGl_FrameBuffer)();
843 const Handle(OpenGl_Context)& aCtx = GetGlContext();
844 Handle(OpenGl_FrameBuffer) aFrameBuffer = new OpenGl_FrameBuffer();
845 if (!aFrameBuffer->Init (aCtx, theWidth, theHeight, GL_RGBA8, GL_DEPTH24_STENCIL8, 0))
847 aFrameBuffer->Release (aCtx.operator->());
848 return Handle(OpenGl_FrameBuffer)();
853 // =======================================================================
854 // function : FBORelease
856 // =======================================================================
857 void OpenGl_Workspace::FBORelease (Handle(OpenGl_FrameBuffer)& theFbo)
859 // activate OpenGL context
866 theFbo->Release (GetGlContext().operator->());
870 // =======================================================================
871 // function : getAligned
873 // =======================================================================
874 inline Standard_Size getAligned (const Standard_Size theNumber,
875 const Standard_Size theAlignment)
877 return theNumber + theAlignment - 1 - (theNumber - 1) % theAlignment;
881 inline void convertRowFromRgba (T* theRgbRow,
882 const Image_ColorRGBA* theRgbaRow,
883 const Standard_Size theWidth)
885 for (Standard_Size aCol = 0; aCol < theWidth; ++aCol)
887 const Image_ColorRGBA& anRgba = theRgbaRow[aCol];
888 T& anRgb = theRgbRow[aCol];
889 anRgb.r() = anRgba.r();
890 anRgb.g() = anRgba.g();
891 anRgb.b() = anRgba.b();
895 // =======================================================================
896 // function : BufferDump
898 // =======================================================================
899 Standard_Boolean OpenGl_Workspace::BufferDump (const Handle(OpenGl_FrameBuffer)& theFbo,
900 Image_PixMap& theImage,
901 const Graphic3d_BufferType& theBufferType)
903 if (theImage.IsEmpty()
906 return Standard_False;
911 bool toSwapRgbaBgra = false;
912 bool toConvRgba2Rgb = false;
913 switch (theImage.Format())
915 #if !defined(GL_ES_VERSION_2_0)
916 case Image_Format_Gray:
917 aFormat = GL_DEPTH_COMPONENT;
918 aType = GL_UNSIGNED_BYTE;
920 case Image_Format_GrayF:
921 aFormat = GL_DEPTH_COMPONENT;
924 case Image_Format_RGB:
926 aType = GL_UNSIGNED_BYTE;
928 case Image_Format_BGR:
930 aType = GL_UNSIGNED_BYTE;
932 case Image_Format_BGRA:
933 case Image_Format_BGR32:
935 aType = GL_UNSIGNED_BYTE;
937 case Image_Format_BGRF:
941 case Image_Format_BGRAF:
946 case Image_Format_Gray:
947 case Image_Format_GrayF:
948 case Image_Format_BGRF:
949 case Image_Format_BGRAF:
950 return Standard_False;
951 case Image_Format_BGRA:
952 case Image_Format_BGR32:
954 aType = GL_UNSIGNED_BYTE;
955 toSwapRgbaBgra = true;
957 case Image_Format_BGR:
958 case Image_Format_RGB:
960 aType = GL_UNSIGNED_BYTE;
961 toConvRgba2Rgb = true;
964 case Image_Format_RGBA:
965 case Image_Format_RGB32:
967 aType = GL_UNSIGNED_BYTE;
969 case Image_Format_RGBF:
973 case Image_Format_RGBAF:
977 case Image_Format_Alpha:
978 case Image_Format_AlphaF:
979 return Standard_False; // GL_ALPHA is no more supported in core context
980 case Image_Format_UNKNOWN:
981 return Standard_False;
986 return Standard_False;
989 #if !defined(GL_ES_VERSION_2_0)
990 GLint aReadBufferPrev = GL_BACK;
991 if (theBufferType == Graphic3d_BT_Depth
992 && aFormat != GL_DEPTH_COMPONENT)
994 return Standard_False;
997 (void )theBufferType;
1001 if (!theFbo.IsNull() && theFbo->IsValid())
1003 theFbo->BindBuffer (GetGlContext());
1007 #if !defined(GL_ES_VERSION_2_0)
1008 glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev);
1009 GLint aDrawBufferPrev = GL_BACK;
1010 glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev);
1011 glReadBuffer (aDrawBufferPrev);
1016 const GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL
1017 glPixelStorei (GL_PACK_ALIGNMENT, anAligment);
1018 bool isBatchCopy = !theImage.IsTopDown();
1020 const GLint anExtraBytes = GLint(theImage.RowExtraBytes());
1021 GLint aPixelsWidth = GLint(theImage.SizeRowBytes() / theImage.SizePixelBytes());
1022 Standard_Size aSizeRowBytesEstim = getAligned (theImage.SizePixelBytes() * aPixelsWidth, anAligment);
1023 if (anExtraBytes < anAligment)
1027 else if (aSizeRowBytesEstim != theImage.SizeRowBytes())
1030 isBatchCopy = false;
1032 #if !defined(GL_ES_VERSION_2_0)
1033 glPixelStorei (GL_PACK_ROW_LENGTH, aPixelsWidth);
1035 if (aPixelsWidth != 0)
1037 isBatchCopy = false;
1042 Handle(NCollection_BaseAllocator) anAlloc = new NCollection_AlignedAllocator (16);
1043 const Standard_Size aRowSize = theImage.SizeX() * 4;
1044 NCollection_Buffer aRowBuffer (anAlloc);
1045 if (!aRowBuffer.Allocate (aRowSize))
1047 return Standard_False;
1050 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
1052 // Image_PixMap rows indexation always starts from the upper corner
1053 // while order in memory depends on the flag and processed by ChangeRow() method
1054 glReadPixels (0, GLint(theImage.SizeY() - aRow - 1), GLsizei (theImage.SizeX()), 1, aFormat, aType, aRowBuffer.ChangeData());
1055 const Image_ColorRGBA* aRowDataRgba = (const Image_ColorRGBA* )aRowBuffer.Data();
1056 if (theImage.Format() == Image_Format_BGR)
1058 convertRowFromRgba ((Image_ColorBGR* )theImage.ChangeRow (aRow), aRowDataRgba, theImage.SizeX());
1062 convertRowFromRgba ((Image_ColorRGB* )theImage.ChangeRow (aRow), aRowDataRgba, theImage.SizeX());
1066 else if (!isBatchCopy)
1069 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
1071 // Image_PixMap rows indexation always starts from the upper corner
1072 // while order in memory depends on the flag and processed by ChangeRow() method
1073 glReadPixels (0, GLint(theImage.SizeY() - aRow - 1), GLsizei (theImage.SizeX()), 1, aFormat, aType, theImage.ChangeRow (aRow));
1078 glReadPixels (0, 0, GLsizei (theImage.SizeX()), GLsizei (theImage.SizeY()), aFormat, aType, theImage.ChangeData());
1080 const bool hasErrors = myGlContext->ResetErrors (true);
1082 glPixelStorei (GL_PACK_ALIGNMENT, 1);
1083 #if !defined(GL_ES_VERSION_2_0)
1084 glPixelStorei (GL_PACK_ROW_LENGTH, 0);
1087 if (!theFbo.IsNull() && theFbo->IsValid())
1089 theFbo->UnbindBuffer (GetGlContext());
1093 #if !defined(GL_ES_VERSION_2_0)
1094 glReadBuffer (aReadBufferPrev);
1100 Image_PixMap::SwapRgbaBgra (theImage);
1106 // =======================================================================
1107 // function : ShouldRender
1109 // =======================================================================
1110 Standard_Boolean OpenGl_RaytraceFilter::ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace,
1111 const OpenGl_Element* theElement)
1113 Standard_Boolean aPrevFilterResult = Standard_True;
1114 if (!myPrevRenderFilter.IsNull())
1116 aPrevFilterResult = myPrevRenderFilter->ShouldRender (theWorkspace, theElement);
1118 return aPrevFilterResult &&
1119 !OpenGl_Raytrace::IsRaytracedElement (theElement);