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