1 // Created on: 2013-09-26
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2013 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
22 #include <OpenGl_AspectFace.hxx>
23 #include <OpenGl_AspectLine.hxx>
24 #include <OpenGl_AspectMarker.hxx>
25 #include <OpenGl_AspectText.hxx>
26 #include <OpenGl_Clipping.hxx>
27 #include <OpenGl_Context.hxx>
28 #include <OpenGl_ShaderManager.hxx>
29 #include <OpenGl_ShaderProgram.hxx>
31 IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderManager, Standard_Transient)
32 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager, Standard_Transient)
34 // =======================================================================
35 // function : OpenGl_ShaderManager
36 // purpose : Creates new empty shader manager
37 // =======================================================================
38 OpenGl_ShaderManager::OpenGl_ShaderManager (OpenGl_Context* theContext)
39 : myContext (theContext),
40 myIsPP (Standard_False)
45 // =======================================================================
46 // function : ~OpenGl_ShaderManager
47 // purpose : Releases resources of shader manager
48 // =======================================================================
49 OpenGl_ShaderManager::~OpenGl_ShaderManager()
51 myProgramList.Clear();
54 // =======================================================================
56 // purpose : Creates new shader program
57 // =======================================================================
58 void OpenGl_ShaderManager::Create (const Handle(Graphic3d_ShaderProgram)& theProxy,
59 TCollection_AsciiString& theShareKey,
60 Handle(OpenGl_ShaderProgram)& theProgram)
63 if (theProxy.IsNull())
68 theShareKey = theProxy->GetId();
69 if (myContext->GetResource<Handle(OpenGl_ShaderProgram)> (theShareKey, theProgram))
71 if (theProgram->Share())
73 myProgramList.Append (theProgram);
78 theProgram = new OpenGl_ShaderProgram (theProxy);
79 if (!theProgram->Initialize (myContext, theProxy->ShaderObjects()))
81 theProgram->Release (myContext);
87 myProgramList.Append (theProgram);
88 myContext->ShareResource (theShareKey, theProgram);
91 // =======================================================================
92 // function : Unregister
93 // purpose : Removes specified shader program from the manager
94 // =======================================================================
95 void OpenGl_ShaderManager::Unregister (TCollection_AsciiString& theShareKey,
96 Handle(OpenGl_ShaderProgram)& theProgram)
98 for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
100 if (anIt.Value() == theProgram)
102 if (!theProgram->UnShare())
105 theProgram.Nullify();
109 myProgramList.Remove (anIt);
110 myMaterialStates.UnBind (theProgram);
115 const TCollection_AsciiString anID = theProgram->myProxy->GetId();
118 myContext->DelayedRelease (theProgram);
119 theProgram.Nullify();
123 theProgram.Nullify();
124 myContext->ReleaseResource (anID, Standard_True);
128 // =======================================================================
129 // function : ShaderPrograms
130 // purpose : Returns list of registered shader programs
131 // =======================================================================
132 const OpenGl_ShaderProgramList& OpenGl_ShaderManager::ShaderPrograms() const
134 return myProgramList;
137 // =======================================================================
139 // purpose : Returns true if no program objects are attached
140 // =======================================================================
141 Standard_Boolean OpenGl_ShaderManager::IsEmpty() const
143 return myProgramList.IsEmpty();
146 // =======================================================================
147 // function : UpdateLightSourceStateTo
148 // purpose : Updates state of OCCT light sources
149 // =======================================================================
150 void OpenGl_ShaderManager::UpdateLightSourceStateTo (const OpenGl_ListOfLight* theLights)
152 myLightSourceState.Set (theLights);
153 myLightSourceState.Update();
156 // =======================================================================
157 // function : SetProjectionState
158 // purpose : Sets new state of OCCT projection transform
159 // =======================================================================
160 void OpenGl_ShaderManager::UpdateProjectionStateTo (const Tmatrix3& theProjectionMatrix)
162 myProjectionState.Set (theProjectionMatrix);
163 myProjectionState.Update();
166 // =======================================================================
167 // function : SetModelWorldState
168 // purpose : Sets new state of OCCT model-world transform
169 // =======================================================================
170 void OpenGl_ShaderManager::UpdateModelWorldStateTo (const Tmatrix3& theModelWorldMatrix)
172 myModelWorldState.Set (theModelWorldMatrix);
173 myModelWorldState.Update();
176 // =======================================================================
177 // function : SetWorldViewState
178 // purpose : Sets new state of OCCT world-view transform
179 // =======================================================================
180 void OpenGl_ShaderManager::UpdateWorldViewStateTo (const Tmatrix3& theWorldViewMatrix)
182 myWorldViewState.Set (theWorldViewMatrix);
183 myWorldViewState.Update();
186 // =======================================================================
187 // function : RevertProjectionStateTo
188 // purpose : Reverts state of OCCT projection transform
189 // =======================================================================
190 void OpenGl_ShaderManager::RevertProjectionStateTo (const Tmatrix3& theProjectionMatrix)
192 myProjectionState.Set (theProjectionMatrix);
193 myProjectionState.Revert();
196 // =======================================================================
197 // function : RevertModelWorldStateTo
198 // purpose : Reverts state of OCCT model-world transform
199 // =======================================================================
200 void OpenGl_ShaderManager::RevertModelWorldStateTo (const Tmatrix3& theModelWorldMatrix)
202 myModelWorldState.Set (theModelWorldMatrix);
203 myModelWorldState.Revert();
206 // =======================================================================
207 // function : RevertWorldViewStateTo
208 // purpose : Reverts state of OCCT world-view transform
209 // =======================================================================
210 void OpenGl_ShaderManager::RevertWorldViewStateTo (const Tmatrix3& theWorldViewMatrix)
212 myWorldViewState.Set (theWorldViewMatrix);
213 myWorldViewState.Revert();
216 // =======================================================================
217 // function : LightSourceState
218 // purpose : Returns current state of OCCT light sources
219 // =======================================================================
220 const OpenGl_LightSourceState& OpenGl_ShaderManager::LightSourceState() const
222 return myLightSourceState;
225 // =======================================================================
226 // function : ProjectionState
227 // purpose : Returns current state of OCCT projection transform
228 // =======================================================================
229 const OpenGl_ProjectionState& OpenGl_ShaderManager::ProjectionState() const
231 return myProjectionState;
234 // =======================================================================
235 // function : ModelWorldState
236 // purpose : Returns current state of OCCT model-world transform
237 // =======================================================================
238 const OpenGl_ModelWorldState& OpenGl_ShaderManager::ModelWorldState() const
240 return myModelWorldState;
243 // =======================================================================
244 // function : WorldViewState
245 // purpose : Returns current state of OCCT world-view transform
246 // =======================================================================
247 const OpenGl_WorldViewState& OpenGl_ShaderManager::WorldViewState() const
249 return myWorldViewState;
252 //! Packed properties of light source
253 class OpenGl_ShaderLightParameters
258 OpenGl_Vec4 Position;
259 OpenGl_Vec4 Direction;
260 OpenGl_Vec4 Parameters;
262 //! Returns packed (serialized) representation of light source properties
263 const OpenGl_Vec4* Packed() { return reinterpret_cast<OpenGl_Vec4*> (this); }
264 static Standard_Integer NbOfVec4() { return 4; }
268 //! Packed light source type information
269 class OpenGl_ShaderLightType
273 Standard_Integer Type;
274 Standard_Integer IsHeadlight;
276 //! Returns packed (serialized) representation of light source type
277 const OpenGl_Vec2i* Packed() { return reinterpret_cast<OpenGl_Vec2i*> (this); }
278 static Standard_Integer NbOfVec2i() { return 1; }
282 // =======================================================================
283 // function : PushLightSourceState
284 // purpose : Pushes state of OCCT light sources to the program
285 // =======================================================================
286 void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
288 if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE)
289 || !theProgram->IsValid())
294 OpenGl_ShaderLightType* aLightTypeArray = new OpenGl_ShaderLightType[OpenGLMaxLights];
295 for (Standard_Integer aLightIt = 0; aLightIt < OpenGLMaxLights; ++aLightIt)
297 aLightTypeArray[aLightIt].Type = -1;
300 const Standard_Integer aLightsDefNb = Min (myLightSourceState.LightSources()->Size(), OpenGLMaxLights);
301 if (aLightsDefNb < 1)
303 theProgram->SetUniform (myContext,
304 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
306 theProgram->SetUniform (myContext,
307 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT),
308 OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
309 theProgram->SetUniform (myContext,
310 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
311 OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
312 aLightTypeArray[0].Packed());
313 theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
317 OpenGl_ShaderLightParameters* aLightParamsArray = new OpenGl_ShaderLightParameters[aLightsDefNb];
319 OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f);
320 Standard_Integer aLightsNb = 0;
321 for (OpenGl_ListOfLight::Iterator anIter (*myLightSourceState.LightSources()); anIter.More(); anIter.Next())
323 const OpenGl_Light& aLight = anIter.Value();
324 if (aLight.Type == Visual3d_TOLS_AMBIENT)
326 anAmbient += aLight.Color;
329 else if (aLightsNb >= OpenGLMaxLights)
334 OpenGl_ShaderLightType& aLightType = aLightTypeArray[aLightsNb];
335 aLightType.Type = aLight.Type;
336 aLightType.IsHeadlight = aLight.IsHeadlight;
338 OpenGl_ShaderLightParameters& aLightParams = aLightParamsArray[aLightsNb];
339 aLightParams.Color = aLight.Color;
340 aLightParams.Position = aLight.Type == Visual3d_TOLS_DIRECTIONAL
343 if (aLight.Type == Visual3d_TOLS_SPOT)
345 aLightParams.Direction = aLight.Direction;
347 aLightParams.Parameters = aLight.Params;
351 theProgram->SetUniform (myContext,
352 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
354 theProgram->SetUniform (myContext,
355 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT),
357 theProgram->SetUniform (myContext,
358 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
359 OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
360 aLightTypeArray[0].Packed());
363 theProgram->SetUniform (myContext,
364 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_PARAMS),
365 aLightsNb * OpenGl_ShaderLightParameters::NbOfVec4(),
366 aLightParamsArray[0].Packed());
368 delete[] aLightParamsArray;
369 delete[] aLightTypeArray;
371 theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
374 // =======================================================================
375 // function : PushProjectionState
376 // purpose : Pushes state of OCCT projection transform to the program
377 // =======================================================================
378 void OpenGl_ShaderManager::PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const
380 if (myProjectionState.Index() == theProgram->ActiveState (OpenGl_PROJECTION_STATE))
385 theProgram->SetUniform (myContext,
386 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX),
387 myProjectionState.ProjectionMatrix());
389 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE);
390 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
392 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse());
395 theProgram->SetUniform (myContext,
396 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE),
397 myProjectionState.ProjectionMatrix(), true);
399 aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE);
400 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
402 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse(), true);
405 theProgram->UpdateState (OpenGl_PROJECTION_STATE, myProjectionState.Index());
408 // =======================================================================
409 // function : PushModelWorldState
410 // purpose : Pushes state of OCCT model-world transform to the program
411 // =======================================================================
412 void OpenGl_ShaderManager::PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const
414 if (myModelWorldState.Index() == theProgram->ActiveState (OpenGl_MODEL_WORLD_STATE))
419 theProgram->SetUniform (myContext,
420 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX),
421 myModelWorldState.ModelWorldMatrix());
423 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE);
424 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
426 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse());
429 theProgram->SetUniform (myContext,
430 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE),
431 myModelWorldState.ModelWorldMatrix(), true);
433 aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE);
434 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
436 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse(), true);
439 theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
442 // =======================================================================
443 // function : PushWorldViewState
444 // purpose : Pushes state of OCCT world-view transform to the program
445 // =======================================================================
446 void OpenGl_ShaderManager::PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const
448 if (myWorldViewState.Index() == theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE))
453 theProgram->SetUniform (myContext,
454 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX),
455 myWorldViewState.WorldViewMatrix());
457 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE);
458 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
460 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse());
463 theProgram->SetUniform (myContext,
464 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE),
465 myWorldViewState.WorldViewMatrix(), true);
467 aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE);
468 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
470 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse(), true);
473 theProgram->UpdateState (OpenGl_WORLD_VIEW_STATE, myWorldViewState.Index());
476 // =======================================================================
477 // function : UpdateClippingState
478 // purpose : Updates state of OCCT clipping planes
479 // =======================================================================
480 void OpenGl_ShaderManager::UpdateClippingState()
482 myClippingState.Update();
485 // =======================================================================
486 // function : RevertClippingState
487 // purpose : Reverts state of OCCT clipping planes
488 // =======================================================================
489 void OpenGl_ShaderManager::RevertClippingState()
491 myClippingState.Revert();
494 // =======================================================================
495 // function : PushClippingState
496 // purpose : Pushes state of OCCT clipping planes to the program
497 // =======================================================================
498 void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const
500 if (myClippingState.Index() == theProgram->ActiveState (OpenGl_CLIP_PLANES_STATE))
505 theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index());
506 const GLint aLocEquations = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_EQUATIONS);
507 const GLint aLocSpaces = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_SPACES);
508 if (aLocEquations == OpenGl_ShaderProgram::INVALID_LOCATION
509 && aLocSpaces == OpenGl_ShaderProgram::INVALID_LOCATION)
514 GLuint aPlanesNb = 0;
515 for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
516 anIter.More(); anIter.Next())
518 const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
519 if (!myContext->Clipping().IsEnabled (aPlane))
531 OpenGl_Vec4* anEquations = new OpenGl_Vec4[aPlanesNb];
532 GLint* aSpaces = new GLint [aPlanesNb];
534 for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
535 anIter.More(); anIter.Next())
537 const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
538 if (!myContext->Clipping().IsEnabled (aPlane))
543 const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
544 anEquations[aPlaneId] = OpenGl_Vec4 ((float) anEquation.x(),
545 (float) anEquation.y(),
546 (float) anEquation.z(),
547 (float) anEquation.w());
548 aSpaces[aPlaneId] = myContext->Clipping().GetEquationSpace (aPlane);
551 theProgram->SetUniform (myContext, aLocEquations, aPlanesNb, anEquations[0].GetData());
552 theProgram->SetUniform (myContext, aLocSpaces, aPlanesNb, aSpaces);
554 delete[] anEquations;
558 // =======================================================================
559 // function : UpdateMaterialStateTo
560 // purpose : Updates state of OCCT material for specified program
561 // =======================================================================
562 void OpenGl_ShaderManager::UpdateMaterialStateTo (const Handle(OpenGl_ShaderProgram)& theProgram,
563 const OpenGl_Element* theAspect)
565 if (myMaterialStates.IsBound (theProgram))
567 myMaterialStates.ChangeFind (theProgram).Set (theAspect);
571 myMaterialStates.Bind (theProgram, OpenGl_MaterialState (theAspect));
574 myMaterialStates.ChangeFind (theProgram).Update();
577 // =======================================================================
578 // function : ResetMaterialStates
579 // purpose : Resets state of OCCT material for all programs
580 // =======================================================================
581 void OpenGl_ShaderManager::ResetMaterialStates()
583 for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
585 anIt.Value()->UpdateState (OpenGl_MATERIALS_STATE, 0);
589 // =======================================================================
590 // function : MaterialState
591 // purpose : Returns state of OCCT material for specified program
592 // =======================================================================
593 const OpenGl_MaterialState* OpenGl_ShaderManager::MaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
595 if (!myMaterialStates.IsBound (theProgram))
598 return &myMaterialStates.Find (theProgram);
604 static const OpenGl_Vec4 THE_COLOR_BLACK_VEC4 (0.0f, 0.0f, 0.0f, 0.0f);
606 // =======================================================================
607 // function : PushAspectFace
609 // =======================================================================
610 static void PushAspectFace (const Handle(OpenGl_Context)& theCtx,
611 const Handle(OpenGl_ShaderProgram)& theProgram,
612 const OpenGl_AspectFace* theAspect)
614 theProgram->SetUniform (theCtx,
615 theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),
616 theAspect->DoTextureMap());
617 theProgram->SetUniform (theCtx,
618 theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER),
619 0 /* GL_TEXTURE0 */);
620 theProgram->SetUniform (theCtx,
621 theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
622 theAspect->DistinguishingMode());
624 const float aDefSpecCol[4] = {1.0f, 1.0f, 1.0f, 1.0f};
625 OpenGl_Vec4 aParams[5];
626 for (Standard_Integer anIndex = 0; anIndex < 2; ++anIndex)
628 const GLint aLoc = theProgram->GetStateLocation (anIndex == 0
629 ? OpenGl_OCCT_FRONT_MATERIAL
630 : OpenGl_OCCT_BACK_MATERIAL);
631 if (aLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
636 const OPENGL_SURF_PROP& aProps = (anIndex == 0) ? theAspect->IntFront() : theAspect->IntBack();
637 const float* aSrcEms = aProps.isphysic ? aProps.emscol.rgb : aProps.matcol.rgb;
638 const OpenGl_Vec4 anEmission (aSrcEms[0] * aProps.emsv,
639 aSrcEms[1] * aProps.emsv,
640 aSrcEms[2] * aProps.emsv,
642 const float* aSrcAmb = aProps.isphysic ? aProps.ambcol.rgb : aProps.matcol.rgb;
643 const OpenGl_Vec4 anAmbient (aSrcAmb[0] * aProps.amb,
644 aSrcAmb[1] * aProps.amb,
645 aSrcAmb[2] * aProps.amb,
647 const float* aSrcDif = aProps.isphysic ? aProps.difcol.rgb : aProps.matcol.rgb;
648 const OpenGl_Vec4 aDiffuse (aSrcDif[0] * aProps.diff,
649 aSrcDif[1] * aProps.diff,
650 aSrcDif[2] * aProps.diff,
652 const float* aSrcSpe = aProps.isphysic ? aProps.speccol.rgb : aDefSpecCol;
653 const OpenGl_Vec4 aSpecular (aSrcSpe[0] * aProps.spec,
654 aSrcSpe[1] * aProps.spec,
655 aSrcSpe[2] * aProps.spec,
658 aParams[0] = anEmission;
659 aParams[1] = anAmbient;
660 aParams[2] = aDiffuse;
661 aParams[3] = aSpecular;
662 aParams[4].x() = aProps.shine;
663 aParams[4].y() = aProps.trans;
664 theProgram->SetUniform (theCtx, aLoc, 5, aParams);
668 // =======================================================================
669 // function : PushAspectLine
671 // =======================================================================
672 static void PushAspectLine (const Handle(OpenGl_Context)& theCtx,
673 const Handle(OpenGl_ShaderProgram)& theProgram,
674 const OpenGl_AspectLine* theAspect)
676 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOff);
677 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
679 const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
680 theAspect->Color().rgb[1],
681 theAspect->Color().rgb[2],
682 theAspect->Color().rgb[3]);
683 OpenGl_Vec4 aParams[5];
684 aParams[0] = THE_COLOR_BLACK_VEC4;
685 aParams[1] = THE_COLOR_BLACK_VEC4;
686 aParams[2] = aDiffuse;
687 aParams[3] = THE_COLOR_BLACK_VEC4;
688 aParams[4].x() = 0.0f; // shininess
689 aParams[4].y() = 0.0f; // transparency
690 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
694 // =======================================================================
695 // function : PushAspectText
697 // =======================================================================
698 static void PushAspectText (const Handle(OpenGl_Context)& theCtx,
699 const Handle(OpenGl_ShaderProgram)& theProgram,
700 const OpenGl_AspectText* theAspect)
702 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn);
703 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
704 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */);
706 OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
707 theAspect->Color().rgb[1],
708 theAspect->Color().rgb[2],
709 theAspect->Color().rgb[3]);
710 if (theAspect->DisplayType() == Aspect_TODT_DEKALE
711 || theAspect->DisplayType() == Aspect_TODT_SUBTITLE)
713 aDiffuse = OpenGl_Vec4 (theAspect->SubtitleColor().rgb[0],
714 theAspect->SubtitleColor().rgb[1],
715 theAspect->SubtitleColor().rgb[2],
716 theAspect->SubtitleColor().rgb[3]);
719 OpenGl_Vec4 aParams[5];
720 aParams[0] = THE_COLOR_BLACK_VEC4;
721 aParams[1] = THE_COLOR_BLACK_VEC4;
722 aParams[2] = aDiffuse;
723 aParams[3] = THE_COLOR_BLACK_VEC4;
724 aParams[4].x() = 0.0f; // shininess
725 aParams[4].y() = 0.0f; // transparency
726 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
730 // =======================================================================
731 // function : PushAspectMarker
733 // =======================================================================
734 static void PushAspectMarker (const Handle(OpenGl_Context)& theCtx,
735 const Handle(OpenGl_ShaderProgram)& theProgram,
736 const OpenGl_AspectMarker* theAspect)
738 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn);
739 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
740 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */);
742 const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
743 theAspect->Color().rgb[1],
744 theAspect->Color().rgb[2],
745 theAspect->Color().rgb[3]);
746 OpenGl_Vec4 aParams[5];
747 aParams[0] = THE_COLOR_BLACK_VEC4;
748 aParams[1] = THE_COLOR_BLACK_VEC4;
749 aParams[2] = aDiffuse;
750 aParams[3] = THE_COLOR_BLACK_VEC4;
751 aParams[4].x() = 0.0f; // shininess
752 aParams[4].y() = 0.0f; // transparency
753 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
757 }; // nameless namespace
759 // =======================================================================
760 // function : PushMaterialState
761 // purpose : Pushes current state of OCCT material to the program
762 // =======================================================================
763 void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
765 if (!myMaterialStates.IsBound (theProgram))
770 const OpenGl_MaterialState& aState = myMaterialStates.Find (theProgram);
771 if (aState.Index() == theProgram->ActiveState (OpenGl_MATERIALS_STATE))
776 if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectFace))
778 PushAspectFace (myContext, theProgram, dynamic_cast<const OpenGl_AspectFace*> (aState.Aspect()));
780 else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectLine))
782 PushAspectLine (myContext, theProgram, dynamic_cast<const OpenGl_AspectLine*> (aState.Aspect()));
784 else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectText))
786 PushAspectText (myContext, theProgram, dynamic_cast<const OpenGl_AspectText*> (aState.Aspect()));
788 else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectMarker))
790 PushAspectMarker (myContext, theProgram, dynamic_cast<const OpenGl_AspectMarker*> (aState.Aspect()));
793 theProgram->UpdateState (OpenGl_MATERIALS_STATE, aState.Index());
796 // =======================================================================
797 // function : PushWorldViewState
798 // purpose : Pushes state of OCCT graphics parameters to the program
799 // =======================================================================
800 void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const
802 PushClippingState (theProgram);
803 PushMaterialState (theProgram);
804 PushWorldViewState (theProgram);
805 PushModelWorldState (theProgram);
806 PushProjectionState (theProgram);
807 PushLightSourceState (theProgram);