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 <InterfaceGraphic.hxx>
20 #include <OpenGl_ArbFBO.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_GlCore15.hxx>
29 #include <OpenGl_SceneGeometry.hxx>
30 #include <OpenGl_Structure.hxx>
31 #include <OpenGl_Sampler.hxx>
32 #include <OpenGl_Texture.hxx>
33 #include <OpenGl_View.hxx>
34 #include <OpenGl_Window.hxx>
36 #include <Graphic3d_TextureParams.hxx>
37 #include <Graphic3d_TransformUtils.hxx>
41 /* OCC22216 NOTE: linker dependency can be switched off by undefining macro.
42 Pragma comment for gl2ps.lib is defined only here. */
44 #pragma comment( lib, "gl2ps.lib" )
50 static const TEL_COLOUR THE_WHITE_COLOR = { { 1.0f, 1.0f, 1.0f, 1.0f } };
51 static const OpenGl_Vec4 THE_BLACK_COLOR (0.0f, 0.0f, 0.0f, 1.0f);
53 static const OpenGl_AspectLine myDefaultAspectLine;
54 static const OpenGl_AspectFace myDefaultAspectFace;
55 static const OpenGl_AspectMarker myDefaultAspectMarker;
57 static const OpenGl_TextParam myDefaultTextParam =
59 16, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM
62 static const OpenGl_Matrix myDefaultMatrix =
64 {{ 1.0F, 0.0F, 0.0F, 0.0F },
65 { 0.0F, 1.0F, 0.0F, 0.0F },
66 { 0.0F, 0.0F, 1.0F, 0.0F },
67 { 0.0F, 0.0F, 0.0F, 1.0F }}
72 // =======================================================================
75 // =======================================================================
76 void OpenGl_Material::Init (const OPENGL_SURF_PROP& theProp)
79 if (theProp.color_mask & OPENGL_AMBIENT_MASK)
81 const float* aSrcAmb = theProp.isphysic ? theProp.ambcol.rgb : theProp.matcol.rgb;
82 Ambient = OpenGl_Vec4 (aSrcAmb[0] * theProp.amb,
83 aSrcAmb[1] * theProp.amb,
84 aSrcAmb[2] * theProp.amb,
89 Ambient = THE_BLACK_COLOR;
92 // diffusion component
93 if (theProp.color_mask & OPENGL_DIFFUSE_MASK)
95 const float* aSrcDif = theProp.isphysic ? theProp.difcol.rgb : theProp.matcol.rgb;
96 Diffuse = OpenGl_Vec4 (aSrcDif[0] * theProp.diff,
97 aSrcDif[1] * theProp.diff,
98 aSrcDif[2] * theProp.diff,
103 Diffuse = THE_BLACK_COLOR;
106 // specular component
107 if (theProp.color_mask & OPENGL_SPECULAR_MASK)
109 const float* aSrcSpe = theProp.isphysic ? theProp.speccol.rgb : THE_WHITE_COLOR.rgb;
110 Specular = OpenGl_Vec4 (aSrcSpe[0] * theProp.spec,
111 aSrcSpe[1] * theProp.spec,
112 aSrcSpe[2] * theProp.spec,
117 Specular = THE_BLACK_COLOR;
120 // emission component
121 if (theProp.color_mask & OPENGL_EMISSIVE_MASK)
123 const float* aSrcEms = theProp.isphysic ? theProp.emscol.rgb : theProp.matcol.rgb;
124 Emission = OpenGl_Vec4 (aSrcEms[0] * theProp.emsv,
125 aSrcEms[1] * theProp.emsv,
126 aSrcEms[2] * theProp.emsv,
131 Emission = THE_BLACK_COLOR;
134 ChangeShine() = theProp.shine;
135 ChangeTransparency() = theProp.trans;
138 // =======================================================================
139 // function : OpenGl_Workspace
141 // =======================================================================
142 OpenGl_Workspace::OpenGl_Workspace (OpenGl_View* theView, const Handle(OpenGl_Window)& theWindow)
144 HighlightColor (&THE_WHITE_COLOR),
146 myWindow (theWindow),
147 myGlContext (!theWindow.IsNull() ? theWindow->GetGlContext() : NULL),
148 myUseZBuffer (Standard_True),
149 myUseDepthWrite (Standard_True),
150 myUseGLLight (Standard_True),
152 AspectLine_set (&myDefaultAspectLine),
153 AspectLine_applied (NULL),
154 AspectFace_set (&myDefaultAspectFace),
155 AspectFace_applied (NULL),
156 AspectMarker_set (&myDefaultAspectMarker),
157 AspectMarker_applied (NULL),
158 ViewMatrix_applied (&myDefaultMatrix),
159 StructureMatrix_applied (&myDefaultMatrix),
160 myCullingMode (TelCullUndefined),
161 myModelViewMatrix (myDefaultMatrix),
162 PolygonOffset_applied (THE_DEFAULT_POFFSET)
164 if (!myGlContext.IsNull() && myGlContext->MakeCurrent())
166 myGlContext->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
168 if (!myGlContext->GetResource ("OpenGl_LineAttributes", myLineAttribs))
170 // share and register for release once the resource is no longer used
171 myLineAttribs = new OpenGl_LineAttributes();
172 myGlContext->ShareResource ("OpenGl_LineAttributes", myLineAttribs);
173 myLineAttribs->Init (myGlContext);
176 // General initialization of the context
178 #if !defined(GL_ES_VERSION_2_0)
179 if (myGlContext->core11 != NULL)
181 // Eviter d'avoir les faces mal orientees en noir.
182 // Pourrait etre utiliser pour detecter les problemes d'orientation
183 glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
185 // Optimisation pour le Fog et l'antialiasing
186 glHint (GL_FOG_HINT, GL_FASTEST);
187 glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST);
190 glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST);
191 glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
195 myDefaultCappingAlgoFilter = new OpenGl_CappingAlgoFilter();
196 myNoneCulling.ChangeCullingMode() = TelCullNone;
197 myNoneCulling.ChangeEdge() = 0;
198 myFrontCulling.ChangeCullingMode() = TelCullBack;
199 myFrontCulling.ChangeEdge() = 0;
202 // =======================================================================
203 // function : ~OpenGl_Workspace
205 // =======================================================================
206 OpenGl_Workspace::~OpenGl_Workspace()
208 if (!myLineAttribs.IsNull())
210 myLineAttribs.Nullify();
211 myGlContext->ReleaseResource ("OpenGl_LineAttributes", Standard_True);
215 // =======================================================================
216 // function : Activate
218 // =======================================================================
219 Standard_Boolean OpenGl_Workspace::Activate()
221 if (myWindow.IsNull() || !myWindow->Activate())
223 return Standard_False;
226 ViewMatrix_applied = &myDefaultMatrix;
227 StructureMatrix_applied = &myDefaultMatrix;
229 ResetAppliedAspect();
231 return Standard_True;
234 //=======================================================================
235 //function : ResetAppliedAspect
236 //purpose : Sets default values of GL parameters in accordance with default aspects
237 //=======================================================================
238 void OpenGl_Workspace::ResetAppliedAspect()
240 myGlContext->BindDefaultVao();
242 NamedStatus = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0;
243 HighlightColor = &THE_WHITE_COLOR;
244 AspectLine_set = &myDefaultAspectLine;
245 AspectLine_applied = NULL;
246 AspectFace_set = &myDefaultAspectFace;
247 AspectFace_applied = NULL;
248 AspectMarker_set = &myDefaultAspectMarker;
249 AspectMarker_applied = NULL;
250 PolygonOffset_applied = THE_DEFAULT_POFFSET;
251 myCullingMode = TelCullUndefined;
253 AspectLine(Standard_True);
254 AspectFace(Standard_True);
255 AspectMarker(Standard_True);
256 AspectText(Standard_True);
258 myGlContext->SetTypeOfLine (myDefaultAspectLine.Type());
259 myGlContext->SetLineWidth (myDefaultAspectLine.Width());
262 // =======================================================================
263 // function : DisableTexture
265 // =======================================================================
266 Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
268 if (myTextureBound.IsNull())
270 return myTextureBound;
273 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
274 if (!aSampler.IsNull())
276 aSampler->Unbind (*myGlContext);
279 #if !defined(GL_ES_VERSION_2_0)
280 // reset texture matrix because some code may expect it is identity
281 if (myGlContext->core11 != NULL)
283 GLint aMatrixMode = GL_TEXTURE;
284 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
285 glMatrixMode (GL_TEXTURE);
287 glMatrixMode (aMatrixMode);
291 myTextureBound->Unbind (myGlContext);
292 switch (myTextureBound->GetTarget())
294 #if !defined(GL_ES_VERSION_2_0)
297 if (myGlContext->core11 != NULL)
299 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
301 glDisable (GL_TEXTURE_GEN_S);
303 glDisable (GL_TEXTURE_1D);
310 #if !defined(GL_ES_VERSION_2_0)
311 if (myGlContext->core11 != NULL)
313 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
315 glDisable (GL_TEXTURE_GEN_S);
316 glDisable (GL_TEXTURE_GEN_T);
317 if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE)
319 glDisable (GL_POINT_SPRITE);
322 glDisable (GL_TEXTURE_2D);
330 Handle(OpenGl_Texture) aPrevTexture = myTextureBound;
331 myTextureBound.Nullify();
335 // =======================================================================
336 // function : setTextureParams
338 // =======================================================================
339 void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& theTexture,
340 const Handle(Graphic3d_TextureParams)& theParams)
342 const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams;
343 if (aParams.IsNull())
348 #if !defined(GL_ES_VERSION_2_0)
349 GLint aMatrixMode = GL_TEXTURE;
350 if (myGlContext->core11 != NULL)
352 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
354 // setup texture matrix
355 glMatrixMode (GL_TEXTURE);
356 OpenGl_Mat4 aTextureMat;
357 const Graphic3d_Vec2& aScale = aParams->Scale();
358 const Graphic3d_Vec2& aTrans = aParams->Translation();
359 Graphic3d_TransformUtils::Scale (aTextureMat, aScale.x(), aScale.y(), 1.0f);
360 Graphic3d_TransformUtils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f);
361 Graphic3d_TransformUtils::Rotate (aTextureMat, -aParams->Rotation(), 0.0f, 0.0f, 1.0f);
362 glLoadMatrixf (aTextureMat);
364 GLint anEnvMode = GL_MODULATE; // lighting mode
365 if (!aParams->IsModulate())
367 anEnvMode = GL_DECAL;
368 if (theTexture->GetFormat() == GL_ALPHA
369 || theTexture->GetFormat() == GL_LUMINANCE)
371 anEnvMode = GL_REPLACE;
375 // setup generation of texture coordinates
376 switch (aParams->GenMode())
378 case Graphic3d_TOTM_OBJECT:
380 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
381 glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData());
382 if (theTexture->GetTarget() != GL_TEXTURE_1D)
384 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
385 glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData());
389 case Graphic3d_TOTM_SPHERE:
391 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
392 if (theTexture->GetTarget() != GL_TEXTURE_1D)
394 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
398 case Graphic3d_TOTM_EYE:
400 myGlContext->WorldViewState.Push();
402 myGlContext->WorldViewState.SetIdentity();
403 myGlContext->ApplyWorldViewMatrix();
405 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
406 glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData());
408 if (theTexture->GetTarget() != GL_TEXTURE_1D)
410 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
411 glTexGenfv (GL_T, GL_EYE_PLANE, aParams->GenPlaneT().GetData());
414 myGlContext->WorldViewState.Pop();
418 case Graphic3d_TOTM_SPRITE:
420 if (myGlContext->core20fwd != NULL)
422 glEnable (GL_POINT_SPRITE);
423 glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
424 anEnvMode = GL_REPLACE;
425 myGlContext->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
429 case Graphic3d_TOTM_MANUAL:
434 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
438 // get active sampler object to override default texture parameters
439 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
441 // setup texture filtering and wrapping
442 //if (theTexture->GetParams() != theParams)
443 const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
444 const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : myGlContext->TextureWrapClamp();
445 switch (theTexture->GetTarget())
447 #if !defined(GL_ES_VERSION_2_0)
450 if (aSampler.IsNull() || !aSampler->IsValid())
452 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
453 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
454 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
458 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
459 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilter);
460 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
468 GLenum aFilterMin = aFilter;
469 if (theTexture->HasMipmaps())
471 aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
472 if (aParams->Filter() == Graphic3d_TOTF_BILINEAR)
474 aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
476 else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR)
478 aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
481 if (myGlContext->extAnis)
483 // setup degree of anisotropy filter
484 const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
486 switch (aParams->AnisoFilter())
488 case Graphic3d_LOTA_QUALITY:
490 aDegree = aMaxDegree;
493 case Graphic3d_LOTA_MIDDLE:
495 aDegree = (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2);
498 case Graphic3d_LOTA_FAST:
503 case Graphic3d_LOTA_OFF:
511 if (aSampler.IsNull() || !aSampler->IsValid())
513 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
517 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
522 if (aSampler.IsNull() || !aSampler->IsValid())
524 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
525 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
526 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
527 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
531 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilterMin);
532 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
533 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
534 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_T, aWrapMode);
542 switch (theTexture->GetTarget())
544 #if !defined(GL_ES_VERSION_2_0)
547 if (myGlContext->core11 != NULL)
549 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
551 glEnable (GL_TEXTURE_GEN_S);
553 glEnable (GL_TEXTURE_1D);
560 #if !defined(GL_ES_VERSION_2_0)
561 if (myGlContext->core11 != NULL)
563 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
565 glEnable (GL_TEXTURE_GEN_S);
566 glEnable (GL_TEXTURE_GEN_T);
568 glEnable (GL_TEXTURE_2D);
576 #if !defined(GL_ES_VERSION_2_0)
577 if (myGlContext->core11 != NULL)
579 glMatrixMode (aMatrixMode); // turn back active matrix
582 theTexture->SetParams (aParams);
585 // =======================================================================
586 // function : EnableTexture
588 // =======================================================================
589 Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture,
590 const Handle(Graphic3d_TextureParams)& theParams)
592 if (theTexture.IsNull() || !theTexture->IsValid())
594 return DisableTexture();
597 if (myTextureBound == theTexture
598 && (theParams.IsNull() || theParams == theTexture->GetParams()))
601 return myTextureBound;
604 Handle(OpenGl_Texture) aPrevTexture = DisableTexture();
605 myTextureBound = theTexture;
606 myTextureBound->Bind (myGlContext);
607 setTextureParams (myTextureBound, theParams);
609 // If custom sampler object is available it will be
610 // used for overriding default texture parameters
611 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
613 if (!aSampler.IsNull() && aSampler->IsValid())
615 aSampler->Bind (*myGlContext);
621 // =======================================================================
622 // function : TelUpdatePolygonOffsets
624 // =======================================================================
625 static void TelUpdatePolygonOffsets (const TEL_POFFSET_PARAM& theOffsetData)
627 if ((theOffsetData.mode & Aspect_POM_Fill) == Aspect_POM_Fill)
629 glEnable (GL_POLYGON_OFFSET_FILL);
633 glDisable (GL_POLYGON_OFFSET_FILL);
636 #if !defined(GL_ES_VERSION_2_0)
637 if ((theOffsetData.mode & Aspect_POM_Line) == Aspect_POM_Line)
639 glEnable (GL_POLYGON_OFFSET_LINE);
643 glDisable (GL_POLYGON_OFFSET_LINE);
646 if ((theOffsetData.mode & Aspect_POM_Point) == Aspect_POM_Point)
648 glEnable (GL_POLYGON_OFFSET_POINT);
652 glDisable (GL_POLYGON_OFFSET_POINT);
656 glPolygonOffset (theOffsetData.factor, theOffsetData.units);
659 // =======================================================================
660 // function : updateMaterial
662 // =======================================================================
663 void OpenGl_Workspace::updateMaterial (const int theFlag)
665 // Case of hidden line
666 if (AspectFace_set->InteriorStyle() == Aspect_IS_HIDDENLINE)
668 myAspectFaceHl = *AspectFace_set; // copy all values including line edge aspect
669 myAspectFaceHl.ChangeIntFront().matcol = myView->BackgroundColor();
670 myAspectFaceHl.ChangeIntFront().color_mask = 0;
671 myAspectFaceHl.ChangeIntFront().color_mask = 0;
673 AspectFace_set = &myAspectFaceHl;
677 const OPENGL_SURF_PROP* aProps = &AspectFace_set->IntFront();
678 GLenum aFace = GL_FRONT_AND_BACK;
679 if (theFlag == TEL_BACK_MATERIAL)
682 aProps = &AspectFace_set->IntBack();
684 else if (AspectFace_set->DistinguishingMode() == TOn
685 && !(NamedStatus & OPENGL_NS_RESMAT))
690 myMatTmp.Init (*aProps);
692 // handling transparency
693 if (NamedStatus & OPENGL_NS_2NDPASSDO)
696 myMatTmp.Diffuse.a() = aProps->env_reflexion;
700 if (aProps->env_reflexion != 0.0f)
702 // if the material reflects the environment scene, the second pass is needed
703 NamedStatus |= OPENGL_NS_2NDPASSNEED;
706 if (aProps->trans != 1.0f)
708 // render transparent
709 myMatTmp.Diffuse.a() = aProps->trans;
710 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
714 glDepthMask (GL_FALSE);
720 if ((NamedStatus & OPENGL_NS_ANTIALIASING) == 0)
722 glBlendFunc (GL_ONE, GL_ZERO);
723 glDisable (GL_BLEND);
727 glDepthMask (GL_TRUE);
732 // do not update material properties in case of zero reflection mode,
733 // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
734 if (aProps->color_mask == 0)
740 if (NamedStatus & OPENGL_NS_RESMAT)
742 #if !defined(GL_ES_VERSION_2_0)
743 if (myGlContext->core11 != NULL)
745 myGlContext->core11->glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
746 myGlContext->core11->glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
747 myGlContext->core11->glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
748 myGlContext->core11->glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
749 myGlContext->core11->glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
753 if (theFlag == TEL_FRONT_MATERIAL)
755 myMatFront = myMatTmp;
756 myMatBack = myMatTmp;
760 myMatBack = myMatTmp;
763 NamedStatus &= ~OPENGL_NS_RESMAT;
768 OpenGl_Material& anOld = (theFlag == TEL_FRONT_MATERIAL)
771 #if !defined(GL_ES_VERSION_2_0)
772 if (myGlContext->core11 != NULL)
774 if (myMatTmp.Ambient.r() != anOld.Ambient.r()
775 || myMatTmp.Ambient.g() != anOld.Ambient.g()
776 || myMatTmp.Ambient.b() != anOld.Ambient.b())
778 myGlContext->core11->glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
780 if (myMatTmp.Diffuse.r() != anOld.Diffuse.r()
781 || myMatTmp.Diffuse.g() != anOld.Diffuse.g()
782 || myMatTmp.Diffuse.b() != anOld.Diffuse.b()
783 || fabs (myMatTmp.Diffuse.a() - anOld.Diffuse.a()) > 0.01f)
785 myGlContext->core11->glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
787 if (myMatTmp.Specular.r() != anOld.Specular.r()
788 || myMatTmp.Specular.g() != anOld.Specular.g()
789 || myMatTmp.Specular.b() != anOld.Specular.b())
791 myGlContext->core11->glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
793 if (myMatTmp.Emission.r() != anOld.Emission.r()
794 || myMatTmp.Emission.g() != anOld.Emission.g()
795 || myMatTmp.Emission.b() != anOld.Emission.b())
797 myGlContext->core11->glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
799 if (myMatTmp.Shine() != anOld.Shine())
801 myGlContext->core11->glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
806 if (aFace == GL_FRONT_AND_BACK)
808 myMatBack = myMatTmp;
812 // =======================================================================
813 // function : SetAspectLine
815 // =======================================================================
816 const OpenGl_AspectLine * OpenGl_Workspace::SetAspectLine(const OpenGl_AspectLine *AnAspect)
818 const OpenGl_AspectLine *AspectLine_old = AspectLine_set;
819 AspectLine_set = AnAspect;
820 return AspectLine_old;
823 // =======================================================================
824 // function : SetAspectFace
826 // =======================================================================
827 const OpenGl_AspectFace * OpenGl_Workspace::SetAspectFace(const OpenGl_AspectFace *AnAspect)
829 const OpenGl_AspectFace *AspectFace_old = AspectFace_set;
830 AspectFace_set = AnAspect;
831 return AspectFace_old;
834 // =======================================================================
835 // function : SetAspectMarker
837 // =======================================================================
838 const OpenGl_AspectMarker * OpenGl_Workspace::SetAspectMarker(const OpenGl_AspectMarker *AnAspect)
840 const OpenGl_AspectMarker *AspectMarker_old = AspectMarker_set;
841 AspectMarker_set = AnAspect;
842 return AspectMarker_old;
845 // =======================================================================
846 // function : SetAspectText
848 // =======================================================================
849 const OpenGl_AspectText * OpenGl_Workspace::SetAspectText(const OpenGl_AspectText *AnAspect)
851 const OpenGl_AspectText *AspectText_old = AspectText_set;
852 AspectText_set = AnAspect;
853 return AspectText_old;
856 // =======================================================================
857 // function : AspectLine
859 // =======================================================================
860 const OpenGl_AspectLine * OpenGl_Workspace::AspectLine(const Standard_Boolean theWithApply)
864 AspectLine_applied = AspectLine_set;
867 return AspectLine_set;
870 // =======================================================================
871 // function : AspectFace
873 // =======================================================================
874 const OpenGl_AspectFace* OpenGl_Workspace::AspectFace (const Standard_Boolean theToApply)
878 return AspectFace_set;
881 if (myView->BackfacingModel() == Graphic3d_TOBM_AUTOMATIC)
883 // manage back face culling mode, disable culling when clipping is enabled
884 TelCullMode aCullingMode = (myGlContext->Clipping().IsClippingOrCappingOn()
885 || AspectFace_set->InteriorStyle() == Aspect_IS_HATCH)
887 : (TelCullMode )AspectFace_set->CullingMode();
888 if (aCullingMode != TelCullNone
889 && !(NamedStatus & OPENGL_NS_2NDPASSDO))
891 // disable culling in case of translucent shading aspect
892 if (AspectFace_set->IntFront().trans != 1.0f)
894 aCullingMode = TelCullNone;
897 if (myCullingMode != aCullingMode)
899 myCullingMode = aCullingMode;
900 switch (myCullingMode)
903 case TelCullUndefined:
905 glDisable (GL_CULL_FACE);
910 glCullFace (GL_FRONT);
911 glEnable (GL_CULL_FACE);
916 glCullFace (GL_BACK);
917 glEnable (GL_CULL_FACE);
924 if (AspectFace_set == AspectFace_applied)
926 return AspectFace_set;
929 #if !defined(GL_ES_VERSION_2_0)
930 const Aspect_InteriorStyle anIntstyle = AspectFace_set->InteriorStyle();
931 if (AspectFace_applied == NULL || AspectFace_applied->InteriorStyle() != anIntstyle)
935 case Aspect_IS_EMPTY:
936 case Aspect_IS_HOLLOW:
938 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
941 case Aspect_IS_HATCH:
943 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
944 myLineAttribs->SetTypeOfHatch (AspectFace_applied != NULL ? AspectFace_applied->Hatch() : TEL_HS_SOLID);
947 case Aspect_IS_SOLID:
948 case Aspect_IS_HIDDENLINE:
950 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
951 if (myGlContext->core11 != NULL)
953 glDisable (GL_POLYGON_STIPPLE);
957 case Aspect_IS_POINT:
959 glPolygonMode (GL_FRONT_AND_BACK, GL_POINT);
965 if (anIntstyle == Aspect_IS_HATCH)
967 const Tint hatchstyle = AspectFace_set->Hatch();
968 if (AspectFace_applied == NULL || AspectFace_applied->Hatch() != hatchstyle)
970 myLineAttribs->SetTypeOfHatch (hatchstyle);
975 // Aspect_POM_None means: do not change current settings
976 if ((AspectFace_set->PolygonOffset().mode & Aspect_POM_None) != Aspect_POM_None)
978 if (PolygonOffset_applied.mode != AspectFace_set->PolygonOffset().mode
979 || PolygonOffset_applied.factor != AspectFace_set->PolygonOffset().factor
980 || PolygonOffset_applied.units != AspectFace_set->PolygonOffset().units)
982 SetPolygonOffset (AspectFace_set->PolygonOffset().mode,
983 AspectFace_set->PolygonOffset().factor,
984 AspectFace_set->PolygonOffset().units);
988 updateMaterial (TEL_FRONT_MATERIAL);
989 if (AspectFace_set->DistinguishingMode() == TOn)
991 updateMaterial (TEL_BACK_MATERIAL);
994 if ((NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
996 if (AspectFace_set->DoTextureMap())
998 EnableTexture (AspectFace_set->TextureRes (myGlContext),
999 AspectFace_set->TextureParams());
1007 AspectFace_applied = AspectFace_set;
1008 return AspectFace_set;
1011 //=======================================================================
1012 //function : SetPolygonOffset
1014 //=======================================================================
1015 void OpenGl_Workspace::SetPolygonOffset (int theMode,
1016 Standard_ShortReal theFactor,
1017 Standard_ShortReal theUnits)
1019 PolygonOffset_applied.mode = theMode;
1020 PolygonOffset_applied.factor = theFactor;
1021 PolygonOffset_applied.units = theUnits;
1023 TelUpdatePolygonOffsets (PolygonOffset_applied);
1026 // =======================================================================
1027 // function : AspectMarker
1029 // =======================================================================
1030 const OpenGl_AspectMarker* OpenGl_Workspace::AspectMarker (const Standard_Boolean theToApply)
1032 if (theToApply && (AspectMarker_set != AspectMarker_applied))
1034 if (!AspectMarker_applied || (AspectMarker_set->Scale() != AspectMarker_applied->Scale()))
1036 #if !defined(GL_ES_VERSION_2_0)
1037 glPointSize (AspectMarker_set->Scale());
1039 gl2psPointSize (AspectMarker_set->Scale());
1043 AspectMarker_applied = AspectMarker_set;
1045 return AspectMarker_set;
1048 // =======================================================================
1049 // function : AspectText
1051 // =======================================================================
1052 const OpenGl_AspectText* OpenGl_Workspace::AspectText (const Standard_Boolean theWithApply)
1056 AspectText_applied = AspectText_set;
1059 return AspectText_set;
1062 // =======================================================================
1065 // =======================================================================
1066 Standard_Integer OpenGl_Workspace::Width() const
1068 return !myView->GlWindow().IsNull() ? myView->GlWindow()->Width() : 0;
1071 // =======================================================================
1072 // function : Height
1074 // =======================================================================
1075 Standard_Integer OpenGl_Workspace::Height() const
1077 return !myView->GlWindow().IsNull() ? myView->GlWindow()->Height() : 0;
1080 // =======================================================================
1081 // function : UseGLLight
1083 // =======================================================================
1084 Standard_Boolean OpenGl_Workspace::UseGLLight() const
1086 return myView->IsGLLightEnabled();
1089 // =======================================================================
1090 // function : AntiAliasingMode
1092 // =======================================================================
1093 Standard_Integer OpenGl_Workspace::AntiAliasingMode() const
1095 return myView->IsAntialiasingEnabled();
1098 // =======================================================================
1099 // function : IsCullingEnabled
1101 // =======================================================================
1102 Standard_Boolean OpenGl_Workspace::IsCullingEnabled() const
1104 return myView->IsCullingEnabled();
1107 // =======================================================================
1108 // function : FBOCreate
1110 // =======================================================================
1111 Graphic3d_PtrFrameBuffer OpenGl_Workspace::FBOCreate (const Standard_Integer theWidth,
1112 const Standard_Integer theHeight)
1114 // activate OpenGL context
1119 const Handle(OpenGl_Context)& aCtx = GetGlContext();
1120 OpenGl_FrameBuffer* aFrameBuffer = new OpenGl_FrameBuffer();
1121 if (!aFrameBuffer->Init (aCtx, theWidth, theHeight))
1123 aFrameBuffer->Release (aCtx.operator->());
1124 delete aFrameBuffer;
1127 return (Graphic3d_PtrFrameBuffer )aFrameBuffer;
1130 // =======================================================================
1131 // function : FBORelease
1133 // =======================================================================
1134 void OpenGl_Workspace::FBORelease (Graphic3d_PtrFrameBuffer theFBOPtr)
1136 // activate OpenGL context
1138 || theFBOPtr == NULL)
1143 // release the object
1144 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer*)theFBOPtr;
1145 if (aFrameBuffer != NULL)
1147 aFrameBuffer->Release (GetGlContext().operator->());
1149 delete aFrameBuffer;
1152 inline bool getDataFormat (const Image_PixMap& theData,
1153 GLenum& thePixelFormat,
1154 GLenum& theDataType)
1156 thePixelFormat = GL_RGB;
1157 theDataType = GL_UNSIGNED_BYTE;
1158 switch (theData.Format())
1160 #if !defined(GL_ES_VERSION_2_0)
1161 case Image_PixMap::ImgGray:
1162 thePixelFormat = GL_DEPTH_COMPONENT;
1163 theDataType = GL_UNSIGNED_BYTE;
1165 case Image_PixMap::ImgGrayF:
1166 thePixelFormat = GL_DEPTH_COMPONENT;
1167 theDataType = GL_FLOAT;
1169 case Image_PixMap::ImgBGR:
1170 thePixelFormat = GL_BGR;
1171 theDataType = GL_UNSIGNED_BYTE;
1173 case Image_PixMap::ImgBGRA:
1174 case Image_PixMap::ImgBGR32:
1175 thePixelFormat = GL_BGRA;
1176 theDataType = GL_UNSIGNED_BYTE;
1178 case Image_PixMap::ImgBGRF:
1179 thePixelFormat = GL_BGR;
1180 theDataType = GL_FLOAT;
1182 case Image_PixMap::ImgBGRAF:
1183 thePixelFormat = GL_BGRA;
1184 theDataType = GL_FLOAT;
1187 case Image_PixMap::ImgGray:
1188 case Image_PixMap::ImgGrayF:
1189 case Image_PixMap::ImgBGR:
1190 case Image_PixMap::ImgBGRA:
1191 case Image_PixMap::ImgBGR32:
1192 case Image_PixMap::ImgBGRF:
1193 case Image_PixMap::ImgBGRAF:
1196 case Image_PixMap::ImgRGB:
1197 thePixelFormat = GL_RGB;
1198 theDataType = GL_UNSIGNED_BYTE;
1200 case Image_PixMap::ImgRGBA:
1201 case Image_PixMap::ImgRGB32:
1202 thePixelFormat = GL_RGBA;
1203 theDataType = GL_UNSIGNED_BYTE;
1205 case Image_PixMap::ImgRGBF:
1206 thePixelFormat = GL_RGB;
1207 theDataType = GL_FLOAT;
1209 case Image_PixMap::ImgRGBAF:
1210 thePixelFormat = GL_RGBA;
1211 theDataType = GL_FLOAT;
1213 case Image_PixMap::ImgAlpha:
1214 case Image_PixMap::ImgAlphaF:
1215 return false; // GL_ALPHA is no more supported in core context
1216 case Image_PixMap::ImgUNKNOWN:
1222 // =======================================================================
1223 // function : getAligned
1225 // =======================================================================
1226 inline Standard_Size getAligned (const Standard_Size theNumber,
1227 const Standard_Size theAlignment)
1229 return theNumber + theAlignment - 1 - (theNumber - 1) % theAlignment;
1232 // =======================================================================
1233 // function : BufferDump
1235 // =======================================================================
1236 Standard_Boolean OpenGl_Workspace::BufferDump (OpenGl_FrameBuffer* theFBOPtr,
1237 Image_PixMap& theImage,
1238 const Graphic3d_BufferType& theBufferType)
1240 GLenum aFormat, aType;
1241 if (theImage.IsEmpty()
1242 || !getDataFormat (theImage, aFormat, aType)
1245 return Standard_False;
1247 #if !defined(GL_ES_VERSION_2_0)
1248 GLint aReadBufferPrev = GL_BACK;
1249 if (theBufferType == Graphic3d_BT_Depth
1250 && aFormat != GL_DEPTH_COMPONENT)
1252 return Standard_False;
1257 if (theFBOPtr != NULL && theFBOPtr->IsValid())
1259 theFBOPtr->BindBuffer (GetGlContext());
1263 #if !defined(GL_ES_VERSION_2_0)
1264 glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev);
1265 GLint aDrawBufferPrev = GL_BACK;
1266 glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev);
1267 glReadBuffer (aDrawBufferPrev);
1272 const GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL
1273 glPixelStorei (GL_PACK_ALIGNMENT, anAligment);
1274 bool isBatchCopy = !theImage.IsTopDown();
1276 const GLint anExtraBytes = GLint(theImage.RowExtraBytes());
1277 GLint aPixelsWidth = GLint(theImage.SizeRowBytes() / theImage.SizePixelBytes());
1278 Standard_Size aSizeRowBytesEstim = getAligned (theImage.SizePixelBytes() * aPixelsWidth, anAligment);
1279 if (anExtraBytes < anAligment)
1283 else if (aSizeRowBytesEstim != theImage.SizeRowBytes())
1286 isBatchCopy = false;
1288 #if !defined(GL_ES_VERSION_2_0)
1289 glPixelStorei (GL_PACK_ROW_LENGTH, aPixelsWidth);
1291 if (aPixelsWidth != 0)
1293 isBatchCopy = false;
1300 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
1302 // Image_PixMap rows indexation always starts from the upper corner
1303 // while order in memory depends on the flag and processed by ChangeRow() method
1304 glReadPixels (0, GLint(theImage.SizeY() - aRow - 1), GLsizei (theImage.SizeX()), 1, aFormat, aType, theImage.ChangeRow (aRow));
1309 glReadPixels (0, 0, GLsizei (theImage.SizeX()), GLsizei (theImage.SizeY()), aFormat, aType, theImage.ChangeData());
1312 glPixelStorei (GL_PACK_ALIGNMENT, 1);
1313 #if !defined(GL_ES_VERSION_2_0)
1314 glPixelStorei (GL_PACK_ROW_LENGTH, 0);
1317 if (theFBOPtr != NULL && theFBOPtr->IsValid())
1319 theFBOPtr->UnbindBuffer (GetGlContext());
1323 #if !defined(GL_ES_VERSION_2_0)
1324 glReadBuffer (aReadBufferPrev);
1327 return Standard_True;
1330 // =======================================================================
1331 // function : CanRender
1333 // =======================================================================
1334 Standard_Boolean OpenGl_RaytraceFilter::CanRender (const OpenGl_Element* theElement)
1336 Standard_Boolean aPrevFilterResult = Standard_True;
1337 if (!myPrevRenderFilter.IsNull())
1339 aPrevFilterResult = myPrevRenderFilter->CanRender (theElement);
1341 return aPrevFilterResult &&
1342 !OpenGl_Raytrace::IsRaytracedElement (theElement);