1 // Created on: 2013-09-26
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2013-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.
18 #include <OpenGl_AspectFace.hxx>
19 #include <OpenGl_AspectLine.hxx>
20 #include <OpenGl_AspectMarker.hxx>
21 #include <OpenGl_AspectText.hxx>
22 #include <OpenGl_Clipping.hxx>
23 #include <OpenGl_Context.hxx>
24 #include <OpenGl_ShaderManager.hxx>
25 #include <OpenGl_ShaderProgram.hxx>
26 #include <OpenGl_Workspace.hxx>
28 IMPLEMENT_STANDARD_HANDLE (OpenGl_SetOfShaderPrograms, Standard_Transient)
29 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_SetOfShaderPrograms, Standard_Transient)
31 IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderManager, Standard_Transient)
32 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager, Standard_Transient)
39 //! Definition of VertColor varying.
40 const char THE_VARY_TexCoord_OUT[] =
41 EOL"THE_SHADER_OUT vec2 TexCoord;";
42 const char THE_VARY_TexCoord_IN[] =
43 EOL"THE_SHADER_IN vec2 TexCoord;";
45 //! Auxiliary function to transform normal
46 const char THE_FUNC_transformNormal[] =
47 EOL"vec3 transformNormal (in vec3 theNormal)"
49 EOL" vec4 aResult = occWorldViewMatrixInverseTranspose"
50 EOL" * occModelWorldMatrixInverseTranspose"
51 EOL" * vec4 (theNormal, 0.0);"
52 EOL" return normalize (aResult.xyz);"
55 //! Global shader variable for color definition with lighting enabled.
56 const char THE_FUNC_lightDef[] =
57 EOL"vec3 Ambient;" //!< Ambient contribution of light sources
58 EOL"vec3 Diffuse;" //!< Diffuse contribution of light sources
59 EOL"vec3 Specular;"; //!< Specular contribution of light sources
61 //! Function computes contribution of isotropic point light source
62 const char THE_FUNC_pointLight[] =
63 EOL"void pointLight (in int theId,"
64 EOL" in vec3 theNormal,"
65 EOL" in vec3 theView,"
66 EOL" in vec3 thePoint,"
67 EOL" in bool theIsFront)"
69 EOL" vec3 aLight = occLight_Position (theId).xyz;"
70 EOL" if (occLight_IsHeadlight (theId) == 0)"
72 EOL" aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 1.0));"
74 EOL" aLight -= thePoint;"
76 EOL" float aDist = length (aLight);"
77 EOL" aLight = aLight * (1.0 / aDist);"
79 EOL" float anAtten = 1.0 / (occLight_ConstAttenuation (theId)"
80 EOL" + occLight_LinearAttenuation (theId) * aDist);"
82 EOL" vec3 aHalf = normalize (aLight + theView);"
84 EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
85 EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
86 EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
88 EOL" float aSpecl = 0.0;"
89 EOL" if (aNdotL > 0.0)"
91 EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
94 EOL"Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten;"
95 EOL"Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;"
98 //! Function computes contribution of spotlight source
99 const char THE_FUNC_spotLight[] =
100 EOL"void spotLight (in int theId,"
101 EOL" in vec3 theNormal,"
102 EOL" in vec3 theView,"
103 EOL" in vec3 thePoint,"
104 EOL" in bool theIsFront)"
106 EOL" vec3 aLight = occLight_Position (theId).xyz;"
107 EOL" vec3 aSpotDir = occLight_SpotDirection (theId).xyz;"
108 EOL" if (occLight_IsHeadlight (theId) == 0)"
110 EOL" aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 1.0));"
111 EOL" aSpotDir = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aSpotDir, 0.0));"
113 EOL" aLight -= thePoint;"
115 EOL" float aDist = length (aLight);"
116 EOL" aLight = aLight * (1.0 / aDist);"
118 EOL" aSpotDir = normalize (aSpotDir);"
120 EOL" float aCosA = dot (aSpotDir, -aLight);"
121 EOL" if (aCosA >= 1.0 || aCosA < cos (occLight_SpotCutOff (theId)))"
126 EOL" float anExponent = occLight_SpotExponent (theId);"
127 EOL" float anAtten = 1.0 / (occLight_ConstAttenuation (theId)"
128 EOL" + occLight_LinearAttenuation (theId) * aDist);"
129 EOL" if (anExponent > 0.0)"
131 EOL" anAtten *= pow (aCosA, anExponent * 128.0);"
134 EOL" vec3 aHalf = normalize (aLight + theView);"
136 EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
137 EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
138 EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
140 EOL" float aSpecl = 0.0;"
141 EOL" if (aNdotL > 0.0)"
143 EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
146 EOL" Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten;"
147 EOL" Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;"
150 //! Function computes contribution of directional light source
151 const char THE_FUNC_directionalLight[] =
152 EOL"void directionalLight (in int theId,"
153 EOL" in vec3 theNormal,"
154 EOL" in vec3 theView,"
155 EOL" in bool theIsFront)"
157 EOL" vec3 aLight = normalize (occLight_Position (theId).xyz);"
158 EOL" if (occLight_IsHeadlight (theId) == 0)"
160 EOL" aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 0.0));"
163 EOL" vec3 aHalf = normalize (aLight + theView);"
165 EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
166 EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
167 EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
169 EOL" float aSpecl = 0.0;"
170 EOL" if (aNdotL > 0.0)"
172 EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
175 EOL" Diffuse += occLight_Diffuse (theId).rgb * aNdotL;"
176 EOL" Specular += occLight_Specular (theId).rgb * aSpecl;"
179 //! Process clipping planes in Fragment Shader.
180 //! Should be added at the beginning of the main() function.
181 const char THE_FRAG_CLIP_PLANES[] =
182 EOL" for (int aPlaneIter = 0; aPlaneIter < occClipPlaneCount; ++aPlaneIter)"
184 EOL" vec4 aClipEquation = occClipPlaneEquations[aPlaneIter];"
185 EOL" int aClipSpace = occClipPlaneSpaces[aPlaneIter];"
186 EOL" if (aClipSpace == OccEquationCoords_World)"
188 EOL" if (dot (aClipEquation.xyz, PositionWorld.xyz) + aClipEquation.w < 0.0)"
193 EOL" else if (aClipSpace == OccEquationCoords_View)"
195 EOL" if (dot (aClipEquation.xyz, Position.xyz) + aClipEquation.w < 0.0)"
204 // =======================================================================
205 // function : OpenGl_ShaderManager
206 // purpose : Creates new empty shader manager
207 // =======================================================================
208 OpenGl_ShaderManager::OpenGl_ShaderManager (OpenGl_Context* theContext)
209 : myShadingModel (Visual3d_TOM_VERTEX),
210 myContext (theContext),
216 // =======================================================================
217 // function : ~OpenGl_ShaderManager
218 // purpose : Releases resources of shader manager
219 // =======================================================================
220 OpenGl_ShaderManager::~OpenGl_ShaderManager()
222 myProgramList.Clear();
225 // =======================================================================
228 // =======================================================================
229 void OpenGl_ShaderManager::clear()
231 myProgramList.Clear();
232 myLightPrograms.Nullify();
233 myFlatPrograms = OpenGl_SetOfShaderPrograms();
234 myMapOfLightPrograms.Clear();
235 myFontProgram.Nullify();
236 myBlitProgram.Nullify();
237 switchLightPrograms();
240 // =======================================================================
242 // purpose : Creates new shader program
243 // =======================================================================
244 Standard_Boolean OpenGl_ShaderManager::Create (const Handle(Graphic3d_ShaderProgram)& theProxy,
245 TCollection_AsciiString& theShareKey,
246 Handle(OpenGl_ShaderProgram)& theProgram)
248 theProgram.Nullify();
249 if (theProxy.IsNull())
251 return Standard_False;
254 theShareKey = theProxy->GetId();
255 if (myContext->GetResource<Handle(OpenGl_ShaderProgram)> (theShareKey, theProgram))
257 if (theProgram->Share())
259 myProgramList.Append (theProgram);
261 return Standard_True;
264 theProgram = new OpenGl_ShaderProgram (theProxy);
265 if (!theProgram->Initialize (myContext, theProxy->ShaderObjects()))
267 theProgram->Release (myContext);
269 theProgram.Nullify();
270 return Standard_False;
273 myProgramList.Append (theProgram);
274 myContext->ShareResource (theShareKey, theProgram);
275 return Standard_True;
278 // =======================================================================
279 // function : Unregister
280 // purpose : Removes specified shader program from the manager
281 // =======================================================================
282 void OpenGl_ShaderManager::Unregister (TCollection_AsciiString& theShareKey,
283 Handle(OpenGl_ShaderProgram)& theProgram)
285 for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
287 if (anIt.Value() == theProgram)
289 if (!theProgram->UnShare())
292 theProgram.Nullify();
296 myProgramList.Remove (anIt);
297 myMaterialStates.UnBind (theProgram);
302 const TCollection_AsciiString anID = theProgram->myProxy->GetId();
305 myContext->DelayedRelease (theProgram);
306 theProgram.Nullify();
310 theProgram.Nullify();
311 myContext->ReleaseResource (anID, Standard_True);
315 // =======================================================================
316 // function : ShaderPrograms
317 // purpose : Returns list of registered shader programs
318 // =======================================================================
319 const OpenGl_ShaderProgramList& OpenGl_ShaderManager::ShaderPrograms() const
321 return myProgramList;
324 // =======================================================================
326 // purpose : Returns true if no program objects are attached
327 // =======================================================================
328 Standard_Boolean OpenGl_ShaderManager::IsEmpty() const
330 return myProgramList.IsEmpty();
333 // =======================================================================
334 // function : switchLightPrograms
336 // =======================================================================
337 void OpenGl_ShaderManager::switchLightPrograms()
339 TCollection_AsciiString aKey (myShadingModel == Visual3d_TOM_FRAGMENT ? "p_" : "g_");
340 const OpenGl_ListOfLight* aLights = myLightSourceState.LightSources();
343 for (OpenGl_ListOfLight::Iterator aLightIter (*aLights); aLightIter.More(); aLightIter.Next())
345 switch (aLightIter.Value().Type)
347 case Visual3d_TOLS_AMBIENT:
348 break; // skip ambient
349 case Visual3d_TOLS_DIRECTIONAL:
352 case Visual3d_TOLS_POSITIONAL:
355 case Visual3d_TOLS_SPOT:
362 if (!myMapOfLightPrograms.Find (aKey, myLightPrograms))
364 myLightPrograms = new OpenGl_SetOfShaderPrograms();
365 myMapOfLightPrograms.Bind (aKey, myLightPrograms);
369 // =======================================================================
370 // function : UpdateLightSourceStateTo
371 // purpose : Updates state of OCCT light sources
372 // =======================================================================
373 void OpenGl_ShaderManager::UpdateLightSourceStateTo (const OpenGl_ListOfLight* theLights)
375 myLightSourceState.Set (theLights);
376 myLightSourceState.Update();
377 switchLightPrograms();
380 // =======================================================================
381 // function : SetShadingModel
383 // =======================================================================
384 void OpenGl_ShaderManager::SetShadingModel (const Visual3d_TypeOfModel theModel)
386 myShadingModel = theModel;
387 switchLightPrograms();
390 // =======================================================================
391 // function : SetProjectionState
392 // purpose : Sets new state of OCCT projection transform
393 // =======================================================================
394 void OpenGl_ShaderManager::UpdateProjectionStateTo (const OpenGl_Mat4& theProjectionMatrix)
396 myProjectionState.Set (theProjectionMatrix);
397 myProjectionState.Update();
400 // =======================================================================
401 // function : SetModelWorldState
402 // purpose : Sets new state of OCCT model-world transform
403 // =======================================================================
404 void OpenGl_ShaderManager::UpdateModelWorldStateTo (const OpenGl_Mat4& theModelWorldMatrix)
406 myModelWorldState.Set (theModelWorldMatrix);
407 myModelWorldState.Update();
410 // =======================================================================
411 // function : SetWorldViewState
412 // purpose : Sets new state of OCCT world-view transform
413 // =======================================================================
414 void OpenGl_ShaderManager::UpdateWorldViewStateTo (const OpenGl_Mat4& theWorldViewMatrix)
416 myWorldViewState.Set (theWorldViewMatrix);
417 myWorldViewState.Update();
420 // =======================================================================
421 // function : LightSourceState
422 // purpose : Returns current state of OCCT light sources
423 // =======================================================================
424 const OpenGl_LightSourceState& OpenGl_ShaderManager::LightSourceState() const
426 return myLightSourceState;
429 // =======================================================================
430 // function : ProjectionState
431 // purpose : Returns current state of OCCT projection transform
432 // =======================================================================
433 const OpenGl_ProjectionState& OpenGl_ShaderManager::ProjectionState() const
435 return myProjectionState;
438 // =======================================================================
439 // function : ModelWorldState
440 // purpose : Returns current state of OCCT model-world transform
441 // =======================================================================
442 const OpenGl_ModelWorldState& OpenGl_ShaderManager::ModelWorldState() const
444 return myModelWorldState;
447 // =======================================================================
448 // function : WorldViewState
449 // purpose : Returns current state of OCCT world-view transform
450 // =======================================================================
451 const OpenGl_WorldViewState& OpenGl_ShaderManager::WorldViewState() const
453 return myWorldViewState;
456 //! Packed properties of light source
457 class OpenGl_ShaderLightParameters
462 OpenGl_Vec4 Position;
463 OpenGl_Vec4 Direction;
464 OpenGl_Vec4 Parameters;
466 //! Returns packed (serialized) representation of light source properties
467 const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
468 static Standard_Integer NbOfVec4() { return 4; }
472 //! Packed light source type information
473 class OpenGl_ShaderLightType
477 Standard_Integer Type;
478 Standard_Integer IsHeadlight;
480 //! Returns packed (serialized) representation of light source type
481 const OpenGl_Vec2i* Packed() const { return reinterpret_cast<const OpenGl_Vec2i*> (this); }
482 static Standard_Integer NbOfVec2i() { return 1; }
486 // =======================================================================
487 // function : PushLightSourceState
488 // purpose : Pushes state of OCCT light sources to the program
489 // =======================================================================
490 void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
492 if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE)
493 || !theProgram->IsValid())
498 OpenGl_ShaderLightType* aLightTypeArray = new OpenGl_ShaderLightType[OpenGLMaxLights];
499 for (Standard_Integer aLightIt = 0; aLightIt < OpenGLMaxLights; ++aLightIt)
501 aLightTypeArray[aLightIt].Type = -1;
504 const Standard_Integer aLightsDefNb = Min (myLightSourceState.LightSources()->Size(), OpenGLMaxLights);
505 if (aLightsDefNb < 1)
507 theProgram->SetUniform (myContext,
508 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
510 theProgram->SetUniform (myContext,
511 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT),
512 OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
513 theProgram->SetUniform (myContext,
514 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
515 OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
516 aLightTypeArray[0].Packed());
517 theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
518 delete[] aLightTypeArray;
522 OpenGl_ShaderLightParameters* aLightParamsArray = new OpenGl_ShaderLightParameters[aLightsDefNb];
524 OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f);
525 Standard_Integer aLightsNb = 0;
526 for (OpenGl_ListOfLight::Iterator anIter (*myLightSourceState.LightSources()); anIter.More(); anIter.Next())
528 const OpenGl_Light& aLight = anIter.Value();
529 if (aLight.Type == Visual3d_TOLS_AMBIENT)
531 anAmbient += aLight.Color;
534 else if (aLightsNb >= OpenGLMaxLights)
539 OpenGl_ShaderLightType& aLightType = aLightTypeArray[aLightsNb];
540 aLightType.Type = aLight.Type;
541 aLightType.IsHeadlight = aLight.IsHeadlight;
543 OpenGl_ShaderLightParameters& aLightParams = aLightParamsArray[aLightsNb];
544 aLightParams.Color = aLight.Color;
545 aLightParams.Position = aLight.Type == Visual3d_TOLS_DIRECTIONAL
548 if (aLight.Type == Visual3d_TOLS_SPOT)
550 aLightParams.Direction = aLight.Direction;
552 aLightParams.Parameters = aLight.Params;
556 theProgram->SetUniform (myContext,
557 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
559 theProgram->SetUniform (myContext,
560 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT),
562 theProgram->SetUniform (myContext,
563 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
564 OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
565 aLightTypeArray[0].Packed());
568 theProgram->SetUniform (myContext,
569 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_PARAMS),
570 aLightsNb * OpenGl_ShaderLightParameters::NbOfVec4(),
571 aLightParamsArray[0].Packed());
573 delete[] aLightParamsArray;
574 delete[] aLightTypeArray;
576 theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
579 // =======================================================================
580 // function : PushProjectionState
581 // purpose : Pushes state of OCCT projection transform to the program
582 // =======================================================================
583 void OpenGl_ShaderManager::PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const
585 if (myProjectionState.Index() == theProgram->ActiveState (OpenGl_PROJECTION_STATE))
590 theProgram->SetUniform (myContext,
591 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX),
592 myProjectionState.ProjectionMatrix());
594 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE);
595 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
597 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse());
600 theProgram->SetUniform (myContext,
601 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE),
602 myProjectionState.ProjectionMatrix(), true);
604 aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE);
605 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
607 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse(), true);
610 theProgram->UpdateState (OpenGl_PROJECTION_STATE, myProjectionState.Index());
613 // =======================================================================
614 // function : PushModelWorldState
615 // purpose : Pushes state of OCCT model-world transform to the program
616 // =======================================================================
617 void OpenGl_ShaderManager::PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const
619 if (myModelWorldState.Index() == theProgram->ActiveState (OpenGl_MODEL_WORLD_STATE))
624 theProgram->SetUniform (myContext,
625 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX),
626 myModelWorldState.ModelWorldMatrix());
628 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE);
629 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
631 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse());
634 theProgram->SetUniform (myContext,
635 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE),
636 myModelWorldState.ModelWorldMatrix(), true);
638 aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE);
639 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
641 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse(), true);
644 theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
647 // =======================================================================
648 // function : PushWorldViewState
649 // purpose : Pushes state of OCCT world-view transform to the program
650 // =======================================================================
651 void OpenGl_ShaderManager::PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const
653 if (myWorldViewState.Index() == theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE))
658 theProgram->SetUniform (myContext,
659 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX),
660 myWorldViewState.WorldViewMatrix());
662 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE);
663 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
665 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse());
668 theProgram->SetUniform (myContext,
669 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE),
670 myWorldViewState.WorldViewMatrix(), true);
672 aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE);
673 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
675 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse(), true);
678 theProgram->UpdateState (OpenGl_WORLD_VIEW_STATE, myWorldViewState.Index());
681 // =======================================================================
682 // function : UpdateClippingState
683 // purpose : Updates state of OCCT clipping planes
684 // =======================================================================
685 void OpenGl_ShaderManager::UpdateClippingState()
687 myClippingState.Update();
690 // =======================================================================
691 // function : RevertClippingState
692 // purpose : Reverts state of OCCT clipping planes
693 // =======================================================================
694 void OpenGl_ShaderManager::RevertClippingState()
696 myClippingState.Revert();
699 // =======================================================================
700 // function : PushClippingState
701 // purpose : Pushes state of OCCT clipping planes to the program
702 // =======================================================================
703 void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const
705 if (myClippingState.Index() == theProgram->ActiveState (OpenGl_CLIP_PLANES_STATE))
710 theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index());
711 const GLint aLocEquations = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_EQUATIONS);
712 const GLint aLocSpaces = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_SPACES);
713 if (aLocEquations == OpenGl_ShaderProgram::INVALID_LOCATION
714 && aLocSpaces == OpenGl_ShaderProgram::INVALID_LOCATION)
720 for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
721 anIter.More(); anIter.Next())
723 const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
724 if (!myContext->Clipping().IsEnabled (aPlane))
736 const Standard_Size MAX_CLIP_PLANES = 8;
737 OpenGl_Vec4* anEquations = new OpenGl_Vec4[MAX_CLIP_PLANES];
738 GLint* aSpaces = new GLint [MAX_CLIP_PLANES];
740 for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
741 anIter.More(); anIter.Next())
743 const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
744 if (!myContext->Clipping().IsEnabled (aPlane))
749 const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
750 anEquations[aPlaneId] = OpenGl_Vec4 ((float) anEquation.x(),
751 (float) anEquation.y(),
752 (float) anEquation.z(),
753 (float) anEquation.w());
754 aSpaces[aPlaneId] = myContext->Clipping().GetEquationSpace (aPlane);
758 theProgram->SetUniform (myContext,
759 theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_COUNT),
761 theProgram->SetUniform (myContext, aLocEquations, MAX_CLIP_PLANES, anEquations);
762 theProgram->SetUniform (myContext, aLocSpaces, MAX_CLIP_PLANES, aSpaces);
764 delete[] anEquations;
768 // =======================================================================
769 // function : UpdateMaterialStateTo
770 // purpose : Updates state of OCCT material for specified program
771 // =======================================================================
772 void OpenGl_ShaderManager::UpdateMaterialStateTo (const Handle(OpenGl_ShaderProgram)& theProgram,
773 const OpenGl_Element* theAspect)
775 if (myMaterialStates.IsBound (theProgram))
777 OpenGl_MaterialState& aState = myMaterialStates.ChangeFind (theProgram);
778 aState.Set (theAspect);
783 myMaterialStates.Bind (theProgram, OpenGl_MaterialState (theAspect));
784 myMaterialStates.ChangeFind (theProgram).Update();
788 // =======================================================================
789 // function : ResetMaterialStates
790 // purpose : Resets state of OCCT material for all programs
791 // =======================================================================
792 void OpenGl_ShaderManager::ResetMaterialStates()
794 for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
796 anIt.Value()->UpdateState (OpenGl_MATERIALS_STATE, 0);
800 // =======================================================================
801 // function : MaterialState
802 // purpose : Returns state of OCCT material for specified program
803 // =======================================================================
804 const OpenGl_MaterialState* OpenGl_ShaderManager::MaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
806 if (!myMaterialStates.IsBound (theProgram))
809 return &myMaterialStates.Find (theProgram);
815 static const OpenGl_Vec4 THE_COLOR_BLACK_VEC4 (0.0f, 0.0f, 0.0f, 0.0f);
817 // =======================================================================
818 // function : PushAspectFace
820 // =======================================================================
821 static void PushAspectFace (const Handle(OpenGl_Context)& theCtx,
822 const Handle(OpenGl_ShaderProgram)& theProgram,
823 const OpenGl_AspectFace* theAspect)
825 theProgram->SetUniform (theCtx,
826 theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),
827 theAspect->DoTextureMap());
828 theProgram->SetUniform (theCtx,
829 theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER),
830 0 /* GL_TEXTURE0 */);
831 theProgram->SetUniform (theCtx,
832 theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
833 theAspect->DistinguishingMode());
835 OpenGl_Material aParams;
836 for (Standard_Integer anIndex = 0; anIndex < 2; ++anIndex)
838 const GLint aLoc = theProgram->GetStateLocation (anIndex == 0
839 ? OpenGl_OCCT_FRONT_MATERIAL
840 : OpenGl_OCCT_BACK_MATERIAL);
841 if (aLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
846 aParams.Init (anIndex == 0 || theAspect->DistinguishingMode() != TOn
847 ? theAspect->IntFront()
848 : theAspect->IntBack());
849 theProgram->SetUniform (theCtx, aLoc, OpenGl_Material::NbOfVec4(),
854 // =======================================================================
855 // function : PushAspectLine
857 // =======================================================================
858 static void PushAspectLine (const Handle(OpenGl_Context)& theCtx,
859 const Handle(OpenGl_ShaderProgram)& theProgram,
860 const OpenGl_AspectLine* theAspect)
862 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOff);
863 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
865 const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
866 theAspect->Color().rgb[1],
867 theAspect->Color().rgb[2],
868 theAspect->Color().rgb[3]);
869 OpenGl_Vec4 aParams[5];
870 aParams[0] = THE_COLOR_BLACK_VEC4;
871 aParams[1] = THE_COLOR_BLACK_VEC4;
872 aParams[2] = aDiffuse;
873 aParams[3] = THE_COLOR_BLACK_VEC4;
874 aParams[4].x() = 0.0f; // shininess
875 aParams[4].y() = 0.0f; // transparency
876 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
880 // =======================================================================
881 // function : PushAspectText
883 // =======================================================================
884 static void PushAspectText (const Handle(OpenGl_Context)& theCtx,
885 const Handle(OpenGl_ShaderProgram)& theProgram,
886 const OpenGl_AspectText* theAspect)
888 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn);
889 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
890 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */);
892 OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
893 theAspect->Color().rgb[1],
894 theAspect->Color().rgb[2],
895 theAspect->Color().rgb[3]);
896 if (theAspect->DisplayType() == Aspect_TODT_DEKALE
897 || theAspect->DisplayType() == Aspect_TODT_SUBTITLE)
899 aDiffuse = OpenGl_Vec4 (theAspect->SubtitleColor().rgb[0],
900 theAspect->SubtitleColor().rgb[1],
901 theAspect->SubtitleColor().rgb[2],
902 theAspect->SubtitleColor().rgb[3]);
905 OpenGl_Vec4 aParams[5];
906 aParams[0] = THE_COLOR_BLACK_VEC4;
907 aParams[1] = THE_COLOR_BLACK_VEC4;
908 aParams[2] = aDiffuse;
909 aParams[3] = THE_COLOR_BLACK_VEC4;
910 aParams[4].x() = 0.0f; // shininess
911 aParams[4].y() = 0.0f; // transparency
912 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
916 // =======================================================================
917 // function : PushAspectMarker
919 // =======================================================================
920 static void PushAspectMarker (const Handle(OpenGl_Context)& theCtx,
921 const Handle(OpenGl_ShaderProgram)& theProgram,
922 const OpenGl_AspectMarker* theAspect)
924 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn);
925 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
926 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */);
928 const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
929 theAspect->Color().rgb[1],
930 theAspect->Color().rgb[2],
931 theAspect->Color().rgb[3]);
932 OpenGl_Vec4 aParams[5];
933 aParams[0] = THE_COLOR_BLACK_VEC4;
934 aParams[1] = THE_COLOR_BLACK_VEC4;
935 aParams[2] = aDiffuse;
936 aParams[3] = THE_COLOR_BLACK_VEC4;
937 aParams[4].x() = 0.0f; // shininess
938 aParams[4].y() = 0.0f; // transparency
939 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
943 }; // nameless namespace
945 // =======================================================================
946 // function : PushMaterialState
947 // purpose : Pushes current state of OCCT material to the program
948 // =======================================================================
949 void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
951 if (!myMaterialStates.IsBound (theProgram))
956 const OpenGl_MaterialState& aState = myMaterialStates.Find (theProgram);
957 if (aState.Index() == theProgram->ActiveState (OpenGl_MATERIALS_STATE))
962 if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectFace))
964 PushAspectFace (myContext, theProgram, dynamic_cast<const OpenGl_AspectFace*> (aState.Aspect()));
966 else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectLine))
968 PushAspectLine (myContext, theProgram, dynamic_cast<const OpenGl_AspectLine*> (aState.Aspect()));
970 else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectText))
972 PushAspectText (myContext, theProgram, dynamic_cast<const OpenGl_AspectText*> (aState.Aspect()));
974 else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectMarker))
976 PushAspectMarker (myContext, theProgram, dynamic_cast<const OpenGl_AspectMarker*> (aState.Aspect()));
979 theProgram->UpdateState (OpenGl_MATERIALS_STATE, aState.Index());
982 // =======================================================================
983 // function : PushWorldViewState
984 // purpose : Pushes state of OCCT graphics parameters to the program
985 // =======================================================================
986 void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const
988 PushClippingState (theProgram);
989 PushMaterialState (theProgram);
990 PushWorldViewState (theProgram);
991 PushModelWorldState (theProgram);
992 PushProjectionState (theProgram);
993 PushLightSourceState (theProgram);
996 // =======================================================================
997 // function : prepareStdProgramFont
999 // =======================================================================
1000 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFont()
1002 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1003 TCollection_AsciiString aSrcVert = TCollection_AsciiString()
1004 + THE_VARY_TexCoord_OUT
1007 EOL" TexCoord = occTexCoord.st;"
1008 EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1011 TCollection_AsciiString
1012 aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, TexCoord.st).a; }";
1013 #if !defined(GL_ES_VERSION_2_0)
1014 if (myContext->core11 == NULL)
1016 aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, TexCoord.st).r; }";
1020 TCollection_AsciiString aSrcFrag = TCollection_AsciiString() +
1021 + THE_VARY_TexCoord_IN
1025 EOL" vec4 aColor = occColor;"
1026 EOL" aColor.a *= getAlpha();"
1027 EOL" if (aColor.a <= 0.285) discard;"
1028 EOL" occFragColor = aColor;"
1031 #if !defined(GL_ES_VERSION_2_0)
1032 if (myContext->core32 != NULL)
1034 aProgramSrc->SetHeader ("#version 150");
1037 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1038 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1039 TCollection_AsciiString aKey;
1040 if (!Create (aProgramSrc, aKey, myFontProgram))
1042 myFontProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1043 return Standard_False;
1045 return Standard_True;
1048 // =======================================================================
1049 // function : prepareStdProgramFboBlit
1051 // =======================================================================
1052 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFboBlit()
1054 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1055 TCollection_AsciiString aSrcVert =
1056 EOL"THE_SHADER_OUT vec2 TexCoord;"
1059 EOL" TexCoord = occVertex.zw;"
1060 EOL" gl_Position = vec4(occVertex.x, occVertex.y, 0.0, 1.0);"
1063 TCollection_AsciiString aSrcFrag =
1064 EOL"uniform sampler2D uColorSampler;"
1065 EOL"uniform sampler2D uDepthSampler;"
1067 EOL"THE_SHADER_IN vec2 TexCoord;"
1071 EOL" gl_FragDepth = occTexture2D (uDepthSampler, TexCoord).r;"
1072 EOL" occFragColor = occTexture2D (uColorSampler, TexCoord);"
1075 #if defined(GL_ES_VERSION_2_0)
1076 if (myContext->IsGlGreaterEqual (3, 0))
1078 aProgramSrc->SetHeader ("#version 300 es");
1082 // there is no way to draw into depth buffer
1084 EOL"uniform sampler2D uColorSampler;"
1086 EOL"THE_SHADER_IN vec2 TexCoord;"
1090 EOL" occFragColor = occTexture2D (uColorSampler, TexCoord);"
1094 if (myContext->core32 != NULL)
1096 aProgramSrc->SetHeader ("#version 150");
1099 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1100 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1101 TCollection_AsciiString aKey;
1102 if (!Create (aProgramSrc, aKey, myBlitProgram))
1104 myBlitProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1105 return Standard_False;
1108 myContext->BindProgram (myBlitProgram);
1109 myBlitProgram->SetSampler (myContext, "uColorSampler", 0);
1110 myBlitProgram->SetSampler (myContext, "uDepthSampler", 1);
1111 myContext->BindProgram (NULL);
1112 return Standard_True;
1115 // =======================================================================
1116 // function : prepareStdProgramFlat
1118 // =======================================================================
1119 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_ShaderProgram)& theProgram,
1120 const Standard_Integer theBits)
1122 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1123 TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain;
1124 TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return occColor; }";
1125 TCollection_AsciiString aSrcFragMainGetColor = EOL" occFragColor = getColor();";
1126 if ((theBits & OpenGl_PO_Point) != 0)
1128 #if defined(GL_ES_VERSION_2_0)
1129 aSrcVertExtraMain += EOL" gl_PointSize = occPointSize;";
1131 if ((theBits & OpenGl_PO_TextureA) != 0)
1133 TCollection_AsciiString
1134 aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, gl_PointCoord).a; }";
1135 #if !defined(GL_ES_VERSION_2_0)
1136 if (myContext->core11 == NULL)
1138 aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, gl_PointCoord).r; }";
1142 aSrcFragGetColor = aSrcGetAlpha
1143 + EOL"vec4 getColor(void)"
1145 EOL" vec4 aColor = occColor;"
1146 EOL" aColor.a *= getAlpha();"
1147 EOL" return aColor;"
1150 aSrcFragMainGetColor =
1151 EOL" vec4 aColor = getColor();"
1152 EOL" if (aColor.a <= 0.1) discard;"
1153 EOL" occFragColor = aColor;";
1155 else if ((theBits & OpenGl_PO_TextureRGB) != 0)
1158 EOL"vec4 getColor(void) { return occTexture2D(occActiveSampler, gl_PointCoord); }";
1159 aSrcFragMainGetColor =
1160 EOL" vec4 aColor = getColor();"
1161 EOL" if (aColor.a <= 0.1) discard;"
1162 EOL" occFragColor = aColor;";
1167 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1169 aSrcVertExtraOut += THE_VARY_TexCoord_OUT;
1170 aSrcFragExtraOut += THE_VARY_TexCoord_IN;
1171 aSrcVertExtraMain +=
1172 EOL" TexCoord = occTexCoord.st;";
1175 EOL"vec4 getColor(void) { return occTexture2D(occActiveSampler, TexCoord.st); }";
1178 if ((theBits & OpenGl_PO_VertColor) != 0)
1180 aSrcVertExtraOut += EOL"THE_SHADER_OUT vec4 VertColor;";
1181 aSrcVertExtraMain += EOL" VertColor = occVertColor;";
1182 aSrcFragExtraOut += EOL"THE_SHADER_IN vec4 VertColor;";
1183 aSrcFragGetColor = EOL"vec4 getColor(void) { return VertColor; }";
1185 if ((theBits & OpenGl_PO_ClipPlanes) != 0)
1188 EOL"THE_SHADER_OUT vec4 PositionWorld;"
1189 EOL"THE_SHADER_OUT vec4 Position;";
1191 EOL"THE_SHADER_IN vec4 PositionWorld;"
1192 EOL"THE_SHADER_IN vec4 Position;";
1193 aSrcVertExtraMain +=
1194 EOL" PositionWorld = occModelWorldMatrix * occVertex;"
1195 EOL" Position = occWorldViewMatrix * PositionWorld;";
1196 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES;
1204 + EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1213 + aSrcFragMainGetColor
1216 #if !defined(GL_ES_VERSION_2_0)
1217 if (myContext->core32 != NULL)
1219 aProgramSrc->SetHeader ("#version 150");
1222 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1223 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1225 TCollection_AsciiString aKey;
1226 if (!Create (aProgramSrc, aKey, theProgram))
1228 theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1229 return Standard_False;
1231 return Standard_True;
1234 // =======================================================================
1235 // function : stdComputeLighting
1237 // =======================================================================
1238 TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (const Standard_Boolean theHasVertColor)
1240 bool aLightsMap[Visual3d_TOLS_SPOT + 1] = { false, false, false, false };
1241 TCollection_AsciiString aLightsFunc, aLightsLoop;
1242 const OpenGl_ListOfLight* aLights = myLightSourceState.LightSources();
1243 if (aLights != NULL)
1245 Standard_Integer anIndex = 0;
1246 for (OpenGl_ListOfLight::Iterator aLightIter (*aLights); aLightIter.More(); aLightIter.Next(), ++anIndex)
1248 switch (aLightIter.Value().Type)
1250 case Visual3d_TOLS_AMBIENT:
1252 break; // skip ambient
1253 case Visual3d_TOLS_DIRECTIONAL:
1254 aLightsLoop = aLightsLoop + EOL" directionalLight (" + anIndex + ", theNormal, theView, theIsFront);";
1256 case Visual3d_TOLS_POSITIONAL:
1257 aLightsLoop = aLightsLoop + EOL" pointLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);";
1259 case Visual3d_TOLS_SPOT:
1260 aLightsLoop = aLightsLoop + EOL" spotLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);";
1264 bool& aTypeBit = aLightsMap[aLightIter.Value().Type];
1271 switch (aLightIter.Value().Type)
1273 case Visual3d_TOLS_AMBIENT: break;
1274 case Visual3d_TOLS_DIRECTIONAL: aLightsFunc += THE_FUNC_directionalLight; break;
1275 case Visual3d_TOLS_POSITIONAL: aLightsFunc += THE_FUNC_pointLight; break;
1276 case Visual3d_TOLS_SPOT: aLightsFunc += THE_FUNC_spotLight; break;
1281 TCollection_AsciiString aGetMatAmbient = "theIsFront ? occFrontMaterial_Ambient() : occBackMaterial_Ambient();";
1282 TCollection_AsciiString aGetMatDiffuse = "theIsFront ? occFrontMaterial_Diffuse() : occBackMaterial_Diffuse();";
1283 if (theHasVertColor)
1285 aGetMatAmbient = "getVertColor();";
1286 aGetMatDiffuse = "getVertColor();";
1289 return TCollection_AsciiString()
1293 EOL"vec4 computeLighting (in vec3 theNormal,"
1294 EOL" in vec3 theView,"
1295 EOL" in vec4 thePoint,"
1296 EOL" in bool theIsFront)"
1298 EOL" Ambient = occLightAmbient.rgb;"
1299 EOL" Diffuse = vec3 (0.0);"
1300 EOL" Specular = vec3 (0.0);"
1301 EOL" vec3 aPoint = thePoint.xyz / thePoint.w;"
1303 + EOL" vec4 aMaterialAmbient = " + aGetMatAmbient
1304 + EOL" vec4 aMaterialDiffuse = " + aGetMatDiffuse
1305 + EOL" vec4 aMaterialSpecular = theIsFront ? occFrontMaterial_Specular() : occBackMaterial_Specular();"
1306 EOL" vec4 aMaterialEmission = theIsFront ? occFrontMaterial_Emission() : occBackMaterial_Emission();"
1307 EOL" return vec4 (Ambient, 1.0) * aMaterialAmbient"
1308 EOL" + vec4 (Diffuse, 1.0) * aMaterialDiffuse"
1309 EOL" + vec4 (Specular, 1.0) * aMaterialSpecular"
1310 EOL" + aMaterialEmission;"
1314 // =======================================================================
1315 // function : prepareStdProgramGouraud
1317 // =======================================================================
1318 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_ShaderProgram)& theProgram,
1319 const Standard_Integer theBits)
1321 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1322 TCollection_AsciiString aSrcVert, aSrcVertColor, aSrcVertExtraOut, aSrcVertExtraMain, aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain;
1323 TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return gl_FrontFacing ? FrontColor : BackColor; }";
1324 if ((theBits & OpenGl_PO_Point) != 0)
1326 #if defined(GL_ES_VERSION_2_0)
1327 aSrcVertExtraMain += EOL" gl_PointSize = occPointSize;";
1330 if ((theBits & OpenGl_PO_VertColor) != 0)
1332 aSrcVertColor = EOL"vec4 getVertColor(void) { return occVertColor; }";
1334 if ((theBits & OpenGl_PO_Point) != 0)
1336 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1339 EOL"vec4 getColor(void)"
1341 EOL" vec4 aColor = gl_FrontFacing ? FrontColor : BackColor;"
1342 EOL" return occTexture2D(occActiveSampler, gl_PointCoord) * aColor;"
1348 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1350 aSrcVertExtraOut += THE_VARY_TexCoord_OUT;
1351 aSrcFragExtraOut += THE_VARY_TexCoord_IN;
1352 aSrcVertExtraMain +=
1353 EOL" TexCoord = occTexCoord.st;";
1356 EOL"vec4 getColor(void)"
1358 EOL" vec4 aColor = gl_FrontFacing ? FrontColor : BackColor;"
1359 EOL" return occTexture2D(occActiveSampler, TexCoord.st) * aColor;"
1363 if ((theBits & OpenGl_PO_ClipPlanes) != 0)
1366 EOL"THE_SHADER_OUT vec4 PositionWorld;"
1367 EOL"THE_SHADER_OUT vec4 Position;";
1369 EOL"THE_SHADER_IN vec4 PositionWorld;"
1370 EOL"THE_SHADER_IN vec4 Position;";
1371 aSrcVertExtraMain +=
1372 EOL" PositionWorld = aPositionWorld;"
1373 EOL" Position = aPosition;";
1374 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES;
1377 const TCollection_AsciiString aLights = stdComputeLighting ((theBits & OpenGl_PO_VertColor) != 0);
1378 aSrcVert = TCollection_AsciiString()
1379 + THE_FUNC_transformNormal
1384 EOL"THE_SHADER_OUT vec4 FrontColor;"
1385 EOL"THE_SHADER_OUT vec4 BackColor;"
1390 EOL" vec4 aPositionWorld = occModelWorldMatrix * occVertex;"
1391 EOL" vec4 aPosition = occWorldViewMatrix * aPositionWorld;"
1392 EOL" vec3 aNormal = transformNormal (occNormal);"
1393 EOL" vec3 aView = vec3 (0.0, 0.0, 1.0);"
1394 EOL" FrontColor = computeLighting (normalize (aNormal), normalize (aView), aPosition, true);"
1395 EOL" BackColor = computeLighting (normalize (aNormal), normalize (aView), aPosition, false);"
1397 + EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1400 aSrcFrag = TCollection_AsciiString()
1401 + EOL"THE_SHADER_IN vec4 FrontColor;"
1402 EOL"THE_SHADER_IN vec4 BackColor;"
1408 + EOL" occFragColor = getColor();"
1411 #if !defined(GL_ES_VERSION_2_0)
1412 if (myContext->core32 != NULL)
1414 aProgramSrc->SetHeader ("#version 150");
1417 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1418 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1419 TCollection_AsciiString aKey;
1420 if (!Create (aProgramSrc, aKey, theProgram))
1422 theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1423 return Standard_False;
1425 return Standard_True;
1428 // =======================================================================
1429 // function : prepareStdProgramPhong
1431 // =======================================================================
1432 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram,
1433 const Standard_Integer theBits)
1435 #define thePhongCompLight "computeLighting (normalize (Normal), normalize (View), Position, gl_FrontFacing)"
1437 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1438 TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcFrag, aSrcFragExtraOut, aSrcFragGetVertColor, aSrcFragExtraMain;
1439 TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return " thePhongCompLight "; }";
1440 if ((theBits & OpenGl_PO_Point) != 0)
1442 #if defined(GL_ES_VERSION_2_0)
1443 aSrcVertExtraMain += EOL" gl_PointSize = occPointSize;";
1446 if ((theBits & OpenGl_PO_VertColor) != 0)
1448 aSrcVertExtraOut += EOL"THE_SHADER_OUT vec4 VertColor;";
1449 aSrcVertExtraMain += EOL" VertColor = occVertColor;";
1450 aSrcFragGetColor = EOL"THE_SHADER_IN vec4 VertColor;"
1451 EOL"vec4 getVertColor(void) { return VertColor; }";
1454 if ((theBits & OpenGl_PO_Point) != 0)
1456 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1459 EOL"vec4 getColor(void)"
1461 EOL" vec4 aColor = " thePhongCompLight ";"
1462 EOL" return occTexture2D(occActiveSampler, gl_PointCoord) * aColor;"
1468 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1470 aSrcVertExtraOut += THE_VARY_TexCoord_OUT;
1471 aSrcFragExtraOut += THE_VARY_TexCoord_IN;
1472 aSrcVertExtraMain +=
1473 EOL" TexCoord = occTexCoord.st;";
1476 EOL"vec4 getColor(void)"
1478 EOL" vec4 aColor = " thePhongCompLight ";"
1479 EOL" return occTexture2D(occActiveSampler, TexCoord.st) * aColor;"
1484 if ((theBits & OpenGl_PO_ClipPlanes) != 0)
1486 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES;
1489 aSrcVert = TCollection_AsciiString()
1490 + THE_FUNC_transformNormal
1492 EOL"THE_SHADER_OUT vec4 PositionWorld;"
1493 EOL"THE_SHADER_OUT vec4 Position;"
1494 EOL"THE_SHADER_OUT vec3 Normal;"
1495 EOL"THE_SHADER_OUT vec3 View;"
1500 EOL" PositionWorld = occModelWorldMatrix * occVertex;"
1501 EOL" Position = occWorldViewMatrix * PositionWorld;"
1502 EOL" Normal = transformNormal (occNormal);"
1503 EOL" View = vec3 (0.0, 0.0, 1.0);"
1505 + EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1508 const TCollection_AsciiString aLights = stdComputeLighting ((theBits & OpenGl_PO_VertColor) != 0);
1509 aSrcFrag = TCollection_AsciiString()
1510 + EOL"THE_SHADER_IN vec4 PositionWorld;"
1511 EOL"THE_SHADER_IN vec4 Position;"
1512 EOL"THE_SHADER_IN vec3 Normal;"
1513 EOL"THE_SHADER_IN vec3 View;"
1516 + aSrcFragGetVertColor
1523 + EOL" occFragColor = getColor();"
1526 #if !defined(GL_ES_VERSION_2_0)
1527 if (myContext->core32 != NULL)
1529 aProgramSrc->SetHeader ("#version 150");
1532 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1533 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1534 TCollection_AsciiString aKey;
1535 if (!Create (aProgramSrc, aKey, theProgram))
1537 theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1538 return Standard_False;
1540 return Standard_True;
1543 // =======================================================================
1544 // function : bindProgramWithState
1546 // =======================================================================
1547 Standard_Boolean OpenGl_ShaderManager::bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram,
1548 const OpenGl_Element* theAspect)
1550 if (!myContext->BindProgram (theProgram))
1552 return Standard_False;
1554 theProgram->ApplyVariables (myContext);
1556 const OpenGl_MaterialState* aMaterialState = MaterialState (theProgram);
1557 if (aMaterialState == NULL || aMaterialState->Aspect() != theAspect)
1559 UpdateMaterialStateTo (theProgram, theAspect);
1562 PushState (theProgram);
1563 return Standard_True;