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