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