1 // Created on: 2013-09-26
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
18 #include <Graphic3d_TextureParams.hxx>
19 #include <OpenGl_AspectFace.hxx>
20 #include <OpenGl_AspectLine.hxx>
21 #include <OpenGl_AspectMarker.hxx>
22 #include <OpenGl_AspectText.hxx>
23 #include <OpenGl_Clipping.hxx>
24 #include <OpenGl_Context.hxx>
25 #include <OpenGl_ShaderManager.hxx>
26 #include <OpenGl_ShaderProgram.hxx>
27 #include <OpenGl_Workspace.hxx>
29 #include <TCollection_ExtendedString.hxx>
34 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager,Standard_Transient)
41 //! Definition of TexCoord varying.
42 const char THE_VARY_TexCoord_OUT[] =
43 EOL"THE_SHADER_OUT vec4 TexCoord;";
44 const char THE_VARY_TexCoord_IN[] =
45 EOL"THE_SHADER_IN vec4 TexCoord;";
46 //! Compute TexCoord value in Vertex Shader
47 const char THE_VARY_TexCoord_Trsf[] =
48 EOL" float aRotSin = occTextureTrsf_RotationSin();"
49 EOL" float aRotCos = occTextureTrsf_RotationCos();"
50 EOL" vec2 aTex2 = (occTexCoord.xy + occTextureTrsf_Translation()) * occTextureTrsf_Scale();"
51 EOL" vec2 aCopy = aTex2;"
52 EOL" aTex2.x = aCopy.x * aRotCos - aCopy.y * aRotSin;"
53 EOL" aTex2.y = aCopy.x * aRotSin + aCopy.y * aRotCos;"
54 EOL" TexCoord = vec4(aTex2, occTexCoord.zw);";
56 //! Auxiliary function to transform normal
57 const char THE_FUNC_transformNormal[] =
58 EOL"vec3 transformNormal (in vec3 theNormal)"
60 EOL" vec4 aResult = occWorldViewMatrixInverseTranspose"
61 EOL" * occModelWorldMatrixInverseTranspose"
62 EOL" * vec4 (theNormal, 0.0);"
63 EOL" return normalize (aResult.xyz);"
66 //! Global shader variable for color definition with lighting enabled.
67 const char THE_FUNC_lightDef[] =
68 EOL"vec3 Ambient;" //!< Ambient contribution of light sources
69 EOL"vec3 Diffuse;" //!< Diffuse contribution of light sources
70 EOL"vec3 Specular;"; //!< Specular contribution of light sources
72 //! Function computes contribution of isotropic point light source
73 const char THE_FUNC_pointLight[] =
74 EOL"void pointLight (in int theId,"
75 EOL" in vec3 theNormal,"
76 EOL" in vec3 theView,"
77 EOL" in vec3 thePoint,"
78 EOL" in bool theIsFront)"
80 EOL" vec3 aLight = occLight_Position (theId).xyz;"
81 EOL" if (occLight_IsHeadlight (theId) == 0)"
83 EOL" aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 1.0));"
85 EOL" aLight -= thePoint;"
87 EOL" float aDist = length (aLight);"
88 EOL" aLight = aLight * (1.0 / aDist);"
90 EOL" float anAtten = 1.0 / (occLight_ConstAttenuation (theId)"
91 EOL" + occLight_LinearAttenuation (theId) * aDist);"
93 EOL" vec3 aHalf = normalize (aLight + theView);"
95 EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
96 EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
97 EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
99 EOL" float aSpecl = 0.0;"
100 EOL" if (aNdotL > 0.0)"
102 EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
105 EOL"Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten;"
106 EOL"Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;"
109 //! Function computes contribution of spotlight source
110 const char THE_FUNC_spotLight[] =
111 EOL"void spotLight (in int theId,"
112 EOL" in vec3 theNormal,"
113 EOL" in vec3 theView,"
114 EOL" in vec3 thePoint,"
115 EOL" in bool theIsFront)"
117 EOL" vec3 aLight = occLight_Position (theId).xyz;"
118 EOL" vec3 aSpotDir = occLight_SpotDirection (theId).xyz;"
119 EOL" if (occLight_IsHeadlight (theId) == 0)"
121 EOL" aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 1.0));"
122 EOL" aSpotDir = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aSpotDir, 0.0));"
124 EOL" aLight -= thePoint;"
126 EOL" float aDist = length (aLight);"
127 EOL" aLight = aLight * (1.0 / aDist);"
129 EOL" aSpotDir = normalize (aSpotDir);"
131 EOL" float aCosA = dot (aSpotDir, -aLight);"
132 EOL" if (aCosA >= 1.0 || aCosA < cos (occLight_SpotCutOff (theId)))"
137 EOL" float anExponent = occLight_SpotExponent (theId);"
138 EOL" float anAtten = 1.0 / (occLight_ConstAttenuation (theId)"
139 EOL" + occLight_LinearAttenuation (theId) * aDist);"
140 EOL" if (anExponent > 0.0)"
142 EOL" anAtten *= pow (aCosA, anExponent * 128.0);"
145 EOL" vec3 aHalf = normalize (aLight + theView);"
147 EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
148 EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
149 EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
151 EOL" float aSpecl = 0.0;"
152 EOL" if (aNdotL > 0.0)"
154 EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
157 EOL" Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten;"
158 EOL" Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;"
161 //! Function computes contribution of directional light source
162 const char THE_FUNC_directionalLight[] =
163 EOL"void directionalLight (in int theId,"
164 EOL" in vec3 theNormal,"
165 EOL" in vec3 theView,"
166 EOL" in bool theIsFront)"
168 EOL" vec3 aLight = normalize (occLight_Position (theId).xyz);"
169 EOL" if (occLight_IsHeadlight (theId) == 0)"
171 EOL" aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 0.0));"
174 EOL" vec3 aHalf = normalize (aLight + theView);"
176 EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
177 EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
178 EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
180 EOL" float aSpecl = 0.0;"
181 EOL" if (aNdotL > 0.0)"
183 EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
186 EOL" Diffuse += occLight_Diffuse (theId).rgb * aNdotL;"
187 EOL" Specular += occLight_Specular (theId).rgb * aSpecl;"
190 //! The same as THE_FUNC_directionalLight but for the light with zero index
191 //! (avoids limitations on some mobile devices).
192 const char THE_FUNC_directionalLightFirst[] =
193 EOL"void directionalLightFirst (in vec3 theNormal,"
194 EOL" in vec3 theView,"
195 EOL" in bool theIsFront)"
197 EOL" vec3 aLight = normalize (occLightSources[1].xyz);"
198 EOL" if (occLight_IsHeadlight (0) == 0)"
200 EOL" aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 0.0));"
203 EOL" vec3 aHalf = normalize (aLight + theView);"
205 EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
206 EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
207 EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
209 EOL" float aSpecl = 0.0;"
210 EOL" if (aNdotL > 0.0)"
212 EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
215 EOL" Diffuse += occLightSources[0].rgb * aNdotL;"
216 EOL" Specular += occLightSources[0].rgb * aSpecl;"
219 //! Process clipping planes in Fragment Shader.
220 //! Should be added at the beginning of the main() function.
221 const char THE_FRAG_CLIP_PLANES[] =
222 EOL" for (int aPlaneIter = 0; aPlaneIter < occClipPlaneCount; ++aPlaneIter)"
224 EOL" vec4 aClipEquation = occClipPlaneEquations[aPlaneIter];"
225 EOL" int aClipSpace = occClipPlaneSpaces[aPlaneIter];"
226 EOL" if (aClipSpace == OccEquationCoords_World)"
228 EOL" if (dot (aClipEquation.xyz, PositionWorld.xyz) + aClipEquation.w < 0.0)"
233 EOL" else if (aClipSpace == OccEquationCoords_View)"
235 EOL" if (dot (aClipEquation.xyz, Position.xyz) + aClipEquation.w < 0.0)"
244 // =======================================================================
245 // function : OpenGl_ShaderManager
246 // purpose : Creates new empty shader manager
247 // =======================================================================
248 OpenGl_ShaderManager::OpenGl_ShaderManager (OpenGl_Context* theContext)
249 : myShadingModel (Graphic3d_TOSM_VERTEX),
250 myContext (theContext),
256 // =======================================================================
257 // function : ~OpenGl_ShaderManager
258 // purpose : Releases resources of shader manager
259 // =======================================================================
260 OpenGl_ShaderManager::~OpenGl_ShaderManager()
262 myProgramList.Clear();
265 // =======================================================================
268 // =======================================================================
269 void OpenGl_ShaderManager::clear()
271 myProgramList.Clear();
272 myLightPrograms.Nullify();
273 myFlatPrograms = OpenGl_SetOfShaderPrograms();
274 myMapOfLightPrograms.Clear();
275 myFontProgram.Nullify();
276 myBlitProgram.Nullify();
277 for (Standard_Integer aModeIter = 0; aModeIter < Graphic3d_StereoMode_NB; ++aModeIter)
279 myStereoPrograms[aModeIter].Nullify();
281 switchLightPrograms();
284 // =======================================================================
286 // purpose : Creates new shader program
287 // =======================================================================
288 Standard_Boolean OpenGl_ShaderManager::Create (const Handle(Graphic3d_ShaderProgram)& theProxy,
289 TCollection_AsciiString& theShareKey,
290 Handle(OpenGl_ShaderProgram)& theProgram)
292 theProgram.Nullify();
293 if (theProxy.IsNull())
295 return Standard_False;
298 theShareKey = theProxy->GetId();
299 if (myContext->GetResource<Handle(OpenGl_ShaderProgram)> (theShareKey, theProgram))
301 if (theProgram->Share())
303 myProgramList.Append (theProgram);
305 return Standard_True;
308 theProgram = new OpenGl_ShaderProgram (theProxy);
309 if (!theProgram->Initialize (myContext, theProxy->ShaderObjects()))
311 theProgram->Release (myContext);
313 theProgram.Nullify();
314 return Standard_False;
317 myProgramList.Append (theProgram);
318 myContext->ShareResource (theShareKey, theProgram);
319 return Standard_True;
322 // =======================================================================
323 // function : Unregister
324 // purpose : Removes specified shader program from the manager
325 // =======================================================================
326 void OpenGl_ShaderManager::Unregister (TCollection_AsciiString& theShareKey,
327 Handle(OpenGl_ShaderProgram)& theProgram)
329 for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
331 if (anIt.Value() == theProgram)
333 if (!theProgram->UnShare())
336 theProgram.Nullify();
340 myProgramList.Remove (anIt);
341 myMaterialStates.UnBind (theProgram);
346 const TCollection_AsciiString anID = theProgram->myProxy->GetId();
349 myContext->DelayedRelease (theProgram);
350 theProgram.Nullify();
354 theProgram.Nullify();
355 myContext->ReleaseResource (anID, Standard_True);
359 // =======================================================================
360 // function : ShaderPrograms
361 // purpose : Returns list of registered shader programs
362 // =======================================================================
363 const OpenGl_ShaderProgramList& OpenGl_ShaderManager::ShaderPrograms() const
365 return myProgramList;
368 // =======================================================================
370 // purpose : Returns true if no program objects are attached
371 // =======================================================================
372 Standard_Boolean OpenGl_ShaderManager::IsEmpty() const
374 return myProgramList.IsEmpty();
377 // =======================================================================
378 // function : switchLightPrograms
380 // =======================================================================
381 void OpenGl_ShaderManager::switchLightPrograms()
383 TCollection_AsciiString aKey (myShadingModel == Graphic3d_TOSM_FRAGMENT ? "p_" : "g_");
384 const OpenGl_ListOfLight* aLights = myLightSourceState.LightSources();
387 for (OpenGl_ListOfLight::Iterator aLightIter (*aLights); aLightIter.More(); aLightIter.Next())
389 switch (aLightIter.Value().Type)
391 case Graphic3d_TOLS_AMBIENT:
392 break; // skip ambient
393 case Graphic3d_TOLS_DIRECTIONAL:
396 case Graphic3d_TOLS_POSITIONAL:
399 case Graphic3d_TOLS_SPOT:
406 if (!myMapOfLightPrograms.Find (aKey, myLightPrograms))
408 myLightPrograms = new OpenGl_SetOfShaderPrograms();
409 myMapOfLightPrograms.Bind (aKey, myLightPrograms);
413 // =======================================================================
414 // function : UpdateLightSourceStateTo
415 // purpose : Updates state of OCCT light sources
416 // =======================================================================
417 void OpenGl_ShaderManager::UpdateLightSourceStateTo (const OpenGl_ListOfLight* theLights)
419 myLightSourceState.Set (theLights);
420 myLightSourceState.Update();
421 switchLightPrograms();
424 // =======================================================================
425 // function : SetShadingModel
427 // =======================================================================
428 void OpenGl_ShaderManager::SetShadingModel (const Graphic3d_TypeOfShadingModel theModel)
430 myShadingModel = theModel;
431 switchLightPrograms();
434 // =======================================================================
435 // function : SetProjectionState
436 // purpose : Sets new state of OCCT projection transform
437 // =======================================================================
438 void OpenGl_ShaderManager::UpdateProjectionStateTo (const OpenGl_Mat4& theProjectionMatrix)
440 myProjectionState.Set (theProjectionMatrix);
441 myProjectionState.Update();
444 // =======================================================================
445 // function : SetModelWorldState
446 // purpose : Sets new state of OCCT model-world transform
447 // =======================================================================
448 void OpenGl_ShaderManager::UpdateModelWorldStateTo (const OpenGl_Mat4& theModelWorldMatrix)
450 myModelWorldState.Set (theModelWorldMatrix);
451 myModelWorldState.Update();
454 // =======================================================================
455 // function : SetWorldViewState
456 // purpose : Sets new state of OCCT world-view transform
457 // =======================================================================
458 void OpenGl_ShaderManager::UpdateWorldViewStateTo (const OpenGl_Mat4& theWorldViewMatrix)
460 myWorldViewState.Set (theWorldViewMatrix);
461 myWorldViewState.Update();
464 // =======================================================================
465 // function : LightSourceState
466 // purpose : Returns current state of OCCT light sources
467 // =======================================================================
468 const OpenGl_LightSourceState& OpenGl_ShaderManager::LightSourceState() const
470 return myLightSourceState;
473 // =======================================================================
474 // function : ProjectionState
475 // purpose : Returns current state of OCCT projection transform
476 // =======================================================================
477 const OpenGl_ProjectionState& OpenGl_ShaderManager::ProjectionState() const
479 return myProjectionState;
482 // =======================================================================
483 // function : ModelWorldState
484 // purpose : Returns current state of OCCT model-world transform
485 // =======================================================================
486 const OpenGl_ModelWorldState& OpenGl_ShaderManager::ModelWorldState() const
488 return myModelWorldState;
491 // =======================================================================
492 // function : WorldViewState
493 // purpose : Returns current state of OCCT world-view transform
494 // =======================================================================
495 const OpenGl_WorldViewState& OpenGl_ShaderManager::WorldViewState() const
497 return myWorldViewState;
500 //! Packed properties of light source
501 class OpenGl_ShaderLightParameters
506 OpenGl_Vec4 Position;
507 OpenGl_Vec4 Direction;
508 OpenGl_Vec4 Parameters;
510 //! Returns packed (serialized) representation of light source properties
511 const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
512 static Standard_Integer NbOfVec4() { return 4; }
516 //! Packed light source type information
517 class OpenGl_ShaderLightType
521 Standard_Integer Type;
522 Standard_Integer IsHeadlight;
524 //! Returns packed (serialized) representation of light source type
525 const OpenGl_Vec2i* Packed() const { return reinterpret_cast<const OpenGl_Vec2i*> (this); }
526 static Standard_Integer NbOfVec2i() { return 1; }
530 // =======================================================================
531 // function : PushLightSourceState
532 // purpose : Pushes state of OCCT light sources to the program
533 // =======================================================================
534 void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
536 if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE)
537 || !theProgram->IsValid())
542 OpenGl_ShaderLightType* aLightTypeArray = new OpenGl_ShaderLightType[OpenGLMaxLights];
543 for (Standard_Integer aLightIt = 0; aLightIt < OpenGLMaxLights; ++aLightIt)
545 aLightTypeArray[aLightIt].Type = -1;
548 const Standard_Integer aLightsDefNb = Min (myLightSourceState.LightSources()->Size(), OpenGLMaxLights);
549 if (aLightsDefNb < 1)
551 theProgram->SetUniform (myContext,
552 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
554 theProgram->SetUniform (myContext,
555 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT),
556 OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
557 theProgram->SetUniform (myContext,
558 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
559 OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
560 aLightTypeArray[0].Packed());
561 theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
562 delete[] aLightTypeArray;
566 OpenGl_ShaderLightParameters* aLightParamsArray = new OpenGl_ShaderLightParameters[aLightsDefNb];
568 OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f);
569 Standard_Integer aLightsNb = 0;
570 for (OpenGl_ListOfLight::Iterator anIter (*myLightSourceState.LightSources()); anIter.More(); anIter.Next())
572 const OpenGl_Light& aLight = anIter.Value();
573 if (aLight.Type == Graphic3d_TOLS_AMBIENT)
575 anAmbient += aLight.Color;
578 else if (aLightsNb >= OpenGLMaxLights)
583 OpenGl_ShaderLightType& aLightType = aLightTypeArray[aLightsNb];
584 aLightType.Type = aLight.Type;
585 aLightType.IsHeadlight = aLight.IsHeadlight;
587 OpenGl_ShaderLightParameters& aLightParams = aLightParamsArray[aLightsNb];
588 aLightParams.Color = aLight.Color;
589 aLightParams.Position = aLight.Type == Graphic3d_TOLS_DIRECTIONAL
592 if (aLight.Type == Graphic3d_TOLS_SPOT)
594 aLightParams.Direction = aLight.Direction;
596 aLightParams.Parameters = aLight.Params;
600 theProgram->SetUniform (myContext,
601 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
603 theProgram->SetUniform (myContext,
604 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT),
606 theProgram->SetUniform (myContext,
607 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
608 OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
609 aLightTypeArray[0].Packed());
612 theProgram->SetUniform (myContext,
613 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_PARAMS),
614 aLightsNb * OpenGl_ShaderLightParameters::NbOfVec4(),
615 aLightParamsArray[0].Packed());
617 delete[] aLightParamsArray;
618 delete[] aLightTypeArray;
620 theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
623 // =======================================================================
624 // function : PushProjectionState
625 // purpose : Pushes state of OCCT projection transform to the program
626 // =======================================================================
627 void OpenGl_ShaderManager::PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const
629 if (myProjectionState.Index() == theProgram->ActiveState (OpenGl_PROJECTION_STATE))
634 theProgram->SetUniform (myContext,
635 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX),
636 myProjectionState.ProjectionMatrix());
638 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE);
639 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
641 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse());
644 theProgram->SetUniform (myContext,
645 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE),
646 myProjectionState.ProjectionMatrix(), true);
648 aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE);
649 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
651 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse(), true);
654 theProgram->UpdateState (OpenGl_PROJECTION_STATE, myProjectionState.Index());
657 // =======================================================================
658 // function : PushModelWorldState
659 // purpose : Pushes state of OCCT model-world transform to the program
660 // =======================================================================
661 void OpenGl_ShaderManager::PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const
663 if (myModelWorldState.Index() == theProgram->ActiveState (OpenGl_MODEL_WORLD_STATE))
668 theProgram->SetUniform (myContext,
669 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX),
670 myModelWorldState.ModelWorldMatrix());
672 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE);
673 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
675 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse());
678 theProgram->SetUniform (myContext,
679 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE),
680 myModelWorldState.ModelWorldMatrix(), true);
682 aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE);
683 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
685 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse(), true);
688 theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
691 // =======================================================================
692 // function : PushWorldViewState
693 // purpose : Pushes state of OCCT world-view transform to the program
694 // =======================================================================
695 void OpenGl_ShaderManager::PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const
697 if (myWorldViewState.Index() == theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE))
702 theProgram->SetUniform (myContext,
703 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX),
704 myWorldViewState.WorldViewMatrix());
706 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE);
707 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
709 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse());
712 theProgram->SetUniform (myContext,
713 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE),
714 myWorldViewState.WorldViewMatrix(), true);
716 aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE);
717 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
719 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse(), true);
722 theProgram->UpdateState (OpenGl_WORLD_VIEW_STATE, myWorldViewState.Index());
725 // =======================================================================
726 // function : UpdateClippingState
727 // purpose : Updates state of OCCT clipping planes
728 // =======================================================================
729 void OpenGl_ShaderManager::UpdateClippingState()
731 myClippingState.Update();
734 // =======================================================================
735 // function : RevertClippingState
736 // purpose : Reverts state of OCCT clipping planes
737 // =======================================================================
738 void OpenGl_ShaderManager::RevertClippingState()
740 myClippingState.Revert();
743 // =======================================================================
744 // function : PushClippingState
745 // purpose : Pushes state of OCCT clipping planes to the program
746 // =======================================================================
747 void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const
749 if (myClippingState.Index() == theProgram->ActiveState (OpenGl_CLIP_PLANES_STATE))
754 theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index());
755 const GLint aLocEquations = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_EQUATIONS);
756 const GLint aLocSpaces = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_SPACES);
757 if (aLocEquations == OpenGl_ShaderProgram::INVALID_LOCATION
758 && aLocSpaces == OpenGl_ShaderProgram::INVALID_LOCATION)
764 for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
765 anIter.More(); anIter.Next())
767 const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
768 if (!myContext->Clipping().IsEnabled (aPlane))
780 const Standard_Size MAX_CLIP_PLANES = 8;
781 OpenGl_Vec4* anEquations = new OpenGl_Vec4[MAX_CLIP_PLANES];
782 GLint* aSpaces = new GLint [MAX_CLIP_PLANES];
784 for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
785 anIter.More(); anIter.Next())
787 const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
788 if (!myContext->Clipping().IsEnabled (aPlane))
793 const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
794 anEquations[aPlaneId] = OpenGl_Vec4 ((float) anEquation.x(),
795 (float) anEquation.y(),
796 (float) anEquation.z(),
797 (float) anEquation.w());
798 aSpaces[aPlaneId] = myContext->Clipping().GetEquationSpace (aPlane);
802 theProgram->SetUniform (myContext,
803 theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_COUNT),
805 theProgram->SetUniform (myContext, aLocEquations, MAX_CLIP_PLANES, anEquations);
806 theProgram->SetUniform (myContext, aLocSpaces, MAX_CLIP_PLANES, aSpaces);
808 delete[] anEquations;
812 // =======================================================================
813 // function : UpdateMaterialStateTo
814 // purpose : Updates state of OCCT material for specified program
815 // =======================================================================
816 void OpenGl_ShaderManager::UpdateMaterialStateTo (const Handle(OpenGl_ShaderProgram)& theProgram,
817 const OpenGl_Element* theAspect)
819 if (myMaterialStates.IsBound (theProgram))
821 OpenGl_MaterialState& aState = myMaterialStates.ChangeFind (theProgram);
822 aState.Set (theAspect);
827 myMaterialStates.Bind (theProgram, OpenGl_MaterialState (theAspect));
828 myMaterialStates.ChangeFind (theProgram).Update();
832 // =======================================================================
833 // function : ResetMaterialStates
834 // purpose : Resets state of OCCT material for all programs
835 // =======================================================================
836 void OpenGl_ShaderManager::ResetMaterialStates()
838 for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
840 anIt.Value()->UpdateState (OpenGl_MATERIALS_STATE, 0);
844 // =======================================================================
845 // function : MaterialState
846 // purpose : Returns state of OCCT material for specified program
847 // =======================================================================
848 const OpenGl_MaterialState* OpenGl_ShaderManager::MaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
850 if (!myMaterialStates.IsBound (theProgram))
853 return &myMaterialStates.Find (theProgram);
856 // =======================================================================
857 // function : SurfaceDetailState
858 // purpose : Returns current state of OCCT surface detail
859 // =======================================================================
860 const OpenGl_SurfaceDetailState& OpenGl_ShaderManager::SurfaceDetailState() const
862 return mySurfaceDetailState;
865 // =======================================================================
866 // function : UpdateSurfaceDetailStateTo
867 // purpose : Updates state of OCCT surface detail
868 // =======================================================================
869 void OpenGl_ShaderManager::UpdateSurfaceDetailStateTo (const Graphic3d_TypeOfSurfaceDetail theDetail)
871 mySurfaceDetailState.Set (theDetail);
872 mySurfaceDetailState.Update();
878 static const OpenGl_Vec4 THE_COLOR_BLACK_VEC4 (0.0f, 0.0f, 0.0f, 0.0f);
880 // =======================================================================
881 // function : PushAspectFace
883 // =======================================================================
884 static void PushAspectFace (const Handle(OpenGl_Context)& theCtx,
885 const Handle(OpenGl_ShaderProgram)& theProgram,
886 const OpenGl_AspectFace* theAspect)
888 theProgram->SetUniform (theCtx,
889 theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),
890 theAspect->DoTextureMap());
891 theProgram->SetUniform (theCtx,
892 theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER),
893 0 /* GL_TEXTURE0 */);
894 theProgram->SetUniform (theCtx,
895 theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
896 theAspect->DistinguishingMode());
898 OpenGl_Material aParams;
899 for (Standard_Integer anIndex = 0; anIndex < 2; ++anIndex)
901 const GLint aLoc = theProgram->GetStateLocation (anIndex == 0
902 ? OpenGl_OCCT_FRONT_MATERIAL
903 : OpenGl_OCCT_BACK_MATERIAL);
904 if (aLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
909 const OPENGL_SURF_PROP& aProp = anIndex == 0 || theAspect->DistinguishingMode() != TOn
910 ? theAspect->IntFront()
911 : theAspect->IntBack();
912 aParams.Init (aProp);
913 aParams.Diffuse.a() = aProp.trans;
914 theProgram->SetUniform (theCtx, aLoc, OpenGl_Material::NbOfVec4(),
919 // =======================================================================
920 // function : PushAspectLine
922 // =======================================================================
923 static void PushAspectLine (const Handle(OpenGl_Context)& theCtx,
924 const Handle(OpenGl_ShaderProgram)& theProgram,
925 const OpenGl_AspectLine* theAspect)
927 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOff);
928 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
930 const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
931 theAspect->Color().rgb[1],
932 theAspect->Color().rgb[2],
933 theAspect->Color().rgb[3]);
934 OpenGl_Vec4 aParams[5];
935 aParams[0] = THE_COLOR_BLACK_VEC4;
936 aParams[1] = THE_COLOR_BLACK_VEC4;
937 aParams[2] = aDiffuse;
938 aParams[3] = THE_COLOR_BLACK_VEC4;
939 aParams[4].x() = 0.0f; // shininess
940 aParams[4].y() = 0.0f; // transparency
941 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
945 // =======================================================================
946 // function : PushAspectText
948 // =======================================================================
949 static void PushAspectText (const Handle(OpenGl_Context)& theCtx,
950 const Handle(OpenGl_ShaderProgram)& theProgram,
951 const OpenGl_AspectText* theAspect)
953 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn);
954 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
955 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */);
957 OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
958 theAspect->Color().rgb[1],
959 theAspect->Color().rgb[2],
960 theAspect->Color().rgb[3]);
961 if (theAspect->DisplayType() == Aspect_TODT_DEKALE
962 || theAspect->DisplayType() == Aspect_TODT_SUBTITLE)
964 aDiffuse = OpenGl_Vec4 (theAspect->SubtitleColor().rgb[0],
965 theAspect->SubtitleColor().rgb[1],
966 theAspect->SubtitleColor().rgb[2],
967 theAspect->SubtitleColor().rgb[3]);
970 OpenGl_Vec4 aParams[5];
971 aParams[0] = THE_COLOR_BLACK_VEC4;
972 aParams[1] = THE_COLOR_BLACK_VEC4;
973 aParams[2] = aDiffuse;
974 aParams[3] = THE_COLOR_BLACK_VEC4;
975 aParams[4].x() = 0.0f; // shininess
976 aParams[4].y() = 0.0f; // transparency
977 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
981 // =======================================================================
982 // function : PushAspectMarker
984 // =======================================================================
985 static void PushAspectMarker (const Handle(OpenGl_Context)& theCtx,
986 const Handle(OpenGl_ShaderProgram)& theProgram,
987 const OpenGl_AspectMarker* theAspect)
989 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn);
990 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
991 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */);
993 const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
994 theAspect->Color().rgb[1],
995 theAspect->Color().rgb[2],
996 theAspect->Color().rgb[3]);
997 OpenGl_Vec4 aParams[5];
998 aParams[0] = THE_COLOR_BLACK_VEC4;
999 aParams[1] = THE_COLOR_BLACK_VEC4;
1000 aParams[2] = aDiffuse;
1001 aParams[3] = THE_COLOR_BLACK_VEC4;
1002 aParams[4].x() = 0.0f; // shininess
1003 aParams[4].y() = 0.0f; // transparency
1004 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
1008 } // nameless namespace
1010 // =======================================================================
1011 // function : PushMaterialState
1012 // purpose : Pushes current state of OCCT material to the program
1013 // =======================================================================
1014 void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
1016 if (!myMaterialStates.IsBound (theProgram))
1021 const OpenGl_MaterialState& aState = myMaterialStates.Find (theProgram);
1022 if (aState.Index() == theProgram->ActiveState (OpenGl_MATERIALS_STATE))
1027 const OpenGl_Element* anAspect = aState.Aspect();
1028 if (typeid (*anAspect) == typeid (OpenGl_AspectFace))
1030 PushAspectFace (myContext, theProgram, dynamic_cast<const OpenGl_AspectFace*> (anAspect));
1032 else if (typeid (*anAspect) == typeid (OpenGl_AspectLine))
1034 PushAspectLine (myContext, theProgram, dynamic_cast<const OpenGl_AspectLine*> (anAspect));
1036 else if (typeid (*anAspect) == typeid (OpenGl_AspectText))
1038 PushAspectText (myContext, theProgram, dynamic_cast<const OpenGl_AspectText*> (anAspect));
1040 else if (typeid (*anAspect) == typeid (OpenGl_AspectMarker))
1042 PushAspectMarker (myContext, theProgram, dynamic_cast<const OpenGl_AspectMarker*> (anAspect));
1045 theProgram->UpdateState (OpenGl_MATERIALS_STATE, aState.Index());
1048 // =======================================================================
1049 // function : PushState
1050 // purpose : Pushes state of OCCT graphics parameters to the program
1051 // =======================================================================
1052 void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const
1054 PushClippingState (theProgram);
1055 PushMaterialState (theProgram);
1056 PushWorldViewState (theProgram);
1057 PushModelWorldState (theProgram);
1058 PushProjectionState (theProgram);
1059 PushLightSourceState (theProgram);
1062 // =======================================================================
1063 // function : prepareStdProgramFont
1065 // =======================================================================
1066 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFont()
1068 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1069 TCollection_AsciiString aSrcVert = TCollection_AsciiString()
1070 + EOL"THE_SHADER_OUT vec2 TexCoord;"
1073 EOL" TexCoord = occTexCoord.st;"
1074 EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1077 TCollection_AsciiString
1078 aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, TexCoord.st).a; }";
1079 #if !defined(GL_ES_VERSION_2_0)
1080 if (myContext->core11 == NULL)
1082 aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, TexCoord.st).r; }";
1086 TCollection_AsciiString aSrcFrag = TCollection_AsciiString() +
1087 + EOL"THE_SHADER_IN vec2 TexCoord;"
1091 EOL" vec4 aColor = occColor;"
1092 EOL" aColor.a *= getAlpha();"
1093 EOL" if (aColor.a <= 0.285) discard;"
1094 EOL" occFragColor = aColor;"
1097 #if !defined(GL_ES_VERSION_2_0)
1098 if (myContext->core32 != NULL)
1100 aProgramSrc->SetHeader ("#version 150");
1103 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1104 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1105 TCollection_AsciiString aKey;
1106 if (!Create (aProgramSrc, aKey, myFontProgram))
1108 myFontProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1109 return Standard_False;
1111 return Standard_True;
1114 // =======================================================================
1115 // function : prepareStdProgramFboBlit
1117 // =======================================================================
1118 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFboBlit()
1120 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1121 TCollection_AsciiString aSrcVert =
1122 EOL"THE_SHADER_OUT vec2 TexCoord;"
1125 EOL" TexCoord = occVertex.zw;"
1126 EOL" gl_Position = vec4(occVertex.x, occVertex.y, 0.0, 1.0);"
1129 TCollection_AsciiString aSrcFrag =
1130 EOL"uniform sampler2D uColorSampler;"
1131 EOL"uniform sampler2D uDepthSampler;"
1133 EOL"THE_SHADER_IN vec2 TexCoord;"
1137 EOL" gl_FragDepth = occTexture2D (uDepthSampler, TexCoord).r;"
1138 EOL" occFragColor = occTexture2D (uColorSampler, TexCoord);"
1141 #if defined(GL_ES_VERSION_2_0)
1142 if (myContext->IsGlGreaterEqual (3, 0))
1144 aProgramSrc->SetHeader ("#version 300 es");
1148 // there is no way to draw into depth buffer
1150 EOL"uniform sampler2D uColorSampler;"
1152 EOL"THE_SHADER_IN vec2 TexCoord;"
1156 EOL" occFragColor = occTexture2D (uColorSampler, TexCoord);"
1160 if (myContext->core32 != NULL)
1162 aProgramSrc->SetHeader ("#version 150");
1165 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1166 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1167 TCollection_AsciiString aKey;
1168 if (!Create (aProgramSrc, aKey, myBlitProgram))
1170 myBlitProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1171 return Standard_False;
1174 myContext->BindProgram (myBlitProgram);
1175 myBlitProgram->SetSampler (myContext, "uColorSampler", 0);
1176 myBlitProgram->SetSampler (myContext, "uDepthSampler", 1);
1177 myContext->BindProgram (NULL);
1178 return Standard_True;
1181 // =======================================================================
1182 // function : prepareStdProgramFlat
1184 // =======================================================================
1185 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_ShaderProgram)& theProgram,
1186 const Standard_Integer theBits)
1188 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1189 TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcVertExtraFunc, aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain;
1190 TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return occColor; }";
1191 TCollection_AsciiString aSrcFragMainGetColor = EOL" occFragColor = getColor();";
1192 if ((theBits & OpenGl_PO_Point) != 0)
1194 #if defined(GL_ES_VERSION_2_0)
1195 aSrcVertExtraMain += EOL" gl_PointSize = occPointSize;";
1197 if ((theBits & OpenGl_PO_TextureA) != 0)
1199 TCollection_AsciiString
1200 aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, gl_PointCoord).a; }";
1201 #if !defined(GL_ES_VERSION_2_0)
1202 if (myContext->core11 == NULL)
1204 aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, gl_PointCoord).r; }";
1206 else if (myContext->IsGlGreaterEqual (2, 1))
1208 aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
1212 aSrcFragGetColor = aSrcGetAlpha
1213 + EOL"vec4 getColor(void)"
1215 EOL" vec4 aColor = occColor;"
1216 EOL" aColor.a *= getAlpha();"
1217 EOL" return aColor;"
1220 aSrcFragMainGetColor =
1221 EOL" vec4 aColor = getColor();"
1222 EOL" if (aColor.a <= 0.1) discard;"
1223 EOL" occFragColor = aColor;";
1225 else if ((theBits & OpenGl_PO_TextureRGB) != 0)
1228 EOL"vec4 getColor(void) { return occTexture2D(occActiveSampler, gl_PointCoord); }";
1229 aSrcFragMainGetColor =
1230 EOL" vec4 aColor = getColor();"
1231 EOL" if (aColor.a <= 0.1) discard;"
1232 EOL" occFragColor = aColor;";
1233 #if !defined(GL_ES_VERSION_2_0)
1234 if (myContext->core11 != NULL
1235 && myContext->IsGlGreaterEqual (2, 1))
1237 aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
1244 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1246 aSrcVertExtraOut += THE_VARY_TexCoord_OUT;
1247 aSrcFragExtraOut += THE_VARY_TexCoord_IN;
1248 aSrcVertExtraMain += THE_VARY_TexCoord_Trsf;
1251 EOL"vec4 getColor(void) { return occTexture2D(occActiveSampler, TexCoord.st / TexCoord.w); }";
1253 else if ((theBits & OpenGl_PO_TextureEnv) != 0)
1255 aSrcVertExtraOut += THE_VARY_TexCoord_OUT;
1256 aSrcFragExtraOut += THE_VARY_TexCoord_IN;
1258 aSrcVertExtraFunc = THE_FUNC_transformNormal;
1260 aSrcVertExtraMain +=
1261 EOL" vec4 aPosition = occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1262 EOL" vec3 aNormal = transformNormal (occNormal);"
1263 EOL" vec3 aReflect = reflect (normalize (aPosition.xyz), aNormal);"
1264 EOL" aReflect.z += 1.0;"
1265 EOL" TexCoord = vec4(aReflect.xy * inversesqrt (dot (aReflect, aReflect)) * 0.5 + vec2 (0.5), 0.0, 1.0);";
1268 EOL"vec4 getColor(void) { return occTexture2D (occActiveSampler, TexCoord.st); }";
1271 if ((theBits & OpenGl_PO_VertColor) != 0)
1273 aSrcVertExtraOut += EOL"THE_SHADER_OUT vec4 VertColor;";
1274 aSrcVertExtraMain += EOL" VertColor = occVertColor;";
1275 aSrcFragExtraOut += EOL"THE_SHADER_IN vec4 VertColor;";
1276 aSrcFragGetColor = EOL"vec4 getColor(void) { return VertColor; }";
1278 if ((theBits & OpenGl_PO_ClipPlanes) != 0)
1281 EOL"THE_SHADER_OUT vec4 PositionWorld;"
1282 EOL"THE_SHADER_OUT vec4 Position;";
1284 EOL"THE_SHADER_IN vec4 PositionWorld;"
1285 EOL"THE_SHADER_IN vec4 Position;";
1286 aSrcVertExtraMain +=
1287 EOL" PositionWorld = occModelWorldMatrix * occVertex;"
1288 EOL" Position = occWorldViewMatrix * PositionWorld;";
1289 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES;
1292 TCollection_AsciiString aSrcVertEndMain;
1293 if ((theBits & OpenGl_PO_StippleLine) != 0)
1295 bool hasGlslBitOps = false;
1296 #if defined(GL_ES_VERSION_2_0)
1297 if (myContext->IsGlGreaterEqual (3, 0))
1299 aProgramSrc->SetHeader ("#version 300 es");
1300 hasGlslBitOps = true;
1303 if (myContext->IsGlGreaterEqual (3, 0))
1305 aProgramSrc->SetHeader ("#version 130");
1306 hasGlslBitOps = true;
1308 else if(myContext->CheckExtension("GL_EXT_gpu_shader4"))
1310 aProgramSrc->SetHeader ("#extension GL_EXT_gpu_shader4 : enable");
1311 hasGlslBitOps = true;
1318 EOL"THE_SHADER_OUT vec2 ScreenSpaceCoord;";
1320 EOL"THE_SHADER_IN vec2 ScreenSpaceCoord;"
1321 EOL"uniform int uPattern;"
1322 EOL"uniform float uFactor;";
1324 EOL" ScreenSpaceCoord = gl_Position.xy / gl_Position.w;";
1325 aSrcFragMainGetColor =
1326 EOL" float anAngle = atan (dFdx (ScreenSpaceCoord.x), dFdy (ScreenSpaceCoord.y));"
1327 EOL" float aRotatePoint = gl_FragCoord.x * sin (anAngle) + gl_FragCoord.y * cos (anAngle);"
1328 EOL" uint aBit = uint (floor (aRotatePoint / uFactor + 0.5)) & 15U;"
1329 EOL" if ((uint (uPattern) & (1U << aBit)) == 0U) discard;"
1330 EOL" vec4 aColor = getColor();"
1331 EOL" if (aColor.a <= 0.1) discard;"
1332 EOL" occFragColor = aColor;";
1336 const TCollection_ExtendedString aWarnMessage =
1337 "Warning: stipple lines in GLSL will be ignored.";
1338 myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
1339 GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage);
1349 + EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1359 + aSrcFragMainGetColor
1362 #if !defined(GL_ES_VERSION_2_0)
1363 if (myContext->core32 != NULL)
1365 aProgramSrc->SetHeader ("#version 150");
1368 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1369 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1371 TCollection_AsciiString aKey;
1372 if (!Create (aProgramSrc, aKey, theProgram))
1374 theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1375 return Standard_False;
1377 return Standard_True;
1380 // =======================================================================
1381 // function : stdComputeLighting
1383 // =======================================================================
1384 TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (const Standard_Boolean theHasVertColor)
1386 Standard_Integer aLightsMap[Graphic3d_TOLS_SPOT + 1] = { 0, 0, 0, 0 };
1387 TCollection_AsciiString aLightsFunc, aLightsLoop;
1388 const OpenGl_ListOfLight* aLights = myLightSourceState.LightSources();
1389 if (aLights != NULL)
1391 Standard_Integer anIndex = 0;
1392 for (OpenGl_ListOfLight::Iterator aLightIter (*aLights); aLightIter.More(); aLightIter.Next(), ++anIndex)
1394 switch (aLightIter.Value().Type)
1396 case Graphic3d_TOLS_AMBIENT:
1398 break; // skip ambient
1399 case Graphic3d_TOLS_DIRECTIONAL:
1400 aLightsLoop = aLightsLoop + EOL" directionalLight (" + anIndex + ", theNormal, theView, theIsFront);";
1402 case Graphic3d_TOLS_POSITIONAL:
1403 aLightsLoop = aLightsLoop + EOL" pointLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);";
1405 case Graphic3d_TOLS_SPOT:
1406 aLightsLoop = aLightsLoop + EOL" spotLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);";
1409 aLightsMap[aLightIter.Value().Type] += 1;
1411 const Standard_Integer aNbLoopLights = aLightsMap[Graphic3d_TOLS_DIRECTIONAL]
1412 + aLightsMap[Graphic3d_TOLS_POSITIONAL]
1413 + aLightsMap[Graphic3d_TOLS_SPOT];
1414 if (aLightsMap[Graphic3d_TOLS_DIRECTIONAL] == 1
1415 && aNbLoopLights == 1)
1417 // use the version with hard-coded first index
1418 aLightsLoop = EOL" directionalLightFirst(theNormal, theView, theIsFront);";
1419 aLightsFunc += THE_FUNC_directionalLightFirst;
1421 else if (aLightsMap[Graphic3d_TOLS_DIRECTIONAL] > 0)
1423 aLightsFunc += THE_FUNC_directionalLight;
1425 if (aLightsMap[Graphic3d_TOLS_POSITIONAL] > 0)
1427 aLightsFunc += THE_FUNC_pointLight;
1429 if (aLightsMap[Graphic3d_TOLS_SPOT] > 0)
1431 aLightsFunc += THE_FUNC_spotLight;
1435 TCollection_AsciiString aGetMatAmbient = "theIsFront ? occFrontMaterial_Ambient() : occBackMaterial_Ambient();";
1436 TCollection_AsciiString aGetMatDiffuse = "theIsFront ? occFrontMaterial_Diffuse() : occBackMaterial_Diffuse();";
1437 if (theHasVertColor)
1439 aGetMatAmbient = "getVertColor();";
1440 aGetMatDiffuse = "getVertColor();";
1443 return TCollection_AsciiString()
1447 EOL"vec4 computeLighting (in vec3 theNormal,"
1448 EOL" in vec3 theView,"
1449 EOL" in vec4 thePoint,"
1450 EOL" in bool theIsFront)"
1452 EOL" Ambient = occLightAmbient.rgb;"
1453 EOL" Diffuse = vec3 (0.0);"
1454 EOL" Specular = vec3 (0.0);"
1455 EOL" vec3 aPoint = thePoint.xyz / thePoint.w;"
1457 + EOL" vec4 aMatAmbient = " + aGetMatAmbient
1458 + EOL" vec4 aMatDiffuse = " + aGetMatDiffuse
1459 + EOL" vec4 aMatSpecular = theIsFront ? occFrontMaterial_Specular() : occBackMaterial_Specular();"
1460 EOL" vec4 aMatEmission = theIsFront ? occFrontMaterial_Emission() : occBackMaterial_Emission();"
1461 EOL" vec3 aColor = Ambient * aMatAmbient.rgb"
1462 EOL" + Diffuse * aMatDiffuse.rgb"
1463 EOL" + Specular * aMatSpecular.rgb"
1464 EOL" + aMatEmission.rgb;"
1465 EOL" return vec4 (aColor, aMatDiffuse.a);"
1469 // =======================================================================
1470 // function : prepareStdProgramGouraud
1472 // =======================================================================
1473 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_ShaderProgram)& theProgram,
1474 const Standard_Integer theBits)
1476 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1477 TCollection_AsciiString aSrcVert, aSrcVertColor, aSrcVertExtraOut, aSrcVertExtraMain, aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain;
1478 TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return gl_FrontFacing ? FrontColor : BackColor; }";
1479 if ((theBits & OpenGl_PO_Point) != 0)
1481 #if defined(GL_ES_VERSION_2_0)
1482 aSrcVertExtraMain += EOL" gl_PointSize = occPointSize;";
1485 if ((theBits & OpenGl_PO_VertColor) != 0)
1487 aSrcVertColor = EOL"vec4 getVertColor(void) { return occVertColor; }";
1489 if ((theBits & OpenGl_PO_Point) != 0)
1491 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1494 EOL"vec4 getColor(void)"
1496 EOL" vec4 aColor = gl_FrontFacing ? FrontColor : BackColor;"
1497 EOL" return occTexture2D(occActiveSampler, gl_PointCoord) * aColor;"
1499 #if !defined(GL_ES_VERSION_2_0)
1500 if (myContext->core11 != NULL
1501 && myContext->IsGlGreaterEqual (2, 1))
1503 aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
1510 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1512 aSrcVertExtraOut += THE_VARY_TexCoord_OUT;
1513 aSrcFragExtraOut += THE_VARY_TexCoord_IN;
1514 aSrcVertExtraMain += THE_VARY_TexCoord_Trsf;
1517 EOL"vec4 getColor(void)"
1519 EOL" vec4 aColor = gl_FrontFacing ? FrontColor : BackColor;"
1520 EOL" return occTexture2D(occActiveSampler, TexCoord.st / TexCoord.w) * aColor;"
1524 if ((theBits & OpenGl_PO_ClipPlanes) != 0)
1527 EOL"THE_SHADER_OUT vec4 PositionWorld;"
1528 EOL"THE_SHADER_OUT vec4 Position;";
1530 EOL"THE_SHADER_IN vec4 PositionWorld;"
1531 EOL"THE_SHADER_IN vec4 Position;";
1532 aSrcVertExtraMain +=
1533 EOL" PositionWorld = aPositionWorld;"
1534 EOL" Position = aPosition;";
1535 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES;
1538 const TCollection_AsciiString aLights = stdComputeLighting ((theBits & OpenGl_PO_VertColor) != 0);
1539 aSrcVert = TCollection_AsciiString()
1540 + THE_FUNC_transformNormal
1545 EOL"THE_SHADER_OUT vec4 FrontColor;"
1546 EOL"THE_SHADER_OUT vec4 BackColor;"
1551 EOL" vec4 aPositionWorld = occModelWorldMatrix * occVertex;"
1552 EOL" vec4 aPosition = occWorldViewMatrix * aPositionWorld;"
1553 EOL" vec3 aNormal = transformNormal (occNormal);"
1554 EOL" vec3 aView = vec3 (0.0, 0.0, 1.0);"
1555 EOL" FrontColor = computeLighting (normalize (aNormal), normalize (aView), aPosition, true);"
1556 EOL" BackColor = computeLighting (normalize (aNormal), normalize (aView), aPosition, false);"
1558 + EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1561 aSrcFrag = TCollection_AsciiString()
1562 + EOL"THE_SHADER_IN vec4 FrontColor;"
1563 EOL"THE_SHADER_IN vec4 BackColor;"
1569 + EOL" occFragColor = getColor();"
1572 #if !defined(GL_ES_VERSION_2_0)
1573 if (myContext->core32 != NULL)
1575 aProgramSrc->SetHeader ("#version 150");
1578 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1579 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1580 TCollection_AsciiString aKey;
1581 if (!Create (aProgramSrc, aKey, theProgram))
1583 theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1584 return Standard_False;
1586 return Standard_True;
1589 // =======================================================================
1590 // function : prepareStdProgramPhong
1592 // =======================================================================
1593 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram,
1594 const Standard_Integer theBits)
1596 #define thePhongCompLight "computeLighting (normalize (Normal), normalize (View), Position, gl_FrontFacing)"
1598 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1599 TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcFrag, aSrcFragExtraOut, aSrcFragGetVertColor, aSrcFragExtraMain;
1600 TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return " thePhongCompLight "; }";
1601 if ((theBits & OpenGl_PO_Point) != 0)
1603 #if defined(GL_ES_VERSION_2_0)
1604 aSrcVertExtraMain += EOL" gl_PointSize = occPointSize;";
1607 if ((theBits & OpenGl_PO_VertColor) != 0)
1609 aSrcVertExtraOut += EOL"THE_SHADER_OUT vec4 VertColor;";
1610 aSrcVertExtraMain += EOL" VertColor = occVertColor;";
1611 aSrcFragGetVertColor = EOL"THE_SHADER_IN vec4 VertColor;"
1612 EOL"vec4 getVertColor(void) { return VertColor; }";
1615 if ((theBits & OpenGl_PO_Point) != 0)
1617 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1620 EOL"vec4 getColor(void)"
1622 EOL" vec4 aColor = " thePhongCompLight ";"
1623 EOL" return occTexture2D(occActiveSampler, gl_PointCoord) * aColor;"
1625 #if !defined(GL_ES_VERSION_2_0)
1626 if (myContext->core11 != NULL
1627 && myContext->IsGlGreaterEqual (2, 1))
1629 aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
1636 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1638 aSrcVertExtraOut += THE_VARY_TexCoord_OUT;
1639 aSrcFragExtraOut += THE_VARY_TexCoord_IN;
1640 aSrcVertExtraMain += THE_VARY_TexCoord_Trsf;
1643 EOL"vec4 getColor(void)"
1645 EOL" vec4 aColor = " thePhongCompLight ";"
1646 EOL" return occTexture2D(occActiveSampler, TexCoord.st / TexCoord.w) * aColor;"
1651 if ((theBits & OpenGl_PO_ClipPlanes) != 0)
1653 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES;
1656 aSrcVert = TCollection_AsciiString()
1657 + THE_FUNC_transformNormal
1659 EOL"THE_SHADER_OUT vec4 PositionWorld;"
1660 EOL"THE_SHADER_OUT vec4 Position;"
1661 EOL"THE_SHADER_OUT vec3 Normal;"
1662 EOL"THE_SHADER_OUT vec3 View;"
1667 EOL" PositionWorld = occModelWorldMatrix * occVertex;"
1668 EOL" Position = occWorldViewMatrix * PositionWorld;"
1669 EOL" Normal = transformNormal (occNormal);"
1670 EOL" View = vec3 (0.0, 0.0, 1.0);"
1672 + EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1675 const TCollection_AsciiString aLights = stdComputeLighting ((theBits & OpenGl_PO_VertColor) != 0);
1676 aSrcFrag = TCollection_AsciiString()
1677 + EOL"THE_SHADER_IN vec4 PositionWorld;"
1678 EOL"THE_SHADER_IN vec4 Position;"
1679 EOL"THE_SHADER_IN vec3 Normal;"
1680 EOL"THE_SHADER_IN vec3 View;"
1683 + aSrcFragGetVertColor
1690 + EOL" occFragColor = getColor();"
1693 #if !defined(GL_ES_VERSION_2_0)
1694 if (myContext->core32 != NULL)
1696 aProgramSrc->SetHeader ("#version 150");
1699 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1700 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1701 TCollection_AsciiString aKey;
1702 if (!Create (aProgramSrc, aKey, theProgram))
1704 theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1705 return Standard_False;
1707 return Standard_True;
1710 // =======================================================================
1711 // function : prepareStdProgramStereo
1713 // =======================================================================
1714 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_ShaderProgram)& theProgram,
1715 const Graphic3d_StereoMode theStereoMode)
1717 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1718 TCollection_AsciiString aSrcVert =
1719 EOL"THE_SHADER_OUT vec2 TexCoord;"
1722 EOL" TexCoord = occVertex.zw;"
1723 EOL" gl_Position = vec4(occVertex.x, occVertex.y, 0.0, 1.0);"
1726 TCollection_AsciiString aSrcFrag;
1727 switch (theStereoMode)
1729 case Graphic3d_StereoMode_Anaglyph:
1732 EOL"uniform sampler2D uLeftSampler;"
1733 EOL"uniform sampler2D uRightSampler;"
1735 EOL"uniform mat4 uMultL;"
1736 EOL"uniform mat4 uMultR;"
1738 EOL"vec4 THE_POW_UP = vec4 (2.2, 2.2, 2.2, 1.0);"
1739 EOL"vec4 THE_POW_DOWN = 1.0 / THE_POW_UP;"
1741 EOL"THE_SHADER_IN vec2 TexCoord;"
1745 EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
1746 EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
1747 EOL" aColorL = pow (aColorL, THE_POW_UP);" // normalize
1748 EOL" aColorR = pow (aColorR, THE_POW_UP);"
1749 EOL" vec4 aColor = uMultR * aColorR + uMultL * aColorL;"
1750 EOL" occFragColor = pow (aColor, THE_POW_DOWN);"
1754 case Graphic3d_StereoMode_RowInterlaced:
1757 EOL"uniform sampler2D uLeftSampler;"
1758 EOL"uniform sampler2D uRightSampler;"
1760 EOL"THE_SHADER_IN vec2 TexCoord;"
1764 EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
1765 EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
1766 EOL" if (int (mod (gl_FragCoord.y - 1023.5, 2.0)) != 1)"
1768 EOL" occFragColor = aColorL;"
1772 EOL" occFragColor = aColorR;"
1777 case Graphic3d_StereoMode_ColumnInterlaced:
1780 EOL"uniform sampler2D uLeftSampler;"
1781 EOL"uniform sampler2D uRightSampler;"
1783 EOL"THE_SHADER_IN vec2 TexCoord;"
1787 EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
1788 EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
1789 EOL" if (int (mod (gl_FragCoord.x - 1023.5, 2.0)) == 1)"
1791 EOL" occFragColor = aColorL;"
1795 EOL" occFragColor = aColorR;"
1800 case Graphic3d_StereoMode_ChessBoard:
1803 EOL"uniform sampler2D uLeftSampler;"
1804 EOL"uniform sampler2D uRightSampler;"
1806 EOL"THE_SHADER_IN vec2 TexCoord;"
1810 EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
1811 EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
1812 EOL" bool isEvenX = int(mod(floor(gl_FragCoord.x - 1023.5), 2.0)) != 1;"
1813 EOL" bool isEvenY = int(mod(floor(gl_FragCoord.y - 1023.5), 2.0)) == 1;"
1814 EOL" if ((isEvenX && isEvenY) || (!isEvenX && !isEvenY))"
1816 EOL" occFragColor = aColorL;"
1820 EOL" occFragColor = aColorR;"
1825 case Graphic3d_StereoMode_SideBySide:
1828 EOL"uniform sampler2D uLeftSampler;"
1829 EOL"uniform sampler2D uRightSampler;"
1831 EOL"THE_SHADER_IN vec2 TexCoord;"
1835 EOL" vec2 aTexCoord = vec2 (TexCoord.x * 2.0, TexCoord.y);"
1836 EOL" if (TexCoord.x > 0.5)"
1838 EOL" aTexCoord.x -= 1.0;"
1840 EOL" vec4 aColorL = occTexture2D (uLeftSampler, aTexCoord);"
1841 EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoord);"
1842 EOL" if (TexCoord.x <= 0.5)"
1844 EOL" occFragColor = aColorL;"
1848 EOL" occFragColor = aColorR;"
1853 case Graphic3d_StereoMode_OverUnder:
1856 EOL"uniform sampler2D uLeftSampler;"
1857 EOL"uniform sampler2D uRightSampler;"
1859 EOL"THE_SHADER_IN vec2 TexCoord;"
1863 EOL" vec2 aTexCoord = vec2 (TexCoord.x, TexCoord.y * 2.0);"
1864 EOL" if (TexCoord.y > 0.5)"
1866 EOL" aTexCoord.y -= 1.0;"
1868 EOL" vec4 aColorL = occTexture2D (uLeftSampler, aTexCoord);"
1869 EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoord);"
1870 EOL" if (TexCoord.y <= 0.5)"
1872 EOL" occFragColor = aColorL;"
1876 EOL" occFragColor = aColorR;"
1881 case Graphic3d_StereoMode_QuadBuffer:
1882 case Graphic3d_StereoMode_SoftPageFlip:
1885 /*const Handle(OpenGl_ShaderProgram)& aProgram = myStereoPrograms[Graphic3d_StereoMode_QuadBuffer];
1886 if (!aProgram.IsNull())
1888 return aProgram->IsValid();
1891 EOL"uniform sampler2D uLeftSampler;"
1892 EOL"uniform sampler2D uRightSampler;"
1894 EOL"THE_SHADER_IN vec2 TexCoord;"
1898 EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
1899 EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
1900 EOL" aColorL.b = 0.0;"
1901 EOL" aColorL.g = 0.0;"
1902 EOL" aColorR.r = 0.0;"
1903 EOL" occFragColor = aColorL + aColorR;"
1909 #if !defined(GL_ES_VERSION_2_0)
1910 if (myContext->core32 != NULL)
1912 aProgramSrc->SetHeader ("#version 150");
1916 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1917 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1918 TCollection_AsciiString aKey;
1919 if (!Create (aProgramSrc, aKey, theProgram))
1921 theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1922 return Standard_False;
1925 myContext->BindProgram (theProgram);
1926 theProgram->SetSampler (myContext, "uLeftSampler", 0);
1927 theProgram->SetSampler (myContext, "uRightSampler", 1);
1928 myContext->BindProgram (NULL);
1929 return Standard_True;
1932 // =======================================================================
1933 // function : bindProgramWithState
1935 // =======================================================================
1936 Standard_Boolean OpenGl_ShaderManager::bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram,
1937 const OpenGl_Element* theAspect)
1939 if (!myContext->BindProgram (theProgram))
1941 return Standard_False;
1943 theProgram->ApplyVariables (myContext);
1945 const OpenGl_MaterialState* aMaterialState = MaterialState (theProgram);
1946 if (aMaterialState == NULL || aMaterialState->Aspect() != theAspect)
1948 UpdateMaterialStateTo (theProgram, theAspect);
1951 PushState (theProgram);
1952 return Standard_True;