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))
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);
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 // =======================================================================
250 // function : PushLightSourceState
251 // purpose : Pushes state of OCCT light sources to the program
252 // =======================================================================
253 void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
255 if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE))
260 theProgram->SetUniform (myContext, theProgram->GetStateLocation (
261 OpenGl_OCC_LIGHT_SOURCE_COUNT), myLightSourceState.LightSources()->Size());
263 OpenGl_ListOfLight::Iterator anIter (*myLightSourceState.LightSources());
264 for (unsigned int anIndex = 0; anIter.More(); anIter.Next())
266 if (anIndex >= OpenGLMaxLights)
271 const OpenGl_Light& aLight = anIter.Value();
272 if (aLight.type == TLightAmbient)
274 OpenGl_Vec3 anAmbient (aLight.col.rgb[0],
278 theProgram->SetUniform (myContext,
279 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_AMBIENT + anIndex), anAmbient);
284 theProgram->SetUniform (myContext,
285 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_TYPE + anIndex), int (aLight.type));
290 OpenGl_Vec3 aDiffuse (aLight.col.rgb[0],
294 OpenGl_Vec3 aPosition (aLight.type == TLightDirectional ? -aLight.dir[0] : aLight.pos[0],
295 aLight.type == TLightDirectional ? -aLight.dir[1] : aLight.pos[1],
296 aLight.type == TLightDirectional ? -aLight.dir[2] : aLight.pos[2]);
298 theProgram->SetUniform (myContext,
299 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_TYPE + anIndex), int (aLight.type));
301 theProgram->SetUniform (myContext,
302 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_HEAD + anIndex), aLight.HeadLight);
304 theProgram->SetUniform (myContext,
305 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_DIFFUSE + anIndex), aDiffuse);
307 theProgram->SetUniform (myContext,
308 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPECULAR + anIndex), aDiffuse);
310 theProgram->SetUniform (myContext,
311 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_POSITION + anIndex), aPosition);
313 theProgram->SetUniform (myContext,
314 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_CONST_ATTENUATION + anIndex), aLight.atten[0]);
316 theProgram->SetUniform (myContext,
317 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_LINEAR_ATTENUATION + anIndex), aLight.atten[1]);
319 if (aLight.type == TLightSpot)
321 OpenGl_Vec3 aDirection (aLight.dir[0],
325 theProgram->SetUniform (myContext,
326 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPOT_CUTOFF + anIndex), aLight.angle);
328 theProgram->SetUniform (myContext,
329 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPOT_EXPONENT + anIndex), aLight.shine);
331 theProgram->SetUniform (myContext,
332 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPOT_DIRECTION + anIndex), aDirection);
338 theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
341 // =======================================================================
342 // function : PushProjectionState
343 // purpose : Pushes state of OCCT projection transform to the program
344 // =======================================================================
345 void OpenGl_ShaderManager::PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const
347 if (myProjectionState.Index() == theProgram->ActiveState (OpenGl_PROJECTION_STATE))
352 theProgram->SetUniform (myContext,
353 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX),
354 myProjectionState.ProjectionMatrix());
356 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE);
357 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
359 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse());
362 theProgram->SetUniform (myContext,
363 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE),
364 myProjectionState.ProjectionMatrix(), true);
366 aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE);
367 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
369 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse(), true);
372 theProgram->UpdateState (OpenGl_PROJECTION_STATE, myProjectionState.Index());
375 // =======================================================================
376 // function : PushModelWorldState
377 // purpose : Pushes state of OCCT model-world transform to the program
378 // =======================================================================
379 void OpenGl_ShaderManager::PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const
381 if (myModelWorldState.Index() == theProgram->ActiveState (OpenGl_MODEL_WORLD_STATE))
386 theProgram->SetUniform (myContext,
387 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX),
388 myModelWorldState.ModelWorldMatrix());
390 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE);
391 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
393 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse());
396 theProgram->SetUniform (myContext,
397 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE),
398 myModelWorldState.ModelWorldMatrix(), true);
400 aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE);
401 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
403 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse(), true);
406 theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
409 // =======================================================================
410 // function : PushWorldViewState
411 // purpose : Pushes state of OCCT world-view transform to the program
412 // =======================================================================
413 void OpenGl_ShaderManager::PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const
415 if (myWorldViewState.Index() == theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE))
420 theProgram->SetUniform (myContext,
421 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX),
422 myWorldViewState.WorldViewMatrix());
424 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE);
425 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
427 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse());
430 theProgram->SetUniform (myContext,
431 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE),
432 myWorldViewState.WorldViewMatrix(), true);
434 aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE);
435 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
437 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse(), true);
440 theProgram->UpdateState (OpenGl_WORLD_VIEW_STATE, myWorldViewState.Index());
443 // =======================================================================
444 // function : UpdateClippingState
445 // purpose : Updates state of OCCT clipping planes
446 // =======================================================================
447 void OpenGl_ShaderManager::UpdateClippingState()
449 myClippingState.Update();
452 // =======================================================================
453 // function : RevertClippingState
454 // purpose : Reverts state of OCCT clipping planes
455 // =======================================================================
456 void OpenGl_ShaderManager::RevertClippingState()
458 myClippingState.Revert();
461 // =======================================================================
462 // function : PushClippingState
463 // purpose : Pushes state of OCCT clipping planes to the program
464 // =======================================================================
465 void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const
467 if (myClippingState.Index() == theProgram->ActiveState (OpenGl_CLIP_PLANES_STATE))
472 Graphic3d_SetOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
473 for (GLuint anIndex = 0; anIter.More(); anIter.Next())
475 const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
476 if (!myContext->Clipping().IsEnabled (aPlane))
481 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_0_EQUATION + anIndex);
482 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
484 const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
485 theProgram->SetUniform (myContext, aLocation, OpenGl_Vec4 ((float) anEquation.x(),
486 (float) anEquation.y(),
487 (float) anEquation.z(),
488 (float) anEquation.w()));
491 theProgram->SetUniform (myContext,
492 theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_0_SPACE + anIndex),
493 myContext->Clipping().GetEquationSpace (aPlane));
497 theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index());
500 // =======================================================================
501 // function : UpdateMaterialStateTo
502 // purpose : Updates state of OCCT material for specified program
503 // =======================================================================
504 void OpenGl_ShaderManager::UpdateMaterialStateTo (const Handle(OpenGl_ShaderProgram)& theProgram,
505 const OpenGl_Element* theAspect)
507 if (myMaterialStates.IsBound (theProgram))
509 myMaterialStates.ChangeFind (theProgram).Set (theAspect);
513 myMaterialStates.Bind (theProgram, OpenGl_MaterialState (theAspect));
516 myMaterialStates.ChangeFind (theProgram).Update();
519 // =======================================================================
520 // function : ResetMaterialStates
521 // purpose : Resets state of OCCT material for all programs
522 // =======================================================================
523 void OpenGl_ShaderManager::ResetMaterialStates()
525 for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
527 anIt.Value()->UpdateState (OpenGl_MATERIALS_STATE, 0);
531 // =======================================================================
532 // function : MaterialState
533 // purpose : Returns state of OCCT material for specified program
534 // =======================================================================
535 const OpenGl_MaterialState* OpenGl_ShaderManager::MaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
537 if (!myMaterialStates.IsBound (theProgram))
540 return &myMaterialStates.Find (theProgram);
546 static const OpenGl_Vec4 THE_COLOR_BLACK_VEC4 (0.0f, 0.0f, 0.0f, 0.0f);
548 // =======================================================================
549 // function : PushAspectFace
551 // =======================================================================
552 static void PushAspectFace (const Handle(OpenGl_Context)& theCtx,
553 const Handle(OpenGl_ShaderProgram)& theProgram,
554 const OpenGl_AspectFace* theAspect)
556 theProgram->SetUniform (theCtx,
557 theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),
558 theAspect->DoTextureMap());
560 theProgram->SetUniform (theCtx,
561 theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER),
562 0 /* GL_TEXTURE0 */);
564 theProgram->SetUniform (theCtx,
565 theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
566 theAspect->DistinguishingMode());
568 for (int anIndex = 0; anIndex < 2; ++anIndex)
570 const OPENGL_SURF_PROP& aProperties = (anIndex == 0) ? theAspect->IntFront() : theAspect->IntBack();
571 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT + anIndex);
572 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
574 OpenGl_Vec4 anAmbient (aProperties.ambcol.rgb[0] * aProperties.amb,
575 aProperties.ambcol.rgb[1] * aProperties.amb,
576 aProperties.ambcol.rgb[2] * aProperties.amb,
577 aProperties.ambcol.rgb[3] * aProperties.amb);
578 theProgram->SetUniform (theCtx, aLocation, anAmbient);
581 aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE + anIndex);
582 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
584 OpenGl_Vec4 aDiffuse (aProperties.difcol.rgb[0] * aProperties.diff,
585 aProperties.difcol.rgb[1] * aProperties.diff,
586 aProperties.difcol.rgb[2] * aProperties.diff,
587 aProperties.difcol.rgb[3] * aProperties.diff);
588 theProgram->SetUniform (theCtx, aLocation, aDiffuse);
591 aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR + anIndex);
592 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
594 OpenGl_Vec4 aSpecular (aProperties.speccol.rgb[0] * aProperties.spec,
595 aProperties.speccol.rgb[1] * aProperties.spec,
596 aProperties.speccol.rgb[2] * aProperties.spec,
597 aProperties.speccol.rgb[3] * aProperties.spec);
598 theProgram->SetUniform (theCtx, aLocation, aSpecular);
601 aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION + anIndex);
602 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
604 OpenGl_Vec4 anEmission (aProperties.emscol.rgb[0] * aProperties.emsv,
605 aProperties.emscol.rgb[1] * aProperties.emsv,
606 aProperties.emscol.rgb[2] * aProperties.emsv,
607 aProperties.emscol.rgb[3] * aProperties.emsv);
608 theProgram->SetUniform (theCtx, aLocation, anEmission);
611 theProgram->SetUniform (theCtx,
612 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SHININESS + anIndex),
615 theProgram->SetUniform (theCtx,
616 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY + anIndex),
621 // =======================================================================
622 // function : PushAspectLine
624 // =======================================================================
625 static void PushAspectLine (const Handle(OpenGl_Context)& theCtx,
626 const Handle(OpenGl_ShaderProgram)& theProgram,
627 const OpenGl_AspectLine* theAspect)
629 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOff);
630 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
632 const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
633 theAspect->Color().rgb[1],
634 theAspect->Color().rgb[2],
635 theAspect->Color().rgb[3]);
636 theProgram->SetUniform (theCtx,
637 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT),
638 THE_COLOR_BLACK_VEC4);
639 theProgram->SetUniform (theCtx,
640 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE),
642 theProgram->SetUniform (theCtx,
643 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR),
644 THE_COLOR_BLACK_VEC4);
645 theProgram->SetUniform (theCtx,
646 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION),
647 THE_COLOR_BLACK_VEC4);
648 theProgram->SetUniform (theCtx,
649 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY),
653 // =======================================================================
654 // function : PushAspectText
656 // =======================================================================
657 static void PushAspectText (const Handle(OpenGl_Context)& theCtx,
658 const Handle(OpenGl_ShaderProgram)& theProgram,
659 const OpenGl_AspectText* theAspect)
661 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn);
662 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
663 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */);
665 OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
666 theAspect->Color().rgb[1],
667 theAspect->Color().rgb[2],
668 theAspect->Color().rgb[3]);
669 if (theAspect->DisplayType() == Aspect_TODT_DEKALE
670 || theAspect->DisplayType() == Aspect_TODT_SUBTITLE)
672 aDiffuse = OpenGl_Vec4 (theAspect->SubtitleColor().rgb[0],
673 theAspect->SubtitleColor().rgb[1],
674 theAspect->SubtitleColor().rgb[2],
675 theAspect->SubtitleColor().rgb[3]);
678 theProgram->SetUniform (theCtx,
679 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT),
680 THE_COLOR_BLACK_VEC4);
681 theProgram->SetUniform (theCtx,
682 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE),
684 theProgram->SetUniform (theCtx,
685 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR),
686 THE_COLOR_BLACK_VEC4);
687 theProgram->SetUniform (theCtx,
688 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION),
689 THE_COLOR_BLACK_VEC4);
690 theProgram->SetUniform (theCtx,
691 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY),
695 // =======================================================================
696 // function : PushAspectMarker
698 // =======================================================================
699 static void PushAspectMarker (const Handle(OpenGl_Context)& theCtx,
700 const Handle(OpenGl_ShaderProgram)& theProgram,
701 const OpenGl_AspectMarker* theAspect)
703 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn);
704 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
705 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */);
707 const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
708 theAspect->Color().rgb[1],
709 theAspect->Color().rgb[2],
710 theAspect->Color().rgb[3]);
712 theProgram->SetUniform (theCtx,
713 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT),
714 THE_COLOR_BLACK_VEC4);
715 theProgram->SetUniform (theCtx,
716 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE),
718 theProgram->SetUniform (theCtx,
719 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR),
720 THE_COLOR_BLACK_VEC4);
721 theProgram->SetUniform (theCtx,
722 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION),
723 THE_COLOR_BLACK_VEC4);
724 theProgram->SetUniform (theCtx,
725 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY),
729 }; // nameless namespace
731 // =======================================================================
732 // function : PushMaterialState
733 // purpose : Pushes current state of OCCT material to the program
734 // =======================================================================
735 void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
737 if (!myMaterialStates.IsBound (theProgram))
742 const OpenGl_MaterialState& aState = myMaterialStates.Find (theProgram);
743 if (aState.Index() == theProgram->ActiveState (OpenGl_MATERIALS_STATE))
748 if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectFace))
750 PushAspectFace (myContext, theProgram, dynamic_cast<const OpenGl_AspectFace*> (aState.Aspect()));
752 else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectLine))
754 PushAspectLine (myContext, theProgram, dynamic_cast<const OpenGl_AspectLine*> (aState.Aspect()));
756 else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectText))
758 PushAspectText (myContext, theProgram, dynamic_cast<const OpenGl_AspectText*> (aState.Aspect()));
760 else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectMarker))
762 PushAspectMarker (myContext, theProgram, dynamic_cast<const OpenGl_AspectMarker*> (aState.Aspect()));
765 theProgram->UpdateState (OpenGl_MATERIALS_STATE, aState.Index());
768 // =======================================================================
769 // function : PushWorldViewState
770 // purpose : Pushes state of OCCT graphics parameters to the program
771 // =======================================================================
772 void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const
774 PushClippingState (theProgram);
775 PushMaterialState (theProgram);
776 PushWorldViewState (theProgram);
777 PushModelWorldState (theProgram);
778 PushProjectionState (theProgram);
779 PushLightSourceState (theProgram);