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_ShaderManager, Standard_Transient)
29 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager, Standard_Transient)
31 // =======================================================================
32 // function : OpenGl_ShaderManager
33 // purpose : Creates new empty shader manager
34 // =======================================================================
35 OpenGl_ShaderManager::OpenGl_ShaderManager (OpenGl_Context* theContext)
36 : myContext (theContext),
37 myIsPP (Standard_False)
42 // =======================================================================
43 // function : ~OpenGl_ShaderManager
44 // purpose : Releases resources of shader manager
45 // =======================================================================
46 OpenGl_ShaderManager::~OpenGl_ShaderManager()
48 myProgramList.Clear();
51 // =======================================================================
53 // purpose : Creates new shader program
54 // =======================================================================
55 void OpenGl_ShaderManager::Create (const Handle(Graphic3d_ShaderProgram)& theProxy,
56 TCollection_AsciiString& theShareKey,
57 Handle(OpenGl_ShaderProgram)& theProgram)
60 if (theProxy.IsNull())
65 theShareKey = theProxy->GetId();
66 if (myContext->GetResource<Handle(OpenGl_ShaderProgram)> (theShareKey, theProgram))
68 if (theProgram->Share())
70 myProgramList.Append (theProgram);
75 theProgram = new OpenGl_ShaderProgram (theProxy);
76 if (!theProgram->Initialize (myContext, theProxy->ShaderObjects()))
78 theProgram->Release (myContext);
84 myProgramList.Append (theProgram);
85 myContext->ShareResource (theShareKey, theProgram);
88 // =======================================================================
89 // function : Unregister
90 // purpose : Removes specified shader program from the manager
91 // =======================================================================
92 void OpenGl_ShaderManager::Unregister (TCollection_AsciiString& theShareKey,
93 Handle(OpenGl_ShaderProgram)& theProgram)
95 for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
97 if (anIt.Value() == theProgram)
99 if (!theProgram->UnShare())
102 theProgram.Nullify();
106 myProgramList.Remove (anIt);
107 myMaterialStates.UnBind (theProgram);
112 const TCollection_AsciiString anID = theProgram->myProxy->GetId();
115 myContext->DelayedRelease (theProgram);
116 theProgram.Nullify();
120 theProgram.Nullify();
121 myContext->ReleaseResource (anID, Standard_True);
125 // =======================================================================
126 // function : ShaderPrograms
127 // purpose : Returns list of registered shader programs
128 // =======================================================================
129 const OpenGl_ShaderProgramList& OpenGl_ShaderManager::ShaderPrograms() const
131 return myProgramList;
134 // =======================================================================
136 // purpose : Returns true if no program objects are attached
137 // =======================================================================
138 Standard_Boolean OpenGl_ShaderManager::IsEmpty() const
140 return myProgramList.IsEmpty();
143 // =======================================================================
144 // function : UpdateLightSourceStateTo
145 // purpose : Updates state of OCCT light sources
146 // =======================================================================
147 void OpenGl_ShaderManager::UpdateLightSourceStateTo (const OpenGl_ListOfLight* theLights)
149 myLightSourceState.Set (theLights);
150 myLightSourceState.Update();
153 // =======================================================================
154 // function : SetProjectionState
155 // purpose : Sets new state of OCCT projection transform
156 // =======================================================================
157 void OpenGl_ShaderManager::UpdateProjectionStateTo (const Tmatrix3* theProjectionMatrix)
159 myProjectionState.Set (theProjectionMatrix);
160 myProjectionState.Update();
163 // =======================================================================
164 // function : SetModelWorldState
165 // purpose : Sets new state of OCCT model-world transform
166 // =======================================================================
167 void OpenGl_ShaderManager::UpdateModelWorldStateTo (const Tmatrix3* theModelWorldMatrix)
169 myModelWorldState.Set (theModelWorldMatrix);
170 myModelWorldState.Update();
173 // =======================================================================
174 // function : SetWorldViewState
175 // purpose : Sets new state of OCCT world-view transform
176 // =======================================================================
177 void OpenGl_ShaderManager::UpdateWorldViewStateTo (const Tmatrix3* theWorldViewMatrix)
179 myWorldViewState.Set (theWorldViewMatrix);
180 myWorldViewState.Update();
183 // =======================================================================
184 // function : RevertProjectionStateTo
185 // purpose : Reverts state of OCCT projection transform
186 // =======================================================================
187 void OpenGl_ShaderManager::RevertProjectionStateTo (const Tmatrix3* theProjectionMatrix)
189 myProjectionState.Set (theProjectionMatrix);
190 myProjectionState.Revert();
193 // =======================================================================
194 // function : RevertModelWorldStateTo
195 // purpose : Reverts state of OCCT model-world transform
196 // =======================================================================
197 void OpenGl_ShaderManager::RevertModelWorldStateTo (const Tmatrix3* theModelWorldMatrix)
199 myModelWorldState.Set (theModelWorldMatrix);
200 myModelWorldState.Revert();
203 // =======================================================================
204 // function : RevertWorldViewStateTo
205 // purpose : Reverts state of OCCT world-view transform
206 // =======================================================================
207 void OpenGl_ShaderManager::RevertWorldViewStateTo (const Tmatrix3* theWorldViewMatrix)
209 myWorldViewState.Set (theWorldViewMatrix);
210 myWorldViewState.Revert();
213 // =======================================================================
214 // function : LightSourceState
215 // purpose : Returns current state of OCCT light sources
216 // =======================================================================
217 const OpenGl_LightSourceState& OpenGl_ShaderManager::LightSourceState() const
219 return myLightSourceState;
222 // =======================================================================
223 // function : ProjectionState
224 // purpose : Returns current state of OCCT projection transform
225 // =======================================================================
226 const OpenGl_ProjectionState& OpenGl_ShaderManager::ProjectionState() const
228 return myProjectionState;
231 // =======================================================================
232 // function : ModelWorldState
233 // purpose : Returns current state of OCCT model-world transform
234 // =======================================================================
235 const OpenGl_ModelWorldState& OpenGl_ShaderManager::ModelWorldState() const
237 return myModelWorldState;
240 // =======================================================================
241 // function : WorldViewState
242 // purpose : Returns current state of OCCT world-view transform
243 // =======================================================================
244 const OpenGl_WorldViewState& OpenGl_ShaderManager::WorldViewState() const
246 return myWorldViewState;
249 //! Packed properties of light source
250 class OpenGl_ShaderLightParameters
255 OpenGl_Vec4 Position;
256 OpenGl_Vec4 Direction;
257 OpenGl_Vec4 Parameters;
259 //! Returns packed (serialized) representation of light source properties
260 const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
261 static Standard_Integer NbOfVec4() { return 4; }
265 //! Packed light source type information
266 class OpenGl_ShaderLightType
270 Standard_Integer Type;
271 Standard_Integer IsHeadlight;
273 //! Returns packed (serialized) representation of light source type
274 const OpenGl_Vec2i* Packed() const { return reinterpret_cast<const OpenGl_Vec2i*> (this); }
275 static Standard_Integer NbOfVec2i() { return 1; }
279 // =======================================================================
280 // function : PushLightSourceState
281 // purpose : Pushes state of OCCT light sources to the program
282 // =======================================================================
283 void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
285 if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE)
286 || !theProgram->IsValid())
291 OpenGl_ShaderLightType* aLightTypeArray = new OpenGl_ShaderLightType[OpenGLMaxLights];
292 for (Standard_Integer aLightIt = 0; aLightIt < OpenGLMaxLights; ++aLightIt)
294 aLightTypeArray[aLightIt].Type = -1;
297 const Standard_Integer aLightsDefNb = Min (myLightSourceState.LightSources()->Size(), OpenGLMaxLights);
298 if (aLightsDefNb < 1)
300 theProgram->SetUniform (myContext,
301 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
303 theProgram->SetUniform (myContext,
304 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT),
305 OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
306 theProgram->SetUniform (myContext,
307 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
308 OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
309 aLightTypeArray[0].Packed());
310 theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
311 delete[] aLightTypeArray;
315 OpenGl_ShaderLightParameters* aLightParamsArray = new OpenGl_ShaderLightParameters[aLightsDefNb];
317 OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f);
318 Standard_Integer aLightsNb = 0;
319 for (OpenGl_ListOfLight::Iterator anIter (*myLightSourceState.LightSources()); anIter.More(); anIter.Next())
321 const OpenGl_Light& aLight = anIter.Value();
322 if (aLight.Type == Visual3d_TOLS_AMBIENT)
324 anAmbient += aLight.Color;
327 else if (aLightsNb >= OpenGLMaxLights)
332 OpenGl_ShaderLightType& aLightType = aLightTypeArray[aLightsNb];
333 aLightType.Type = aLight.Type;
334 aLightType.IsHeadlight = aLight.IsHeadlight;
336 OpenGl_ShaderLightParameters& aLightParams = aLightParamsArray[aLightsNb];
337 aLightParams.Color = aLight.Color;
338 aLightParams.Position = aLight.Type == Visual3d_TOLS_DIRECTIONAL
341 if (aLight.Type == Visual3d_TOLS_SPOT)
343 aLightParams.Direction = aLight.Direction;
345 aLightParams.Parameters = aLight.Params;
349 theProgram->SetUniform (myContext,
350 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
352 theProgram->SetUniform (myContext,
353 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT),
355 theProgram->SetUniform (myContext,
356 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
357 OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
358 aLightTypeArray[0].Packed());
361 theProgram->SetUniform (myContext,
362 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_PARAMS),
363 aLightsNb * OpenGl_ShaderLightParameters::NbOfVec4(),
364 aLightParamsArray[0].Packed());
366 delete[] aLightParamsArray;
367 delete[] aLightTypeArray;
369 theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
372 // =======================================================================
373 // function : PushProjectionState
374 // purpose : Pushes state of OCCT projection transform to the program
375 // =======================================================================
376 void OpenGl_ShaderManager::PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const
378 if (myProjectionState.Index() == theProgram->ActiveState (OpenGl_PROJECTION_STATE))
383 theProgram->SetUniform (myContext,
384 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX),
385 myProjectionState.ProjectionMatrix());
387 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE);
388 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
390 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse());
393 theProgram->SetUniform (myContext,
394 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE),
395 myProjectionState.ProjectionMatrix(), true);
397 aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE);
398 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
400 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse(), true);
403 theProgram->UpdateState (OpenGl_PROJECTION_STATE, myProjectionState.Index());
406 // =======================================================================
407 // function : PushModelWorldState
408 // purpose : Pushes state of OCCT model-world transform to the program
409 // =======================================================================
410 void OpenGl_ShaderManager::PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const
412 if (myModelWorldState.Index() == theProgram->ActiveState (OpenGl_MODEL_WORLD_STATE))
417 theProgram->SetUniform (myContext,
418 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX),
419 myModelWorldState.ModelWorldMatrix());
421 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE);
422 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
424 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse());
427 theProgram->SetUniform (myContext,
428 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE),
429 myModelWorldState.ModelWorldMatrix(), true);
431 aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE);
432 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
434 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse(), true);
437 theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
440 // =======================================================================
441 // function : PushWorldViewState
442 // purpose : Pushes state of OCCT world-view transform to the program
443 // =======================================================================
444 void OpenGl_ShaderManager::PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const
446 if (myWorldViewState.Index() == theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE))
451 theProgram->SetUniform (myContext,
452 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX),
453 myWorldViewState.WorldViewMatrix());
455 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE);
456 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
458 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse());
461 theProgram->SetUniform (myContext,
462 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE),
463 myWorldViewState.WorldViewMatrix(), true);
465 aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE);
466 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
468 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse(), true);
471 theProgram->UpdateState (OpenGl_WORLD_VIEW_STATE, myWorldViewState.Index());
474 // =======================================================================
475 // function : UpdateClippingState
476 // purpose : Updates state of OCCT clipping planes
477 // =======================================================================
478 void OpenGl_ShaderManager::UpdateClippingState()
480 myClippingState.Update();
483 // =======================================================================
484 // function : RevertClippingState
485 // purpose : Reverts state of OCCT clipping planes
486 // =======================================================================
487 void OpenGl_ShaderManager::RevertClippingState()
489 myClippingState.Revert();
492 // =======================================================================
493 // function : PushClippingState
494 // purpose : Pushes state of OCCT clipping planes to the program
495 // =======================================================================
496 void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const
498 if (myClippingState.Index() == theProgram->ActiveState (OpenGl_CLIP_PLANES_STATE))
503 theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index());
504 const GLint aLocEquations = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_EQUATIONS);
505 const GLint aLocSpaces = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_SPACES);
506 if (aLocEquations == OpenGl_ShaderProgram::INVALID_LOCATION
507 && aLocSpaces == OpenGl_ShaderProgram::INVALID_LOCATION)
513 for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
514 anIter.More(); anIter.Next())
516 const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
517 if (!myContext->Clipping().IsEnabled (aPlane))
529 const Standard_Size MAX_CLIP_PLANES = 8;
530 OpenGl_Vec4* anEquations = new OpenGl_Vec4[MAX_CLIP_PLANES];
531 GLint* aSpaces = new GLint [MAX_CLIP_PLANES];
533 for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
534 anIter.More(); anIter.Next())
536 const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
537 if (!myContext->Clipping().IsEnabled (aPlane))
542 const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
543 anEquations[aPlaneId] = OpenGl_Vec4 ((float) anEquation.x(),
544 (float) anEquation.y(),
545 (float) anEquation.z(),
546 (float) anEquation.w());
547 aSpaces[aPlaneId] = myContext->Clipping().GetEquationSpace (aPlane);
551 theProgram->SetUniform (myContext,
552 theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_COUNT),
554 theProgram->SetUniform (myContext, aLocEquations, MAX_CLIP_PLANES, anEquations);
555 theProgram->SetUniform (myContext, aLocSpaces, MAX_CLIP_PLANES, aSpaces);
557 delete[] anEquations;
561 // =======================================================================
562 // function : UpdateMaterialStateTo
563 // purpose : Updates state of OCCT material for specified program
564 // =======================================================================
565 void OpenGl_ShaderManager::UpdateMaterialStateTo (const Handle(OpenGl_ShaderProgram)& theProgram,
566 const OpenGl_Element* theAspect)
568 if (myMaterialStates.IsBound (theProgram))
570 myMaterialStates.ChangeFind (theProgram).Set (theAspect);
574 myMaterialStates.Bind (theProgram, OpenGl_MaterialState (theAspect));
577 myMaterialStates.ChangeFind (theProgram).Update();
580 // =======================================================================
581 // function : ResetMaterialStates
582 // purpose : Resets state of OCCT material for all programs
583 // =======================================================================
584 void OpenGl_ShaderManager::ResetMaterialStates()
586 for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
588 anIt.Value()->UpdateState (OpenGl_MATERIALS_STATE, 0);
592 // =======================================================================
593 // function : MaterialState
594 // purpose : Returns state of OCCT material for specified program
595 // =======================================================================
596 const OpenGl_MaterialState* OpenGl_ShaderManager::MaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
598 if (!myMaterialStates.IsBound (theProgram))
601 return &myMaterialStates.Find (theProgram);
607 static const OpenGl_Vec4 THE_COLOR_BLACK_VEC4 (0.0f, 0.0f, 0.0f, 0.0f);
609 // =======================================================================
610 // function : PushAspectFace
612 // =======================================================================
613 static void PushAspectFace (const Handle(OpenGl_Context)& theCtx,
614 const Handle(OpenGl_ShaderProgram)& theProgram,
615 const OpenGl_AspectFace* theAspect)
617 theProgram->SetUniform (theCtx,
618 theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),
619 theAspect->DoTextureMap());
620 theProgram->SetUniform (theCtx,
621 theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER),
622 0 /* GL_TEXTURE0 */);
623 theProgram->SetUniform (theCtx,
624 theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
625 theAspect->DistinguishingMode());
627 OpenGl_Material aParams;
628 for (Standard_Integer anIndex = 0; anIndex < 2; ++anIndex)
630 const GLint aLoc = theProgram->GetStateLocation (anIndex == 0
631 ? OpenGl_OCCT_FRONT_MATERIAL
632 : OpenGl_OCCT_BACK_MATERIAL);
633 if (aLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
638 aParams.Init (anIndex == 0 ? theAspect->IntFront() : theAspect->IntBack());
639 theProgram->SetUniform (theCtx, aLoc, OpenGl_Material::NbOfVec4(),
644 // =======================================================================
645 // function : PushAspectLine
647 // =======================================================================
648 static void PushAspectLine (const Handle(OpenGl_Context)& theCtx,
649 const Handle(OpenGl_ShaderProgram)& theProgram,
650 const OpenGl_AspectLine* theAspect)
652 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOff);
653 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
655 const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
656 theAspect->Color().rgb[1],
657 theAspect->Color().rgb[2],
658 theAspect->Color().rgb[3]);
659 OpenGl_Vec4 aParams[5];
660 aParams[0] = THE_COLOR_BLACK_VEC4;
661 aParams[1] = THE_COLOR_BLACK_VEC4;
662 aParams[2] = aDiffuse;
663 aParams[3] = THE_COLOR_BLACK_VEC4;
664 aParams[4].x() = 0.0f; // shininess
665 aParams[4].y() = 0.0f; // transparency
666 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
670 // =======================================================================
671 // function : PushAspectText
673 // =======================================================================
674 static void PushAspectText (const Handle(OpenGl_Context)& theCtx,
675 const Handle(OpenGl_ShaderProgram)& theProgram,
676 const OpenGl_AspectText* theAspect)
678 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn);
679 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
680 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */);
682 OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
683 theAspect->Color().rgb[1],
684 theAspect->Color().rgb[2],
685 theAspect->Color().rgb[3]);
686 if (theAspect->DisplayType() == Aspect_TODT_DEKALE
687 || theAspect->DisplayType() == Aspect_TODT_SUBTITLE)
689 aDiffuse = OpenGl_Vec4 (theAspect->SubtitleColor().rgb[0],
690 theAspect->SubtitleColor().rgb[1],
691 theAspect->SubtitleColor().rgb[2],
692 theAspect->SubtitleColor().rgb[3]);
695 OpenGl_Vec4 aParams[5];
696 aParams[0] = THE_COLOR_BLACK_VEC4;
697 aParams[1] = THE_COLOR_BLACK_VEC4;
698 aParams[2] = aDiffuse;
699 aParams[3] = THE_COLOR_BLACK_VEC4;
700 aParams[4].x() = 0.0f; // shininess
701 aParams[4].y() = 0.0f; // transparency
702 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
706 // =======================================================================
707 // function : PushAspectMarker
709 // =======================================================================
710 static void PushAspectMarker (const Handle(OpenGl_Context)& theCtx,
711 const Handle(OpenGl_ShaderProgram)& theProgram,
712 const OpenGl_AspectMarker* theAspect)
714 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn);
715 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
716 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */);
718 const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
719 theAspect->Color().rgb[1],
720 theAspect->Color().rgb[2],
721 theAspect->Color().rgb[3]);
722 OpenGl_Vec4 aParams[5];
723 aParams[0] = THE_COLOR_BLACK_VEC4;
724 aParams[1] = THE_COLOR_BLACK_VEC4;
725 aParams[2] = aDiffuse;
726 aParams[3] = THE_COLOR_BLACK_VEC4;
727 aParams[4].x() = 0.0f; // shininess
728 aParams[4].y() = 0.0f; // transparency
729 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
733 }; // nameless namespace
735 // =======================================================================
736 // function : PushMaterialState
737 // purpose : Pushes current state of OCCT material to the program
738 // =======================================================================
739 void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
741 if (!myMaterialStates.IsBound (theProgram))
746 const OpenGl_MaterialState& aState = myMaterialStates.Find (theProgram);
747 if (aState.Index() == theProgram->ActiveState (OpenGl_MATERIALS_STATE))
752 if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectFace))
754 PushAspectFace (myContext, theProgram, dynamic_cast<const OpenGl_AspectFace*> (aState.Aspect()));
756 else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectLine))
758 PushAspectLine (myContext, theProgram, dynamic_cast<const OpenGl_AspectLine*> (aState.Aspect()));
760 else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectText))
762 PushAspectText (myContext, theProgram, dynamic_cast<const OpenGl_AspectText*> (aState.Aspect()));
764 else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectMarker))
766 PushAspectMarker (myContext, theProgram, dynamic_cast<const OpenGl_AspectMarker*> (aState.Aspect()));
769 theProgram->UpdateState (OpenGl_MATERIALS_STATE, aState.Index());
772 // =======================================================================
773 // function : PushWorldViewState
774 // purpose : Pushes state of OCCT graphics parameters to the program
775 // =======================================================================
776 void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const
778 PushClippingState (theProgram);
779 PushMaterialState (theProgram);
780 PushWorldViewState (theProgram);
781 PushModelWorldState (theProgram);
782 PushProjectionState (theProgram);
783 PushLightSourceState (theProgram);