Test bugs vis bug24130 should be OK when OpenCL is present, corrected
[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
252// =======================================================================
253// function : PushLightSourceState
254// purpose : Pushes state of OCCT light sources to the program
255// =======================================================================
256void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
257{
258 if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE))
259 {
260 return;
261 }
262
263 theProgram->SetUniform (myContext, theProgram->GetStateLocation (
264 OpenGl_OCC_LIGHT_SOURCE_COUNT), myLightSourceState.LightSources()->Size());
265
266 OpenGl_ListOfLight::Iterator anIter (*myLightSourceState.LightSources());
267 for (unsigned int anIndex = 0; anIter.More(); anIter.Next())
268 {
269 if (anIndex >= OpenGLMaxLights)
270 {
271 break;
272 }
273
274 const OpenGl_Light& aLight = anIter.Value();
275 if (aLight.type == TLightAmbient)
276 {
277 OpenGl_Vec3 anAmbient (aLight.col.rgb[0],
278 aLight.col.rgb[1],
279 aLight.col.rgb[2]);
280
281 theProgram->SetUniform (myContext,
282 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_AMBIENT + anIndex), anAmbient);
283
284 anIter.Next();
285 if (!anIter.More())
286 {
287 theProgram->SetUniform (myContext,
288 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_TYPE + anIndex), int (aLight.type));
289 break;
290 }
291 }
292
293 OpenGl_Vec3 aDiffuse (aLight.col.rgb[0],
294 aLight.col.rgb[1],
295 aLight.col.rgb[2]);
296
297 OpenGl_Vec3 aPosition (aLight.type == TLightDirectional ? -aLight.dir[0] : aLight.pos[0],
298 aLight.type == TLightDirectional ? -aLight.dir[1] : aLight.pos[1],
299 aLight.type == TLightDirectional ? -aLight.dir[2] : aLight.pos[2]);
300
301 theProgram->SetUniform (myContext,
302 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_TYPE + anIndex), int (aLight.type));
303
304 theProgram->SetUniform (myContext,
305 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_HEAD + anIndex), aLight.HeadLight);
306
307 theProgram->SetUniform (myContext,
308 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_DIFFUSE + anIndex), aDiffuse);
309
310 theProgram->SetUniform (myContext,
311 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPECULAR + anIndex), aDiffuse);
312
313 theProgram->SetUniform (myContext,
314 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_POSITION + anIndex), aPosition);
315
316 theProgram->SetUniform (myContext,
317 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_CONST_ATTENUATION + anIndex), aLight.atten[0]);
318
319 theProgram->SetUniform (myContext,
320 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_LINEAR_ATTENUATION + anIndex), aLight.atten[1]);
321
322 if (aLight.type == TLightSpot)
323 {
324 OpenGl_Vec3 aDirection (aLight.dir[0],
325 aLight.dir[1],
326 aLight.dir[2]);
327
328 theProgram->SetUniform (myContext,
329 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPOT_CUTOFF + anIndex), aLight.angle);
330
331 theProgram->SetUniform (myContext,
332 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPOT_EXPONENT + anIndex), aLight.shine);
333
334 theProgram->SetUniform (myContext,
335 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPOT_DIRECTION + anIndex), aDirection);
336 }
337
338 ++anIndex;
339 }
340
341 theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
342}
343
344// =======================================================================
345// function : PushProjectionState
346// purpose : Pushes state of OCCT projection transform to the program
347// =======================================================================
348void OpenGl_ShaderManager::PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const
349{
350 if (myProjectionState.Index() == theProgram->ActiveState (OpenGl_PROJECTION_STATE))
351 {
352 return;
353 }
354
355 theProgram->SetUniform (myContext,
356 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX),
357 myProjectionState.ProjectionMatrix());
358
359 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE);
360 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
361 {
362 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse());
363 }
364
365 theProgram->SetUniform (myContext,
366 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE),
367 myProjectionState.ProjectionMatrix(), true);
368
369 aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE);
370 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
371 {
372 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse(), true);
373 }
374
375 theProgram->UpdateState (OpenGl_PROJECTION_STATE, myProjectionState.Index());
376}
377
378// =======================================================================
379// function : PushModelWorldState
380// purpose : Pushes state of OCCT model-world transform to the program
381// =======================================================================
382void OpenGl_ShaderManager::PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const
383{
384 if (myModelWorldState.Index() == theProgram->ActiveState (OpenGl_MODEL_WORLD_STATE))
385 {
386 return;
387 }
388
389 theProgram->SetUniform (myContext,
390 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX),
391 myModelWorldState.ModelWorldMatrix());
392
393 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE);
394 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
395 {
396 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse());
397 }
398
399 theProgram->SetUniform (myContext,
400 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE),
401 myModelWorldState.ModelWorldMatrix(), true);
402
403 aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE);
404 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
405 {
406 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse(), true);
407 }
408
409 theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
410}
411
412// =======================================================================
413// function : PushWorldViewState
414// purpose : Pushes state of OCCT world-view transform to the program
415// =======================================================================
416void OpenGl_ShaderManager::PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const
417{
418 if (myWorldViewState.Index() == theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE))
419 {
420 return;
421 }
422
423 theProgram->SetUniform (myContext,
424 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX),
425 myWorldViewState.WorldViewMatrix());
426
427 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE);
428 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
429 {
430 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse());
431 }
432
433 theProgram->SetUniform (myContext,
434 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE),
435 myWorldViewState.WorldViewMatrix(), true);
436
437 aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE);
438 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
439 {
440 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse(), true);
441 }
442
443 theProgram->UpdateState (OpenGl_WORLD_VIEW_STATE, myWorldViewState.Index());
444}
445
446// =======================================================================
447// function : UpdateClippingState
448// purpose : Updates state of OCCT clipping planes
449// =======================================================================
450void OpenGl_ShaderManager::UpdateClippingState()
451{
452 myClippingState.Update();
453}
454
455// =======================================================================
456// function : RevertClippingState
457// purpose : Reverts state of OCCT clipping planes
458// =======================================================================
459void OpenGl_ShaderManager::RevertClippingState()
460{
461 myClippingState.Revert();
462}
463
464// =======================================================================
465// function : PushClippingState
466// purpose : Pushes state of OCCT clipping planes to the program
467// =======================================================================
468void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const
469{
470 if (myClippingState.Index() == theProgram->ActiveState (OpenGl_CLIP_PLANES_STATE))
471 {
472 return;
473 }
474
475 Graphic3d_SetOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
476 for (GLuint anIndex = 0; anIter.More(); anIter.Next())
477 {
478 const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
479 if (!myContext->Clipping().IsEnabled (aPlane))
480 {
481 continue;
482 }
483
484 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_0_EQUATION + anIndex);
485 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
486 {
487 const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
488 theProgram->SetUniform (myContext, aLocation, OpenGl_Vec4 ((float) anEquation.x(),
489 (float) anEquation.y(),
490 (float) anEquation.z(),
491 (float) anEquation.w()));
492 }
493
494 theProgram->SetUniform (myContext,
495 theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_0_SPACE + anIndex),
496 myContext->Clipping().GetEquationSpace (aPlane));
497 ++anIndex;
498 }
499
500 theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index());
501}
502
503// =======================================================================
504// function : UpdateMaterialStateTo
505// purpose : Updates state of OCCT material for specified program
506// =======================================================================
507void OpenGl_ShaderManager::UpdateMaterialStateTo (const Handle(OpenGl_ShaderProgram)& theProgram,
508 const OpenGl_Element* theAspect)
509{
510 if (myMaterialStates.IsBound (theProgram))
511 {
512 myMaterialStates.ChangeFind (theProgram).Set (theAspect);
513 }
514 else
515 {
516 myMaterialStates.Bind (theProgram, OpenGl_MaterialState (theAspect));
517 }
518
519 myMaterialStates.ChangeFind (theProgram).Update();
520}
521
522// =======================================================================
523// function : ResetMaterialStates
524// purpose : Resets state of OCCT material for all programs
525// =======================================================================
526void OpenGl_ShaderManager::ResetMaterialStates()
527{
528 for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
529 {
530 anIt.Value()->UpdateState (OpenGl_MATERIALS_STATE, 0);
531 }
532}
533
534// =======================================================================
535// function : MaterialState
536// purpose : Returns state of OCCT material for specified program
537// =======================================================================
538const OpenGl_MaterialState* OpenGl_ShaderManager::MaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
539{
540 if (!myMaterialStates.IsBound (theProgram))
541 return NULL;
542
543 return &myMaterialStates.Find (theProgram);
544}
545
546namespace
547{
548
549static const OpenGl_Vec4 THE_COLOR_BLACK_VEC4 (0.0f, 0.0f, 0.0f, 0.0f);
550
551// =======================================================================
552// function : PushAspectFace
553// purpose :
554// =======================================================================
555static void PushAspectFace (const Handle(OpenGl_Context)& theCtx,
556 const Handle(OpenGl_ShaderProgram)& theProgram,
557 const OpenGl_AspectFace* theAspect)
558{
559 theProgram->SetUniform (theCtx,
560 theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),
561 theAspect->DoTextureMap());
562
563 theProgram->SetUniform (theCtx,
564 theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER),
565 0 /* GL_TEXTURE0 */);
566
567 theProgram->SetUniform (theCtx,
568 theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
569 theAspect->DistinguishingMode());
570
571 for (int anIndex = 0; anIndex < 2; ++anIndex)
572 {
573 const OPENGL_SURF_PROP& aProperties = (anIndex == 0) ? theAspect->IntFront() : theAspect->IntBack();
574 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT + anIndex);
575 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
576 {
577 OpenGl_Vec4 anAmbient (aProperties.ambcol.rgb[0] * aProperties.amb,
578 aProperties.ambcol.rgb[1] * aProperties.amb,
579 aProperties.ambcol.rgb[2] * aProperties.amb,
580 aProperties.ambcol.rgb[3] * aProperties.amb);
581 theProgram->SetUniform (theCtx, aLocation, anAmbient);
582 }
583
584 aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE + anIndex);
585 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
586 {
587 OpenGl_Vec4 aDiffuse (aProperties.difcol.rgb[0] * aProperties.diff,
588 aProperties.difcol.rgb[1] * aProperties.diff,
589 aProperties.difcol.rgb[2] * aProperties.diff,
590 aProperties.difcol.rgb[3] * aProperties.diff);
591 theProgram->SetUniform (theCtx, aLocation, aDiffuse);
592 }
593
594 aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR + anIndex);
595 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
596 {
597 OpenGl_Vec4 aSpecular (aProperties.speccol.rgb[0] * aProperties.spec,
598 aProperties.speccol.rgb[1] * aProperties.spec,
599 aProperties.speccol.rgb[2] * aProperties.spec,
600 aProperties.speccol.rgb[3] * aProperties.spec);
601 theProgram->SetUniform (theCtx, aLocation, aSpecular);
602 }
603
604 aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION + anIndex);
605 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
606 {
607 OpenGl_Vec4 anEmission (aProperties.emscol.rgb[0] * aProperties.emsv,
608 aProperties.emscol.rgb[1] * aProperties.emsv,
609 aProperties.emscol.rgb[2] * aProperties.emsv,
610 aProperties.emscol.rgb[3] * aProperties.emsv);
611 theProgram->SetUniform (theCtx, aLocation, anEmission);
612 }
613
614 theProgram->SetUniform (theCtx,
615 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SHININESS + anIndex),
616 aProperties.shine);
617
618 theProgram->SetUniform (theCtx,
619 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY + anIndex),
620 aProperties.trans);
621 }
622}
623
624// =======================================================================
625// function : PushAspectLine
626// purpose :
627// =======================================================================
628static void PushAspectLine (const Handle(OpenGl_Context)& theCtx,
629 const Handle(OpenGl_ShaderProgram)& theProgram,
630 const OpenGl_AspectLine* theAspect)
631{
632 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOff);
633 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
634
635 const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
636 theAspect->Color().rgb[1],
637 theAspect->Color().rgb[2],
638 theAspect->Color().rgb[3]);
639 theProgram->SetUniform (theCtx,
640 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT),
641 THE_COLOR_BLACK_VEC4);
642 theProgram->SetUniform (theCtx,
643 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE),
644 aDiffuse);
645 theProgram->SetUniform (theCtx,
646 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR),
647 THE_COLOR_BLACK_VEC4);
648 theProgram->SetUniform (theCtx,
649 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION),
650 THE_COLOR_BLACK_VEC4);
651 theProgram->SetUniform (theCtx,
652 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY),
653 0.0f);
654}
655
656// =======================================================================
657// function : PushAspectText
658// purpose :
659// =======================================================================
660static void PushAspectText (const Handle(OpenGl_Context)& theCtx,
661 const Handle(OpenGl_ShaderProgram)& theProgram,
662 const OpenGl_AspectText* theAspect)
663{
664 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn);
665 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
666 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */);
667
668 OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
669 theAspect->Color().rgb[1],
670 theAspect->Color().rgb[2],
671 theAspect->Color().rgb[3]);
672 if (theAspect->DisplayType() == Aspect_TODT_DEKALE
673 || theAspect->DisplayType() == Aspect_TODT_SUBTITLE)
674 {
675 aDiffuse = OpenGl_Vec4 (theAspect->SubtitleColor().rgb[0],
676 theAspect->SubtitleColor().rgb[1],
677 theAspect->SubtitleColor().rgb[2],
678 theAspect->SubtitleColor().rgb[3]);
679 }
680
681 theProgram->SetUniform (theCtx,
682 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT),
683 THE_COLOR_BLACK_VEC4);
684 theProgram->SetUniform (theCtx,
685 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE),
686 aDiffuse);
687 theProgram->SetUniform (theCtx,
688 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR),
689 THE_COLOR_BLACK_VEC4);
690 theProgram->SetUniform (theCtx,
691 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION),
692 THE_COLOR_BLACK_VEC4);
693 theProgram->SetUniform (theCtx,
694 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY),
695 0.0f);
696}
697
698// =======================================================================
699// function : PushAspectMarker
700// purpose :
701// =======================================================================
702static void PushAspectMarker (const Handle(OpenGl_Context)& theCtx,
703 const Handle(OpenGl_ShaderProgram)& theProgram,
704 const OpenGl_AspectMarker* theAspect)
705{
706 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn);
707 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
708 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */);
709
710 const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
711 theAspect->Color().rgb[1],
712 theAspect->Color().rgb[2],
713 theAspect->Color().rgb[3]);
714
715 theProgram->SetUniform (theCtx,
716 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT),
717 THE_COLOR_BLACK_VEC4);
718 theProgram->SetUniform (theCtx,
719 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE),
720 aDiffuse);
721 theProgram->SetUniform (theCtx,
722 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR),
723 THE_COLOR_BLACK_VEC4);
724 theProgram->SetUniform (theCtx,
725 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION),
726 THE_COLOR_BLACK_VEC4);
727 theProgram->SetUniform (theCtx,
728 theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY),
729 0.0f);
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);
783}