0024348: TKOpenGl - the same GLSL program can not be re-assigned
[occt.git] / src / OpenGl / OpenGl_ShaderManager.cxx
CommitLineData
30f0ad28 1// Created on: 2013-09-26
2// Created by: Denis BOGOLEPOV
3// Copyright (c) 2013 OPEN CASCADE SAS
4//
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.
9//
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.
12//
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.
19
20#include <typeinfo>
21
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>
30
31IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderManager, Standard_Transient)
32IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager, Standard_Transient)
33
34// =======================================================================
35// function : OpenGl_ShaderManager
36// purpose : Creates new empty shader manager
37// =======================================================================
38OpenGl_ShaderManager::OpenGl_ShaderManager (OpenGl_Context* theContext)
39: myContext (theContext),
40 myIsPP (Standard_False)
41{
42 //
43}
44
45// =======================================================================
46// function : ~OpenGl_ShaderManager
47// purpose : Releases resources of shader manager
48// =======================================================================
49OpenGl_ShaderManager::~OpenGl_ShaderManager()
50{
51 myProgramList.Clear();
52}
53
54// =======================================================================
55// function : Create
56// purpose : Creates new shader program
57// =======================================================================
392ac980 58void OpenGl_ShaderManager::Create (const Handle(Graphic3d_ShaderProgram)& theProxy,
59 TCollection_AsciiString& theShareKey,
60 Handle(OpenGl_ShaderProgram)& theProgram)
30f0ad28 61{
392ac980 62 theProgram.Nullify();
63 if (theProxy.IsNull())
30f0ad28 64 {
392ac980 65 return;
30f0ad28 66 }
392ac980 67
68 theShareKey = theProxy->GetId();
69 if (myContext->GetResource<Handle(OpenGl_ShaderProgram)> (theShareKey, theProgram))
70 {
05dd08ce 71 if (theProgram->Share())
72 {
73 myProgramList.Append (theProgram);
74 }
392ac980 75 return;
76 }
77
78 theProgram = new OpenGl_ShaderProgram (theProxy);
79 if (!theProgram->Initialize (myContext, theProxy->ShaderObjects()))
30f0ad28 80 {
392ac980 81 theProgram->Release (myContext);
82 theShareKey.Clear();
83 theProgram.Nullify();
84 return;
30f0ad28 85 }
30f0ad28 86
392ac980 87 myProgramList.Append (theProgram);
88 myContext->ShareResource (theShareKey, theProgram);
30f0ad28 89}
90
91// =======================================================================
92// function : Unregister
93// purpose : Removes specified shader program from the manager
94// =======================================================================
392ac980 95void OpenGl_ShaderManager::Unregister (TCollection_AsciiString& theShareKey,
96 Handle(OpenGl_ShaderProgram)& theProgram)
30f0ad28 97{
98 for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
99 {
100 if (anIt.Value() == theProgram)
101 {
392ac980 102 if (!theProgram->UnShare())
103 {
104 theShareKey.Clear();
105 theProgram.Nullify();
106 return;
107 }
108
30f0ad28 109 myProgramList.Remove (anIt);
392ac980 110 myMaterialStates.UnBind (theProgram);
30f0ad28 111 break;
112 }
113 }
114
115 const TCollection_AsciiString anID = theProgram->myProxy->GetId();
116 if (anID.IsEmpty())
117 {
118 myContext->DelayedRelease (theProgram);
119 theProgram.Nullify();
120 }
121 else
122 {
123 theProgram.Nullify();
05dd08ce 124 myContext->ReleaseResource (anID, Standard_True);
30f0ad28 125 }
126}
127
128// =======================================================================
129// function : ShaderPrograms
130// purpose : Returns list of registered shader programs
131// =======================================================================
132const OpenGl_ShaderProgramList& OpenGl_ShaderManager::ShaderPrograms() const
133{
134 return myProgramList;
135}
136
137// =======================================================================
138// function : Empty
139// purpose : Returns true if no program objects are attached
140// =======================================================================
141Standard_Boolean OpenGl_ShaderManager::IsEmpty() const
142{
143 return myProgramList.IsEmpty();
144}
145
146// =======================================================================
147// function : UpdateLightSourceStateTo
148// purpose : Updates state of OCCT light sources
149// =======================================================================
150void OpenGl_ShaderManager::UpdateLightSourceStateTo (const OpenGl_ListOfLight* theLights)
151{
152 myLightSourceState.Set (theLights);
153 myLightSourceState.Update();
154}
155
156// =======================================================================
157// function : SetProjectionState
158// purpose : Sets new state of OCCT projection transform
159// =======================================================================
160void OpenGl_ShaderManager::UpdateProjectionStateTo (const Tmatrix3& theProjectionMatrix)
161{
162 myProjectionState.Set (theProjectionMatrix);
163 myProjectionState.Update();
164}
165
166// =======================================================================
167// function : SetModelWorldState
168// purpose : Sets new state of OCCT model-world transform
169// =======================================================================
170void OpenGl_ShaderManager::UpdateModelWorldStateTo (const Tmatrix3& theModelWorldMatrix)
171{
172 myModelWorldState.Set (theModelWorldMatrix);
173 myModelWorldState.Update();
174}
175
176// =======================================================================
177// function : SetWorldViewState
178// purpose : Sets new state of OCCT world-view transform
179// =======================================================================
180void OpenGl_ShaderManager::UpdateWorldViewStateTo (const Tmatrix3& theWorldViewMatrix)
181{
182 myWorldViewState.Set (theWorldViewMatrix);
183 myWorldViewState.Update();
184}
185
186// =======================================================================
187// function : RevertProjectionStateTo
188// purpose : Reverts state of OCCT projection transform
189// =======================================================================
190void OpenGl_ShaderManager::RevertProjectionStateTo (const Tmatrix3& theProjectionMatrix)
191{
192 myProjectionState.Set (theProjectionMatrix);
193 myProjectionState.Revert();
194}
195
196// =======================================================================
197// function : RevertModelWorldStateTo
198// purpose : Reverts state of OCCT model-world transform
199// =======================================================================
200void OpenGl_ShaderManager::RevertModelWorldStateTo (const Tmatrix3& theModelWorldMatrix)
201{
202 myModelWorldState.Set (theModelWorldMatrix);
203 myModelWorldState.Revert();
204}
205
206// =======================================================================
207// function : RevertWorldViewStateTo
208// purpose : Reverts state of OCCT world-view transform
209// =======================================================================
210void OpenGl_ShaderManager::RevertWorldViewStateTo (const Tmatrix3& theWorldViewMatrix)
211{
212 myWorldViewState.Set (theWorldViewMatrix);
213 myWorldViewState.Revert();
214}
215
216// =======================================================================
217// function : LightSourceState
218// purpose : Returns current state of OCCT light sources
219// =======================================================================
220const OpenGl_LightSourceState& OpenGl_ShaderManager::LightSourceState() const
221{
222 return myLightSourceState;
223}
224
225// =======================================================================
226// function : ProjectionState
227// purpose : Returns current state of OCCT projection transform
228// =======================================================================
229const OpenGl_ProjectionState& OpenGl_ShaderManager::ProjectionState() const
230{
231 return myProjectionState;
232}
233
234// =======================================================================
235// function : ModelWorldState
236// purpose : Returns current state of OCCT model-world transform
237// =======================================================================
238const OpenGl_ModelWorldState& OpenGl_ShaderManager::ModelWorldState() const
239{
240 return myModelWorldState;
241}
242
243// =======================================================================
244// function : WorldViewState
245// purpose : Returns current state of OCCT world-view transform
246// =======================================================================
247const OpenGl_WorldViewState& OpenGl_ShaderManager::WorldViewState() const
248{
249 return myWorldViewState;
250}
251
4fe9ad57 252//! Packed properties of light source
253class OpenGl_ShaderLightParameters
254{
255public:
256
257 OpenGl_Vec4 Color;
258 OpenGl_Vec4 Position;
259 OpenGl_Vec4 Direction;
260 OpenGl_Vec4 Parameters;
261
262 //! Returns packed (serialized) representation of light source properties
263 const OpenGl_Vec4* Packed() { return reinterpret_cast<OpenGl_Vec4*> (this); }
264 static Standard_Size NbOfVec4() { return 4; }
265
266};
267
268//! Packed light source type information
269class OpenGl_ShaderLightType
270{
271public:
272
273 Standard_Integer Type;
274 Standard_Integer IsHeadlight;
275
276 //! Returns packed (serialized) representation of light source type
277 const OpenGl_Vec2i* Packed() { return reinterpret_cast<OpenGl_Vec2i*> (this); }
278 static Standard_Size NbOfVec2i() { return 1; }
279
280};
281
30f0ad28 282// =======================================================================
283// function : PushLightSourceState
284// purpose : Pushes state of OCCT light sources to the program
285// =======================================================================
286void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
287{
12381341 288 if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE)
289 || !theProgram->IsValid())
30f0ad28 290 {
291 return;
292 }
30f0ad28 293
12381341 294 const Standard_Integer aLightsDefNb = Min (myLightSourceState.LightSources()->Size(), OpenGLMaxLights);
295 if (aLightsDefNb < 1)
296 {
30f0ad28 297 theProgram->SetUniform (myContext,
12381341 298 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
299 0);
30f0ad28 300 theProgram->SetUniform (myContext,
12381341 301 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT),
302 OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
303 theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
304 return;
305 }
30f0ad28 306
4fe9ad57 307 OpenGl_ShaderLightParameters* aLightParamsArray = new OpenGl_ShaderLightParameters[aLightsDefNb];
308 OpenGl_ShaderLightType* aLightTypeArray = new OpenGl_ShaderLightType[aLightsDefNb];
30f0ad28 309
12381341 310 OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f);
311 Standard_Integer aLightsNb = 0;
312 for (OpenGl_ListOfLight::Iterator anIter (*myLightSourceState.LightSources()); anIter.More(); anIter.Next())
313 {
314 const OpenGl_Light& aLight = anIter.Value();
315 if (aLight.Type == Visual3d_TOLS_AMBIENT)
30f0ad28 316 {
12381341 317 anAmbient += aLight.Color;
318 continue;
319 }
320 else if (aLightsNb >= OpenGLMaxLights)
321 {
322 continue;
323 }
30f0ad28 324
4fe9ad57 325 OpenGl_ShaderLightType& aLightType = aLightTypeArray[aLightsNb];
326 aLightType.Type = aLight.Type;
327 aLightType.IsHeadlight = aLight.IsHeadlight;
30f0ad28 328
4fe9ad57 329 OpenGl_ShaderLightParameters& aLightParams = aLightParamsArray[aLightsNb];
330 aLightParams.Color = aLight.Color;
331 aLightParams.Position = aLight.Type == Visual3d_TOLS_DIRECTIONAL
332 ? -aLight.Direction
333 : aLight.Position;
12381341 334 if (aLight.Type == Visual3d_TOLS_SPOT)
335 {
4fe9ad57 336 aLightParams.Direction = aLight.Direction;
30f0ad28 337 }
4fe9ad57 338 aLightParams.Parameters = aLight.Params;
12381341 339 ++aLightsNb;
340 }
30f0ad28 341
12381341 342 theProgram->SetUniform (myContext,
343 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
344 aLightsNb);
345 theProgram->SetUniform (myContext,
346 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT),
347 anAmbient);
348 if (aLightsNb > 0)
349 {
4fe9ad57 350 theProgram->SetUniform (myContext,
351 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
352 aLightsNb * OpenGl_ShaderLightType::NbOfVec2i(),
353 aLightTypeArray[0].Packed());
354 theProgram->SetUniform (myContext,
355 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_PARAMS),
356 aLightsNb * OpenGl_ShaderLightParameters::NbOfVec4(),
357 aLightParamsArray[0].Packed());
30f0ad28 358 }
4fe9ad57 359 delete[] aLightParamsArray;
360 delete[] aLightTypeArray;
30f0ad28 361
362 theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
363}
364
365// =======================================================================
366// function : PushProjectionState
367// purpose : Pushes state of OCCT projection transform to the program
368// =======================================================================
369void OpenGl_ShaderManager::PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const
370{
371 if (myProjectionState.Index() == theProgram->ActiveState (OpenGl_PROJECTION_STATE))
372 {
373 return;
374 }
375
376 theProgram->SetUniform (myContext,
377 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX),
378 myProjectionState.ProjectionMatrix());
379
380 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE);
381 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
382 {
383 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse());
384 }
385
386 theProgram->SetUniform (myContext,
387 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE),
388 myProjectionState.ProjectionMatrix(), true);
389
390 aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE);
391 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
392 {
393 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse(), true);
394 }
395
396 theProgram->UpdateState (OpenGl_PROJECTION_STATE, myProjectionState.Index());
397}
398
399// =======================================================================
400// function : PushModelWorldState
401// purpose : Pushes state of OCCT model-world transform to the program
402// =======================================================================
403void OpenGl_ShaderManager::PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const
404{
405 if (myModelWorldState.Index() == theProgram->ActiveState (OpenGl_MODEL_WORLD_STATE))
406 {
407 return;
408 }
409
410 theProgram->SetUniform (myContext,
411 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX),
412 myModelWorldState.ModelWorldMatrix());
413
414 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE);
415 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
416 {
417 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse());
418 }
419
420 theProgram->SetUniform (myContext,
421 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE),
422 myModelWorldState.ModelWorldMatrix(), true);
423
424 aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE);
425 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
426 {
427 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse(), true);
428 }
429
430 theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
431}
432
433// =======================================================================
434// function : PushWorldViewState
435// purpose : Pushes state of OCCT world-view transform to the program
436// =======================================================================
437void OpenGl_ShaderManager::PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const
438{
439 if (myWorldViewState.Index() == theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE))
440 {
441 return;
442 }
443
444 theProgram->SetUniform (myContext,
445 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX),
446 myWorldViewState.WorldViewMatrix());
447
448 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE);
449 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
450 {
451 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse());
452 }
453
454 theProgram->SetUniform (myContext,
455 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE),
456 myWorldViewState.WorldViewMatrix(), true);
457
458 aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE);
459 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
460 {
461 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse(), true);
462 }
463
464 theProgram->UpdateState (OpenGl_WORLD_VIEW_STATE, myWorldViewState.Index());
465}
466
467// =======================================================================
468// function : UpdateClippingState
469// purpose : Updates state of OCCT clipping planes
470// =======================================================================
471void OpenGl_ShaderManager::UpdateClippingState()
472{
473 myClippingState.Update();
474}
475
476// =======================================================================
477// function : RevertClippingState
478// purpose : Reverts state of OCCT clipping planes
479// =======================================================================
480void OpenGl_ShaderManager::RevertClippingState()
481{
482 myClippingState.Revert();
483}
484
485// =======================================================================
486// function : PushClippingState
487// purpose : Pushes state of OCCT clipping planes to the program
488// =======================================================================
489void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const
490{
491 if (myClippingState.Index() == theProgram->ActiveState (OpenGl_CLIP_PLANES_STATE))
492 {
493 return;
494 }
495
12381341 496 theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index());
497 const GLint aLocEquations = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_EQUATIONS);
498 const GLint aLocSpaces = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_SPACES);
499 if (aLocEquations == OpenGl_ShaderProgram::INVALID_LOCATION
500 && aLocSpaces == OpenGl_ShaderProgram::INVALID_LOCATION)
501 {
502 return;
503 }
504
505 GLuint aPlanesNb = 0;
506 for (Graphic3d_SetOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
507 anIter.More(); anIter.Next())
30f0ad28 508 {
509 const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
510 if (!myContext->Clipping().IsEnabled (aPlane))
511 {
512 continue;
513 }
514
12381341 515 ++aPlanesNb;
516 }
517 if (aPlanesNb < 1)
518 {
519 return;
520 }
521
522 OpenGl_Vec4* anEquations = new OpenGl_Vec4[aPlanesNb];
523 GLint* aSpaces = new GLint [aPlanesNb];
524 GLuint aPlaneId = 0;
525 for (Graphic3d_SetOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
526 anIter.More(); anIter.Next())
527 {
528 const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
529 if (!myContext->Clipping().IsEnabled (aPlane))
30f0ad28 530 {
12381341 531 continue;
30f0ad28 532 }
533
12381341 534 const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
535 anEquations[aPlaneId] = OpenGl_Vec4 ((float) anEquation.x(),
536 (float) anEquation.y(),
537 (float) anEquation.z(),
538 (float) anEquation.w());
539 aSpaces[aPlaneId] = myContext->Clipping().GetEquationSpace (aPlane);
540 ++aPlaneId;
30f0ad28 541 }
4fe9ad57 542 theProgram->SetUniform (myContext, aLocEquations, aPlanesNb, anEquations[0].GetData());
543 theProgram->SetUniform (myContext, aLocSpaces, aPlanesNb, aSpaces);
544
12381341 545 delete[] anEquations;
546 delete[] aSpaces;
30f0ad28 547}
548
549// =======================================================================
550// function : UpdateMaterialStateTo
551// purpose : Updates state of OCCT material for specified program
552// =======================================================================
553void OpenGl_ShaderManager::UpdateMaterialStateTo (const Handle(OpenGl_ShaderProgram)& theProgram,
554 const OpenGl_Element* theAspect)
555{
556 if (myMaterialStates.IsBound (theProgram))
557 {
558 myMaterialStates.ChangeFind (theProgram).Set (theAspect);
559 }
560 else
561 {
562 myMaterialStates.Bind (theProgram, OpenGl_MaterialState (theAspect));
563 }
564
565 myMaterialStates.ChangeFind (theProgram).Update();
566}
567
568// =======================================================================
569// function : ResetMaterialStates
570// purpose : Resets state of OCCT material for all programs
571// =======================================================================
572void OpenGl_ShaderManager::ResetMaterialStates()
573{
574 for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
575 {
576 anIt.Value()->UpdateState (OpenGl_MATERIALS_STATE, 0);
577 }
578}
579
580// =======================================================================
581// function : MaterialState
582// purpose : Returns state of OCCT material for specified program
583// =======================================================================
584const OpenGl_MaterialState* OpenGl_ShaderManager::MaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
585{
586 if (!myMaterialStates.IsBound (theProgram))
587 return NULL;
588
589 return &myMaterialStates.Find (theProgram);
590}
591
592namespace
593{
594
595static const OpenGl_Vec4 THE_COLOR_BLACK_VEC4 (0.0f, 0.0f, 0.0f, 0.0f);
596
597// =======================================================================
598// function : PushAspectFace
599// purpose :
600// =======================================================================
601static void PushAspectFace (const Handle(OpenGl_Context)& theCtx,
602 const Handle(OpenGl_ShaderProgram)& theProgram,
603 const OpenGl_AspectFace* theAspect)
604{
605 theProgram->SetUniform (theCtx,
606 theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),
607 theAspect->DoTextureMap());
30f0ad28 608 theProgram->SetUniform (theCtx,
609 theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER),
610 0 /* GL_TEXTURE0 */);
30f0ad28 611 theProgram->SetUniform (theCtx,
612 theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
613 theAspect->DistinguishingMode());
614
12381341 615 OpenGl_Vec4 aParams[5];
616 for (Standard_Integer anIndex = 0; anIndex < 2; ++anIndex)
30f0ad28 617 {
12381341 618 const GLint aLoc = theProgram->GetStateLocation (anIndex == 0
619 ? OpenGl_OCCT_FRONT_MATERIAL
620 : OpenGl_OCCT_BACK_MATERIAL);
621 if (aLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
30f0ad28 622 {
12381341 623 continue;
30f0ad28 624 }
30f0ad28 625
12381341 626 const OPENGL_SURF_PROP& aProps = (anIndex == 0) ? theAspect->IntFront() : theAspect->IntBack();
627 const OpenGl_Vec4 anEmission (aProps.emscol.rgb[0] * aProps.emsv,
628 aProps.emscol.rgb[1] * aProps.emsv,
629 aProps.emscol.rgb[2] * aProps.emsv,
630 aProps.emscol.rgb[3] * aProps.emsv);
631 const OpenGl_Vec4 anAmbient (aProps.ambcol.rgb[0] * aProps.amb,
632 aProps.ambcol.rgb[1] * aProps.amb,
633 aProps.ambcol.rgb[2] * aProps.amb,
634 aProps.ambcol.rgb[3] * aProps.amb);
635 const OpenGl_Vec4 aDiffuse (aProps.difcol.rgb[0] * aProps.diff,
636 aProps.difcol.rgb[1] * aProps.diff,
637 aProps.difcol.rgb[2] * aProps.diff,
638 aProps.difcol.rgb[3] * aProps.diff);
639 const OpenGl_Vec4 aSpecular (aProps.speccol.rgb[0] * aProps.spec,
640 aProps.speccol.rgb[1] * aProps.spec,
641 aProps.speccol.rgb[2] * aProps.spec,
642 aProps.speccol.rgb[3] * aProps.spec);
643 aParams[0] = anEmission;
644 aParams[1] = anAmbient;
645 aParams[2] = aDiffuse;
646 aParams[3] = aSpecular;
647 aParams[4].x() = aProps.shine;
648 aParams[4].y() = aProps.trans;
4fe9ad57 649 theProgram->SetUniform (theCtx, aLoc, 5, aParams);
30f0ad28 650 }
651}
652
653// =======================================================================
654// function : PushAspectLine
655// purpose :
656// =======================================================================
657static void PushAspectLine (const Handle(OpenGl_Context)& theCtx,
658 const Handle(OpenGl_ShaderProgram)& theProgram,
659 const OpenGl_AspectLine* theAspect)
660{
661 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOff);
662 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
663
664 const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
665 theAspect->Color().rgb[1],
666 theAspect->Color().rgb[2],
667 theAspect->Color().rgb[3]);
12381341 668 OpenGl_Vec4 aParams[5];
669 aParams[0] = THE_COLOR_BLACK_VEC4;
670 aParams[1] = THE_COLOR_BLACK_VEC4;
671 aParams[2] = aDiffuse;
672 aParams[3] = THE_COLOR_BLACK_VEC4;
673 aParams[4].x() = 0.0f; // shininess
674 aParams[4].y() = 0.0f; // transparency
4fe9ad57 675 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
676 5, aParams);
30f0ad28 677}
678
679// =======================================================================
680// function : PushAspectText
681// purpose :
682// =======================================================================
683static void PushAspectText (const Handle(OpenGl_Context)& theCtx,
684 const Handle(OpenGl_ShaderProgram)& theProgram,
685 const OpenGl_AspectText* theAspect)
686{
687 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn);
688 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
689 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */);
690
691 OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
692 theAspect->Color().rgb[1],
693 theAspect->Color().rgb[2],
694 theAspect->Color().rgb[3]);
695 if (theAspect->DisplayType() == Aspect_TODT_DEKALE
696 || theAspect->DisplayType() == Aspect_TODT_SUBTITLE)
697 {
698 aDiffuse = OpenGl_Vec4 (theAspect->SubtitleColor().rgb[0],
699 theAspect->SubtitleColor().rgb[1],
700 theAspect->SubtitleColor().rgb[2],
701 theAspect->SubtitleColor().rgb[3]);
702 }
703
12381341 704 OpenGl_Vec4 aParams[5];
705 aParams[0] = THE_COLOR_BLACK_VEC4;
706 aParams[1] = THE_COLOR_BLACK_VEC4;
707 aParams[2] = aDiffuse;
708 aParams[3] = THE_COLOR_BLACK_VEC4;
709 aParams[4].x() = 0.0f; // shininess
710 aParams[4].y() = 0.0f; // transparency
4fe9ad57 711 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
712 5, aParams);
30f0ad28 713}
714
715// =======================================================================
716// function : PushAspectMarker
717// purpose :
718// =======================================================================
719static void PushAspectMarker (const Handle(OpenGl_Context)& theCtx,
720 const Handle(OpenGl_ShaderProgram)& theProgram,
721 const OpenGl_AspectMarker* theAspect)
722{
723 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn);
724 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
725 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */);
726
727 const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
728 theAspect->Color().rgb[1],
729 theAspect->Color().rgb[2],
730 theAspect->Color().rgb[3]);
12381341 731 OpenGl_Vec4 aParams[5];
732 aParams[0] = THE_COLOR_BLACK_VEC4;
733 aParams[1] = THE_COLOR_BLACK_VEC4;
734 aParams[2] = aDiffuse;
735 aParams[3] = THE_COLOR_BLACK_VEC4;
736 aParams[4].x() = 0.0f; // shininess
737 aParams[4].y() = 0.0f; // transparency
4fe9ad57 738 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
739 5, aParams);
30f0ad28 740}
741
742}; // nameless namespace
743
744// =======================================================================
745// function : PushMaterialState
746// purpose : Pushes current state of OCCT material to the program
747// =======================================================================
748void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
749{
750 if (!myMaterialStates.IsBound (theProgram))
751 {
752 return;
753 }
754
755 const OpenGl_MaterialState& aState = myMaterialStates.Find (theProgram);
756 if (aState.Index() == theProgram->ActiveState (OpenGl_MATERIALS_STATE))
757 {
758 return;
759 }
760
761 if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectFace))
762 {
763 PushAspectFace (myContext, theProgram, dynamic_cast<const OpenGl_AspectFace*> (aState.Aspect()));
764 }
765 else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectLine))
766 {
767 PushAspectLine (myContext, theProgram, dynamic_cast<const OpenGl_AspectLine*> (aState.Aspect()));
768 }
769 else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectText))
770 {
771 PushAspectText (myContext, theProgram, dynamic_cast<const OpenGl_AspectText*> (aState.Aspect()));
772 }
773 else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectMarker))
774 {
775 PushAspectMarker (myContext, theProgram, dynamic_cast<const OpenGl_AspectMarker*> (aState.Aspect()));
776 }
777
778 theProgram->UpdateState (OpenGl_MATERIALS_STATE, aState.Index());
779}
780
781// =======================================================================
782// function : PushWorldViewState
783// purpose : Pushes state of OCCT graphics parameters to the program
784// =======================================================================
785void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const
786{
787 PushClippingState (theProgram);
788 PushMaterialState (theProgram);
789 PushWorldViewState (theProgram);
790 PushModelWorldState (theProgram);
791 PushProjectionState (theProgram);
792 PushLightSourceState (theProgram);
12381341 793}