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>
31 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager,Standard_Transient)
36 //! Clipping planes limit (see the same definition in Declarations.glsl).
37 static const Standard_Size THE_MAX_CLIP_PLANES = 8;
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 flip gl_PointCoord vertically
57 #define THE_VEC2_glPointCoord "vec2 (gl_PointCoord.x, 1.0 - gl_PointCoord.y)"
59 //! Auxiliary function to transform normal
60 const char THE_FUNC_transformNormal[] =
61 EOL"vec3 transformNormal (in vec3 theNormal)"
63 EOL" vec4 aResult = occWorldViewMatrixInverseTranspose"
64 EOL" * occModelWorldMatrixInverseTranspose"
65 EOL" * vec4 (theNormal, 0.0);"
66 EOL" return normalize (aResult.xyz);"
69 //! Global shader variable for color definition with lighting enabled.
70 const char THE_FUNC_lightDef[] =
71 EOL"vec3 Ambient;" //!< Ambient contribution of light sources
72 EOL"vec3 Diffuse;" //!< Diffuse contribution of light sources
73 EOL"vec3 Specular;"; //!< Specular contribution of light sources
75 //! Function computes contribution of isotropic point light source
76 const char THE_FUNC_pointLight[] =
77 EOL"void pointLight (in int theId,"
78 EOL" in vec3 theNormal,"
79 EOL" in vec3 theView,"
80 EOL" in vec3 thePoint,"
81 EOL" in bool theIsFront)"
83 EOL" vec3 aLight = occLight_Position (theId).xyz;"
84 EOL" if (occLight_IsHeadlight (theId) == 0)"
86 EOL" aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0));"
88 EOL" aLight -= thePoint;"
90 EOL" float aDist = length (aLight);"
91 EOL" aLight = aLight * (1.0 / aDist);"
93 EOL" float anAtten = 1.0 / (occLight_ConstAttenuation (theId)"
94 EOL" + occLight_LinearAttenuation (theId) * aDist);"
96 EOL" vec3 aHalf = normalize (aLight + theView);"
98 EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
99 EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
100 EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
102 EOL" float aSpecl = 0.0;"
103 EOL" if (aNdotL > 0.0)"
105 EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
108 EOL"Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten;"
109 EOL"Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;"
112 //! Function computes contribution of spotlight source
113 const char THE_FUNC_spotLight[] =
114 EOL"void spotLight (in int theId,"
115 EOL" in vec3 theNormal,"
116 EOL" in vec3 theView,"
117 EOL" in vec3 thePoint,"
118 EOL" in bool theIsFront)"
120 EOL" vec3 aLight = occLight_Position (theId).xyz;"
121 EOL" vec3 aSpotDir = occLight_SpotDirection (theId).xyz;"
122 EOL" if (occLight_IsHeadlight (theId) == 0)"
124 EOL" aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0));"
125 EOL" aSpotDir = vec3 (occWorldViewMatrix * vec4 (aSpotDir, 0.0));"
127 EOL" aLight -= thePoint;"
129 EOL" float aDist = length (aLight);"
130 EOL" aLight = aLight * (1.0 / aDist);"
132 EOL" aSpotDir = normalize (aSpotDir);"
134 EOL" float aCosA = dot (aSpotDir, -aLight);"
135 EOL" if (aCosA >= 1.0 || aCosA < cos (occLight_SpotCutOff (theId)))"
140 EOL" float anExponent = occLight_SpotExponent (theId);"
141 EOL" float anAtten = 1.0 / (occLight_ConstAttenuation (theId)"
142 EOL" + occLight_LinearAttenuation (theId) * aDist);"
143 EOL" if (anExponent > 0.0)"
145 EOL" anAtten *= pow (aCosA, anExponent * 128.0);"
148 EOL" vec3 aHalf = normalize (aLight + theView);"
150 EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
151 EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
152 EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
154 EOL" float aSpecl = 0.0;"
155 EOL" if (aNdotL > 0.0)"
157 EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
160 EOL" Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten;"
161 EOL" Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;"
164 //! Function computes contribution of directional light source
165 const char THE_FUNC_directionalLight[] =
166 EOL"void directionalLight (in int theId,"
167 EOL" in vec3 theNormal,"
168 EOL" in vec3 theView,"
169 EOL" in bool theIsFront)"
171 EOL" vec3 aLight = normalize (occLight_Position (theId).xyz);"
172 EOL" if (occLight_IsHeadlight (theId) == 0)"
174 EOL" aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0));"
177 EOL" vec3 aHalf = normalize (aLight + theView);"
179 EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
180 EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
181 EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
183 EOL" float aSpecl = 0.0;"
184 EOL" if (aNdotL > 0.0)"
186 EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
189 EOL" Diffuse += occLight_Diffuse (theId).rgb * aNdotL;"
190 EOL" Specular += occLight_Specular (theId).rgb * aSpecl;"
193 //! The same as THE_FUNC_directionalLight but for the light with zero index
194 //! (avoids limitations on some mobile devices).
195 const char THE_FUNC_directionalLightFirst[] =
196 EOL"void directionalLightFirst (in vec3 theNormal,"
197 EOL" in vec3 theView,"
198 EOL" in bool theIsFront)"
200 EOL" vec3 aLight = normalize (occLightSources[1].xyz);"
201 EOL" if (occLight_IsHeadlight (0) == 0)"
203 EOL" aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0));"
206 EOL" vec3 aHalf = normalize (aLight + theView);"
208 EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
209 EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
210 EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
212 EOL" float aSpecl = 0.0;"
213 EOL" if (aNdotL > 0.0)"
215 EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
218 EOL" Diffuse += occLightSources[0].rgb * aNdotL;"
219 EOL" Specular += occLightSources[0].rgb * aSpecl;"
222 //! Process clipping planes in Fragment Shader.
223 //! Should be added at the beginning of the main() function.
224 const char THE_FRAG_CLIP_PLANES_N[] =
225 EOL" for (int aPlaneIter = 0; aPlaneIter < occClipPlaneCount; ++aPlaneIter)"
227 EOL" vec4 aClipEquation = occClipPlaneEquations[aPlaneIter];"
228 EOL" if (dot (aClipEquation.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation.w < 0.0)"
234 //! Process 1 clipping plane in Fragment Shader.
235 const char THE_FRAG_CLIP_PLANES_1[] =
236 EOL" vec4 aClipEquation0 = occClipPlaneEquations[0];"
237 EOL" if (dot (aClipEquation0.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation0.w < 0.0)"
242 //! Process 2 clipping planes in Fragment Shader.
243 const char THE_FRAG_CLIP_PLANES_2[] =
244 EOL" vec4 aClipEquation0 = occClipPlaneEquations[0];"
245 EOL" vec4 aClipEquation1 = occClipPlaneEquations[1];"
246 EOL" if (dot (aClipEquation0.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation0.w < 0.0"
247 EOL" || dot (aClipEquation1.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation1.w < 0.0)"
252 #if !defined(GL_ES_VERSION_2_0)
254 static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
255 static const GLfloat THE_DEFAULT_SPOT_DIR[3] = { 0.0f, 0.0f, -1.0f };
256 static const GLfloat THE_DEFAULT_SPOT_EXPONENT = 0.0f;
257 static const GLfloat THE_DEFAULT_SPOT_CUTOFF = 180.0f;
259 //! Bind FFP light source.
260 static void bindLight (const OpenGl_Light& theLight,
261 const GLenum theLightGlId,
262 const OpenGl_Mat4& theModelView,
263 OpenGl_Context* theCtx)
265 // the light is a headlight?
266 if (theLight.IsHeadlight)
268 theCtx->core11->glMatrixMode (GL_MODELVIEW);
269 theCtx->core11->glLoadIdentity();
273 switch (theLight.Type)
275 case Graphic3d_TOLS_AMBIENT : break; // handled by separate if-clause at beginning of method
276 case Graphic3d_TOLS_DIRECTIONAL:
278 // if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one
279 const OpenGl_Vec4 anInfDir = -theLight.Direction;
281 // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE.
282 theCtx->core11->glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
283 theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
284 theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
285 theCtx->core11->glLightfv (theLightGlId, GL_POSITION, anInfDir.GetData());
286 theCtx->core11->glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
287 theCtx->core11->glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
288 theCtx->core11->glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
291 case Graphic3d_TOLS_POSITIONAL:
293 // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE
294 const OpenGl_Vec4 aPosition (static_cast<float>(theLight.Position.x()), static_cast<float>(theLight.Position.y()), static_cast<float>(theLight.Position.z()), 1.0f);
295 theCtx->core11->glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
296 theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
297 theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
298 theCtx->core11->glLightfv (theLightGlId, GL_POSITION, aPosition.GetData());
299 theCtx->core11->glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
300 theCtx->core11->glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
301 theCtx->core11->glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
302 theCtx->core11->glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
303 theCtx->core11->glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
304 theCtx->core11->glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0);
307 case Graphic3d_TOLS_SPOT:
309 const OpenGl_Vec4 aPosition (static_cast<float>(theLight.Position.x()), static_cast<float>(theLight.Position.y()), static_cast<float>(theLight.Position.z()), 1.0f);
310 theCtx->core11->glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
311 theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
312 theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
313 theCtx->core11->glLightfv (theLightGlId, GL_POSITION, aPosition.GetData());
314 theCtx->core11->glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.Direction.GetData());
315 theCtx->core11->glLightf (theLightGlId, GL_SPOT_EXPONENT, theLight.Concentration() * 128.0f);
316 theCtx->core11->glLightf (theLightGlId, GL_SPOT_CUTOFF, (theLight.Angle() * 180.0f) / GLfloat(M_PI));
317 theCtx->core11->glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
318 theCtx->core11->glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
319 theCtx->core11->glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0f);
324 // restore matrix in case of headlight
325 if (theLight.IsHeadlight)
327 theCtx->core11->glLoadMatrixf (theModelView.GetData());
330 glEnable (theLightGlId);
336 // =======================================================================
337 // function : OpenGl_ShaderManager
338 // purpose : Creates new empty shader manager
339 // =======================================================================
340 OpenGl_ShaderManager::OpenGl_ShaderManager (OpenGl_Context* theContext)
341 : myFfpProgram (new OpenGl_ShaderProgramFFP()),
342 myShadingModel (Graphic3d_TOSM_VERTEX),
343 myContext (theContext),
344 myHasLocalOrigin (Standard_False),
350 // =======================================================================
351 // function : ~OpenGl_ShaderManager
352 // purpose : Releases resources of shader manager
353 // =======================================================================
354 OpenGl_ShaderManager::~OpenGl_ShaderManager()
356 myProgramList.Clear();
359 // =======================================================================
362 // =======================================================================
363 void OpenGl_ShaderManager::clear()
365 myProgramList.Clear();
366 myLightPrograms.Nullify();
367 myFlatPrograms = OpenGl_SetOfShaderPrograms();
368 myMapOfLightPrograms.Clear();
369 myFontProgram.Nullify();
370 myBlitProgram.Nullify();
371 for (Standard_Integer aModeIter = 0; aModeIter < Graphic3d_StereoMode_NB; ++aModeIter)
373 myStereoPrograms[aModeIter].Nullify();
375 switchLightPrograms();
378 // =======================================================================
380 // purpose : Creates new shader program
381 // =======================================================================
382 Standard_Boolean OpenGl_ShaderManager::Create (const Handle(Graphic3d_ShaderProgram)& theProxy,
383 TCollection_AsciiString& theShareKey,
384 Handle(OpenGl_ShaderProgram)& theProgram)
386 theProgram.Nullify();
387 if (theProxy.IsNull())
389 return Standard_False;
392 theShareKey = theProxy->GetId();
393 if (myContext->GetResource<Handle(OpenGl_ShaderProgram)> (theShareKey, theProgram))
395 if (theProgram->Share())
397 myProgramList.Append (theProgram);
399 return Standard_True;
402 theProgram = new OpenGl_ShaderProgram (theProxy);
403 if (!theProgram->Initialize (myContext, theProxy->ShaderObjects()))
405 theProgram->Release (myContext);
407 theProgram.Nullify();
408 return Standard_False;
411 myProgramList.Append (theProgram);
412 myContext->ShareResource (theShareKey, theProgram);
413 return Standard_True;
416 // =======================================================================
417 // function : Unregister
418 // purpose : Removes specified shader program from the manager
419 // =======================================================================
420 void OpenGl_ShaderManager::Unregister (TCollection_AsciiString& theShareKey,
421 Handle(OpenGl_ShaderProgram)& theProgram)
423 for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
425 if (anIt.Value() == theProgram)
427 if (!theProgram->UnShare())
430 theProgram.Nullify();
434 myProgramList.Remove (anIt);
439 const TCollection_AsciiString anID = theProgram->myProxy->GetId();
442 myContext->DelayedRelease (theProgram);
443 theProgram.Nullify();
447 theProgram.Nullify();
448 myContext->ReleaseResource (anID, Standard_True);
452 // =======================================================================
453 // function : ShaderPrograms
454 // purpose : Returns list of registered shader programs
455 // =======================================================================
456 const OpenGl_ShaderProgramList& OpenGl_ShaderManager::ShaderPrograms() const
458 return myProgramList;
461 // =======================================================================
463 // purpose : Returns true if no program objects are attached
464 // =======================================================================
465 Standard_Boolean OpenGl_ShaderManager::IsEmpty() const
467 return myProgramList.IsEmpty();
470 // =======================================================================
471 // function : switchLightPrograms
473 // =======================================================================
474 void OpenGl_ShaderManager::switchLightPrograms()
476 TCollection_AsciiString aKey (myShadingModel == Graphic3d_TOSM_FRAGMENT ? "p_" : "g_");
477 const OpenGl_ListOfLight* aLights = myLightSourceState.LightSources();
480 for (OpenGl_ListOfLight::Iterator aLightIter (*aLights); aLightIter.More(); aLightIter.Next())
482 switch (aLightIter.Value().Type)
484 case Graphic3d_TOLS_AMBIENT:
485 break; // skip ambient
486 case Graphic3d_TOLS_DIRECTIONAL:
489 case Graphic3d_TOLS_POSITIONAL:
492 case Graphic3d_TOLS_SPOT:
499 if (!myMapOfLightPrograms.Find (aKey, myLightPrograms))
501 myLightPrograms = new OpenGl_SetOfShaderPrograms();
502 myMapOfLightPrograms.Bind (aKey, myLightPrograms);
506 // =======================================================================
507 // function : UpdateLightSourceStateTo
508 // purpose : Updates state of OCCT light sources
509 // =======================================================================
510 void OpenGl_ShaderManager::UpdateLightSourceStateTo (const OpenGl_ListOfLight* theLights)
512 myLightSourceState.Set (theLights);
513 myLightSourceState.Update();
514 switchLightPrograms();
517 // =======================================================================
518 // function : UpdateLightSourceState
520 // =======================================================================
521 void OpenGl_ShaderManager::UpdateLightSourceState()
523 myLightSourceState.Update();
526 // =======================================================================
527 // function : SetShadingModel
529 // =======================================================================
530 void OpenGl_ShaderManager::SetShadingModel (const Graphic3d_TypeOfShadingModel theModel)
532 myShadingModel = theModel;
533 switchLightPrograms();
536 // =======================================================================
537 // function : SetProjectionState
538 // purpose : Sets new state of OCCT projection transform
539 // =======================================================================
540 void OpenGl_ShaderManager::UpdateProjectionStateTo (const OpenGl_Mat4& theProjectionMatrix)
542 myProjectionState.Set (theProjectionMatrix);
543 myProjectionState.Update();
546 // =======================================================================
547 // function : SetModelWorldState
548 // purpose : Sets new state of OCCT model-world transform
549 // =======================================================================
550 void OpenGl_ShaderManager::UpdateModelWorldStateTo (const OpenGl_Mat4& theModelWorldMatrix)
552 myModelWorldState.Set (theModelWorldMatrix);
553 myModelWorldState.Update();
556 // =======================================================================
557 // function : SetWorldViewState
558 // purpose : Sets new state of OCCT world-view transform
559 // =======================================================================
560 void OpenGl_ShaderManager::UpdateWorldViewStateTo (const OpenGl_Mat4& theWorldViewMatrix)
562 myWorldViewState.Set (theWorldViewMatrix);
563 myWorldViewState.Update();
566 // =======================================================================
567 // function : PushLightSourceState
568 // purpose : Pushes state of OCCT light sources to the program
569 // =======================================================================
570 void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
572 if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE))
577 theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
578 if (theProgram == myFfpProgram)
580 #if !defined(GL_ES_VERSION_2_0)
581 if (myContext->core11 == NULL)
586 if (myContext->core11 != NULL)
588 GLenum aLightGlId = GL_LIGHT0;
589 OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f);
590 const OpenGl_Mat4 aModelView = myWorldViewState.WorldViewMatrix() * myModelWorldState.ModelWorldMatrix();
591 for (OpenGl_ListOfLight::Iterator aLightIt (*myLightSourceState.LightSources()); aLightIt.More(); aLightIt.Next())
593 const OpenGl_Light& aLight = aLightIt.Value();
594 if (aLight.Type == Graphic3d_TOLS_AMBIENT)
596 anAmbient += aLight.Color;
599 else if (aLightGlId > GL_LIGHT7) // OpenGLMaxLights - only 8 lights in OpenGL...
604 bindLight (aLightIt.Value(), aLightGlId, aModelView, myContext);
608 // apply accumulated ambient color
609 anAmbient.a() = 1.0f;
610 myContext->core11->glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbient.GetData());
612 // GL_LIGHTING is managed by drawers to switch between shaded / no lighting output,
613 // therefore managing the state here does not have any effect - do it just for consistency.
614 if (aLightGlId != GL_LIGHT0)
616 ::glEnable (GL_LIGHTING);
620 ::glDisable (GL_LIGHTING);
622 // switch off unused lights
623 for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
625 ::glDisable (aLightGlId);
632 for (Standard_Integer aLightIt = 0; aLightIt < OpenGLMaxLights; ++aLightIt)
634 myLightTypeArray[aLightIt].Type = -1;
637 const Standard_Integer aLightsDefNb = Min (myLightSourceState.LightSources()->Size(), OpenGLMaxLights);
638 if (aLightsDefNb < 1)
640 theProgram->SetUniform (myContext,
641 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
643 theProgram->SetUniform (myContext,
644 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT),
645 OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
646 theProgram->SetUniform (myContext,
647 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
648 OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
649 myLightTypeArray[0].Packed());
653 OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f);
654 Standard_Integer aLightsNb = 0;
655 for (OpenGl_ListOfLight::Iterator anIter (*myLightSourceState.LightSources()); anIter.More(); anIter.Next())
657 const OpenGl_Light& aLight = anIter.Value();
658 if (aLight.Type == Graphic3d_TOLS_AMBIENT)
660 anAmbient += aLight.Color;
663 else if (aLightsNb >= OpenGLMaxLights)
668 OpenGl_ShaderLightType& aLightType = myLightTypeArray[aLightsNb];
669 aLightType.Type = aLight.Type;
670 aLightType.IsHeadlight = aLight.IsHeadlight;
672 OpenGl_ShaderLightParameters& aLightParams = myLightParamsArray[aLightsNb];
673 aLightParams.Color = aLight.Color;
674 if (aLight.Type == Graphic3d_TOLS_DIRECTIONAL)
676 aLightParams.Position = -aLight.Direction;
678 else if (!aLight.IsHeadlight)
680 aLightParams.Position.x() = static_cast<float>(aLight.Position.x() - myLocalOrigin.X());
681 aLightParams.Position.y() = static_cast<float>(aLight.Position.y() - myLocalOrigin.Y());
682 aLightParams.Position.z() = static_cast<float>(aLight.Position.z() - myLocalOrigin.Z());
683 aLightParams.Position.w() = 1.0f;
687 aLightParams.Position.x() = static_cast<float>(aLight.Position.x());
688 aLightParams.Position.y() = static_cast<float>(aLight.Position.y());
689 aLightParams.Position.z() = static_cast<float>(aLight.Position.z());
690 aLightParams.Position.w() = 1.0f;
693 if (aLight.Type == Graphic3d_TOLS_SPOT)
695 aLightParams.Direction = aLight.Direction;
697 aLightParams.Parameters = aLight.Params;
701 theProgram->SetUniform (myContext,
702 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
704 theProgram->SetUniform (myContext,
705 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT),
707 theProgram->SetUniform (myContext,
708 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
709 OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
710 myLightTypeArray[0].Packed());
713 theProgram->SetUniform (myContext,
714 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_PARAMS),
715 aLightsNb * OpenGl_ShaderLightParameters::NbOfVec4(),
716 myLightParamsArray[0].Packed());
720 // =======================================================================
721 // function : PushProjectionState
722 // purpose : Pushes state of OCCT projection transform to the program
723 // =======================================================================
724 void OpenGl_ShaderManager::PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const
726 if (myProjectionState.Index() == theProgram->ActiveState (OpenGl_PROJECTION_STATE))
731 theProgram->UpdateState (OpenGl_PROJECTION_STATE, myProjectionState.Index());
732 if (theProgram == myFfpProgram)
734 #if !defined(GL_ES_VERSION_2_0)
735 if (myContext->core11 != NULL)
737 myContext->core11->glMatrixMode (GL_PROJECTION);
738 myContext->core11->glLoadMatrixf (myProjectionState.ProjectionMatrix());
744 theProgram->SetUniform (myContext,
745 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX),
746 myProjectionState.ProjectionMatrix());
748 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE);
749 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
751 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse());
754 theProgram->SetUniform (myContext,
755 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE),
756 myProjectionState.ProjectionMatrix(), true);
758 aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE);
759 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
761 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse(), true);
765 // =======================================================================
766 // function : PushModelWorldState
767 // purpose : Pushes state of OCCT model-world transform to the program
768 // =======================================================================
769 void OpenGl_ShaderManager::PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const
771 if (myModelWorldState.Index() == theProgram->ActiveState (OpenGl_MODEL_WORLD_STATE))
776 theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
777 if (theProgram == myFfpProgram)
779 #if !defined(GL_ES_VERSION_2_0)
780 if (myContext->core11 != NULL)
782 const OpenGl_Mat4 aModelView = myWorldViewState.WorldViewMatrix() * myModelWorldState.ModelWorldMatrix();
783 myContext->core11->glMatrixMode (GL_MODELVIEW);
784 myContext->core11->glLoadMatrixf (aModelView.GetData());
785 theProgram->UpdateState (OpenGl_WORLD_VIEW_STATE, myWorldViewState.Index());
791 theProgram->SetUniform (myContext,
792 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX),
793 myModelWorldState.ModelWorldMatrix());
795 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE);
796 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
798 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse());
801 theProgram->SetUniform (myContext,
802 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE),
803 myModelWorldState.ModelWorldMatrix(), true);
805 aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE);
806 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
808 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse(), true);
812 // =======================================================================
813 // function : PushWorldViewState
814 // purpose : Pushes state of OCCT world-view transform to the program
815 // =======================================================================
816 void OpenGl_ShaderManager::PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const
818 if (myWorldViewState.Index() == theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE))
823 theProgram->UpdateState (OpenGl_WORLD_VIEW_STATE, myWorldViewState.Index());
824 if (theProgram == myFfpProgram)
826 #if !defined(GL_ES_VERSION_2_0)
827 if (myContext->core11 != NULL)
829 const OpenGl_Mat4 aModelView = myWorldViewState.WorldViewMatrix() * myModelWorldState.ModelWorldMatrix();
830 myContext->core11->glMatrixMode (GL_MODELVIEW);
831 myContext->core11->glLoadMatrixf (aModelView.GetData());
832 theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
838 theProgram->SetUniform (myContext,
839 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX),
840 myWorldViewState.WorldViewMatrix());
842 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE);
843 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
845 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse());
848 theProgram->SetUniform (myContext,
849 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE),
850 myWorldViewState.WorldViewMatrix(), true);
852 aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE);
853 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
855 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse(), true);
859 // =======================================================================
860 // function : UpdateClippingState
861 // purpose : Updates state of OCCT clipping planes
862 // =======================================================================
863 void OpenGl_ShaderManager::UpdateClippingState()
865 myClippingState.Update();
868 // =======================================================================
869 // function : RevertClippingState
870 // purpose : Reverts state of OCCT clipping planes
871 // =======================================================================
872 void OpenGl_ShaderManager::RevertClippingState()
874 myClippingState.Revert();
877 // =======================================================================
878 // function : PushClippingState
879 // purpose : Pushes state of OCCT clipping planes to the program
880 // =======================================================================
881 void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const
883 if (myClippingState.Index() == theProgram->ActiveState (OpenGl_CLIP_PLANES_STATE))
888 theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index());
889 if (theProgram == myFfpProgram)
891 #if !defined(GL_ES_VERSION_2_0)
892 if (myContext->core11 == NULL)
897 const Standard_Integer aNbMaxPlanes = Min (myContext->MaxClipPlanes(), THE_MAX_CLIP_PLANES);
898 OpenGl_Vec4d anEquations[THE_MAX_CLIP_PLANES];
899 Standard_Integer aPlaneId = 0;
900 Standard_Boolean toRestoreModelView = Standard_False;
901 for (OpenGl_ClippingIterator aPlaneIter (myContext->Clipping()); aPlaneIter.More(); aPlaneIter.Next())
903 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIter.Value();
904 if (aPlaneIter.IsDisabled())
908 else if (aPlaneId >= aNbMaxPlanes)
910 myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
911 GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
912 TCollection_ExtendedString("Warning: clipping planes limit (") + aNbMaxPlanes + ") has been exceeded.");
916 const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
917 OpenGl_Vec4d& aPlaneEq = anEquations[aPlaneId];
918 aPlaneEq.x() = anEquation.x();
919 aPlaneEq.y() = anEquation.y();
920 aPlaneEq.z() = anEquation.z();
921 aPlaneEq.w() = anEquation.w();
922 if (myHasLocalOrigin)
924 const gp_XYZ aPos = aPlane->ToPlane().Position().Location().XYZ() - myLocalOrigin;
925 const Standard_Real aD = -(anEquation.x() * aPos.X() + anEquation.y() * aPos.Y() + anEquation.z() * aPos.Z());
929 const GLenum anFfpPlaneID = GL_CLIP_PLANE0 + aPlaneId;
930 if (anFfpPlaneID == GL_CLIP_PLANE0)
932 // set either identity or pure view matrix
933 toRestoreModelView = Standard_True;
934 myContext->core11->glMatrixMode (GL_MODELVIEW);
935 myContext->core11->glLoadMatrixf (myWorldViewState.WorldViewMatrix().GetData());
938 ::glEnable (anFfpPlaneID);
939 myContext->core11->glClipPlane (anFfpPlaneID, aPlaneEq);
944 // switch off unused lights
945 for (; aPlaneId < aNbMaxPlanes; ++aPlaneId)
947 ::glDisable (GL_CLIP_PLANE0 + aPlaneId);
950 // restore combined model-view matrix
951 if (toRestoreModelView)
953 const OpenGl_Mat4 aModelView = myWorldViewState.WorldViewMatrix() * myModelWorldState.ModelWorldMatrix();
954 myContext->core11->glLoadMatrixf (aModelView.GetData());
960 const GLint aLocEquations = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_EQUATIONS);
961 if (aLocEquations == OpenGl_ShaderProgram::INVALID_LOCATION)
966 const GLint aNbPlanes = Min (myContext->Clipping().NbClippingOrCappingOn(), THE_MAX_CLIP_PLANES);
967 theProgram->SetUniform (myContext,
968 theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_COUNT),
975 OpenGl_Vec4 anEquations[THE_MAX_CLIP_PLANES];
977 for (OpenGl_ClippingIterator aPlaneIter (myContext->Clipping()); aPlaneIter.More(); aPlaneIter.Next())
979 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIter.Value();
980 if (aPlaneIter.IsDisabled())
984 else if (aPlaneId >= THE_MAX_CLIP_PLANES)
986 myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
987 GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
988 "Warning: clipping planes limit (8) has been exceeded.");
992 const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
993 OpenGl_Vec4& aPlaneEq = anEquations[aPlaneId];
994 aPlaneEq.x() = float(anEquation.x());
995 aPlaneEq.y() = float(anEquation.y());
996 aPlaneEq.z() = float(anEquation.z());
997 aPlaneEq.w() = float(anEquation.w());
998 if (myHasLocalOrigin)
1000 const gp_XYZ aPos = aPlane->ToPlane().Position().Location().XYZ() - myLocalOrigin;
1001 const Standard_Real aD = -(anEquation.x() * aPos.X() + anEquation.y() * aPos.Y() + anEquation.z() * aPos.Z());
1002 aPlaneEq.w() = float(aD);
1007 theProgram->SetUniform (myContext, aLocEquations, THE_MAX_CLIP_PLANES, anEquations);
1010 // =======================================================================
1011 // function : PushMaterialState
1013 // =======================================================================
1014 void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
1016 if (myMaterialState.Index() == theProgram->ActiveState (OpenGl_MATERIAL_STATE))
1021 const OpenGl_Material& aFrontMat = myMaterialState.FrontMaterial();
1022 const OpenGl_Material& aBackMat = myMaterialState.BackMaterial();
1023 theProgram->UpdateState (OpenGl_MATERIAL_STATE, myMaterialState.Index());
1024 if (theProgram == myFfpProgram)
1026 #if !defined(GL_ES_VERSION_2_0)
1027 if (myContext->core11 == NULL)
1032 const GLenum aFrontFace = myMaterialState.ToDistinguish() ? GL_FRONT : GL_FRONT_AND_BACK;
1033 myContext->core11->glMaterialfv(aFrontFace, GL_AMBIENT, aFrontMat.Ambient.GetData());
1034 myContext->core11->glMaterialfv(aFrontFace, GL_DIFFUSE, aFrontMat.Diffuse.GetData());
1035 myContext->core11->glMaterialfv(aFrontFace, GL_SPECULAR, aFrontMat.Specular.GetData());
1036 myContext->core11->glMaterialfv(aFrontFace, GL_EMISSION, aFrontMat.Emission.GetData());
1037 myContext->core11->glMaterialf (aFrontFace, GL_SHININESS, aFrontMat.Shine());
1038 if (myMaterialState.ToDistinguish())
1040 myContext->core11->glMaterialfv(GL_BACK, GL_AMBIENT, aBackMat.Ambient.GetData());
1041 myContext->core11->glMaterialfv(GL_BACK, GL_DIFFUSE, aBackMat.Diffuse.GetData());
1042 myContext->core11->glMaterialfv(GL_BACK, GL_SPECULAR, aBackMat.Specular.GetData());
1043 myContext->core11->glMaterialfv(GL_BACK, GL_EMISSION, aBackMat.Emission.GetData());
1044 myContext->core11->glMaterialf (GL_BACK, GL_SHININESS, aBackMat.Shine());
1050 theProgram->SetUniform (myContext,
1051 theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),
1052 myMaterialState.ToMapTexture() ? 1 : 0);
1053 theProgram->SetUniform (myContext,
1054 theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
1055 myMaterialState.ToDistinguish() ? 1 : 0);
1057 const GLint aLocFront = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL);
1058 if (aLocFront != OpenGl_ShaderProgram::INVALID_LOCATION)
1060 theProgram->SetUniform (myContext, aLocFront, OpenGl_Material::NbOfVec4(),
1061 aFrontMat.Packed());
1064 const GLint aLocBack = theProgram->GetStateLocation (OpenGl_OCCT_BACK_MATERIAL);
1065 if (aLocBack != OpenGl_ShaderProgram::INVALID_LOCATION)
1067 theProgram->SetUniform (myContext, aLocBack, OpenGl_Material::NbOfVec4(),
1072 // =======================================================================
1073 // function : PushState
1074 // purpose : Pushes state of OCCT graphics parameters to the program
1075 // =======================================================================
1076 void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const
1078 const Handle(OpenGl_ShaderProgram)& aProgram = !theProgram.IsNull() ? theProgram : myFfpProgram;
1079 PushClippingState (aProgram);
1080 PushWorldViewState (aProgram);
1081 PushModelWorldState (aProgram);
1082 PushProjectionState (aProgram);
1083 PushLightSourceState (aProgram);
1084 PushMaterialState (aProgram);
1087 // =======================================================================
1088 // function : prepareStdProgramFont
1090 // =======================================================================
1091 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFont()
1093 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1094 TCollection_AsciiString aSrcVert = TCollection_AsciiString()
1095 + EOL"THE_SHADER_OUT vec2 TexCoord;"
1098 EOL" TexCoord = occTexCoord.st;"
1099 EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1102 TCollection_AsciiString
1103 aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, TexCoord.st).a; }";
1104 #if !defined(GL_ES_VERSION_2_0)
1105 if (myContext->core11 == NULL)
1107 aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, TexCoord.st).r; }";
1111 TCollection_AsciiString aSrcFrag = TCollection_AsciiString() +
1112 + EOL"THE_SHADER_IN vec2 TexCoord;"
1116 EOL" vec4 aColor = occColor;"
1117 EOL" aColor.a *= getAlpha();"
1118 EOL" if (aColor.a <= 0.285) discard;"
1119 EOL" occFragColor = aColor;"
1122 #if !defined(GL_ES_VERSION_2_0)
1123 if (myContext->core32 != NULL)
1125 aProgramSrc->SetHeader ("#version 150");
1128 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1129 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1130 TCollection_AsciiString aKey;
1131 if (!Create (aProgramSrc, aKey, myFontProgram))
1133 myFontProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1134 return Standard_False;
1136 return Standard_True;
1139 // =======================================================================
1140 // function : prepareStdProgramFboBlit
1142 // =======================================================================
1143 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFboBlit()
1145 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1146 TCollection_AsciiString aSrcVert =
1147 EOL"THE_SHADER_OUT vec2 TexCoord;"
1150 EOL" TexCoord = occVertex.zw;"
1151 EOL" gl_Position = vec4(occVertex.x, occVertex.y, 0.0, 1.0);"
1154 TCollection_AsciiString aSrcFrag =
1155 EOL"uniform sampler2D uColorSampler;"
1156 EOL"uniform sampler2D uDepthSampler;"
1158 EOL"THE_SHADER_IN vec2 TexCoord;"
1162 EOL" gl_FragDepth = occTexture2D (uDepthSampler, TexCoord).r;"
1163 EOL" occFragColor = occTexture2D (uColorSampler, TexCoord);"
1166 #if defined(GL_ES_VERSION_2_0)
1167 if (myContext->IsGlGreaterEqual (3, 0))
1169 aProgramSrc->SetHeader ("#version 300 es");
1171 else if (myContext->extFragDepth)
1173 aProgramSrc->SetHeader ("#extension GL_EXT_frag_depth : enable"
1174 EOL"#define gl_FragDepth gl_FragDepthEXT");
1178 // there is no way to draw into depth buffer
1180 EOL"uniform sampler2D uColorSampler;"
1182 EOL"THE_SHADER_IN vec2 TexCoord;"
1186 EOL" occFragColor = occTexture2D (uColorSampler, TexCoord);"
1190 if (myContext->core32 != NULL)
1192 aProgramSrc->SetHeader ("#version 150");
1195 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1196 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1197 TCollection_AsciiString aKey;
1198 if (!Create (aProgramSrc, aKey, myBlitProgram))
1200 myBlitProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1201 return Standard_False;
1204 myContext->BindProgram (myBlitProgram);
1205 myBlitProgram->SetSampler (myContext, "uColorSampler", 0);
1206 myBlitProgram->SetSampler (myContext, "uDepthSampler", 1);
1207 myContext->BindProgram (NULL);
1208 return Standard_True;
1211 // =======================================================================
1212 // function : pointSpriteAlphaSrc
1214 // =======================================================================
1215 TCollection_AsciiString OpenGl_ShaderManager::pointSpriteAlphaSrc (const Standard_Integer theBits)
1217 TCollection_AsciiString aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, " THE_VEC2_glPointCoord ").a; }";
1218 #if !defined(GL_ES_VERSION_2_0)
1219 if (myContext->core11 == NULL
1220 && (theBits & OpenGl_PO_TextureA) != 0)
1222 aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, " THE_VEC2_glPointCoord ").r; }";
1227 return aSrcGetAlpha;
1233 // =======================================================================
1234 // function : textureUsed
1236 // =======================================================================
1237 static bool textureUsed (const Standard_Integer theBits)
1239 return (theBits & OpenGl_PO_TextureA) != 0 || (theBits & OpenGl_PO_TextureRGB) != 0;
1244 // =======================================================================
1245 // function : prepareStdProgramFlat
1247 // =======================================================================
1248 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_ShaderProgram)& theProgram,
1249 const Standard_Integer theBits)
1251 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1252 TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcVertExtraFunc, aSrcGetAlpha, aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain;
1253 TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return occColor; }";
1254 TCollection_AsciiString aSrcFragMainGetColor = EOL" occFragColor = getColor();";
1255 if ((theBits & OpenGl_PO_Point) != 0)
1257 #if defined(GL_ES_VERSION_2_0)
1258 aSrcVertExtraMain += EOL" gl_PointSize = occPointSize;";
1261 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1264 EOL"vec4 getColor(void) { return occTexture2D(occActiveSampler, " THE_VEC2_glPointCoord "); }";
1267 if (textureUsed (theBits))
1269 aSrcGetAlpha = pointSpriteAlphaSrc (theBits);
1271 #if !defined(GL_ES_VERSION_2_0)
1272 if (myContext->core11 != NULL
1273 && myContext->IsGlGreaterEqual (2, 1))
1275 aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
1279 aSrcFragMainGetColor =
1280 EOL" vec4 aColor = getColor();"
1281 EOL" aColor.a = getAlpha();"
1282 EOL" if (aColor.a <= 0.1) discard;"
1283 EOL" occFragColor = aColor;";
1287 aSrcFragMainGetColor =
1288 EOL" vec4 aColor = getColor();"
1289 EOL" if (aColor.a <= 0.1) discard;"
1290 EOL" occFragColor = aColor;";
1295 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1297 aSrcVertExtraOut += THE_VARY_TexCoord_OUT;
1298 aSrcFragExtraOut += THE_VARY_TexCoord_IN;
1299 aSrcVertExtraMain += THE_VARY_TexCoord_Trsf;
1302 EOL"vec4 getColor(void) { return occTexture2D(occActiveSampler, TexCoord.st / TexCoord.w); }";
1304 else if ((theBits & OpenGl_PO_TextureEnv) != 0)
1306 aSrcVertExtraOut += THE_VARY_TexCoord_OUT;
1307 aSrcFragExtraOut += THE_VARY_TexCoord_IN;
1309 aSrcVertExtraFunc = THE_FUNC_transformNormal;
1311 aSrcVertExtraMain +=
1312 EOL" vec4 aPosition = occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1313 EOL" vec3 aNormal = transformNormal (occNormal);"
1314 EOL" vec3 aReflect = reflect (normalize (aPosition.xyz), aNormal);"
1315 EOL" aReflect.z += 1.0;"
1316 EOL" TexCoord = vec4(aReflect.xy * inversesqrt (dot (aReflect, aReflect)) * 0.5 + vec2 (0.5), 0.0, 1.0);";
1319 EOL"vec4 getColor(void) { return occTexture2D (occActiveSampler, TexCoord.st); }";
1322 if ((theBits & OpenGl_PO_VertColor) != 0)
1324 aSrcVertExtraOut += EOL"THE_SHADER_OUT vec4 VertColor;";
1325 aSrcVertExtraMain += EOL" VertColor = occVertColor;";
1326 aSrcFragExtraOut += EOL"THE_SHADER_IN vec4 VertColor;";
1327 aSrcFragGetColor = EOL"vec4 getColor(void) { return VertColor; }";
1329 if ((theBits & OpenGl_PO_ClipPlanesN) != 0)
1332 EOL"THE_SHADER_OUT vec4 PositionWorld;"
1333 EOL"THE_SHADER_OUT vec4 Position;";
1335 EOL"THE_SHADER_IN vec4 PositionWorld;"
1336 EOL"THE_SHADER_IN vec4 Position;";
1337 aSrcVertExtraMain +=
1338 EOL" PositionWorld = occModelWorldMatrix * occVertex;"
1339 EOL" Position = occWorldViewMatrix * PositionWorld;";
1341 if ((theBits & OpenGl_PO_ClipPlanes1) != 0)
1343 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_1;
1345 else if ((theBits & OpenGl_PO_ClipPlanes2) != 0)
1347 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_2;
1351 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_N;
1355 TCollection_AsciiString aSrcVertEndMain;
1356 if ((theBits & OpenGl_PO_StippleLine) != 0)
1358 bool hasGlslBitOps = false;
1359 #if defined(GL_ES_VERSION_2_0)
1360 if (myContext->IsGlGreaterEqual (3, 0))
1362 aProgramSrc->SetHeader ("#version 300 es");
1363 hasGlslBitOps = true;
1366 if (myContext->IsGlGreaterEqual (3, 0))
1368 aProgramSrc->SetHeader ("#version 130");
1369 hasGlslBitOps = true;
1371 else if(myContext->CheckExtension("GL_EXT_gpu_shader4"))
1373 aProgramSrc->SetHeader ("#extension GL_EXT_gpu_shader4 : enable");
1374 hasGlslBitOps = true;
1381 EOL"THE_SHADER_OUT vec2 ScreenSpaceCoord;";
1383 EOL"THE_SHADER_IN vec2 ScreenSpaceCoord;"
1384 EOL"uniform int uPattern;"
1385 EOL"uniform float uFactor;";
1387 EOL" ScreenSpaceCoord = gl_Position.xy / gl_Position.w;";
1388 aSrcFragMainGetColor =
1389 EOL" float anAngle = atan (dFdx (ScreenSpaceCoord.x), dFdy (ScreenSpaceCoord.y));"
1390 EOL" float aRotatePoint = gl_FragCoord.x * sin (anAngle) + gl_FragCoord.y * cos (anAngle);"
1391 EOL" uint aBit = uint (floor (aRotatePoint / uFactor + 0.5)) & 15U;"
1392 EOL" if ((uint (uPattern) & (1U << aBit)) == 0U) discard;"
1393 EOL" vec4 aColor = getColor();"
1394 EOL" if (aColor.a <= 0.1) discard;"
1395 EOL" occFragColor = aColor;";
1399 const TCollection_ExtendedString aWarnMessage =
1400 "Warning: stipple lines in GLSL will be ignored.";
1401 myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
1402 GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage);
1412 + EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1423 + aSrcFragMainGetColor
1426 #if !defined(GL_ES_VERSION_2_0)
1427 if (myContext->core32 != NULL)
1429 aProgramSrc->SetHeader ("#version 150");
1432 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1433 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1435 TCollection_AsciiString aKey;
1436 if (!Create (aProgramSrc, aKey, theProgram))
1438 theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1439 return Standard_False;
1441 return Standard_True;
1444 // =======================================================================
1445 // function : pointSpriteShadingSrc
1447 // =======================================================================
1448 TCollection_AsciiString OpenGl_ShaderManager::pointSpriteShadingSrc (const TCollection_AsciiString theBaseColorSrc,
1449 const Standard_Integer theBits)
1451 TCollection_AsciiString aSrcFragGetColor;
1452 if ((theBits & OpenGl_PO_TextureA) != 0)
1454 aSrcFragGetColor = pointSpriteAlphaSrc (theBits) +
1455 EOL"vec4 getColor(void)"
1457 EOL" vec4 aColor = " + theBaseColorSrc + ";"
1458 EOL" aColor.a = getAlpha();"
1459 EOL" if (aColor.a <= 0.1) discard;"
1460 EOL" return aColor;"
1463 else if ((theBits & OpenGl_PO_TextureRGB) != 0)
1465 aSrcFragGetColor = TCollection_AsciiString() +
1466 EOL"vec4 getColor(void)"
1468 EOL" vec4 aColor = " + theBaseColorSrc + ";"
1469 EOL" aColor = occTexture2D(occActiveSampler, " THE_VEC2_glPointCoord ") * aColor;"
1470 EOL" if (aColor.a <= 0.1) discard;"
1471 EOL" return aColor;"
1475 return aSrcFragGetColor;
1478 // =======================================================================
1479 // function : stdComputeLighting
1481 // =======================================================================
1482 TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (const Standard_Boolean theHasVertColor)
1484 Standard_Integer aLightsMap[Graphic3d_TOLS_SPOT + 1] = { 0, 0, 0, 0 };
1485 TCollection_AsciiString aLightsFunc, aLightsLoop;
1486 const OpenGl_ListOfLight* aLights = myLightSourceState.LightSources();
1487 if (aLights != NULL)
1489 Standard_Integer anIndex = 0;
1490 for (OpenGl_ListOfLight::Iterator aLightIter (*aLights); aLightIter.More(); aLightIter.Next(), ++anIndex)
1492 switch (aLightIter.Value().Type)
1494 case Graphic3d_TOLS_AMBIENT:
1496 break; // skip ambient
1497 case Graphic3d_TOLS_DIRECTIONAL:
1498 aLightsLoop = aLightsLoop + EOL" directionalLight (" + anIndex + ", theNormal, theView, theIsFront);";
1500 case Graphic3d_TOLS_POSITIONAL:
1501 aLightsLoop = aLightsLoop + EOL" pointLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);";
1503 case Graphic3d_TOLS_SPOT:
1504 aLightsLoop = aLightsLoop + EOL" spotLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);";
1507 aLightsMap[aLightIter.Value().Type] += 1;
1509 const Standard_Integer aNbLoopLights = aLightsMap[Graphic3d_TOLS_DIRECTIONAL]
1510 + aLightsMap[Graphic3d_TOLS_POSITIONAL]
1511 + aLightsMap[Graphic3d_TOLS_SPOT];
1512 if (aLightsMap[Graphic3d_TOLS_DIRECTIONAL] == 1
1513 && aNbLoopLights == 1)
1515 // use the version with hard-coded first index
1516 aLightsLoop = EOL" directionalLightFirst(theNormal, theView, theIsFront);";
1517 aLightsFunc += THE_FUNC_directionalLightFirst;
1519 else if (aLightsMap[Graphic3d_TOLS_DIRECTIONAL] > 0)
1521 aLightsFunc += THE_FUNC_directionalLight;
1523 if (aLightsMap[Graphic3d_TOLS_POSITIONAL] > 0)
1525 aLightsFunc += THE_FUNC_pointLight;
1527 if (aLightsMap[Graphic3d_TOLS_SPOT] > 0)
1529 aLightsFunc += THE_FUNC_spotLight;
1533 TCollection_AsciiString aGetMatAmbient = "theIsFront ? occFrontMaterial_Ambient() : occBackMaterial_Ambient();";
1534 TCollection_AsciiString aGetMatDiffuse = "theIsFront ? occFrontMaterial_Diffuse() : occBackMaterial_Diffuse();";
1535 if (theHasVertColor)
1537 aGetMatAmbient = "getVertColor();";
1538 aGetMatDiffuse = "getVertColor();";
1541 return TCollection_AsciiString()
1545 EOL"vec4 computeLighting (in vec3 theNormal,"
1546 EOL" in vec3 theView,"
1547 EOL" in vec4 thePoint,"
1548 EOL" in bool theIsFront)"
1550 EOL" Ambient = occLightAmbient.rgb;"
1551 EOL" Diffuse = vec3 (0.0);"
1552 EOL" Specular = vec3 (0.0);"
1553 EOL" vec3 aPoint = thePoint.xyz / thePoint.w;"
1555 + EOL" vec4 aMatAmbient = " + aGetMatAmbient
1556 + EOL" vec4 aMatDiffuse = " + aGetMatDiffuse
1557 + EOL" vec4 aMatSpecular = theIsFront ? occFrontMaterial_Specular() : occBackMaterial_Specular();"
1558 EOL" vec4 aMatEmission = theIsFront ? occFrontMaterial_Emission() : occBackMaterial_Emission();"
1559 EOL" vec3 aColor = Ambient * aMatAmbient.rgb"
1560 EOL" + Diffuse * aMatDiffuse.rgb"
1561 EOL" + Specular * aMatSpecular.rgb"
1562 EOL" + aMatEmission.rgb;"
1563 EOL" return vec4 (aColor, aMatDiffuse.a);"
1567 // =======================================================================
1568 // function : prepareStdProgramGouraud
1570 // =======================================================================
1571 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_ShaderProgram)& theProgram,
1572 const Standard_Integer theBits)
1574 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1575 TCollection_AsciiString aSrcVert, aSrcVertColor, aSrcVertExtraOut, aSrcVertExtraMain, aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain;
1576 TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return gl_FrontFacing ? FrontColor : BackColor; }";
1577 if ((theBits & OpenGl_PO_Point) != 0)
1579 #if defined(GL_ES_VERSION_2_0)
1580 aSrcVertExtraMain += EOL" gl_PointSize = occPointSize;";
1583 if (textureUsed (theBits))
1585 #if !defined(GL_ES_VERSION_2_0)
1586 if (myContext->core11 != NULL
1587 && myContext->IsGlGreaterEqual (2, 1))
1589 aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
1593 aSrcFragGetColor = pointSpriteShadingSrc ("gl_FrontFacing ? FrontColor : BackColor", theBits);
1598 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1600 aSrcVertExtraOut += THE_VARY_TexCoord_OUT;
1601 aSrcFragExtraOut += THE_VARY_TexCoord_IN;
1602 aSrcVertExtraMain += THE_VARY_TexCoord_Trsf;
1605 EOL"vec4 getColor(void)"
1607 EOL" vec4 aColor = gl_FrontFacing ? FrontColor : BackColor;"
1608 EOL" return occTexture2D(occActiveSampler, TexCoord.st / TexCoord.w) * aColor;"
1613 if ((theBits & OpenGl_PO_VertColor) != 0)
1615 aSrcVertColor = EOL"vec4 getVertColor(void) { return occVertColor; }";
1618 if ((theBits & OpenGl_PO_ClipPlanesN) != 0)
1621 EOL"THE_SHADER_OUT vec4 PositionWorld;"
1622 EOL"THE_SHADER_OUT vec4 Position;";
1624 EOL"THE_SHADER_IN vec4 PositionWorld;"
1625 EOL"THE_SHADER_IN vec4 Position;";
1626 aSrcVertExtraMain +=
1627 EOL" PositionWorld = aPositionWorld;"
1628 EOL" Position = aPosition;";
1630 if ((theBits & OpenGl_PO_ClipPlanes1) != 0)
1632 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_1;
1634 else if ((theBits & OpenGl_PO_ClipPlanes2) != 0)
1636 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_2;
1640 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_N;
1644 const TCollection_AsciiString aLights = stdComputeLighting ((theBits & OpenGl_PO_VertColor) != 0);
1645 aSrcVert = TCollection_AsciiString()
1646 + THE_FUNC_transformNormal
1651 EOL"THE_SHADER_OUT vec4 FrontColor;"
1652 EOL"THE_SHADER_OUT vec4 BackColor;"
1657 EOL" vec4 aPositionWorld = occModelWorldMatrix * occVertex;"
1658 EOL" vec4 aPosition = occWorldViewMatrix * aPositionWorld;"
1659 EOL" vec3 aNormal = transformNormal (occNormal);"
1660 EOL" vec3 aView = vec3 (0.0, 0.0, 1.0);"
1661 EOL" FrontColor = computeLighting (normalize (aNormal), normalize (aView), aPosition, true);"
1662 EOL" BackColor = computeLighting (normalize (aNormal), normalize (aView), aPosition, false);"
1664 + EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1667 aSrcFrag = TCollection_AsciiString()
1668 + EOL"THE_SHADER_IN vec4 FrontColor;"
1669 EOL"THE_SHADER_IN vec4 BackColor;"
1675 + EOL" occFragColor = getColor();"
1678 #if !defined(GL_ES_VERSION_2_0)
1679 if (myContext->core32 != NULL)
1681 aProgramSrc->SetHeader ("#version 150");
1684 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1685 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1686 TCollection_AsciiString aKey;
1687 if (!Create (aProgramSrc, aKey, theProgram))
1689 theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1690 return Standard_False;
1692 return Standard_True;
1695 // =======================================================================
1696 // function : prepareStdProgramPhong
1698 // =======================================================================
1699 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram,
1700 const Standard_Integer theBits)
1702 #define thePhongCompLight "computeLighting (normalize (Normal), normalize (View), Position, gl_FrontFacing)"
1704 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1705 TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcFrag, aSrcFragExtraOut, aSrcFragGetVertColor, aSrcFragExtraMain;
1706 TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return " thePhongCompLight "; }";
1707 if ((theBits & OpenGl_PO_Point) != 0)
1709 #if defined(GL_ES_VERSION_2_0)
1710 aSrcVertExtraMain += EOL" gl_PointSize = occPointSize;";
1713 if (textureUsed (theBits))
1715 #if !defined(GL_ES_VERSION_2_0)
1716 if (myContext->core11 != NULL
1717 && myContext->IsGlGreaterEqual (2, 1))
1719 aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
1723 aSrcFragGetColor = pointSpriteShadingSrc (thePhongCompLight, theBits);
1728 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1730 aSrcVertExtraOut += THE_VARY_TexCoord_OUT;
1731 aSrcFragExtraOut += THE_VARY_TexCoord_IN;
1732 aSrcVertExtraMain += THE_VARY_TexCoord_Trsf;
1735 EOL"vec4 getColor(void)"
1737 EOL" vec4 aColor = " thePhongCompLight ";"
1738 EOL" return occTexture2D(occActiveSampler, TexCoord.st / TexCoord.w) * aColor;"
1743 if ((theBits & OpenGl_PO_VertColor) != 0)
1745 aSrcVertExtraOut += EOL"THE_SHADER_OUT vec4 VertColor;";
1746 aSrcVertExtraMain += EOL" VertColor = occVertColor;";
1747 aSrcFragGetVertColor = EOL"THE_SHADER_IN vec4 VertColor;"
1748 EOL"vec4 getVertColor(void) { return VertColor; }";
1751 if ((theBits & OpenGl_PO_ClipPlanesN) != 0)
1753 if ((theBits & OpenGl_PO_ClipPlanes1) != 0)
1755 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_1;
1757 else if ((theBits & OpenGl_PO_ClipPlanes2) != 0)
1759 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_2;
1763 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_N;
1767 aSrcVert = TCollection_AsciiString()
1768 + THE_FUNC_transformNormal
1770 EOL"THE_SHADER_OUT vec4 PositionWorld;"
1771 EOL"THE_SHADER_OUT vec4 Position;"
1772 EOL"THE_SHADER_OUT vec3 Normal;"
1773 EOL"THE_SHADER_OUT vec3 View;"
1778 EOL" PositionWorld = occModelWorldMatrix * occVertex;"
1779 EOL" Position = occWorldViewMatrix * PositionWorld;"
1780 EOL" Normal = transformNormal (occNormal);"
1781 EOL" View = vec3 (0.0, 0.0, 1.0);"
1783 + EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1786 const TCollection_AsciiString aLights = stdComputeLighting ((theBits & OpenGl_PO_VertColor) != 0);
1787 aSrcFrag = TCollection_AsciiString()
1788 + EOL"THE_SHADER_IN vec4 PositionWorld;"
1789 EOL"THE_SHADER_IN vec4 Position;"
1790 EOL"THE_SHADER_IN vec3 Normal;"
1791 EOL"THE_SHADER_IN vec3 View;"
1794 + aSrcFragGetVertColor
1801 + EOL" occFragColor = getColor();"
1804 #if !defined(GL_ES_VERSION_2_0)
1805 if (myContext->core32 != NULL)
1807 aProgramSrc->SetHeader ("#version 150");
1810 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1811 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1812 TCollection_AsciiString aKey;
1813 if (!Create (aProgramSrc, aKey, theProgram))
1815 theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1816 return Standard_False;
1818 return Standard_True;
1821 // =======================================================================
1822 // function : prepareStdProgramStereo
1824 // =======================================================================
1825 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_ShaderProgram)& theProgram,
1826 const Graphic3d_StereoMode theStereoMode)
1828 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1829 TCollection_AsciiString aSrcVert =
1830 EOL"THE_SHADER_OUT vec2 TexCoord;"
1833 EOL" TexCoord = occVertex.zw;"
1834 EOL" gl_Position = vec4(occVertex.x, occVertex.y, 0.0, 1.0);"
1837 TCollection_AsciiString aSrcFrag;
1838 switch (theStereoMode)
1840 case Graphic3d_StereoMode_Anaglyph:
1843 EOL"uniform sampler2D uLeftSampler;"
1844 EOL"uniform sampler2D uRightSampler;"
1846 EOL"uniform mat4 uMultL;"
1847 EOL"uniform mat4 uMultR;"
1849 EOL"const vec4 THE_POW_UP = vec4 (2.2, 2.2, 2.2, 1.0);"
1850 EOL"const vec4 THE_POW_DOWN = 1.0 / vec4 (2.2, 2.2, 2.2, 1.0);"
1852 EOL"THE_SHADER_IN vec2 TexCoord;"
1856 EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
1857 EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
1858 EOL" aColorL = pow (aColorL, THE_POW_UP);" // normalize
1859 EOL" aColorR = pow (aColorR, THE_POW_UP);"
1860 EOL" vec4 aColor = uMultR * aColorR + uMultL * aColorL;"
1861 EOL" occFragColor = pow (aColor, THE_POW_DOWN);"
1865 case Graphic3d_StereoMode_RowInterlaced:
1868 EOL"uniform sampler2D uLeftSampler;"
1869 EOL"uniform sampler2D uRightSampler;"
1871 EOL"THE_SHADER_IN vec2 TexCoord;"
1875 EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
1876 EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
1877 EOL" if (int (mod (gl_FragCoord.y - 1023.5, 2.0)) != 1)"
1879 EOL" occFragColor = aColorL;"
1883 EOL" occFragColor = aColorR;"
1888 case Graphic3d_StereoMode_ColumnInterlaced:
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" if (int (mod (gl_FragCoord.x - 1023.5, 2.0)) == 1)"
1902 EOL" occFragColor = aColorL;"
1906 EOL" occFragColor = aColorR;"
1911 case Graphic3d_StereoMode_ChessBoard:
1914 EOL"uniform sampler2D uLeftSampler;"
1915 EOL"uniform sampler2D uRightSampler;"
1917 EOL"THE_SHADER_IN vec2 TexCoord;"
1921 EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
1922 EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
1923 EOL" bool isEvenX = int(mod(floor(gl_FragCoord.x - 1023.5), 2.0)) != 1;"
1924 EOL" bool isEvenY = int(mod(floor(gl_FragCoord.y - 1023.5), 2.0)) == 1;"
1925 EOL" if ((isEvenX && isEvenY) || (!isEvenX && !isEvenY))"
1927 EOL" occFragColor = aColorL;"
1931 EOL" occFragColor = aColorR;"
1936 case Graphic3d_StereoMode_SideBySide:
1939 EOL"uniform sampler2D uLeftSampler;"
1940 EOL"uniform sampler2D uRightSampler;"
1942 EOL"THE_SHADER_IN vec2 TexCoord;"
1946 EOL" vec2 aTexCoord = vec2 (TexCoord.x * 2.0, TexCoord.y);"
1947 EOL" if (TexCoord.x > 0.5)"
1949 EOL" aTexCoord.x -= 1.0;"
1951 EOL" vec4 aColorL = occTexture2D (uLeftSampler, aTexCoord);"
1952 EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoord);"
1953 EOL" if (TexCoord.x <= 0.5)"
1955 EOL" occFragColor = aColorL;"
1959 EOL" occFragColor = aColorR;"
1964 case Graphic3d_StereoMode_OverUnder:
1967 EOL"uniform sampler2D uLeftSampler;"
1968 EOL"uniform sampler2D uRightSampler;"
1970 EOL"THE_SHADER_IN vec2 TexCoord;"
1974 EOL" vec2 aTexCoord = vec2 (TexCoord.x, TexCoord.y * 2.0);"
1975 EOL" if (TexCoord.y > 0.5)"
1977 EOL" aTexCoord.y -= 1.0;"
1979 EOL" vec4 aColorL = occTexture2D (uLeftSampler, aTexCoord);"
1980 EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoord);"
1981 EOL" if (TexCoord.y <= 0.5)"
1983 EOL" occFragColor = aColorL;"
1987 EOL" occFragColor = aColorR;"
1992 case Graphic3d_StereoMode_QuadBuffer:
1993 case Graphic3d_StereoMode_SoftPageFlip:
1996 /*const Handle(OpenGl_ShaderProgram)& aProgram = myStereoPrograms[Graphic3d_StereoMode_QuadBuffer];
1997 if (!aProgram.IsNull())
1999 return aProgram->IsValid();
2002 EOL"uniform sampler2D uLeftSampler;"
2003 EOL"uniform sampler2D uRightSampler;"
2005 EOL"THE_SHADER_IN vec2 TexCoord;"
2009 EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
2010 EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
2011 EOL" aColorL.b = 0.0;"
2012 EOL" aColorL.g = 0.0;"
2013 EOL" aColorR.r = 0.0;"
2014 EOL" occFragColor = aColorL + aColorR;"
2020 #if !defined(GL_ES_VERSION_2_0)
2021 if (myContext->core32 != NULL)
2023 aProgramSrc->SetHeader ("#version 150");
2027 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
2028 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
2029 TCollection_AsciiString aKey;
2030 if (!Create (aProgramSrc, aKey, theProgram))
2032 theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
2033 return Standard_False;
2036 myContext->BindProgram (theProgram);
2037 theProgram->SetSampler (myContext, "uLeftSampler", 0);
2038 theProgram->SetSampler (myContext, "uRightSampler", 1);
2039 myContext->BindProgram (NULL);
2040 return Standard_True;
2043 // =======================================================================
2044 // function : bindProgramWithState
2046 // =======================================================================
2047 Standard_Boolean OpenGl_ShaderManager::bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram)
2049 const Standard_Boolean isBound = myContext->BindProgram (theProgram);
2051 && !theProgram.IsNull())
2053 theProgram->ApplyVariables (myContext);
2055 PushState (theProgram);