1 // Created on: 2011-09-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OpenGl_Workspace.hxx>
18 #include <OpenGl_ArbFBO.hxx>
19 #include <OpenGl_Aspects.hxx>
20 #include <OpenGl_Context.hxx>
21 #include <OpenGl_Element.hxx>
22 #include <OpenGl_FrameBuffer.hxx>
23 #include <OpenGl_GlCore15.hxx>
24 #include <OpenGl_SceneGeometry.hxx>
25 #include <OpenGl_Structure.hxx>
26 #include <OpenGl_Sampler.hxx>
27 #include <OpenGl_ShaderManager.hxx>
28 #include <OpenGl_Texture.hxx>
29 #include <OpenGl_View.hxx>
30 #include <OpenGl_Window.hxx>
32 #include <Graphic3d_TextureParams.hxx>
33 #include <Graphic3d_TransformUtils.hxx>
34 #include <NCollection_AlignedAllocator.hxx>
36 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Workspace,Standard_Transient)
40 static const OpenGl_Vec4 THE_WHITE_COLOR (1.0f, 1.0f, 1.0f, 1.0f);
41 static const OpenGl_Vec4 THE_BLACK_COLOR (0.0f, 0.0f, 0.0f, 1.0f);
43 static const OpenGl_Matrix myDefaultMatrix =
45 {{ 1.0F, 0.0F, 0.0F, 0.0F },
46 { 0.0F, 1.0F, 0.0F, 0.0F },
47 { 0.0F, 0.0F, 1.0F, 0.0F },
48 { 0.0F, 0.0F, 0.0F, 1.0F }}
53 // =======================================================================
56 // =======================================================================
57 void OpenGl_Material::Init (const OpenGl_Context& theCtx,
58 const Graphic3d_MaterialAspect& theMat,
59 const Quantity_Color& theInteriorColor)
61 ChangeShine() = 128.0f * theMat.Shininess();
62 ChangeTransparency() = theMat.Alpha();
64 const OpenGl_Vec3& aSrcAmb = theMat.AmbientColor();
65 const OpenGl_Vec3& aSrcDif = theMat.DiffuseColor();
66 const OpenGl_Vec3& aSrcSpe = theMat.SpecularColor();
67 const OpenGl_Vec3& aSrcEms = theMat.EmissiveColor();
68 Specular.SetValues (aSrcSpe, 1.0f); // interior color is ignored for Specular
69 switch (theMat.MaterialType())
71 case Graphic3d_MATERIAL_ASPECT:
73 Ambient .SetValues (aSrcAmb * theInteriorColor, 1.0f);
74 Diffuse .SetValues (aSrcDif * theInteriorColor, 1.0f);
75 Emission.SetValues (aSrcEms * theInteriorColor, 1.0f);
78 case Graphic3d_MATERIAL_PHYSIC:
80 Ambient .SetValues (aSrcAmb, 1.0f);
81 Diffuse .SetValues (aSrcDif, 1.0f);
82 Emission.SetValues (aSrcEms, 1.0f);
87 Ambient = theCtx.Vec4FromQuantityColor (Ambient);
88 Diffuse = theCtx.Vec4FromQuantityColor (Diffuse);
89 Specular = theCtx.Vec4FromQuantityColor (Specular);
90 Emission = theCtx.Vec4FromQuantityColor (Emission);
93 // =======================================================================
94 // function : OpenGl_Workspace
96 // =======================================================================
97 OpenGl_Workspace::OpenGl_Workspace (OpenGl_View* theView, const Handle(OpenGl_Window)& theWindow)
100 myGlContext (!theWindow.IsNull() ? theWindow->GetGlContext() : NULL),
101 myUseZBuffer (Standard_True),
102 myUseDepthWrite (Standard_True),
104 myNbSkippedTranspElems (0),
105 myRenderFilter (OpenGl_RenderFilter_Empty),
107 myAspectsSet (&myDefaultAspects),
109 ViewMatrix_applied (&myDefaultMatrix),
110 StructureMatrix_applied (&myDefaultMatrix),
111 myToAllowFaceCulling (false),
112 myModelViewMatrix (myDefaultMatrix)
114 if (!myGlContext.IsNull() && myGlContext->MakeCurrent())
116 myGlContext->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
118 // General initialization of the context
119 #if !defined(GL_ES_VERSION_2_0)
120 if (myGlContext->core11 != NULL)
122 // enable two-side lighting by default
123 glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
124 glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST);
125 if (myGlContext->caps->ffpEnable)
127 glHint (GL_FOG_HINT, GL_FASTEST);
131 glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST);
132 glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
133 if (myGlContext->Vendor() == "microsoft corporation"
134 && !myGlContext->IsGlGreaterEqual (1, 2))
136 // this software implementation causes too slow rendering into GL_FRONT on modern Windows
137 theView->SetImmediateModeDrawToFront (false);
142 myNoneCulling .Aspect()->SetSuppressBackFaces (false);
143 myNoneCulling .Aspect()->SetDrawEdges (false);
144 myNoneCulling .Aspect()->SetAlphaMode (Graphic3d_AlphaMode_Opaque);
146 myFrontCulling.Aspect()->SetSuppressBackFaces (true);
147 myFrontCulling.Aspect()->SetDrawEdges (false);
148 myFrontCulling.Aspect()->SetAlphaMode (Graphic3d_AlphaMode_Opaque);
151 // =======================================================================
152 // function : Activate
154 // =======================================================================
155 Standard_Boolean OpenGl_Workspace::Activate()
157 if (myWindow.IsNull() || !myWindow->Activate())
159 return Standard_False;
162 ViewMatrix_applied = &myDefaultMatrix;
163 StructureMatrix_applied = &myDefaultMatrix;
165 ResetAppliedAspect();
167 // reset state for safety
168 myGlContext->BindProgram (Handle(OpenGl_ShaderProgram)());
169 if (myGlContext->core20fwd != NULL)
171 myGlContext->core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
173 if (myGlContext->caps->ffpEnable)
175 myGlContext->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
177 return Standard_True;
180 //=======================================================================
181 //function : ResetAppliedAspect
182 //purpose : Sets default values of GL parameters in accordance with default aspects
183 //=======================================================================
184 void OpenGl_Workspace::ResetAppliedAspect()
186 myGlContext->BindDefaultVao();
188 myHighlightStyle.Nullify();
189 myToAllowFaceCulling = false;
190 myAspectsSet = &myDefaultAspects;
191 myAspectsApplied.Nullify();
192 myGlContext->SetPolygonOffset (Graphic3d_PolygonOffset());
195 myGlContext->SetTypeOfLine (myDefaultAspects.Aspect()->LineType());
196 myGlContext->SetLineWidth (myDefaultAspects.Aspect()->LineWidth());
197 if (myGlContext->core15fwd != NULL)
199 myGlContext->core15fwd->glActiveTexture (GL_TEXTURE0);
203 // =======================================================================
204 // function : SetDefaultPolygonOffset
206 // =======================================================================
207 Graphic3d_PolygonOffset OpenGl_Workspace::SetDefaultPolygonOffset (const Graphic3d_PolygonOffset& theOffset)
209 Graphic3d_PolygonOffset aPrev = myDefaultAspects.Aspect()->PolygonOffset();
210 myDefaultAspects.Aspect()->SetPolygonOffset (theOffset);
211 if (myAspectsApplied == myDefaultAspects.Aspect()
212 || myAspectsApplied.IsNull()
213 || (myAspectsApplied->PolygonOffset().Mode & Aspect_POM_None) == Aspect_POM_None)
215 myGlContext->SetPolygonOffset (theOffset);
220 // =======================================================================
221 // function : SetAspects
223 // =======================================================================
224 const OpenGl_Aspects* OpenGl_Workspace::SetAspects (const OpenGl_Aspects* theAspect)
226 const OpenGl_Aspects* aPrevAspects = myAspectsSet;
227 myAspectsSet = theAspect;
231 // =======================================================================
232 // function : ApplyAspects
234 // =======================================================================
235 const OpenGl_Aspects* OpenGl_Workspace::ApplyAspects()
237 if (myView->BackfacingModel() == Graphic3d_TOBM_AUTOMATIC)
239 bool toSuppressBackFaces = myToAllowFaceCulling
240 && myAspectsSet->Aspect()->ToSuppressBackFaces();
241 if (toSuppressBackFaces)
243 if (myAspectsSet->Aspect()->InteriorStyle() == Aspect_IS_HATCH
244 || myAspectsSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_Blend
245 || myAspectsSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_Mask
246 || (myAspectsSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_BlendAuto
247 && myAspectsSet->Aspect()->FrontMaterial().Transparency() != 0.0f))
249 // disable culling in case of translucent shading aspect
250 toSuppressBackFaces = false;
253 myGlContext->SetCullBackFaces (toSuppressBackFaces);
256 if (myAspectsSet->Aspect() == myAspectsApplied
257 && myHighlightStyle == myAspectFaceAppliedWithHL)
261 myAspectFaceAppliedWithHL = myHighlightStyle;
263 // Aspect_POM_None means: do not change current settings
264 if ((myAspectsSet->Aspect()->PolygonOffset().Mode & Aspect_POM_None) != Aspect_POM_None)
266 myGlContext->SetPolygonOffset (myAspectsSet->Aspect()->PolygonOffset());
269 const Aspect_InteriorStyle anIntstyle = myAspectsSet->Aspect()->InteriorStyle();
270 if (myAspectsApplied.IsNull()
271 || myAspectsApplied->InteriorStyle() != anIntstyle)
273 #if !defined(GL_ES_VERSION_2_0)
274 myGlContext->SetPolygonMode (anIntstyle == Aspect_IS_POINT ? GL_POINT : GL_FILL);
275 myGlContext->SetPolygonHatchEnabled (anIntstyle == Aspect_IS_HATCH);
279 #if !defined(GL_ES_VERSION_2_0)
280 if (anIntstyle == Aspect_IS_HATCH)
282 myGlContext->SetPolygonHatchStyle (myAspectsSet->Aspect()->HatchStyle());
286 // Case of hidden line
287 if (anIntstyle == Aspect_IS_HIDDENLINE)
289 // copy all values including line edge aspect
290 *myAspectFaceHl.Aspect() = *myAspectsSet->Aspect();
291 myAspectFaceHl.Aspect()->SetShadingModel (Graphic3d_TOSM_UNLIT);
292 myAspectFaceHl.Aspect()->SetInteriorColor (myView->BackgroundColor().GetRGB());
293 myAspectFaceHl.Aspect()->SetDistinguish (false);
294 myAspectFaceHl.SetNoLighting();
295 myAspectsSet = &myAspectFaceHl;
299 myGlContext->SetShadingMaterial (myAspectsSet, myHighlightStyle);
302 const Handle(OpenGl_TextureSet)& aTextureSet = myAspectsSet->TextureSet (myGlContext, ToHighlight());
303 if (!aTextureSet.IsNull()
304 || myAspectsSet->Aspect()->ToMapTexture())
306 myGlContext->BindTextures (aTextureSet);
310 myGlContext->BindTextures (myEnvironmentTexture);
313 myAspectsApplied = myAspectsSet->Aspect();
317 // =======================================================================
320 // =======================================================================
321 Standard_Integer OpenGl_Workspace::Width() const
323 return !myView->GlWindow().IsNull() ? myView->GlWindow()->Width() : 0;
326 // =======================================================================
329 // =======================================================================
330 Standard_Integer OpenGl_Workspace::Height() const
332 return !myView->GlWindow().IsNull() ? myView->GlWindow()->Height() : 0;
335 // =======================================================================
336 // function : FBOCreate
338 // =======================================================================
339 Handle(OpenGl_FrameBuffer) OpenGl_Workspace::FBOCreate (const Standard_Integer theWidth,
340 const Standard_Integer theHeight)
342 // activate OpenGL context
344 return Handle(OpenGl_FrameBuffer)();
347 const Handle(OpenGl_Context)& aCtx = GetGlContext();
348 aCtx->BindTextures (Handle(OpenGl_TextureSet)());
349 Handle(OpenGl_FrameBuffer) aFrameBuffer = new OpenGl_FrameBuffer();
350 if (!aFrameBuffer->Init (aCtx, theWidth, theHeight, GL_SRGB8_ALPHA8, GL_DEPTH24_STENCIL8, 0))
352 aFrameBuffer->Release (aCtx.operator->());
353 return Handle(OpenGl_FrameBuffer)();
358 // =======================================================================
359 // function : FBORelease
361 // =======================================================================
362 void OpenGl_Workspace::FBORelease (Handle(OpenGl_FrameBuffer)& theFbo)
364 // activate OpenGL context
371 theFbo->Release (GetGlContext().operator->());
375 // =======================================================================
376 // function : BufferDump
378 // =======================================================================
379 Standard_Boolean OpenGl_Workspace::BufferDump (const Handle(OpenGl_FrameBuffer)& theFbo,
380 Image_PixMap& theImage,
381 const Graphic3d_BufferType& theBufferType)
383 return !theImage.IsEmpty()
385 && OpenGl_FrameBuffer::BufferDump (GetGlContext(), theFbo, theImage, theBufferType);
388 // =======================================================================
389 // function : ShouldRender
391 // =======================================================================
392 bool OpenGl_Workspace::ShouldRender (const OpenGl_Element* theElement)
394 // render only non-raytracable elements when RayTracing is enabled
395 if ((myRenderFilter & OpenGl_RenderFilter_NonRaytraceableOnly) != 0)
397 if (OpenGl_Raytrace::IsRaytracedElement (theElement))
402 else if ((myRenderFilter & OpenGl_RenderFilter_FillModeOnly) != 0)
404 if (!theElement->IsFillDrawMode())
410 // handle opaque/transparency render passes
411 if ((myRenderFilter & OpenGl_RenderFilter_OpaqueOnly) != 0)
413 if (!theElement->IsFillDrawMode())
418 if (OpenGl_Context::CheckIsTransparent (myAspectsSet, myHighlightStyle))
420 ++myNbSkippedTranspElems;
424 else if ((myRenderFilter & OpenGl_RenderFilter_TransparentOnly) != 0)
426 if (!theElement->IsFillDrawMode())
428 if (dynamic_cast<const OpenGl_Aspects*> (theElement) == NULL)
433 else if (!OpenGl_Context::CheckIsTransparent (myAspectsSet, myHighlightStyle))