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>
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 TEL_COLOUR 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 OPENGL_SURF_PROP& theProp)
78 if (theProp.color_mask & OPENGL_AMBIENT_MASK)
80 const float* aSrcAmb = theProp.isphysic ? theProp.ambcol.rgb : theProp.matcol.rgb;
81 Ambient = OpenGl_Vec4 (aSrcAmb[0] * theProp.amb,
82 aSrcAmb[1] * theProp.amb,
83 aSrcAmb[2] * theProp.amb,
88 Ambient = THE_BLACK_COLOR;
91 // diffusion component
92 if (theProp.color_mask & OPENGL_DIFFUSE_MASK)
94 const float* aSrcDif = theProp.isphysic ? theProp.difcol.rgb : theProp.matcol.rgb;
95 Diffuse = OpenGl_Vec4 (aSrcDif[0] * theProp.diff,
96 aSrcDif[1] * theProp.diff,
97 aSrcDif[2] * theProp.diff,
102 Diffuse = THE_BLACK_COLOR;
105 // specular component
106 if (theProp.color_mask & OPENGL_SPECULAR_MASK)
108 const float* aSrcSpe = theProp.isphysic ? theProp.speccol.rgb : THE_WHITE_COLOR.rgb;
109 Specular = OpenGl_Vec4 (aSrcSpe[0] * theProp.spec,
110 aSrcSpe[1] * theProp.spec,
111 aSrcSpe[2] * theProp.spec,
116 Specular = THE_BLACK_COLOR;
119 // emission component
120 if (theProp.color_mask & OPENGL_EMISSIVE_MASK)
122 const float* aSrcEms = theProp.isphysic ? theProp.emscol.rgb : theProp.matcol.rgb;
123 Emission = OpenGl_Vec4 (aSrcEms[0] * theProp.emsv,
124 aSrcEms[1] * theProp.emsv,
125 aSrcEms[2] * theProp.emsv,
130 Emission = THE_BLACK_COLOR;
133 ChangeShine() = theProp.shine;
134 ChangeTransparency() = theProp.trans;
137 // =======================================================================
138 // function : OpenGl_Workspace
140 // =======================================================================
141 OpenGl_Workspace::OpenGl_Workspace (OpenGl_View* theView, const Handle(OpenGl_Window)& theWindow)
143 HighlightColor (&THE_WHITE_COLOR),
145 myWindow (theWindow),
146 myGlContext (!theWindow.IsNull() ? theWindow->GetGlContext() : NULL),
147 myUseZBuffer (Standard_True),
148 myUseDepthWrite (Standard_True),
149 myUseGLLight (Standard_True),
151 AspectLine_set (&myDefaultAspectLine),
152 AspectLine_applied (NULL),
153 AspectFace_set (&myDefaultAspectFace),
154 AspectFace_applied (NULL),
155 AspectMarker_set (&myDefaultAspectMarker),
156 AspectMarker_applied (NULL),
157 AspectText_set (&myDefaultAspectText),
158 AspectText_applied (NULL),
159 ViewMatrix_applied (&myDefaultMatrix),
160 StructureMatrix_applied (&myDefaultMatrix),
161 myCullingMode (TelCullUndefined),
162 myModelViewMatrix (myDefaultMatrix),
163 PolygonOffset_applied (THE_DEFAULT_POFFSET)
165 if (!myGlContext.IsNull() && myGlContext->MakeCurrent())
167 myGlContext->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
169 if (!myGlContext->GetResource ("OpenGl_LineAttributes", myLineAttribs))
171 // share and register for release once the resource is no longer used
172 myLineAttribs = new OpenGl_LineAttributes();
173 myGlContext->ShareResource ("OpenGl_LineAttributes", myLineAttribs);
174 myLineAttribs->Init (myGlContext);
177 // General initialization of the context
179 #if !defined(GL_ES_VERSION_2_0)
180 if (myGlContext->core11 != NULL)
182 // Eviter d'avoir les faces mal orientees en noir.
183 // Pourrait etre utiliser pour detecter les problemes d'orientation
184 glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
186 // Optimisation pour le Fog et l'antialiasing
187 glHint (GL_FOG_HINT, GL_FASTEST);
188 glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST);
191 glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST);
192 glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
196 myDefaultCappingAlgoFilter = new OpenGl_CappingAlgoFilter();
197 myNoneCulling.ChangeCullingMode() = TelCullNone;
198 myNoneCulling.ChangeEdge() = 0;
199 myFrontCulling.ChangeCullingMode() = TelCullBack;
200 myFrontCulling.ChangeEdge() = 0;
203 // =======================================================================
204 // function : ~OpenGl_Workspace
206 // =======================================================================
207 OpenGl_Workspace::~OpenGl_Workspace()
209 if (!myLineAttribs.IsNull())
211 myLineAttribs.Nullify();
212 myGlContext->ReleaseResource ("OpenGl_LineAttributes", Standard_True);
216 // =======================================================================
217 // function : Activate
219 // =======================================================================
220 Standard_Boolean OpenGl_Workspace::Activate()
222 if (myWindow.IsNull() || !myWindow->Activate())
224 return Standard_False;
227 ViewMatrix_applied = &myDefaultMatrix;
228 StructureMatrix_applied = &myDefaultMatrix;
230 ResetAppliedAspect();
232 return Standard_True;
235 //=======================================================================
236 //function : ResetAppliedAspect
237 //purpose : Sets default values of GL parameters in accordance with default aspects
238 //=======================================================================
239 void OpenGl_Workspace::ResetAppliedAspect()
241 myGlContext->BindDefaultVao();
243 NamedStatus = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0;
244 HighlightColor = &THE_WHITE_COLOR;
245 AspectLine_set = &myDefaultAspectLine;
246 AspectLine_applied = NULL;
247 AspectFace_set = &myDefaultAspectFace;
248 AspectFace_applied = NULL;
249 AspectMarker_set = &myDefaultAspectMarker;
250 AspectMarker_applied = NULL;
251 AspectText_set = &myDefaultAspectText;
252 AspectText_applied = NULL;
254 PolygonOffset_applied = THE_DEFAULT_POFFSET;
255 myCullingMode = TelCullUndefined;
257 AspectLine(Standard_True);
258 AspectFace(Standard_True);
259 AspectMarker(Standard_True);
260 AspectText(Standard_True);
262 myGlContext->SetTypeOfLine (myDefaultAspectLine.Type());
263 myGlContext->SetLineWidth (myDefaultAspectLine.Width());
266 // =======================================================================
267 // function : DisableTexture
269 // =======================================================================
270 Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
272 if (myTextureBound.IsNull())
274 return myTextureBound;
277 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
278 if (!aSampler.IsNull())
280 aSampler->Unbind (*myGlContext);
283 #if !defined(GL_ES_VERSION_2_0)
284 // reset texture matrix because some code may expect it is identity
285 if (myGlContext->core11 != NULL)
287 GLint aMatrixMode = GL_TEXTURE;
288 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
289 glMatrixMode (GL_TEXTURE);
291 glMatrixMode (aMatrixMode);
295 myTextureBound->Unbind (myGlContext);
296 switch (myTextureBound->GetTarget())
298 #if !defined(GL_ES_VERSION_2_0)
301 if (myGlContext->core11 != NULL)
303 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
305 glDisable (GL_TEXTURE_GEN_S);
307 glDisable (GL_TEXTURE_1D);
314 #if !defined(GL_ES_VERSION_2_0)
315 if (myGlContext->core11 != NULL)
317 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
319 glDisable (GL_TEXTURE_GEN_S);
320 glDisable (GL_TEXTURE_GEN_T);
321 if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE)
323 glDisable (GL_POINT_SPRITE);
326 glDisable (GL_TEXTURE_2D);
334 Handle(OpenGl_Texture) aPrevTexture = myTextureBound;
335 myTextureBound.Nullify();
339 // =======================================================================
340 // function : setTextureParams
342 // =======================================================================
343 void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& theTexture,
344 const Handle(Graphic3d_TextureParams)& theParams)
346 const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams;
347 if (aParams.IsNull())
352 #if !defined(GL_ES_VERSION_2_0)
353 if (myGlContext->core11 != NULL)
355 GLint anEnvMode = GL_MODULATE; // lighting mode
356 if (!aParams->IsModulate())
358 anEnvMode = GL_DECAL;
359 if (theTexture->GetFormat() == GL_ALPHA
360 || theTexture->GetFormat() == GL_LUMINANCE)
362 anEnvMode = GL_REPLACE;
366 // setup generation of texture coordinates
367 switch (aParams->GenMode())
369 case Graphic3d_TOTM_OBJECT:
371 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
372 glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData());
373 if (theTexture->GetTarget() != GL_TEXTURE_1D)
375 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
376 glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData());
380 case Graphic3d_TOTM_SPHERE:
382 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
383 if (theTexture->GetTarget() != GL_TEXTURE_1D)
385 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
389 case Graphic3d_TOTM_EYE:
391 myGlContext->WorldViewState.Push();
393 myGlContext->WorldViewState.SetIdentity();
394 myGlContext->ApplyWorldViewMatrix();
396 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
397 glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData());
399 if (theTexture->GetTarget() != GL_TEXTURE_1D)
401 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
402 glTexGenfv (GL_T, GL_EYE_PLANE, aParams->GenPlaneT().GetData());
405 myGlContext->WorldViewState.Pop();
409 case Graphic3d_TOTM_SPRITE:
411 if (myGlContext->core20fwd != NULL)
413 glEnable (GL_POINT_SPRITE);
414 glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
415 anEnvMode = GL_REPLACE;
416 myGlContext->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
420 case Graphic3d_TOTM_MANUAL:
425 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
429 // get active sampler object to override default texture parameters
430 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
432 // setup texture filtering and wrapping
433 //if (theTexture->GetParams() != theParams)
434 const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
435 const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : myGlContext->TextureWrapClamp();
436 switch (theTexture->GetTarget())
438 #if !defined(GL_ES_VERSION_2_0)
441 if (aSampler.IsNull() || !aSampler->IsValid())
443 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
444 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
445 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
449 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
450 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilter);
451 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
459 GLenum aFilterMin = aFilter;
460 if (theTexture->HasMipmaps())
462 aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
463 if (aParams->Filter() == Graphic3d_TOTF_BILINEAR)
465 aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
467 else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR)
469 aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
472 if (myGlContext->extAnis)
474 // setup degree of anisotropy filter
475 const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
477 switch (aParams->AnisoFilter())
479 case Graphic3d_LOTA_QUALITY:
481 aDegree = aMaxDegree;
484 case Graphic3d_LOTA_MIDDLE:
486 aDegree = (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2);
489 case Graphic3d_LOTA_FAST:
494 case Graphic3d_LOTA_OFF:
502 if (aSampler.IsNull() || !aSampler->IsValid())
504 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
508 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
513 if (aSampler.IsNull() || !aSampler->IsValid())
515 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
516 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
517 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
518 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
522 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilterMin);
523 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
524 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
525 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_T, aWrapMode);
533 switch (theTexture->GetTarget())
535 #if !defined(GL_ES_VERSION_2_0)
538 if (myGlContext->core11 != NULL)
540 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
542 glEnable (GL_TEXTURE_GEN_S);
544 glEnable (GL_TEXTURE_1D);
551 #if !defined(GL_ES_VERSION_2_0)
552 if (myGlContext->core11 != NULL)
554 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
556 glEnable (GL_TEXTURE_GEN_S);
557 glEnable (GL_TEXTURE_GEN_T);
559 glEnable (GL_TEXTURE_2D);
567 theTexture->SetParams (aParams);
570 // =======================================================================
571 // function : EnableTexture
573 // =======================================================================
574 Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture,
575 const Handle(Graphic3d_TextureParams)& theParams)
577 if (theTexture.IsNull() || !theTexture->IsValid())
579 return DisableTexture();
582 if (myTextureBound == theTexture
583 && (theParams.IsNull() || theParams == theTexture->GetParams()))
586 return myTextureBound;
589 Handle(OpenGl_Texture) aPrevTexture = DisableTexture();
590 myTextureBound = theTexture;
591 myTextureBound->Bind (myGlContext);
592 setTextureParams (myTextureBound, theParams);
594 // If custom sampler object is available it will be
595 // used for overriding default texture parameters
596 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
598 if (!aSampler.IsNull() && aSampler->IsValid())
600 aSampler->Bind (*myGlContext);
606 // =======================================================================
607 // function : TelUpdatePolygonOffsets
609 // =======================================================================
610 static void TelUpdatePolygonOffsets (const TEL_POFFSET_PARAM& theOffsetData)
612 if ((theOffsetData.mode & Aspect_POM_Fill) == Aspect_POM_Fill)
614 glEnable (GL_POLYGON_OFFSET_FILL);
618 glDisable (GL_POLYGON_OFFSET_FILL);
621 #if !defined(GL_ES_VERSION_2_0)
622 if ((theOffsetData.mode & Aspect_POM_Line) == Aspect_POM_Line)
624 glEnable (GL_POLYGON_OFFSET_LINE);
628 glDisable (GL_POLYGON_OFFSET_LINE);
631 if ((theOffsetData.mode & Aspect_POM_Point) == Aspect_POM_Point)
633 glEnable (GL_POLYGON_OFFSET_POINT);
637 glDisable (GL_POLYGON_OFFSET_POINT);
641 glPolygonOffset (theOffsetData.factor, theOffsetData.units);
644 // =======================================================================
645 // function : updateMaterial
647 // =======================================================================
648 void OpenGl_Workspace::updateMaterial (const int theFlag)
650 // Case of hidden line
651 if (AspectFace_set->InteriorStyle() == Aspect_IS_HIDDENLINE)
653 myAspectFaceHl = *AspectFace_set; // copy all values including line edge aspect
654 myAspectFaceHl.ChangeIntFront().matcol = myView->BackgroundColor();
655 myAspectFaceHl.ChangeIntFront().color_mask = 0;
656 myAspectFaceHl.ChangeIntFront().color_mask = 0;
658 AspectFace_set = &myAspectFaceHl;
662 const OPENGL_SURF_PROP* aProps = &AspectFace_set->IntFront();
663 GLenum aFace = GL_FRONT_AND_BACK;
664 if (theFlag == TEL_BACK_MATERIAL)
667 aProps = &AspectFace_set->IntBack();
669 else if (AspectFace_set->DistinguishingMode() == TOn
670 && !(NamedStatus & OPENGL_NS_RESMAT))
675 myMatTmp.Init (*aProps);
677 // handling transparency
678 if (NamedStatus & OPENGL_NS_2NDPASSDO)
681 myMatTmp.Diffuse.a() = aProps->env_reflexion;
685 if (aProps->env_reflexion != 0.0f)
687 // if the material reflects the environment scene, the second pass is needed
688 NamedStatus |= OPENGL_NS_2NDPASSNEED;
691 if (aProps->trans != 1.0f)
693 // render transparent
694 myMatTmp.Diffuse.a() = aProps->trans;
695 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
699 glDepthMask (GL_FALSE);
705 if ((NamedStatus & OPENGL_NS_ANTIALIASING) == 0)
707 glBlendFunc (GL_ONE, GL_ZERO);
708 glDisable (GL_BLEND);
712 glDepthMask (GL_TRUE);
717 // do not update material properties in case of zero reflection mode,
718 // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
719 if (aProps->color_mask == 0)
725 if (NamedStatus & OPENGL_NS_RESMAT)
727 #if !defined(GL_ES_VERSION_2_0)
728 if (myGlContext->core11 != NULL)
730 myGlContext->core11->glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
731 myGlContext->core11->glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
732 myGlContext->core11->glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
733 myGlContext->core11->glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
734 myGlContext->core11->glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
738 if (theFlag == TEL_FRONT_MATERIAL)
740 myMatFront = myMatTmp;
741 myMatBack = myMatTmp;
745 myMatBack = myMatTmp;
748 NamedStatus &= ~OPENGL_NS_RESMAT;
753 OpenGl_Material& anOld = (theFlag == TEL_FRONT_MATERIAL)
756 #if !defined(GL_ES_VERSION_2_0)
757 if (myGlContext->core11 != NULL)
759 if (myMatTmp.Ambient.r() != anOld.Ambient.r()
760 || myMatTmp.Ambient.g() != anOld.Ambient.g()
761 || myMatTmp.Ambient.b() != anOld.Ambient.b())
763 myGlContext->core11->glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
765 if (myMatTmp.Diffuse.r() != anOld.Diffuse.r()
766 || myMatTmp.Diffuse.g() != anOld.Diffuse.g()
767 || myMatTmp.Diffuse.b() != anOld.Diffuse.b()
768 || fabs (myMatTmp.Diffuse.a() - anOld.Diffuse.a()) > 0.01f)
770 myGlContext->core11->glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
772 if (myMatTmp.Specular.r() != anOld.Specular.r()
773 || myMatTmp.Specular.g() != anOld.Specular.g()
774 || myMatTmp.Specular.b() != anOld.Specular.b())
776 myGlContext->core11->glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
778 if (myMatTmp.Emission.r() != anOld.Emission.r()
779 || myMatTmp.Emission.g() != anOld.Emission.g()
780 || myMatTmp.Emission.b() != anOld.Emission.b())
782 myGlContext->core11->glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
784 if (myMatTmp.Shine() != anOld.Shine())
786 myGlContext->core11->glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
791 if (aFace == GL_FRONT_AND_BACK)
793 myMatBack = myMatTmp;
797 // =======================================================================
798 // function : SetAspectLine
800 // =======================================================================
801 const OpenGl_AspectLine * OpenGl_Workspace::SetAspectLine(const OpenGl_AspectLine *AnAspect)
803 const OpenGl_AspectLine *AspectLine_old = AspectLine_set;
804 AspectLine_set = AnAspect;
805 return AspectLine_old;
808 // =======================================================================
809 // function : SetAspectFace
811 // =======================================================================
812 const OpenGl_AspectFace * OpenGl_Workspace::SetAspectFace(const OpenGl_AspectFace *AnAspect)
814 const OpenGl_AspectFace *AspectFace_old = AspectFace_set;
815 AspectFace_set = AnAspect;
816 return AspectFace_old;
819 // =======================================================================
820 // function : SetAspectMarker
822 // =======================================================================
823 const OpenGl_AspectMarker * OpenGl_Workspace::SetAspectMarker(const OpenGl_AspectMarker *AnAspect)
825 const OpenGl_AspectMarker *AspectMarker_old = AspectMarker_set;
826 AspectMarker_set = AnAspect;
827 return AspectMarker_old;
830 // =======================================================================
831 // function : SetAspectText
833 // =======================================================================
834 const OpenGl_AspectText * OpenGl_Workspace::SetAspectText(const OpenGl_AspectText *AnAspect)
836 const OpenGl_AspectText *AspectText_old = AspectText_set;
837 AspectText_set = AnAspect;
838 return AspectText_old;
841 // =======================================================================
842 // function : AspectLine
844 // =======================================================================
845 const OpenGl_AspectLine * OpenGl_Workspace::AspectLine(const Standard_Boolean theWithApply)
849 AspectLine_applied = AspectLine_set;
852 return AspectLine_set;
855 // =======================================================================
856 // function : AspectFace
858 // =======================================================================
859 const OpenGl_AspectFace* OpenGl_Workspace::AspectFace (const Standard_Boolean theToApply)
863 return AspectFace_set;
866 if (myView->BackfacingModel() == Graphic3d_TOBM_AUTOMATIC)
868 // manage back face culling mode, disable culling when clipping is enabled
869 TelCullMode aCullingMode = (myGlContext->Clipping().IsClippingOrCappingOn()
870 || AspectFace_set->InteriorStyle() == Aspect_IS_HATCH)
872 : (TelCullMode )AspectFace_set->CullingMode();
873 if (aCullingMode != TelCullNone
874 && !(NamedStatus & OPENGL_NS_2NDPASSDO))
876 // disable culling in case of translucent shading aspect
877 if (AspectFace_set->IntFront().trans != 1.0f)
879 aCullingMode = TelCullNone;
882 if (myCullingMode != aCullingMode)
884 myCullingMode = aCullingMode;
885 switch (myCullingMode)
888 case TelCullUndefined:
890 glDisable (GL_CULL_FACE);
895 glCullFace (GL_FRONT);
896 glEnable (GL_CULL_FACE);
901 glCullFace (GL_BACK);
902 glEnable (GL_CULL_FACE);
909 if (AspectFace_set == AspectFace_applied)
911 return AspectFace_set;
914 #if !defined(GL_ES_VERSION_2_0)
915 const Aspect_InteriorStyle anIntstyle = AspectFace_set->InteriorStyle();
916 if (AspectFace_applied == NULL || AspectFace_applied->InteriorStyle() != anIntstyle)
920 case Aspect_IS_EMPTY:
921 case Aspect_IS_HOLLOW:
923 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
926 case Aspect_IS_HATCH:
928 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
929 myLineAttribs->SetTypeOfHatch (AspectFace_applied != NULL ? AspectFace_applied->Hatch() : TEL_HS_SOLID);
932 case Aspect_IS_SOLID:
933 case Aspect_IS_HIDDENLINE:
935 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
936 if (myGlContext->core11 != NULL)
938 glDisable (GL_POLYGON_STIPPLE);
942 case Aspect_IS_POINT:
944 glPolygonMode (GL_FRONT_AND_BACK, GL_POINT);
950 if (anIntstyle == Aspect_IS_HATCH)
952 const Tint hatchstyle = AspectFace_set->Hatch();
953 if (AspectFace_applied == NULL || AspectFace_applied->Hatch() != hatchstyle)
955 myLineAttribs->SetTypeOfHatch (hatchstyle);
960 // Aspect_POM_None means: do not change current settings
961 if ((AspectFace_set->PolygonOffset().mode & Aspect_POM_None) != Aspect_POM_None)
963 if (PolygonOffset_applied.mode != AspectFace_set->PolygonOffset().mode
964 || PolygonOffset_applied.factor != AspectFace_set->PolygonOffset().factor
965 || PolygonOffset_applied.units != AspectFace_set->PolygonOffset().units)
967 SetPolygonOffset (AspectFace_set->PolygonOffset().mode,
968 AspectFace_set->PolygonOffset().factor,
969 AspectFace_set->PolygonOffset().units);
973 updateMaterial (TEL_FRONT_MATERIAL);
974 if (AspectFace_set->DistinguishingMode() == TOn)
976 updateMaterial (TEL_BACK_MATERIAL);
979 if (AspectFace_set->DoTextureMap())
981 EnableTexture (AspectFace_set->TextureRes (myGlContext),
982 AspectFace_set->TextureParams());
986 if (!myEnvironmentTexture.IsNull())
988 EnableTexture (myEnvironmentTexture,
989 myEnvironmentTexture->GetParams());
997 AspectFace_applied = AspectFace_set;
998 return AspectFace_set;
1001 //=======================================================================
1002 //function : SetPolygonOffset
1004 //=======================================================================
1005 void OpenGl_Workspace::SetPolygonOffset (int theMode,
1006 Standard_ShortReal theFactor,
1007 Standard_ShortReal theUnits)
1009 PolygonOffset_applied.mode = theMode;
1010 PolygonOffset_applied.factor = theFactor;
1011 PolygonOffset_applied.units = theUnits;
1013 TelUpdatePolygonOffsets (PolygonOffset_applied);
1016 // =======================================================================
1017 // function : AspectMarker
1019 // =======================================================================
1020 const OpenGl_AspectMarker* OpenGl_Workspace::AspectMarker (const Standard_Boolean theToApply)
1022 if (theToApply && (AspectMarker_set != AspectMarker_applied))
1024 if (!AspectMarker_applied || (AspectMarker_set->Scale() != AspectMarker_applied->Scale()))
1026 #if !defined(GL_ES_VERSION_2_0)
1027 glPointSize (AspectMarker_set->Scale());
1029 gl2psPointSize (AspectMarker_set->Scale());
1033 AspectMarker_applied = AspectMarker_set;
1035 return AspectMarker_set;
1038 // =======================================================================
1039 // function : AspectText
1041 // =======================================================================
1042 const OpenGl_AspectText* OpenGl_Workspace::AspectText (const Standard_Boolean theWithApply)
1046 AspectText_applied = AspectText_set;
1049 return AspectText_set;
1052 // =======================================================================
1055 // =======================================================================
1056 Standard_Integer OpenGl_Workspace::Width() const
1058 return !myView->GlWindow().IsNull() ? myView->GlWindow()->Width() : 0;
1061 // =======================================================================
1062 // function : Height
1064 // =======================================================================
1065 Standard_Integer OpenGl_Workspace::Height() const
1067 return !myView->GlWindow().IsNull() ? myView->GlWindow()->Height() : 0;
1070 // =======================================================================
1071 // function : UseGLLight
1073 // =======================================================================
1074 Standard_Boolean OpenGl_Workspace::UseGLLight() const
1076 return myView->IsGLLightEnabled();
1079 // =======================================================================
1080 // function : AntiAliasingMode
1082 // =======================================================================
1083 Standard_Integer OpenGl_Workspace::AntiAliasingMode() const
1085 return myView->IsAntialiasingEnabled();
1088 // =======================================================================
1089 // function : IsCullingEnabled
1091 // =======================================================================
1092 Standard_Boolean OpenGl_Workspace::IsCullingEnabled() const
1094 return myView->IsCullingEnabled();
1097 // =======================================================================
1098 // function : FBOCreate
1100 // =======================================================================
1101 Handle(OpenGl_FrameBuffer) OpenGl_Workspace::FBOCreate (const Standard_Integer theWidth,
1102 const Standard_Integer theHeight)
1104 // activate OpenGL context
1106 return Handle(OpenGl_FrameBuffer)();
1111 const Handle(OpenGl_Context)& aCtx = GetGlContext();
1112 Handle(OpenGl_FrameBuffer) aFrameBuffer = new OpenGl_FrameBuffer();
1113 if (!aFrameBuffer->Init (aCtx, theWidth, theHeight, GL_RGBA8, GL_DEPTH24_STENCIL8, 0))
1115 aFrameBuffer->Release (aCtx.operator->());
1116 return Handle(OpenGl_FrameBuffer)();
1118 return aFrameBuffer;
1121 // =======================================================================
1122 // function : FBORelease
1124 // =======================================================================
1125 void OpenGl_Workspace::FBORelease (Handle(OpenGl_FrameBuffer)& theFbo)
1127 // activate OpenGL context
1134 theFbo->Release (GetGlContext().operator->());
1138 inline bool getDataFormat (const Image_PixMap& theData,
1139 GLenum& thePixelFormat,
1140 GLenum& theDataType)
1142 thePixelFormat = GL_RGB;
1143 theDataType = GL_UNSIGNED_BYTE;
1144 switch (theData.Format())
1146 #if !defined(GL_ES_VERSION_2_0)
1147 case Image_PixMap::ImgGray:
1148 thePixelFormat = GL_DEPTH_COMPONENT;
1149 theDataType = GL_UNSIGNED_BYTE;
1151 case Image_PixMap::ImgGrayF:
1152 thePixelFormat = GL_DEPTH_COMPONENT;
1153 theDataType = GL_FLOAT;
1155 case Image_PixMap::ImgBGR:
1156 thePixelFormat = GL_BGR;
1157 theDataType = GL_UNSIGNED_BYTE;
1159 case Image_PixMap::ImgBGRA:
1160 case Image_PixMap::ImgBGR32:
1161 thePixelFormat = GL_BGRA;
1162 theDataType = GL_UNSIGNED_BYTE;
1164 case Image_PixMap::ImgBGRF:
1165 thePixelFormat = GL_BGR;
1166 theDataType = GL_FLOAT;
1168 case Image_PixMap::ImgBGRAF:
1169 thePixelFormat = GL_BGRA;
1170 theDataType = GL_FLOAT;
1173 case Image_PixMap::ImgGray:
1174 case Image_PixMap::ImgGrayF:
1175 case Image_PixMap::ImgBGR:
1176 case Image_PixMap::ImgBGRA:
1177 case Image_PixMap::ImgBGR32:
1178 case Image_PixMap::ImgBGRF:
1179 case Image_PixMap::ImgBGRAF:
1182 case Image_PixMap::ImgRGB:
1183 thePixelFormat = GL_RGB;
1184 theDataType = GL_UNSIGNED_BYTE;
1186 case Image_PixMap::ImgRGBA:
1187 case Image_PixMap::ImgRGB32:
1188 thePixelFormat = GL_RGBA;
1189 theDataType = GL_UNSIGNED_BYTE;
1191 case Image_PixMap::ImgRGBF:
1192 thePixelFormat = GL_RGB;
1193 theDataType = GL_FLOAT;
1195 case Image_PixMap::ImgRGBAF:
1196 thePixelFormat = GL_RGBA;
1197 theDataType = GL_FLOAT;
1199 case Image_PixMap::ImgAlpha:
1200 case Image_PixMap::ImgAlphaF:
1201 return false; // GL_ALPHA is no more supported in core context
1202 case Image_PixMap::ImgUNKNOWN:
1208 // =======================================================================
1209 // function : getAligned
1211 // =======================================================================
1212 inline Standard_Size getAligned (const Standard_Size theNumber,
1213 const Standard_Size theAlignment)
1215 return theNumber + theAlignment - 1 - (theNumber - 1) % theAlignment;
1218 // =======================================================================
1219 // function : BufferDump
1221 // =======================================================================
1222 Standard_Boolean OpenGl_Workspace::BufferDump (const Handle(OpenGl_FrameBuffer)& theFbo,
1223 Image_PixMap& theImage,
1224 const Graphic3d_BufferType& theBufferType)
1226 GLenum aFormat, aType;
1227 if (theImage.IsEmpty()
1228 || !getDataFormat (theImage, aFormat, aType)
1231 return Standard_False;
1233 #if !defined(GL_ES_VERSION_2_0)
1234 GLint aReadBufferPrev = GL_BACK;
1235 if (theBufferType == Graphic3d_BT_Depth
1236 && aFormat != GL_DEPTH_COMPONENT)
1238 return Standard_False;
1241 (void )theBufferType;
1245 if (!theFbo.IsNull() && theFbo->IsValid())
1247 theFbo->BindBuffer (GetGlContext());
1251 #if !defined(GL_ES_VERSION_2_0)
1252 glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev);
1253 GLint aDrawBufferPrev = GL_BACK;
1254 glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev);
1255 glReadBuffer (aDrawBufferPrev);
1260 const GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL
1261 glPixelStorei (GL_PACK_ALIGNMENT, anAligment);
1262 bool isBatchCopy = !theImage.IsTopDown();
1264 const GLint anExtraBytes = GLint(theImage.RowExtraBytes());
1265 GLint aPixelsWidth = GLint(theImage.SizeRowBytes() / theImage.SizePixelBytes());
1266 Standard_Size aSizeRowBytesEstim = getAligned (theImage.SizePixelBytes() * aPixelsWidth, anAligment);
1267 if (anExtraBytes < anAligment)
1271 else if (aSizeRowBytesEstim != theImage.SizeRowBytes())
1274 isBatchCopy = false;
1276 #if !defined(GL_ES_VERSION_2_0)
1277 glPixelStorei (GL_PACK_ROW_LENGTH, aPixelsWidth);
1279 if (aPixelsWidth != 0)
1281 isBatchCopy = false;
1288 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
1290 // Image_PixMap rows indexation always starts from the upper corner
1291 // while order in memory depends on the flag and processed by ChangeRow() method
1292 glReadPixels (0, GLint(theImage.SizeY() - aRow - 1), GLsizei (theImage.SizeX()), 1, aFormat, aType, theImage.ChangeRow (aRow));
1297 glReadPixels (0, 0, GLsizei (theImage.SizeX()), GLsizei (theImage.SizeY()), aFormat, aType, theImage.ChangeData());
1300 glPixelStorei (GL_PACK_ALIGNMENT, 1);
1301 #if !defined(GL_ES_VERSION_2_0)
1302 glPixelStorei (GL_PACK_ROW_LENGTH, 0);
1305 if (!theFbo.IsNull() && theFbo->IsValid())
1307 theFbo->UnbindBuffer (GetGlContext());
1311 #if !defined(GL_ES_VERSION_2_0)
1312 glReadBuffer (aReadBufferPrev);
1315 return Standard_True;
1318 // =======================================================================
1319 // function : CanRender
1321 // =======================================================================
1322 Standard_Boolean OpenGl_RaytraceFilter::CanRender (const OpenGl_Element* theElement)
1324 Standard_Boolean aPrevFilterResult = Standard_True;
1325 if (!myPrevRenderFilter.IsNull())
1327 aPrevFilterResult = myPrevRenderFilter->CanRender (theElement);
1329 return aPrevFilterResult &&
1330 !OpenGl_Raytrace::IsRaytracedElement (theElement);