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 if (myGlContext->core11 != NULL)
351 GLint anEnvMode = GL_MODULATE; // lighting mode
352 if (!aParams->IsModulate())
354 anEnvMode = GL_DECAL;
355 if (theTexture->GetFormat() == GL_ALPHA
356 || theTexture->GetFormat() == GL_LUMINANCE)
358 anEnvMode = GL_REPLACE;
362 // setup generation of texture coordinates
363 switch (aParams->GenMode())
365 case Graphic3d_TOTM_OBJECT:
367 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
368 glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData());
369 if (theTexture->GetTarget() != GL_TEXTURE_1D)
371 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
372 glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData());
376 case Graphic3d_TOTM_SPHERE:
378 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
379 if (theTexture->GetTarget() != GL_TEXTURE_1D)
381 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
385 case Graphic3d_TOTM_EYE:
387 myGlContext->WorldViewState.Push();
389 myGlContext->WorldViewState.SetIdentity();
390 myGlContext->ApplyWorldViewMatrix();
392 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
393 glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData());
395 if (theTexture->GetTarget() != GL_TEXTURE_1D)
397 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
398 glTexGenfv (GL_T, GL_EYE_PLANE, aParams->GenPlaneT().GetData());
401 myGlContext->WorldViewState.Pop();
405 case Graphic3d_TOTM_SPRITE:
407 if (myGlContext->core20fwd != NULL)
409 glEnable (GL_POINT_SPRITE);
410 glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
411 anEnvMode = GL_REPLACE;
412 myGlContext->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
416 case Graphic3d_TOTM_MANUAL:
421 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
425 // get active sampler object to override default texture parameters
426 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
428 // setup texture filtering and wrapping
429 //if (theTexture->GetParams() != theParams)
430 const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
431 const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : myGlContext->TextureWrapClamp();
432 switch (theTexture->GetTarget())
434 #if !defined(GL_ES_VERSION_2_0)
437 if (aSampler.IsNull() || !aSampler->IsValid())
439 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
440 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
441 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
445 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
446 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilter);
447 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
455 GLenum aFilterMin = aFilter;
456 if (theTexture->HasMipmaps())
458 aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
459 if (aParams->Filter() == Graphic3d_TOTF_BILINEAR)
461 aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
463 else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR)
465 aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
468 if (myGlContext->extAnis)
470 // setup degree of anisotropy filter
471 const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
473 switch (aParams->AnisoFilter())
475 case Graphic3d_LOTA_QUALITY:
477 aDegree = aMaxDegree;
480 case Graphic3d_LOTA_MIDDLE:
482 aDegree = (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2);
485 case Graphic3d_LOTA_FAST:
490 case Graphic3d_LOTA_OFF:
498 if (aSampler.IsNull() || !aSampler->IsValid())
500 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
504 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
509 if (aSampler.IsNull() || !aSampler->IsValid())
511 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
512 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
513 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
514 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
518 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilterMin);
519 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
520 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
521 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_T, aWrapMode);
529 switch (theTexture->GetTarget())
531 #if !defined(GL_ES_VERSION_2_0)
534 if (myGlContext->core11 != NULL)
536 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
538 glEnable (GL_TEXTURE_GEN_S);
540 glEnable (GL_TEXTURE_1D);
547 #if !defined(GL_ES_VERSION_2_0)
548 if (myGlContext->core11 != NULL)
550 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
552 glEnable (GL_TEXTURE_GEN_S);
553 glEnable (GL_TEXTURE_GEN_T);
555 glEnable (GL_TEXTURE_2D);
563 theTexture->SetParams (aParams);
566 // =======================================================================
567 // function : EnableTexture
569 // =======================================================================
570 Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture,
571 const Handle(Graphic3d_TextureParams)& theParams)
573 if (theTexture.IsNull() || !theTexture->IsValid())
575 return DisableTexture();
578 if (myTextureBound == theTexture
579 && (theParams.IsNull() || theParams == theTexture->GetParams()))
582 return myTextureBound;
585 Handle(OpenGl_Texture) aPrevTexture = DisableTexture();
586 myTextureBound = theTexture;
587 myTextureBound->Bind (myGlContext);
588 setTextureParams (myTextureBound, theParams);
590 // If custom sampler object is available it will be
591 // used for overriding default texture parameters
592 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
594 if (!aSampler.IsNull() && aSampler->IsValid())
596 aSampler->Bind (*myGlContext);
602 // =======================================================================
603 // function : TelUpdatePolygonOffsets
605 // =======================================================================
606 static void TelUpdatePolygonOffsets (const TEL_POFFSET_PARAM& theOffsetData)
608 if ((theOffsetData.mode & Aspect_POM_Fill) == Aspect_POM_Fill)
610 glEnable (GL_POLYGON_OFFSET_FILL);
614 glDisable (GL_POLYGON_OFFSET_FILL);
617 #if !defined(GL_ES_VERSION_2_0)
618 if ((theOffsetData.mode & Aspect_POM_Line) == Aspect_POM_Line)
620 glEnable (GL_POLYGON_OFFSET_LINE);
624 glDisable (GL_POLYGON_OFFSET_LINE);
627 if ((theOffsetData.mode & Aspect_POM_Point) == Aspect_POM_Point)
629 glEnable (GL_POLYGON_OFFSET_POINT);
633 glDisable (GL_POLYGON_OFFSET_POINT);
637 glPolygonOffset (theOffsetData.factor, theOffsetData.units);
640 // =======================================================================
641 // function : updateMaterial
643 // =======================================================================
644 void OpenGl_Workspace::updateMaterial (const int theFlag)
646 // Case of hidden line
647 if (AspectFace_set->InteriorStyle() == Aspect_IS_HIDDENLINE)
649 myAspectFaceHl = *AspectFace_set; // copy all values including line edge aspect
650 myAspectFaceHl.ChangeIntFront().matcol = myView->BackgroundColor();
651 myAspectFaceHl.ChangeIntFront().color_mask = 0;
652 myAspectFaceHl.ChangeIntFront().color_mask = 0;
654 AspectFace_set = &myAspectFaceHl;
658 const OPENGL_SURF_PROP* aProps = &AspectFace_set->IntFront();
659 GLenum aFace = GL_FRONT_AND_BACK;
660 if (theFlag == TEL_BACK_MATERIAL)
663 aProps = &AspectFace_set->IntBack();
665 else if (AspectFace_set->DistinguishingMode() == TOn
666 && !(NamedStatus & OPENGL_NS_RESMAT))
671 myMatTmp.Init (*aProps);
673 // handling transparency
674 if (NamedStatus & OPENGL_NS_2NDPASSDO)
677 myMatTmp.Diffuse.a() = aProps->env_reflexion;
681 if (aProps->env_reflexion != 0.0f)
683 // if the material reflects the environment scene, the second pass is needed
684 NamedStatus |= OPENGL_NS_2NDPASSNEED;
687 if (aProps->trans != 1.0f)
689 // render transparent
690 myMatTmp.Diffuse.a() = aProps->trans;
691 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
695 glDepthMask (GL_FALSE);
701 if ((NamedStatus & OPENGL_NS_ANTIALIASING) == 0)
703 glBlendFunc (GL_ONE, GL_ZERO);
704 glDisable (GL_BLEND);
708 glDepthMask (GL_TRUE);
713 // do not update material properties in case of zero reflection mode,
714 // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
715 if (aProps->color_mask == 0)
721 if (NamedStatus & OPENGL_NS_RESMAT)
723 #if !defined(GL_ES_VERSION_2_0)
724 if (myGlContext->core11 != NULL)
726 myGlContext->core11->glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
727 myGlContext->core11->glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
728 myGlContext->core11->glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
729 myGlContext->core11->glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
730 myGlContext->core11->glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
734 if (theFlag == TEL_FRONT_MATERIAL)
736 myMatFront = myMatTmp;
737 myMatBack = myMatTmp;
741 myMatBack = myMatTmp;
744 NamedStatus &= ~OPENGL_NS_RESMAT;
749 OpenGl_Material& anOld = (theFlag == TEL_FRONT_MATERIAL)
752 #if !defined(GL_ES_VERSION_2_0)
753 if (myGlContext->core11 != NULL)
755 if (myMatTmp.Ambient.r() != anOld.Ambient.r()
756 || myMatTmp.Ambient.g() != anOld.Ambient.g()
757 || myMatTmp.Ambient.b() != anOld.Ambient.b())
759 myGlContext->core11->glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
761 if (myMatTmp.Diffuse.r() != anOld.Diffuse.r()
762 || myMatTmp.Diffuse.g() != anOld.Diffuse.g()
763 || myMatTmp.Diffuse.b() != anOld.Diffuse.b()
764 || fabs (myMatTmp.Diffuse.a() - anOld.Diffuse.a()) > 0.01f)
766 myGlContext->core11->glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
768 if (myMatTmp.Specular.r() != anOld.Specular.r()
769 || myMatTmp.Specular.g() != anOld.Specular.g()
770 || myMatTmp.Specular.b() != anOld.Specular.b())
772 myGlContext->core11->glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
774 if (myMatTmp.Emission.r() != anOld.Emission.r()
775 || myMatTmp.Emission.g() != anOld.Emission.g()
776 || myMatTmp.Emission.b() != anOld.Emission.b())
778 myGlContext->core11->glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
780 if (myMatTmp.Shine() != anOld.Shine())
782 myGlContext->core11->glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
787 if (aFace == GL_FRONT_AND_BACK)
789 myMatBack = myMatTmp;
793 // =======================================================================
794 // function : SetAspectLine
796 // =======================================================================
797 const OpenGl_AspectLine * OpenGl_Workspace::SetAspectLine(const OpenGl_AspectLine *AnAspect)
799 const OpenGl_AspectLine *AspectLine_old = AspectLine_set;
800 AspectLine_set = AnAspect;
801 return AspectLine_old;
804 // =======================================================================
805 // function : SetAspectFace
807 // =======================================================================
808 const OpenGl_AspectFace * OpenGl_Workspace::SetAspectFace(const OpenGl_AspectFace *AnAspect)
810 const OpenGl_AspectFace *AspectFace_old = AspectFace_set;
811 AspectFace_set = AnAspect;
812 return AspectFace_old;
815 // =======================================================================
816 // function : SetAspectMarker
818 // =======================================================================
819 const OpenGl_AspectMarker * OpenGl_Workspace::SetAspectMarker(const OpenGl_AspectMarker *AnAspect)
821 const OpenGl_AspectMarker *AspectMarker_old = AspectMarker_set;
822 AspectMarker_set = AnAspect;
823 return AspectMarker_old;
826 // =======================================================================
827 // function : SetAspectText
829 // =======================================================================
830 const OpenGl_AspectText * OpenGl_Workspace::SetAspectText(const OpenGl_AspectText *AnAspect)
832 const OpenGl_AspectText *AspectText_old = AspectText_set;
833 AspectText_set = AnAspect;
834 return AspectText_old;
837 // =======================================================================
838 // function : AspectLine
840 // =======================================================================
841 const OpenGl_AspectLine * OpenGl_Workspace::AspectLine(const Standard_Boolean theWithApply)
845 AspectLine_applied = AspectLine_set;
848 return AspectLine_set;
851 // =======================================================================
852 // function : AspectFace
854 // =======================================================================
855 const OpenGl_AspectFace* OpenGl_Workspace::AspectFace (const Standard_Boolean theToApply)
859 return AspectFace_set;
862 if (myView->BackfacingModel() == Graphic3d_TOBM_AUTOMATIC)
864 // manage back face culling mode, disable culling when clipping is enabled
865 TelCullMode aCullingMode = (myGlContext->Clipping().IsClippingOrCappingOn()
866 || AspectFace_set->InteriorStyle() == Aspect_IS_HATCH)
868 : (TelCullMode )AspectFace_set->CullingMode();
869 if (aCullingMode != TelCullNone
870 && !(NamedStatus & OPENGL_NS_2NDPASSDO))
872 // disable culling in case of translucent shading aspect
873 if (AspectFace_set->IntFront().trans != 1.0f)
875 aCullingMode = TelCullNone;
878 if (myCullingMode != aCullingMode)
880 myCullingMode = aCullingMode;
881 switch (myCullingMode)
884 case TelCullUndefined:
886 glDisable (GL_CULL_FACE);
891 glCullFace (GL_FRONT);
892 glEnable (GL_CULL_FACE);
897 glCullFace (GL_BACK);
898 glEnable (GL_CULL_FACE);
905 if (AspectFace_set == AspectFace_applied)
907 return AspectFace_set;
910 #if !defined(GL_ES_VERSION_2_0)
911 const Aspect_InteriorStyle anIntstyle = AspectFace_set->InteriorStyle();
912 if (AspectFace_applied == NULL || AspectFace_applied->InteriorStyle() != anIntstyle)
916 case Aspect_IS_EMPTY:
917 case Aspect_IS_HOLLOW:
919 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
922 case Aspect_IS_HATCH:
924 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
925 myLineAttribs->SetTypeOfHatch (AspectFace_applied != NULL ? AspectFace_applied->Hatch() : TEL_HS_SOLID);
928 case Aspect_IS_SOLID:
929 case Aspect_IS_HIDDENLINE:
931 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
932 if (myGlContext->core11 != NULL)
934 glDisable (GL_POLYGON_STIPPLE);
938 case Aspect_IS_POINT:
940 glPolygonMode (GL_FRONT_AND_BACK, GL_POINT);
946 if (anIntstyle == Aspect_IS_HATCH)
948 const Tint hatchstyle = AspectFace_set->Hatch();
949 if (AspectFace_applied == NULL || AspectFace_applied->Hatch() != hatchstyle)
951 myLineAttribs->SetTypeOfHatch (hatchstyle);
956 // Aspect_POM_None means: do not change current settings
957 if ((AspectFace_set->PolygonOffset().mode & Aspect_POM_None) != Aspect_POM_None)
959 if (PolygonOffset_applied.mode != AspectFace_set->PolygonOffset().mode
960 || PolygonOffset_applied.factor != AspectFace_set->PolygonOffset().factor
961 || PolygonOffset_applied.units != AspectFace_set->PolygonOffset().units)
963 SetPolygonOffset (AspectFace_set->PolygonOffset().mode,
964 AspectFace_set->PolygonOffset().factor,
965 AspectFace_set->PolygonOffset().units);
969 updateMaterial (TEL_FRONT_MATERIAL);
970 if (AspectFace_set->DistinguishingMode() == TOn)
972 updateMaterial (TEL_BACK_MATERIAL);
975 if ((NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
977 if (AspectFace_set->DoTextureMap())
979 EnableTexture (AspectFace_set->TextureRes (myGlContext),
980 AspectFace_set->TextureParams());
988 AspectFace_applied = AspectFace_set;
989 return AspectFace_set;
992 //=======================================================================
993 //function : SetPolygonOffset
995 //=======================================================================
996 void OpenGl_Workspace::SetPolygonOffset (int theMode,
997 Standard_ShortReal theFactor,
998 Standard_ShortReal theUnits)
1000 PolygonOffset_applied.mode = theMode;
1001 PolygonOffset_applied.factor = theFactor;
1002 PolygonOffset_applied.units = theUnits;
1004 TelUpdatePolygonOffsets (PolygonOffset_applied);
1007 // =======================================================================
1008 // function : AspectMarker
1010 // =======================================================================
1011 const OpenGl_AspectMarker* OpenGl_Workspace::AspectMarker (const Standard_Boolean theToApply)
1013 if (theToApply && (AspectMarker_set != AspectMarker_applied))
1015 if (!AspectMarker_applied || (AspectMarker_set->Scale() != AspectMarker_applied->Scale()))
1017 #if !defined(GL_ES_VERSION_2_0)
1018 glPointSize (AspectMarker_set->Scale());
1020 gl2psPointSize (AspectMarker_set->Scale());
1024 AspectMarker_applied = AspectMarker_set;
1026 return AspectMarker_set;
1029 // =======================================================================
1030 // function : AspectText
1032 // =======================================================================
1033 const OpenGl_AspectText* OpenGl_Workspace::AspectText (const Standard_Boolean theWithApply)
1037 AspectText_applied = AspectText_set;
1040 return AspectText_set;
1043 // =======================================================================
1046 // =======================================================================
1047 Standard_Integer OpenGl_Workspace::Width() const
1049 return !myView->GlWindow().IsNull() ? myView->GlWindow()->Width() : 0;
1052 // =======================================================================
1053 // function : Height
1055 // =======================================================================
1056 Standard_Integer OpenGl_Workspace::Height() const
1058 return !myView->GlWindow().IsNull() ? myView->GlWindow()->Height() : 0;
1061 // =======================================================================
1062 // function : UseGLLight
1064 // =======================================================================
1065 Standard_Boolean OpenGl_Workspace::UseGLLight() const
1067 return myView->IsGLLightEnabled();
1070 // =======================================================================
1071 // function : AntiAliasingMode
1073 // =======================================================================
1074 Standard_Integer OpenGl_Workspace::AntiAliasingMode() const
1076 return myView->IsAntialiasingEnabled();
1079 // =======================================================================
1080 // function : IsCullingEnabled
1082 // =======================================================================
1083 Standard_Boolean OpenGl_Workspace::IsCullingEnabled() const
1085 return myView->IsCullingEnabled();
1088 // =======================================================================
1089 // function : FBOCreate
1091 // =======================================================================
1092 Graphic3d_PtrFrameBuffer OpenGl_Workspace::FBOCreate (const Standard_Integer theWidth,
1093 const Standard_Integer theHeight)
1095 // activate OpenGL context
1100 const Handle(OpenGl_Context)& aCtx = GetGlContext();
1101 OpenGl_FrameBuffer* aFrameBuffer = new OpenGl_FrameBuffer();
1102 if (!aFrameBuffer->Init (aCtx, theWidth, theHeight))
1104 aFrameBuffer->Release (aCtx.operator->());
1105 delete aFrameBuffer;
1108 return (Graphic3d_PtrFrameBuffer )aFrameBuffer;
1111 // =======================================================================
1112 // function : FBORelease
1114 // =======================================================================
1115 void OpenGl_Workspace::FBORelease (Graphic3d_PtrFrameBuffer theFBOPtr)
1117 // activate OpenGL context
1119 || theFBOPtr == NULL)
1124 // release the object
1125 OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer*)theFBOPtr;
1126 if (aFrameBuffer != NULL)
1128 aFrameBuffer->Release (GetGlContext().operator->());
1130 delete aFrameBuffer;
1133 inline bool getDataFormat (const Image_PixMap& theData,
1134 GLenum& thePixelFormat,
1135 GLenum& theDataType)
1137 thePixelFormat = GL_RGB;
1138 theDataType = GL_UNSIGNED_BYTE;
1139 switch (theData.Format())
1141 #if !defined(GL_ES_VERSION_2_0)
1142 case Image_PixMap::ImgGray:
1143 thePixelFormat = GL_DEPTH_COMPONENT;
1144 theDataType = GL_UNSIGNED_BYTE;
1146 case Image_PixMap::ImgGrayF:
1147 thePixelFormat = GL_DEPTH_COMPONENT;
1148 theDataType = GL_FLOAT;
1150 case Image_PixMap::ImgBGR:
1151 thePixelFormat = GL_BGR;
1152 theDataType = GL_UNSIGNED_BYTE;
1154 case Image_PixMap::ImgBGRA:
1155 case Image_PixMap::ImgBGR32:
1156 thePixelFormat = GL_BGRA;
1157 theDataType = GL_UNSIGNED_BYTE;
1159 case Image_PixMap::ImgBGRF:
1160 thePixelFormat = GL_BGR;
1161 theDataType = GL_FLOAT;
1163 case Image_PixMap::ImgBGRAF:
1164 thePixelFormat = GL_BGRA;
1165 theDataType = GL_FLOAT;
1168 case Image_PixMap::ImgGray:
1169 case Image_PixMap::ImgGrayF:
1170 case Image_PixMap::ImgBGR:
1171 case Image_PixMap::ImgBGRA:
1172 case Image_PixMap::ImgBGR32:
1173 case Image_PixMap::ImgBGRF:
1174 case Image_PixMap::ImgBGRAF:
1177 case Image_PixMap::ImgRGB:
1178 thePixelFormat = GL_RGB;
1179 theDataType = GL_UNSIGNED_BYTE;
1181 case Image_PixMap::ImgRGBA:
1182 case Image_PixMap::ImgRGB32:
1183 thePixelFormat = GL_RGBA;
1184 theDataType = GL_UNSIGNED_BYTE;
1186 case Image_PixMap::ImgRGBF:
1187 thePixelFormat = GL_RGB;
1188 theDataType = GL_FLOAT;
1190 case Image_PixMap::ImgRGBAF:
1191 thePixelFormat = GL_RGBA;
1192 theDataType = GL_FLOAT;
1194 case Image_PixMap::ImgAlpha:
1195 case Image_PixMap::ImgAlphaF:
1196 return false; // GL_ALPHA is no more supported in core context
1197 case Image_PixMap::ImgUNKNOWN:
1203 // =======================================================================
1204 // function : getAligned
1206 // =======================================================================
1207 inline Standard_Size getAligned (const Standard_Size theNumber,
1208 const Standard_Size theAlignment)
1210 return theNumber + theAlignment - 1 - (theNumber - 1) % theAlignment;
1213 // =======================================================================
1214 // function : BufferDump
1216 // =======================================================================
1217 Standard_Boolean OpenGl_Workspace::BufferDump (OpenGl_FrameBuffer* theFBOPtr,
1218 Image_PixMap& theImage,
1219 const Graphic3d_BufferType& theBufferType)
1221 GLenum aFormat, aType;
1222 if (theImage.IsEmpty()
1223 || !getDataFormat (theImage, aFormat, aType)
1226 return Standard_False;
1228 #if !defined(GL_ES_VERSION_2_0)
1229 GLint aReadBufferPrev = GL_BACK;
1230 if (theBufferType == Graphic3d_BT_Depth
1231 && aFormat != GL_DEPTH_COMPONENT)
1233 return Standard_False;
1238 if (theFBOPtr != NULL && theFBOPtr->IsValid())
1240 theFBOPtr->BindBuffer (GetGlContext());
1244 #if !defined(GL_ES_VERSION_2_0)
1245 glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev);
1246 GLint aDrawBufferPrev = GL_BACK;
1247 glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev);
1248 glReadBuffer (aDrawBufferPrev);
1253 const GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL
1254 glPixelStorei (GL_PACK_ALIGNMENT, anAligment);
1255 bool isBatchCopy = !theImage.IsTopDown();
1257 const GLint anExtraBytes = GLint(theImage.RowExtraBytes());
1258 GLint aPixelsWidth = GLint(theImage.SizeRowBytes() / theImage.SizePixelBytes());
1259 Standard_Size aSizeRowBytesEstim = getAligned (theImage.SizePixelBytes() * aPixelsWidth, anAligment);
1260 if (anExtraBytes < anAligment)
1264 else if (aSizeRowBytesEstim != theImage.SizeRowBytes())
1267 isBatchCopy = false;
1269 #if !defined(GL_ES_VERSION_2_0)
1270 glPixelStorei (GL_PACK_ROW_LENGTH, aPixelsWidth);
1272 if (aPixelsWidth != 0)
1274 isBatchCopy = false;
1281 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
1283 // Image_PixMap rows indexation always starts from the upper corner
1284 // while order in memory depends on the flag and processed by ChangeRow() method
1285 glReadPixels (0, GLint(theImage.SizeY() - aRow - 1), GLsizei (theImage.SizeX()), 1, aFormat, aType, theImage.ChangeRow (aRow));
1290 glReadPixels (0, 0, GLsizei (theImage.SizeX()), GLsizei (theImage.SizeY()), aFormat, aType, theImage.ChangeData());
1293 glPixelStorei (GL_PACK_ALIGNMENT, 1);
1294 #if !defined(GL_ES_VERSION_2_0)
1295 glPixelStorei (GL_PACK_ROW_LENGTH, 0);
1298 if (theFBOPtr != NULL && theFBOPtr->IsValid())
1300 theFBOPtr->UnbindBuffer (GetGlContext());
1304 #if !defined(GL_ES_VERSION_2_0)
1305 glReadBuffer (aReadBufferPrev);
1308 return Standard_True;
1311 // =======================================================================
1312 // function : CanRender
1314 // =======================================================================
1315 Standard_Boolean OpenGl_RaytraceFilter::CanRender (const OpenGl_Element* theElement)
1317 Standard_Boolean aPrevFilterResult = Standard_True;
1318 if (!myPrevRenderFilter.IsNull())
1320 aPrevFilterResult = myPrevRenderFilter->CanRender (theElement);
1322 return aPrevFilterResult &&
1323 !OpenGl_Raytrace::IsRaytracedElement (theElement);