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_Aspects.hxx>
20 #include <OpenGl_ClippingIterator.hxx>
21 #include <OpenGl_Context.hxx>
22 #include <OpenGl_ShaderManager.hxx>
23 #include <OpenGl_ShaderProgram.hxx>
24 #include <OpenGl_VertexBufferCompat.hxx>
25 #include <OpenGl_PointSprite.hxx>
26 #include <OpenGl_Workspace.hxx>
28 #include <TCollection_ExtendedString.hxx>
30 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager,Standard_Transient)
34 //! Number specifying maximum number of light sources to prepare a GLSL program with unrolled loop.
35 const Standard_Integer THE_NB_UNROLLED_LIGHTS_MAX = 32;
37 //! Compute the size of array storing holding light sources definition.
38 static Standard_Integer roundUpMaxLightSources (Standard_Integer theNbLights)
40 Standard_Integer aMaxLimit = THE_NB_UNROLLED_LIGHTS_MAX;
41 for (; aMaxLimit < theNbLights; aMaxLimit *= 2) {}
47 //! Compute TexCoord value in Vertex Shader
48 const char THE_VARY_TexCoord_Trsf[] =
49 EOL" float aRotSin = occTextureTrsf_RotationSin();"
50 EOL" float aRotCos = occTextureTrsf_RotationCos();"
51 EOL" vec2 aTex2 = (occTexCoord.xy + occTextureTrsf_Translation()) * occTextureTrsf_Scale();"
52 EOL" vec2 aCopy = aTex2;"
53 EOL" aTex2.x = aCopy.x * aRotCos - aCopy.y * aRotSin;"
54 EOL" aTex2.y = aCopy.x * aRotSin + aCopy.y * aRotCos;"
55 EOL" TexCoord = vec4(aTex2, occTexCoord.zw);";
57 //! Auxiliary function to flip gl_PointCoord vertically
58 #define THE_VEC2_glPointCoord "vec2 (gl_PointCoord.x, 1.0 - gl_PointCoord.y)"
60 //! Auxiliary function to transform normal
61 const char THE_FUNC_transformNormal[] =
62 EOL"vec3 transformNormal (in vec3 theNormal)"
64 EOL" vec4 aResult = occWorldViewMatrixInverseTranspose"
65 EOL" * occModelWorldMatrixInverseTranspose"
66 EOL" * vec4 (theNormal, 0.0);"
67 EOL" return normalize (aResult.xyz);"
70 //! Global shader variable for color definition with lighting enabled.
71 const char THE_FUNC_lightDef[] =
72 EOL"vec3 Ambient;" //!< Ambient contribution of light sources
73 EOL"vec3 Diffuse;" //!< Diffuse contribution of light sources
74 EOL"vec3 Specular;"; //!< Specular contribution of light sources
76 //! Function computes contribution of isotropic point light source
77 const char THE_FUNC_pointLight[] =
78 EOL"void pointLight (in int theId,"
79 EOL" in vec3 theNormal,"
80 EOL" in vec3 theView,"
81 EOL" in vec3 thePoint,"
82 EOL" in bool theIsFront)"
84 EOL" vec3 aLight = occLight_Position (theId).xyz;"
85 EOL" if (occLight_IsHeadlight (theId) == 0)"
87 EOL" aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0));"
89 EOL" aLight -= thePoint;"
91 EOL" float aDist = length (aLight);"
92 EOL" aLight = aLight * (1.0 / aDist);"
94 EOL" float anAtten = 1.0 / (occLight_ConstAttenuation (theId)"
95 EOL" + occLight_LinearAttenuation (theId) * aDist);"
97 EOL" vec3 aHalf = normalize (aLight + theView);"
99 EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
100 EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
101 EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
103 EOL" float aSpecl = 0.0;"
104 EOL" if (aNdotL > 0.0)"
106 EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
109 EOL" Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten;"
110 EOL" Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;"
113 //! Function computes contribution of spotlight source
114 const char THE_FUNC_spotLight[] =
115 EOL"void spotLight (in int theId,"
116 EOL" in vec3 theNormal,"
117 EOL" in vec3 theView,"
118 EOL" in vec3 thePoint,"
119 EOL" in bool theIsFront)"
121 EOL" vec3 aLight = occLight_Position (theId).xyz;"
122 EOL" vec3 aSpotDir = occLight_SpotDirection (theId).xyz;"
123 EOL" if (occLight_IsHeadlight (theId) == 0)"
125 EOL" aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 1.0));"
126 EOL" aSpotDir = vec3 (occWorldViewMatrix * vec4 (aSpotDir, 0.0));"
128 EOL" aLight -= thePoint;"
130 EOL" float aDist = length (aLight);"
131 EOL" aLight = aLight * (1.0 / aDist);"
133 EOL" aSpotDir = normalize (aSpotDir);"
135 EOL" float aCosA = dot (aSpotDir, -aLight);"
136 EOL" if (aCosA >= 1.0 || aCosA < cos (occLight_SpotCutOff (theId)))"
141 EOL" float anExponent = occLight_SpotExponent (theId);"
142 EOL" float anAtten = 1.0 / (occLight_ConstAttenuation (theId)"
143 EOL" + occLight_LinearAttenuation (theId) * aDist);"
144 EOL" if (anExponent > 0.0)"
146 EOL" anAtten *= pow (aCosA, anExponent * 128.0);"
149 EOL" vec3 aHalf = normalize (aLight + theView);"
151 EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
152 EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
153 EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
155 EOL" float aSpecl = 0.0;"
156 EOL" if (aNdotL > 0.0)"
158 EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
161 EOL" Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten;"
162 EOL" Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;"
165 //! Function computes contribution of directional light source
166 const char THE_FUNC_directionalLight[] =
167 EOL"void directionalLight (in int theId,"
168 EOL" in vec3 theNormal,"
169 EOL" in vec3 theView,"
170 EOL" in bool theIsFront)"
172 EOL" vec3 aLight = normalize (occLight_Position (theId).xyz);"
173 EOL" if (occLight_IsHeadlight (theId) == 0)"
175 EOL" aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0));"
178 EOL" vec3 aHalf = normalize (aLight + theView);"
180 EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
181 EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
182 EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
184 EOL" float aSpecl = 0.0;"
185 EOL" if (aNdotL > 0.0)"
187 EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
190 EOL" Diffuse += occLight_Diffuse (theId).rgb * aNdotL;"
191 EOL" Specular += occLight_Specular (theId).rgb * aSpecl;"
194 //! The same as THE_FUNC_directionalLight but for the light with zero index
195 //! (avoids limitations on some mobile devices).
196 const char THE_FUNC_directionalLightFirst[] =
197 EOL"void directionalLightFirst (in vec3 theNormal,"
198 EOL" in vec3 theView,"
199 EOL" in bool theIsFront)"
201 EOL" vec3 aLight = normalize (occLightSources[1].xyz);"
202 EOL" if (occLight_IsHeadlight (0) == 0)"
204 EOL" aLight = vec3 (occWorldViewMatrix * vec4 (aLight, 0.0));"
207 EOL" vec3 aHalf = normalize (aLight + theView);"
209 EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
210 EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
211 EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
213 EOL" float aSpecl = 0.0;"
214 EOL" if (aNdotL > 0.0)"
216 EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
219 EOL" Diffuse += occLightSources[0].rgb * aNdotL;"
220 EOL" Specular += occLightSources[0].rgb * aSpecl;"
223 //! Process clipping planes in Fragment Shader.
224 //! Should be added at the beginning of the main() function.
225 const char THE_FRAG_CLIP_PLANES_N[] =
226 EOL" for (int aPlaneIter = 0; aPlaneIter < occClipPlaneCount; ++aPlaneIter)"
228 EOL" vec4 aClipEquation = occClipPlaneEquations[aPlaneIter];"
229 EOL" if (dot (aClipEquation.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation.w < 0.0)"
235 //! Process chains of clipping planes in Fragment Shader.
236 const char THE_FRAG_CLIP_CHAINS_N[] =
237 EOL" for (int aPlaneIter = 0; aPlaneIter < occClipPlaneCount;)"
239 EOL" vec4 aClipEquation = occClipPlaneEquations[aPlaneIter];"
240 EOL" if (dot (aClipEquation.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation.w < 0.0)"
242 EOL" if (occClipPlaneChains[aPlaneIter] == 1)"
246 EOL" aPlaneIter += 1;"
250 EOL" aPlaneIter += occClipPlaneChains[aPlaneIter];"
254 //! Process 1 clipping plane in Fragment Shader.
255 const char THE_FRAG_CLIP_PLANES_1[] =
256 EOL" vec4 aClipEquation0 = occClipPlaneEquations[0];"
257 EOL" if (dot (aClipEquation0.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation0.w < 0.0)"
262 //! Process 2 clipping planes in Fragment Shader.
263 const char THE_FRAG_CLIP_PLANES_2[] =
264 EOL" vec4 aClipEquation0 = occClipPlaneEquations[0];"
265 EOL" vec4 aClipEquation1 = occClipPlaneEquations[1];"
266 EOL" if (dot (aClipEquation0.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation0.w < 0.0"
267 EOL" || dot (aClipEquation1.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation1.w < 0.0)"
272 //! Process a chain of 2 clipping planes in Fragment Shader (3/4 section).
273 const char THE_FRAG_CLIP_CHAINS_2[] =
274 EOL" vec4 aClipEquation0 = occClipPlaneEquations[0];"
275 EOL" vec4 aClipEquation1 = occClipPlaneEquations[1];"
276 EOL" if (dot (aClipEquation0.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation0.w < 0.0"
277 EOL" && dot (aClipEquation1.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation1.w < 0.0)"
282 //! Modify color for Wireframe presentation.
283 const char THE_FRAG_WIREFRAME_COLOR[] =
284 EOL"vec4 getFinalColor(void)"
286 EOL" float aDistance = min (min (EdgeDistance[0], EdgeDistance[1]), EdgeDistance[2]);"
287 EOL" bool isHollow = occWireframeColor.a < 0.0;"
288 EOL" float aMixVal = smoothstep (occLineWidth - occLineFeather * 0.5, occLineWidth + occLineFeather * 0.5, aDistance);"
289 EOL" vec4 aMixColor = isHollow"
290 EOL" ? vec4 (getColor().rgb, 1.0 - aMixVal)" // edges only (of interior color)
291 EOL" : mix (occWireframeColor, getColor(), aMixVal);" // interior + edges
292 EOL" return aMixColor;"
295 //! Compute gl_Position vertex shader output.
296 const char THE_VERT_gl_Position[] =
297 EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;";
299 //! Displace gl_Position alongside vertex normal for outline rendering.
300 //! This code adds silhouette only for smooth surfaces of closed primitive, and produces visual artifacts on sharp edges.
301 const char THE_VERT_gl_Position_OUTLINE[] =
302 EOL" float anOutlineDisp = occOrthoScale > 0.0 ? occOrthoScale : gl_Position.w;"
303 EOL" vec4 anOutlinePos = occVertex + vec4 (occNormal * (occSilhouetteThickness * anOutlineDisp), 0.0);"
304 EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * anOutlinePos;";
306 #if !defined(GL_ES_VERSION_2_0)
308 static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
309 static const GLfloat THE_DEFAULT_SPOT_DIR[3] = { 0.0f, 0.0f, -1.0f };
310 static const GLfloat THE_DEFAULT_SPOT_EXPONENT = 0.0f;
311 static const GLfloat THE_DEFAULT_SPOT_CUTOFF = 180.0f;
313 //! Bind FFP light source.
314 static void bindLight (const Graphic3d_CLight& theLight,
315 const GLenum theLightGlId,
316 const OpenGl_Mat4& theModelView,
317 OpenGl_Context* theCtx)
319 // the light is a headlight?
320 if (theLight.IsHeadlight())
322 theCtx->core11->glMatrixMode (GL_MODELVIEW);
323 theCtx->core11->glLoadIdentity();
327 const Graphic3d_Vec4& aLightColor = theLight.PackedColor();
328 switch (theLight.Type())
330 case Graphic3d_TOLS_AMBIENT : break; // handled by separate if-clause at beginning of method
331 case Graphic3d_TOLS_DIRECTIONAL:
333 // if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one
334 const OpenGl_Vec4 anInfDir = -theLight.PackedDirection();
336 // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE.
337 theCtx->core11->glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
338 theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE, aLightColor.GetData());
339 theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR, aLightColor.GetData());
340 theCtx->core11->glLightfv (theLightGlId, GL_POSITION, anInfDir.GetData());
341 theCtx->core11->glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
342 theCtx->core11->glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
343 theCtx->core11->glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
346 case Graphic3d_TOLS_POSITIONAL:
348 // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE
349 const OpenGl_Vec4 aPosition (static_cast<float>(theLight.Position().X()), static_cast<float>(theLight.Position().Y()), static_cast<float>(theLight.Position().Z()), 1.0f);
350 theCtx->core11->glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
351 theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE, aLightColor.GetData());
352 theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR, aLightColor.GetData());
353 theCtx->core11->glLightfv (theLightGlId, GL_POSITION, aPosition.GetData());
354 theCtx->core11->glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
355 theCtx->core11->glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
356 theCtx->core11->glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
357 theCtx->core11->glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
358 theCtx->core11->glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
359 theCtx->core11->glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0);
362 case Graphic3d_TOLS_SPOT:
364 const OpenGl_Vec4 aPosition (static_cast<float>(theLight.Position().X()), static_cast<float>(theLight.Position().Y()), static_cast<float>(theLight.Position().Z()), 1.0f);
365 theCtx->core11->glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
366 theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE, aLightColor.GetData());
367 theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR, aLightColor.GetData());
368 theCtx->core11->glLightfv (theLightGlId, GL_POSITION, aPosition.GetData());
369 theCtx->core11->glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.PackedDirection().GetData());
370 theCtx->core11->glLightf (theLightGlId, GL_SPOT_EXPONENT, theLight.Concentration() * 128.0f);
371 theCtx->core11->glLightf (theLightGlId, GL_SPOT_CUTOFF, (theLight.Angle() * 180.0f) / GLfloat(M_PI));
372 theCtx->core11->glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
373 theCtx->core11->glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
374 theCtx->core11->glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0f);
379 // restore matrix in case of headlight
380 if (theLight.IsHeadlight())
382 theCtx->core11->glLoadMatrixf (theModelView.GetData());
385 glEnable (theLightGlId);
389 //! Generate map key for light sources configuration.
390 static TCollection_AsciiString genLightKey (const Handle(Graphic3d_LightSet)& theLights)
392 if (theLights->NbEnabled() <= THE_NB_UNROLLED_LIGHTS_MAX)
394 return TCollection_AsciiString ("l_") + theLights->KeyEnabledLong();
397 const Standard_Integer aMaxLimit = roundUpMaxLightSources (theLights->NbEnabled());
398 return TCollection_AsciiString ("l_") + theLights->KeyEnabledShort() + aMaxLimit;
402 // =======================================================================
403 // function : OpenGl_ShaderManager
404 // purpose : Creates new empty shader manager
405 // =======================================================================
406 OpenGl_ShaderManager::OpenGl_ShaderManager (OpenGl_Context* theContext)
407 : myFfpProgram (new OpenGl_ShaderProgramFFP()),
408 myShadingModel (Graphic3d_TOSM_VERTEX),
409 myUnlitPrograms (new OpenGl_SetOfPrograms()),
410 myContext (theContext),
411 myHasLocalOrigin (Standard_False),
417 // =======================================================================
418 // function : ~OpenGl_ShaderManager
419 // purpose : Releases resources of shader manager
420 // =======================================================================
421 OpenGl_ShaderManager::~OpenGl_ShaderManager()
423 myProgramList.Clear();
426 // =======================================================================
429 // =======================================================================
430 void OpenGl_ShaderManager::clear()
432 myProgramList.Clear();
433 myLightPrograms.Nullify();
434 myUnlitPrograms = new OpenGl_SetOfPrograms();
435 myOutlinePrograms.Nullify();
436 myMapOfLightPrograms.Clear();
437 myFontProgram.Nullify();
438 myBlitProgram.Nullify();
439 myBoundBoxProgram.Nullify();
440 myBoundBoxVertBuffer.Nullify();
441 for (Standard_Integer aModeIter = 0; aModeIter < Graphic3d_StereoMode_NB; ++aModeIter)
443 myStereoPrograms[aModeIter].Nullify();
445 switchLightPrograms();
448 // =======================================================================
450 // purpose : Creates new shader program
451 // =======================================================================
452 Standard_Boolean OpenGl_ShaderManager::Create (const Handle(Graphic3d_ShaderProgram)& theProxy,
453 TCollection_AsciiString& theShareKey,
454 Handle(OpenGl_ShaderProgram)& theProgram)
456 theProgram.Nullify();
457 if (theProxy.IsNull())
459 return Standard_False;
462 theShareKey = theProxy->GetId();
463 if (myContext->GetResource<Handle(OpenGl_ShaderProgram)> (theShareKey, theProgram))
465 if (theProgram->Share())
467 myProgramList.Append (theProgram);
469 return Standard_True;
472 theProgram = new OpenGl_ShaderProgram (theProxy);
473 if (!theProgram->Initialize (myContext, theProxy->ShaderObjects()))
475 theProgram->Release (myContext);
477 theProgram.Nullify();
478 return Standard_False;
481 myProgramList.Append (theProgram);
482 myContext->ShareResource (theShareKey, theProgram);
483 return Standard_True;
486 // =======================================================================
487 // function : Unregister
488 // purpose : Removes specified shader program from the manager
489 // =======================================================================
490 void OpenGl_ShaderManager::Unregister (TCollection_AsciiString& theShareKey,
491 Handle(OpenGl_ShaderProgram)& theProgram)
493 for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
495 if (anIt.Value() == theProgram)
497 if (!theProgram->UnShare())
500 theProgram.Nullify();
504 myProgramList.Remove (anIt);
509 const TCollection_AsciiString anID = theProgram->myProxy->GetId();
512 myContext->DelayedRelease (theProgram);
513 theProgram.Nullify();
517 theProgram.Nullify();
518 myContext->ReleaseResource (anID, Standard_True);
522 // =======================================================================
523 // function : ShaderPrograms
524 // purpose : Returns list of registered shader programs
525 // =======================================================================
526 const OpenGl_ShaderProgramList& OpenGl_ShaderManager::ShaderPrograms() const
528 return myProgramList;
531 // =======================================================================
533 // purpose : Returns true if no program objects are attached
534 // =======================================================================
535 Standard_Boolean OpenGl_ShaderManager::IsEmpty() const
537 return myProgramList.IsEmpty();
540 // =======================================================================
541 // function : switchLightPrograms
543 // =======================================================================
544 void OpenGl_ShaderManager::switchLightPrograms()
546 const Handle(Graphic3d_LightSet)& aLights = myLightSourceState.LightSources();
547 if (aLights.IsNull())
549 if (!myMapOfLightPrograms.Find ("unlit", myLightPrograms))
551 myLightPrograms = new OpenGl_SetOfShaderPrograms (myUnlitPrograms);
552 myMapOfLightPrograms.Bind ("unlit", myLightPrograms);
557 const TCollection_AsciiString aKey = genLightKey (aLights);
558 if (!myMapOfLightPrograms.Find (aKey, myLightPrograms))
560 myLightPrograms = new OpenGl_SetOfShaderPrograms();
561 myMapOfLightPrograms.Bind (aKey, myLightPrograms);
565 // =======================================================================
566 // function : UpdateLightSourceStateTo
567 // purpose : Updates state of OCCT light sources
568 // =======================================================================
569 void OpenGl_ShaderManager::UpdateLightSourceStateTo (const Handle(Graphic3d_LightSet)& theLights)
571 myLightSourceState.Set (theLights);
572 myLightSourceState.Update();
573 switchLightPrograms();
576 // =======================================================================
577 // function : UpdateLightSourceState
579 // =======================================================================
580 void OpenGl_ShaderManager::UpdateLightSourceState()
582 myLightSourceState.Update();
585 // =======================================================================
586 // function : SetShadingModel
588 // =======================================================================
589 void OpenGl_ShaderManager::SetShadingModel (const Graphic3d_TypeOfShadingModel theModel)
591 if (theModel == Graphic3d_TOSM_DEFAULT)
593 throw Standard_ProgramError ("OpenGl_ShaderManager::SetShadingModel() - attempt to set invalid Shading Model!");
596 myShadingModel = theModel;
597 switchLightPrograms();
600 // =======================================================================
601 // function : SetProjectionState
602 // purpose : Sets new state of OCCT projection transform
603 // =======================================================================
604 void OpenGl_ShaderManager::UpdateProjectionStateTo (const OpenGl_Mat4& theProjectionMatrix)
606 myProjectionState.Set (theProjectionMatrix);
607 myProjectionState.Update();
610 // =======================================================================
611 // function : SetModelWorldState
612 // purpose : Sets new state of OCCT model-world transform
613 // =======================================================================
614 void OpenGl_ShaderManager::UpdateModelWorldStateTo (const OpenGl_Mat4& theModelWorldMatrix)
616 myModelWorldState.Set (theModelWorldMatrix);
617 myModelWorldState.Update();
620 // =======================================================================
621 // function : SetWorldViewState
622 // purpose : Sets new state of OCCT world-view transform
623 // =======================================================================
624 void OpenGl_ShaderManager::UpdateWorldViewStateTo (const OpenGl_Mat4& theWorldViewMatrix)
626 myWorldViewState.Set (theWorldViewMatrix);
627 myWorldViewState.Update();
630 // =======================================================================
631 // function : PushLightSourceState
632 // purpose : Pushes state of OCCT light sources to the program
633 // =======================================================================
634 void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
636 if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE))
641 theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
642 if (theProgram == myFfpProgram)
644 #if !defined(GL_ES_VERSION_2_0)
645 if (myContext->core11 == NULL)
650 GLenum aLightGlId = GL_LIGHT0;
651 const OpenGl_Mat4 aModelView = myWorldViewState.WorldViewMatrix() * myModelWorldState.ModelWorldMatrix();
652 for (Graphic3d_LightSet::Iterator aLightIt (myLightSourceState.LightSources(), Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient);
653 aLightIt.More(); aLightIt.Next())
655 if (aLightGlId > GL_LIGHT7) // only 8 lights in FFP...
657 myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
658 "Warning: light sources limit (8) has been exceeded within Fixed-function pipeline.");
662 bindLight (*aLightIt.Value(), aLightGlId, aModelView, myContext);
666 // apply accumulated ambient color
667 const Graphic3d_Vec4 anAmbient = !myLightSourceState.LightSources().IsNull()
668 ? myLightSourceState.LightSources()->AmbientColor()
669 : Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 1.0f);
670 myContext->core11->glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbient.GetData());
672 // GL_LIGHTING is managed by drawers to switch between shaded / no lighting output,
673 // therefore managing the state here does not have any effect - do it just for consistency.
674 if (aLightGlId != GL_LIGHT0)
676 ::glEnable (GL_LIGHTING);
680 ::glDisable (GL_LIGHTING);
682 // switch off unused lights
683 for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
685 ::glDisable (aLightGlId);
691 const Standard_Integer aNbLightsMax = theProgram->NbLightsMax();
692 const GLint anAmbientLoc = theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT);
693 if (aNbLightsMax == 0
694 && anAmbientLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
699 if (myLightTypeArray.Size() < aNbLightsMax)
701 myLightTypeArray .Resize (0, aNbLightsMax - 1, false);
702 myLightParamsArray.Resize (0, aNbLightsMax - 1, false);
704 for (Standard_Integer aLightIt = 0; aLightIt < aNbLightsMax; ++aLightIt)
706 myLightTypeArray.ChangeValue (aLightIt).Type = -1;
709 if (myLightSourceState.LightSources().IsNull()
710 || myLightSourceState.LightSources()->IsEmpty())
712 theProgram->SetUniform (myContext,
713 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
715 theProgram->SetUniform (myContext,
717 OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
718 theProgram->SetUniform (myContext,
719 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
720 aNbLightsMax * OpenGl_ShaderLightType::NbOfVec2i(),
721 myLightTypeArray.First().Packed());
725 Standard_Integer aLightsNb = 0;
726 for (Graphic3d_LightSet::Iterator anIter (myLightSourceState.LightSources(), Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient);
727 anIter.More(); anIter.Next())
729 const Graphic3d_CLight& aLight = *anIter.Value();
730 if (aLightsNb >= aNbLightsMax)
732 if (aNbLightsMax != 0)
734 myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
735 TCollection_AsciiString("Warning: light sources limit (") + aNbLightsMax + ") has been exceeded.");
740 OpenGl_ShaderLightType& aLightType = myLightTypeArray.ChangeValue (aLightsNb);
741 OpenGl_ShaderLightParameters& aLightParams = myLightParamsArray.ChangeValue (aLightsNb);
742 if (!aLight.IsEnabled()) // has no affect with Graphic3d_LightSet::IterationFilter_ExcludeDisabled - here just for consistency
744 // if it is desired to keep disabled light in the same order - we can replace it with a black light so that it will have no influence on result
745 aLightType.Type = -1; // Graphic3d_TOLS_AMBIENT can be used instead
746 aLightType.IsHeadlight = false;
747 aLightParams.Color = OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 0.0f);
752 aLightType.Type = aLight.Type();
753 aLightType.IsHeadlight = aLight.IsHeadlight();
754 aLightParams.Color = aLight.PackedColor();
755 if (aLight.Type() == Graphic3d_TOLS_DIRECTIONAL)
757 aLightParams.Position = -aLight.PackedDirection();
759 else if (!aLight.IsHeadlight())
761 aLightParams.Position.x() = static_cast<float>(aLight.Position().X() - myLocalOrigin.X());
762 aLightParams.Position.y() = static_cast<float>(aLight.Position().Y() - myLocalOrigin.Y());
763 aLightParams.Position.z() = static_cast<float>(aLight.Position().Z() - myLocalOrigin.Z());
764 aLightParams.Position.w() = 1.0f;
768 aLightParams.Position.x() = static_cast<float>(aLight.Position().X());
769 aLightParams.Position.y() = static_cast<float>(aLight.Position().Y());
770 aLightParams.Position.z() = static_cast<float>(aLight.Position().Z());
771 aLightParams.Position.w() = 1.0f;
774 if (aLight.Type() == Graphic3d_TOLS_SPOT)
776 aLightParams.Direction = aLight.PackedDirection();
778 aLightParams.Parameters = aLight.PackedParams();
782 const Graphic3d_Vec4& anAmbient = myLightSourceState.LightSources()->AmbientColor();
783 theProgram->SetUniform (myContext,
784 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
786 theProgram->SetUniform (myContext,
789 theProgram->SetUniform (myContext,
790 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
791 aNbLightsMax * OpenGl_ShaderLightType::NbOfVec2i(),
792 myLightTypeArray.First().Packed());
795 theProgram->SetUniform (myContext,
796 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_PARAMS),
797 aLightsNb * OpenGl_ShaderLightParameters::NbOfVec4(),
798 myLightParamsArray.First().Packed());
802 // =======================================================================
803 // function : PushProjectionState
804 // purpose : Pushes state of OCCT projection transform to the program
805 // =======================================================================
806 void OpenGl_ShaderManager::PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const
808 if (myProjectionState.Index() == theProgram->ActiveState (OpenGl_PROJECTION_STATE))
813 theProgram->UpdateState (OpenGl_PROJECTION_STATE, myProjectionState.Index());
814 if (theProgram == myFfpProgram)
816 #if !defined(GL_ES_VERSION_2_0)
817 if (myContext->core11 != NULL)
819 myContext->core11->glMatrixMode (GL_PROJECTION);
820 myContext->core11->glLoadMatrixf (myProjectionState.ProjectionMatrix());
826 theProgram->SetUniform (myContext,
827 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX),
828 myProjectionState.ProjectionMatrix());
830 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE);
831 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
833 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse());
836 theProgram->SetUniform (myContext,
837 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE),
838 myProjectionState.ProjectionMatrix(), true);
840 aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE);
841 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
843 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse(), true);
847 // =======================================================================
848 // function : PushModelWorldState
849 // purpose : Pushes state of OCCT model-world transform to the program
850 // =======================================================================
851 void OpenGl_ShaderManager::PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const
853 if (myModelWorldState.Index() == theProgram->ActiveState (OpenGl_MODEL_WORLD_STATE))
858 theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
859 if (theProgram == myFfpProgram)
861 #if !defined(GL_ES_VERSION_2_0)
862 if (myContext->core11 != NULL)
864 const OpenGl_Mat4 aModelView = myWorldViewState.WorldViewMatrix() * myModelWorldState.ModelWorldMatrix();
865 myContext->core11->glMatrixMode (GL_MODELVIEW);
866 myContext->core11->glLoadMatrixf (aModelView.GetData());
867 theProgram->UpdateState (OpenGl_WORLD_VIEW_STATE, myWorldViewState.Index());
873 theProgram->SetUniform (myContext,
874 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX),
875 myModelWorldState.ModelWorldMatrix());
877 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE);
878 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
880 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse());
883 theProgram->SetUniform (myContext,
884 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE),
885 myModelWorldState.ModelWorldMatrix(), true);
887 aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE);
888 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
890 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse(), true);
894 // =======================================================================
895 // function : PushWorldViewState
896 // purpose : Pushes state of OCCT world-view transform to the program
897 // =======================================================================
898 void OpenGl_ShaderManager::PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const
900 if (myWorldViewState.Index() == theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE))
905 theProgram->UpdateState (OpenGl_WORLD_VIEW_STATE, myWorldViewState.Index());
906 if (theProgram == myFfpProgram)
908 #if !defined(GL_ES_VERSION_2_0)
909 if (myContext->core11 != NULL)
911 const OpenGl_Mat4 aModelView = myWorldViewState.WorldViewMatrix() * myModelWorldState.ModelWorldMatrix();
912 myContext->core11->glMatrixMode (GL_MODELVIEW);
913 myContext->core11->glLoadMatrixf (aModelView.GetData());
914 theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
920 theProgram->SetUniform (myContext,
921 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX),
922 myWorldViewState.WorldViewMatrix());
924 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE);
925 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
927 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse());
930 theProgram->SetUniform (myContext,
931 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE),
932 myWorldViewState.WorldViewMatrix(), true);
934 aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE);
935 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
937 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse(), true);
941 // =======================================================================
942 // function : UpdateClippingState
943 // purpose : Updates state of OCCT clipping planes
944 // =======================================================================
945 void OpenGl_ShaderManager::UpdateClippingState()
947 myClippingState.Update();
950 // =======================================================================
951 // function : RevertClippingState
952 // purpose : Reverts state of OCCT clipping planes
953 // =======================================================================
954 void OpenGl_ShaderManager::RevertClippingState()
956 myClippingState.Revert();
959 // =======================================================================
960 // function : PushClippingState
961 // purpose : Pushes state of OCCT clipping planes to the program
962 // =======================================================================
963 void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const
965 if (myClippingState.Index() == theProgram->ActiveState (OpenGl_CLIP_PLANES_STATE))
970 theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index());
971 if (theProgram == myFfpProgram)
973 #if !defined(GL_ES_VERSION_2_0)
974 if (myContext->core11 == NULL)
979 const Standard_Integer aNbMaxPlanes = myContext->MaxClipPlanes();
980 if (myClipPlaneArrayFfp.Size() < aNbMaxPlanes)
982 myClipPlaneArrayFfp.Resize (0, aNbMaxPlanes - 1, false);
985 Standard_Integer aPlaneId = 0;
986 Standard_Boolean toRestoreModelView = Standard_False;
987 const Handle(Graphic3d_ClipPlane)& aCappedChain = myContext->Clipping().CappedChain();
988 for (OpenGl_ClippingIterator aPlaneIter (myContext->Clipping()); aPlaneIter.More(); aPlaneIter.Next())
990 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIter.Value();
991 if (aPlaneIter.IsDisabled()
993 || (aPlane == aCappedChain
994 && myContext->Clipping().IsCappingEnableAllExcept()))
998 else if (aPlaneId >= aNbMaxPlanes)
1000 myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
1001 TCollection_ExtendedString("Warning: clipping planes limit (") + aNbMaxPlanes + ") has been exceeded.");
1005 const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
1006 OpenGl_Vec4d& aPlaneEq = myClipPlaneArrayFfp.ChangeValue (aPlaneId);
1007 aPlaneEq.x() = anEquation.x();
1008 aPlaneEq.y() = anEquation.y();
1009 aPlaneEq.z() = anEquation.z();
1010 aPlaneEq.w() = anEquation.w();
1011 if (myHasLocalOrigin)
1013 const gp_XYZ aPos = aPlane->ToPlane().Position().Location().XYZ() - myLocalOrigin;
1014 const Standard_Real aD = -(anEquation.x() * aPos.X() + anEquation.y() * aPos.Y() + anEquation.z() * aPos.Z());
1018 const GLenum anFfpPlaneID = GL_CLIP_PLANE0 + aPlaneId;
1019 if (anFfpPlaneID == GL_CLIP_PLANE0)
1021 // set either identity or pure view matrix
1022 toRestoreModelView = Standard_True;
1023 myContext->core11->glMatrixMode (GL_MODELVIEW);
1024 myContext->core11->glLoadMatrixf (myWorldViewState.WorldViewMatrix().GetData());
1027 ::glEnable (anFfpPlaneID);
1028 myContext->core11->glClipPlane (anFfpPlaneID, aPlaneEq);
1033 // switch off unused lights
1034 for (; aPlaneId < aNbMaxPlanes; ++aPlaneId)
1036 ::glDisable (GL_CLIP_PLANE0 + aPlaneId);
1039 // restore combined model-view matrix
1040 if (toRestoreModelView)
1042 const OpenGl_Mat4 aModelView = myWorldViewState.WorldViewMatrix() * myModelWorldState.ModelWorldMatrix();
1043 myContext->core11->glLoadMatrixf (aModelView.GetData());
1049 const GLint aLocEquations = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_EQUATIONS);
1050 if (aLocEquations == OpenGl_ShaderProgram::INVALID_LOCATION)
1055 const Standard_Integer aNbClipPlanesMax = theProgram->NbClipPlanesMax();
1056 const Standard_Integer aNbPlanes = Min (myContext->Clipping().NbClippingOrCappingOn(), aNbClipPlanesMax);
1059 theProgram->SetUniform (myContext, theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_COUNT), 0);
1063 if (myClipPlaneArray.Size() < aNbClipPlanesMax)
1065 myClipPlaneArray.Resize (0, aNbClipPlanesMax - 1, false);
1066 myClipChainArray.Resize (0, aNbClipPlanesMax - 1, false);
1069 Standard_Integer aPlaneId = 0;
1070 const Handle(Graphic3d_ClipPlane)& aCappedChain = myContext->Clipping().CappedChain();
1071 for (OpenGl_ClippingIterator aPlaneIter (myContext->Clipping()); aPlaneIter.More(); aPlaneIter.Next())
1073 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIter.Value();
1074 if (aPlaneIter.IsDisabled())
1079 if (myContext->Clipping().IsCappingDisableAllExcept())
1081 // enable only specific (sub) plane
1082 if (aPlane != aCappedChain)
1087 Standard_Integer aSubPlaneIndex = 1;
1088 for (const Graphic3d_ClipPlane* aSubPlaneIter = aCappedChain.get(); aSubPlaneIter != NULL; aSubPlaneIter = aSubPlaneIter->ChainNextPlane().get(), ++aSubPlaneIndex)
1090 if (aSubPlaneIndex == myContext->Clipping().CappedSubPlane())
1092 addClippingPlane (aPlaneId, *aSubPlaneIter, aSubPlaneIter->GetEquation(), 1);
1098 else if (aPlane == aCappedChain) // && myContext->Clipping().IsCappingEnableAllExcept()
1100 // enable sub-planes within processed Chain as reversed and ORed, excluding filtered plane
1101 if (aPlaneId + aPlane->NbChainNextPlanes() - 1 > aNbClipPlanesMax)
1103 myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
1104 TCollection_AsciiString("Error: clipping planes limit (") + aNbClipPlanesMax + ") has been exceeded.");
1108 Standard_Integer aSubPlaneIndex = 1;
1109 for (const Graphic3d_ClipPlane* aSubPlaneIter = aPlane.get(); aSubPlaneIter != NULL; aSubPlaneIter = aSubPlaneIter->ChainNextPlane().get(), ++aSubPlaneIndex)
1111 if (aSubPlaneIndex != -myContext->Clipping().CappedSubPlane())
1113 addClippingPlane (aPlaneId, *aSubPlaneIter, aSubPlaneIter->ReversedEquation(), 1);
1120 if (aPlaneId + aPlane->NbChainNextPlanes() > aNbClipPlanesMax)
1122 myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
1123 TCollection_AsciiString("Error: clipping planes limit (") + aNbClipPlanesMax + ") has been exceeded.");
1126 for (const Graphic3d_ClipPlane* aSubPlaneIter = aPlane.get(); aSubPlaneIter != NULL; aSubPlaneIter = aSubPlaneIter->ChainNextPlane().get())
1128 addClippingPlane (aPlaneId, *aSubPlaneIter, aSubPlaneIter->GetEquation(), aSubPlaneIter->NbChainNextPlanes());
1133 theProgram->SetUniform (myContext, theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_COUNT), aPlaneId);
1134 theProgram->SetUniform (myContext, aLocEquations, aNbClipPlanesMax, &myClipPlaneArray.First());
1135 theProgram->SetUniform (myContext, theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_CHAINS), aNbClipPlanesMax, &myClipChainArray.First());
1138 // =======================================================================
1139 // function : PushMaterialState
1141 // =======================================================================
1142 void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
1144 if (myMaterialState.Index() == theProgram->ActiveState (OpenGl_MATERIAL_STATE))
1149 const OpenGl_Material& aFrontMat = myMaterialState.FrontMaterial();
1150 const OpenGl_Material& aBackMat = myMaterialState.BackMaterial();
1151 theProgram->UpdateState (OpenGl_MATERIAL_STATE, myMaterialState.Index());
1152 if (theProgram == myFfpProgram)
1154 #if !defined(GL_ES_VERSION_2_0)
1155 if (myContext->core11 == NULL)
1160 if (myMaterialState.AlphaCutoff() < ShortRealLast())
1162 glAlphaFunc (GL_GEQUAL, myMaterialState.AlphaCutoff());
1163 glEnable (GL_ALPHA_TEST);
1167 glDisable (GL_ALPHA_TEST);
1170 const GLenum aFrontFace = myMaterialState.ToDistinguish() ? GL_FRONT : GL_FRONT_AND_BACK;
1171 myContext->core11->glMaterialfv(aFrontFace, GL_AMBIENT, aFrontMat.Ambient.GetData());
1172 myContext->core11->glMaterialfv(aFrontFace, GL_DIFFUSE, aFrontMat.Diffuse.GetData());
1173 myContext->core11->glMaterialfv(aFrontFace, GL_SPECULAR, aFrontMat.Specular.GetData());
1174 myContext->core11->glMaterialfv(aFrontFace, GL_EMISSION, aFrontMat.Emission.GetData());
1175 myContext->core11->glMaterialf (aFrontFace, GL_SHININESS, aFrontMat.Shine());
1176 if (myMaterialState.ToDistinguish())
1178 myContext->core11->glMaterialfv(GL_BACK, GL_AMBIENT, aBackMat.Ambient.GetData());
1179 myContext->core11->glMaterialfv(GL_BACK, GL_DIFFUSE, aBackMat.Diffuse.GetData());
1180 myContext->core11->glMaterialfv(GL_BACK, GL_SPECULAR, aBackMat.Specular.GetData());
1181 myContext->core11->glMaterialfv(GL_BACK, GL_EMISSION, aBackMat.Emission.GetData());
1182 myContext->core11->glMaterialf (GL_BACK, GL_SHININESS, aBackMat.Shine());
1188 theProgram->SetUniform (myContext,
1189 theProgram->GetStateLocation (OpenGl_OCCT_ALPHA_CUTOFF),
1190 myMaterialState.AlphaCutoff());
1191 theProgram->SetUniform (myContext,
1192 theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),
1193 myMaterialState.ToMapTexture() ? 1 : 0);
1194 theProgram->SetUniform (myContext,
1195 theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
1196 myMaterialState.ToDistinguish() ? 1 : 0);
1198 if (const OpenGl_ShaderUniformLocation aLocFront = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL))
1200 theProgram->SetUniform (myContext, aLocFront, OpenGl_Material::NbOfVec4(),
1201 aFrontMat.Packed());
1203 if (const OpenGl_ShaderUniformLocation aLocBack = theProgram->GetStateLocation (OpenGl_OCCT_BACK_MATERIAL))
1205 theProgram->SetUniform (myContext, aLocBack, OpenGl_Material::NbOfVec4(),
1210 // =======================================================================
1211 // function : PushOitState
1212 // purpose : Pushes state of OIT uniforms to the specified program
1213 // =======================================================================
1214 void OpenGl_ShaderManager::PushOitState (const Handle(OpenGl_ShaderProgram)& theProgram) const
1216 if (!theProgram->IsValid())
1221 if (myOitState.Index() == theProgram->ActiveState (OpenGL_OIT_STATE))
1226 const GLint aLocOutput = theProgram->GetStateLocation (OpenGl_OCCT_OIT_OUTPUT);
1227 if (aLocOutput != OpenGl_ShaderProgram::INVALID_LOCATION)
1229 theProgram->SetUniform (myContext, aLocOutput, myOitState.ToEnableWrite());
1232 const GLint aLocDepthFactor = theProgram->GetStateLocation (OpenGl_OCCT_OIT_DEPTH_FACTOR);
1233 if (aLocDepthFactor != OpenGl_ShaderProgram::INVALID_LOCATION)
1235 theProgram->SetUniform (myContext, aLocDepthFactor, myOitState.DepthFactor());
1239 // =======================================================================
1240 // function : PushInteriorState
1242 // =======================================================================
1243 void OpenGl_ShaderManager::PushInteriorState (const Handle(OpenGl_ShaderProgram)& theProgram,
1244 const Handle(Graphic3d_Aspects)& theAspect) const
1246 if (theProgram.IsNull()
1247 || !theProgram->IsValid())
1252 if (const OpenGl_ShaderUniformLocation aLocViewPort = theProgram->GetStateLocation (OpenGl_OCCT_VIEWPORT))
1254 theProgram->SetUniform (myContext, aLocViewPort, OpenGl_Vec4 ((float )myContext->Viewport()[0], (float )myContext->Viewport()[1], (float )myContext->Viewport()[2], (float )myContext->Viewport()[3]));
1256 if (const OpenGl_ShaderUniformLocation aLocLineWidth = theProgram->GetStateLocation (OpenGl_OCCT_LINE_WIDTH))
1258 theProgram->SetUniform (myContext, aLocLineWidth, theAspect->EdgeWidth() * myContext->LineWidthScale());
1259 theProgram->SetUniform (myContext, theProgram->GetStateLocation (OpenGl_OCCT_LINE_FEATHER), myContext->LineFeather() * myContext->LineWidthScale());
1261 if (const OpenGl_ShaderUniformLocation aLocWireframeColor = theProgram->GetStateLocation (OpenGl_OCCT_WIREFRAME_COLOR))
1263 if (theAspect->InteriorStyle() == Aspect_IS_HOLLOW)
1265 theProgram->SetUniform (myContext, aLocWireframeColor, OpenGl_Vec4 (-1.0f, -1.0f, -1.0f, -1.0f));
1269 theProgram->SetUniform (myContext, aLocWireframeColor, theAspect->EdgeColorRGBA());
1272 if (const OpenGl_ShaderUniformLocation aLocQuadModeState = theProgram->GetStateLocation (OpenGl_OCCT_QUAD_MODE_STATE))
1274 theProgram->SetUniform (myContext, aLocQuadModeState, theAspect->ToSkipFirstEdge() ? 1 : 0);
1278 // =======================================================================
1279 // function : PushState
1280 // purpose : Pushes state of OCCT graphics parameters to the program
1281 // =======================================================================
1282 void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const
1284 const Handle(OpenGl_ShaderProgram)& aProgram = !theProgram.IsNull() ? theProgram : myFfpProgram;
1285 PushClippingState (aProgram);
1286 PushWorldViewState (aProgram);
1287 PushModelWorldState (aProgram);
1288 PushProjectionState (aProgram);
1289 PushLightSourceState (aProgram);
1290 PushMaterialState (aProgram);
1291 PushOitState (aProgram);
1294 // =======================================================================
1295 // function : prepareStdProgramFont
1297 // =======================================================================
1298 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFont()
1300 OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
1301 aUniforms .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_FRAGMENT));
1302 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec2 TexCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
1304 TCollection_AsciiString aSrcVert = TCollection_AsciiString()
1307 EOL" TexCoord = occTexCoord.st;"
1308 + THE_VERT_gl_Position
1311 TCollection_AsciiString
1312 aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occSamplerBaseColor, TexCoord.st).a; }";
1313 #if !defined(GL_ES_VERSION_2_0)
1314 if (myContext->core11 == NULL)
1316 aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occSamplerBaseColor, TexCoord.st).r; }";
1320 TCollection_AsciiString aSrcFrag =
1324 EOL" vec4 aColor = occColor;"
1325 EOL" aColor.a *= getAlpha();"
1326 EOL" if (aColor.a <= 0.285) discard;"
1327 EOL" occSetFragColor (aColor);"
1330 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1331 defaultGlslVersion (aProgramSrc, "font", 0);
1332 aProgramSrc->SetDefaultSampler (false);
1333 aProgramSrc->SetNbLightsMax (0);
1334 aProgramSrc->SetNbClipPlanesMax (0);
1335 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
1336 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
1337 TCollection_AsciiString aKey;
1338 if (!Create (aProgramSrc, aKey, myFontProgram))
1340 myFontProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1341 return Standard_False;
1343 return Standard_True;
1346 // =======================================================================
1347 // function : prepareStdProgramFboBlit
1349 // =======================================================================
1350 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFboBlit()
1352 OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
1353 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec2 TexCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
1355 TCollection_AsciiString aSrcVert =
1358 EOL" TexCoord = occVertex.zw;"
1359 EOL" gl_Position = vec4(occVertex.x, occVertex.y, 0.0, 1.0);"
1362 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D uColorSampler", Graphic3d_TOS_FRAGMENT));
1363 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D uDepthSampler", Graphic3d_TOS_FRAGMENT));
1364 TCollection_AsciiString aSrcFrag =
1367 EOL" gl_FragDepth = occTexture2D (uDepthSampler, TexCoord).r;"
1368 EOL" occSetFragColor (occTexture2D (uColorSampler, TexCoord));"
1371 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1372 #if defined(GL_ES_VERSION_2_0)
1373 if (myContext->IsGlGreaterEqual (3, 0))
1375 aProgramSrc->SetHeader ("#version 300 es");
1377 else if (myContext->extFragDepth)
1379 aProgramSrc->SetHeader ("#extension GL_EXT_frag_depth : enable"
1380 EOL"#define gl_FragDepth gl_FragDepthEXT");
1384 // there is no way to draw into depth buffer
1388 EOL" occSetFragColor (occTexture2D (uColorSampler, TexCoord));"
1392 if (myContext->core32 != NULL)
1394 aProgramSrc->SetHeader ("#version 150");
1397 aProgramSrc->SetId ("occt_blit");
1398 aProgramSrc->SetDefaultSampler (false);
1399 aProgramSrc->SetNbLightsMax (0);
1400 aProgramSrc->SetNbClipPlanesMax (0);
1401 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
1402 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
1403 TCollection_AsciiString aKey;
1404 if (!Create (aProgramSrc, aKey, myBlitProgram))
1406 myBlitProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1407 return Standard_False;
1410 myContext->BindProgram (myBlitProgram);
1411 myBlitProgram->SetSampler (myContext, "uColorSampler", Graphic3d_TextureUnit_0);
1412 myBlitProgram->SetSampler (myContext, "uDepthSampler", Graphic3d_TextureUnit_1);
1413 myContext->BindProgram (NULL);
1414 return Standard_True;
1417 // =======================================================================
1418 // function : prepareStdProgramOitCompositing
1420 // =======================================================================
1421 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramOitCompositing (const Standard_Boolean theMsaa)
1423 Handle(OpenGl_ShaderProgram)& aProgram = myOitCompositingProgram[theMsaa ? 1 : 0];
1424 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1425 TCollection_AsciiString aSrcVert, aSrcFrag;
1427 OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
1428 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec2 TexCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
1433 EOL" TexCoord = occVertex.zw;"
1434 EOL" gl_Position = vec4 (occVertex.x, occVertex.y, 0.0, 1.0);"
1439 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D uAccumTexture", Graphic3d_TOS_FRAGMENT));
1440 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D uWeightTexture", Graphic3d_TOS_FRAGMENT));
1444 EOL" vec4 aAccum = occTexture2D (uAccumTexture, TexCoord);"
1445 EOL" float aWeight = occTexture2D (uWeightTexture, TexCoord).r;"
1446 EOL" occSetFragColor (vec4 (aAccum.rgb / max (aWeight, 0.00001), aAccum.a));"
1448 #if !defined(GL_ES_VERSION_2_0)
1449 if (myContext->IsGlGreaterEqual (3, 2))
1451 aProgramSrc->SetHeader ("#version 150");
1454 if (myContext->IsGlGreaterEqual (3, 0))
1456 aProgramSrc->SetHeader ("#version 300 es");
1462 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2DMS uAccumTexture", Graphic3d_TOS_FRAGMENT));
1463 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2DMS uWeightTexture", Graphic3d_TOS_FRAGMENT));
1467 EOL" ivec2 aTexel = ivec2 (vec2 (textureSize (uAccumTexture)) * TexCoord);"
1468 EOL" vec4 aAccum = texelFetch (uAccumTexture, aTexel, gl_SampleID);"
1469 EOL" float aWeight = texelFetch (uWeightTexture, aTexel, gl_SampleID).r;"
1470 EOL" occSetFragColor (vec4 (aAccum.rgb / max (aWeight, 0.00001), aAccum.a));"
1472 #if !defined(GL_ES_VERSION_2_0)
1473 if (myContext->IsGlGreaterEqual (4, 0))
1475 aProgramSrc->SetHeader ("#version 400");
1478 if (myContext->IsGlGreaterEqual (3, 2))
1480 aProgramSrc->SetHeader ("#version 320 es");
1482 else if (myContext->IsGlGreaterEqual (3, 0))
1484 aProgramSrc->SetHeader ("#version 300 es"); // with GL_OES_sample_variables extension
1489 aProgramSrc->SetId (theMsaa ? "occt_weight-oit-msaa" : "occt_weight-oit");
1490 aProgramSrc->SetDefaultSampler (false);
1491 aProgramSrc->SetNbLightsMax (0);
1492 aProgramSrc->SetNbClipPlanesMax (0);
1493 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
1494 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
1495 TCollection_AsciiString aKey;
1496 if (!Create (aProgramSrc, aKey, aProgram))
1498 aProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1499 return Standard_False;
1502 myContext->BindProgram (aProgram);
1503 aProgram->SetSampler (myContext, "uAccumTexture", Graphic3d_TextureUnit_0);
1504 aProgram->SetSampler (myContext, "uWeightTexture", Graphic3d_TextureUnit_1);
1505 myContext->BindProgram (Handle(OpenGl_ShaderProgram)());
1506 return Standard_True;
1509 // =======================================================================
1510 // function : pointSpriteAlphaSrc
1512 // =======================================================================
1513 TCollection_AsciiString OpenGl_ShaderManager::pointSpriteAlphaSrc (Standard_Integer theBits)
1515 TCollection_AsciiString aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occSamplerPointSprite, " THE_VEC2_glPointCoord ").a; }";
1516 #if !defined(GL_ES_VERSION_2_0)
1517 if (myContext->core11 == NULL
1518 && (theBits & OpenGl_PO_PointSpriteA) == OpenGl_PO_PointSpriteA)
1520 aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occSamplerPointSprite, " THE_VEC2_glPointCoord ").r; }";
1525 return aSrcGetAlpha;
1528 // =======================================================================
1529 // function : defaultGlslVersion
1531 // =======================================================================
1532 int OpenGl_ShaderManager::defaultGlslVersion (const Handle(Graphic3d_ShaderProgram)& theProgram,
1533 const TCollection_AsciiString& theName,
1535 bool theUsesDerivates) const
1537 int aBits = theBits;
1538 #if !defined(GL_ES_VERSION_2_0)
1539 if (myContext->core32 != NULL)
1541 theProgram->SetHeader ("#version 150");
1545 if ((theBits & OpenGl_PO_StippleLine) != 0)
1547 if (myContext->IsGlGreaterEqual (3, 0))
1549 theProgram->SetHeader ("#version 130");
1551 else if (myContext->CheckExtension ("GL_EXT_gpu_shader4"))
1553 // GL_EXT_gpu_shader4 defines GLSL type "unsigned int", while core GLSL specs define type "uint"
1554 theProgram->SetHeader ("#extension GL_EXT_gpu_shader4 : enable\n"
1555 "#define uint unsigned int");
1559 aBits = aBits & ~OpenGl_PO_StippleLine;
1563 (void )theUsesDerivates;
1565 // prefer "100 es" on OpenGL ES 3.0- devices (save the features unavailable before "300 es")
1566 // and "300 es" on OpenGL ES 3.1+ devices
1567 if (myContext->IsGlGreaterEqual (3, 1))
1569 if ((theBits & OpenGl_PO_NeedsGeomShader) != 0)
1571 theProgram->SetHeader (myContext->hasGeometryStage != OpenGl_FeatureInExtensions ? "#version 320 es" : "#version 310 es");
1575 theProgram->SetHeader ("#version 300 es");
1580 if ((theBits & OpenGl_PO_WriteOit) != 0
1581 || (theBits & OpenGl_PO_StippleLine) != 0)
1583 if (myContext->IsGlGreaterEqual (3, 0))
1585 theProgram->SetHeader ("#version 300 es");
1589 aBits = aBits & ~OpenGl_PO_WriteOit;
1590 aBits = aBits & ~OpenGl_PO_StippleLine;
1593 if (theUsesDerivates)
1595 if (myContext->IsGlGreaterEqual (3, 0))
1597 theProgram->SetHeader ("#version 300 es");
1599 else if (myContext->oesStdDerivatives)
1601 theProgram->SetHeader ("#extension GL_OES_standard_derivatives : enable");
1607 // should fit OpenGl_PO_NB
1609 Sprintf (aBitsStr, "%04x", aBits);
1610 theProgram->SetId (TCollection_AsciiString ("occt_") + theName + aBitsStr);
1614 // =======================================================================
1615 // function : prepareGeomMainSrc
1617 // =======================================================================
1618 TCollection_AsciiString OpenGl_ShaderManager::prepareGeomMainSrc (OpenGl_ShaderObject::ShaderVariableList& theUnifoms,
1619 OpenGl_ShaderObject::ShaderVariableList& theStageInOuts,
1620 Standard_Integer theBits)
1622 if ((theBits & OpenGl_PO_NeedsGeomShader) == 0)
1624 return TCollection_AsciiString();
1627 TCollection_AsciiString aSrcMainGeom =
1631 if ((theBits & OpenGl_PO_MeshEdges) != 0)
1633 theUnifoms.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 occViewport", Graphic3d_TOS_GEOMETRY));
1634 theUnifoms.Append (OpenGl_ShaderObject::ShaderVariable ("bool occIsQuadMode", Graphic3d_TOS_GEOMETRY));
1635 theUnifoms.Append (OpenGl_ShaderObject::ShaderVariable ("float occLineWidth", Graphic3d_TOS_GEOMETRY));
1636 theUnifoms.Append (OpenGl_ShaderObject::ShaderVariable ("float occLineWidth", Graphic3d_TOS_FRAGMENT));
1637 theUnifoms.Append (OpenGl_ShaderObject::ShaderVariable ("float occLineFeather", Graphic3d_TOS_FRAGMENT));
1638 theUnifoms.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 occWireframeColor", Graphic3d_TOS_FRAGMENT));
1639 theStageInOuts.Append(OpenGl_ShaderObject::ShaderVariable ("vec3 EdgeDistance", Graphic3d_TOS_GEOMETRY | Graphic3d_TOS_FRAGMENT));
1641 aSrcMainGeom = TCollection_AsciiString()
1642 + EOL"vec3 ViewPortTransform (vec4 theVec)"
1644 EOL" vec3 aWinCoord = theVec.xyz / theVec.w;"
1645 EOL" aWinCoord = aWinCoord * 0.5 + 0.5;"
1646 EOL" aWinCoord.xy = aWinCoord.xy * occViewport.zw + occViewport.xy;"
1647 EOL" return aWinCoord;"
1650 + EOL" vec3 aSideA = ViewPortTransform (gl_in[2].gl_Position) - ViewPortTransform (gl_in[1].gl_Position);"
1651 EOL" vec3 aSideB = ViewPortTransform (gl_in[2].gl_Position) - ViewPortTransform (gl_in[0].gl_Position);"
1652 EOL" vec3 aSideC = ViewPortTransform (gl_in[1].gl_Position) - ViewPortTransform (gl_in[0].gl_Position);"
1653 EOL" float aQuadArea = abs (aSideB.x * aSideC.y - aSideB.y * aSideC.x);"
1654 EOL" vec3 aLenABC = vec3 (length (aSideA), length (aSideB), length (aSideC));"
1655 EOL" vec3 aHeightABC = vec3 (aQuadArea) / aLenABC;"
1656 EOL" aHeightABC = max (aHeightABC, vec3 (10.0 * occLineWidth));" // avoid shrunk presentation disappearing at distance
1657 EOL" float aQuadModeHeightC = occIsQuadMode ? occLineWidth + 1.0 : 0.0;";
1660 for (Standard_Integer aVertIter = 0; aVertIter < 3; ++aVertIter)
1662 const TCollection_AsciiString aVertIndex (aVertIter);
1663 // pass variables from Vertex shader to Fragment shader through Geometry shader
1664 for (OpenGl_ShaderObject::ShaderVariableList::Iterator aVarListIter (theStageInOuts); aVarListIter.More(); aVarListIter.Next())
1666 if (aVarListIter.Value().Stages == (Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT))
1668 const TCollection_AsciiString aVarName = aVarListIter.Value().Name.Token (" ", 2);
1669 aSrcMainGeom += TCollection_AsciiString()
1670 + EOL" geomOut." + aVarName + " = geomIn[" + aVertIndex + "]." + aVarName + ";";
1674 if ((theBits & OpenGl_PO_MeshEdges) != 0)
1678 case 0: aSrcMainGeom += EOL" EdgeDistance = vec3 (aHeightABC[0], 0.0, aQuadModeHeightC);"; break;
1679 case 1: aSrcMainGeom += EOL" EdgeDistance = vec3 (0.0, aHeightABC[1], aQuadModeHeightC);"; break;
1680 case 2: aSrcMainGeom += EOL" EdgeDistance = vec3 (0.0, 0.0, aHeightABC[2]);"; break;
1683 aSrcMainGeom += TCollection_AsciiString()
1684 + EOL" gl_Position = gl_in[" + aVertIndex + "].gl_Position;"
1685 EOL" EmitVertex();";
1688 EOL" EndPrimitive();"
1691 return aSrcMainGeom;
1694 // =======================================================================
1695 // function : prepareStdProgramUnlit
1697 // =======================================================================
1698 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramUnlit (Handle(OpenGl_ShaderProgram)& theProgram,
1699 Standard_Integer theBits,
1700 Standard_Boolean theIsOutline)
1702 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1703 TCollection_AsciiString aSrcVert, aSrcVertExtraMain, aSrcVertExtraFunc, aSrcGetAlpha, aSrcVertEndMain;
1704 TCollection_AsciiString aSrcFrag, aSrcFragExtraMain;
1705 TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return occColor; }";
1706 TCollection_AsciiString aSrcFragMainGetColor = EOL" occSetFragColor (getFinalColor());";
1707 OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
1709 if ((theBits & OpenGl_PO_IsPoint) != 0)
1711 #if defined(GL_ES_VERSION_2_0)
1712 aSrcVertExtraMain += EOL" gl_PointSize = occPointSize;";
1715 if ((theBits & OpenGl_PO_PointSprite) != 0)
1717 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerPointSprite", Graphic3d_TOS_FRAGMENT));
1718 if ((theBits & OpenGl_PO_PointSpriteA) != OpenGl_PO_PointSpriteA)
1721 EOL"vec4 getColor(void) { return occTexture2D(occSamplerPointSprite, " THE_VEC2_glPointCoord "); }";
1723 else if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB
1724 && (theBits & OpenGl_PO_VertColor) == 0)
1726 aUniforms .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_VERTEX));
1727 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 VertColor", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
1728 aSrcVertExtraMain +=
1729 EOL" VertColor = occTexture2D (occSamplerBaseColor, occTexCoord.xy);";
1731 EOL"vec4 getColor(void) { return VertColor; }";
1734 aSrcGetAlpha = pointSpriteAlphaSrc (theBits);
1736 #if !defined(GL_ES_VERSION_2_0)
1737 if (myContext->core11 != NULL
1738 && myContext->IsGlGreaterEqual (2, 1))
1740 aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
1744 aSrcFragMainGetColor =
1745 EOL" vec4 aColor = getColor();"
1746 EOL" aColor.a = getAlpha();"
1747 EOL" if (aColor.a <= 0.1) discard;"
1748 EOL" occSetFragColor (aColor);";
1752 if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB
1753 && (theBits & OpenGl_PO_VertColor) == 0)
1755 aUniforms .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_VERTEX));
1756 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 VertColor", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
1757 aSrcVertExtraMain +=
1758 EOL" VertColor = occTexture2D (occSamplerBaseColor, occTexCoord.xy);";
1760 EOL"vec4 getColor(void) { return VertColor; }";
1763 aSrcFragMainGetColor =
1764 EOL" vec4 aColor = getColor();"
1765 EOL" if (aColor.a <= 0.1) discard;"
1766 EOL" occSetFragColor (aColor);";
1771 if ((theBits & OpenGl_PO_TextureRGB) != 0 || (theBits & OpenGl_PO_TextureEnv) != 0)
1773 aUniforms .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_FRAGMENT));
1774 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 TexCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
1777 if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB)
1779 aSrcVertExtraMain += THE_VARY_TexCoord_Trsf;
1782 EOL"vec4 getColor(void) { return occTexture2D(occSamplerBaseColor, TexCoord.st / TexCoord.w); }";
1784 else if ((theBits & OpenGl_PO_TextureEnv) != 0)
1786 aSrcVertExtraFunc = THE_FUNC_transformNormal;
1788 aSrcVertExtraMain +=
1789 EOL" vec4 aPosition = occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1790 EOL" vec3 aNormal = transformNormal (occNormal);"
1791 EOL" vec3 aReflect = reflect (normalize (aPosition.xyz), aNormal);"
1792 EOL" aReflect.z += 1.0;"
1793 EOL" TexCoord = vec4(aReflect.xy * inversesqrt (dot (aReflect, aReflect)) * 0.5 + vec2 (0.5), 0.0, 1.0);";
1796 EOL"vec4 getColor(void) { return occTexture2D (occSamplerBaseColor, TexCoord.st); }";
1799 if ((theBits & OpenGl_PO_VertColor) != 0)
1801 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 VertColor", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
1802 aSrcVertExtraMain += EOL" VertColor = occVertColor;";
1803 aSrcFragGetColor = EOL"vec4 getColor(void) { return VertColor; }";
1806 int aNbClipPlanes = 0;
1807 if ((theBits & OpenGl_PO_ClipPlanesN) != 0)
1809 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 PositionWorld", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
1810 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 Position", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
1811 aSrcVertExtraMain +=
1812 EOL" PositionWorld = occModelWorldMatrix * occVertex;"
1813 EOL" Position = occWorldViewMatrix * PositionWorld;";
1815 if ((theBits & OpenGl_PO_ClipPlanesN) == OpenGl_PO_ClipPlanesN)
1817 aNbClipPlanes = Graphic3d_ShaderProgram::THE_MAX_CLIP_PLANES_DEFAULT;
1818 aSrcFragExtraMain += (theBits & OpenGl_PO_ClipChains) != 0
1819 ? THE_FRAG_CLIP_CHAINS_N
1820 : THE_FRAG_CLIP_PLANES_N;
1822 else if ((theBits & OpenGl_PO_ClipPlanes1) != 0)
1825 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_1;
1827 else if ((theBits & OpenGl_PO_ClipPlanes2) != 0)
1830 aSrcFragExtraMain += (theBits & OpenGl_PO_ClipChains) != 0
1831 ? THE_FRAG_CLIP_CHAINS_2
1832 : THE_FRAG_CLIP_PLANES_2;
1835 if ((theBits & OpenGl_PO_WriteOit) != 0)
1837 aProgramSrc->SetNbFragmentOutputs (2);
1838 aProgramSrc->SetWeightOitOutput (true);
1843 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("float occOrthoScale", Graphic3d_TOS_VERTEX));
1844 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("float occSilhouetteThickness", Graphic3d_TOS_VERTEX));
1845 aSrcVertEndMain = THE_VERT_gl_Position_OUTLINE;
1847 else if ((theBits & OpenGl_PO_StippleLine) != 0)
1849 const Standard_Integer aBits = defaultGlslVersion (aProgramSrc, "unlit", theBits);
1850 if ((aBits & OpenGl_PO_StippleLine) != 0)
1852 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("int uPattern", Graphic3d_TOS_FRAGMENT));
1853 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("float uFactor", Graphic3d_TOS_FRAGMENT));
1854 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec2 ScreenSpaceCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
1856 EOL" ScreenSpaceCoord = gl_Position.xy / gl_Position.w;";
1857 aSrcFragMainGetColor =
1858 EOL" float anAngle = atan (dFdx (ScreenSpaceCoord.x), dFdy (ScreenSpaceCoord.y));"
1859 EOL" float aRotatePoint = gl_FragCoord.x * sin (anAngle) + gl_FragCoord.y * cos (anAngle);"
1860 EOL" uint aBit = uint (floor (aRotatePoint / uFactor + 0.5)) & 15U;"
1861 EOL" if ((uint (uPattern) & (1U << aBit)) == 0U) discard;"
1862 EOL" vec4 aColor = getFinalColor();"
1863 EOL" if (aColor.a <= 0.1) discard;"
1864 EOL" occSetFragColor (aColor);";
1868 myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, "Warning: stipple lines in GLSL will be ignored.");
1877 + THE_VERT_gl_Position
1881 TCollection_AsciiString aSrcGeom = prepareGeomMainSrc (aUniforms, aStageInOuts, theBits);
1882 aSrcFragGetColor += (theBits & OpenGl_PO_MeshEdges) != 0
1883 ? THE_FRAG_WIREFRAME_COLOR
1884 : EOL"#define getFinalColor getColor";
1892 + aSrcFragMainGetColor
1895 defaultGlslVersion (aProgramSrc, theIsOutline ? "outline" : "unlit", theBits);
1896 aProgramSrc->SetDefaultSampler (false);
1897 aProgramSrc->SetNbLightsMax (0);
1898 aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
1899 aProgramSrc->SetAlphaTest ((theBits & OpenGl_PO_AlphaTest) != 0);
1900 const Standard_Integer aNbGeomInputVerts = !aSrcGeom.IsEmpty() ? 3 : 0;
1901 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts, "", "", aNbGeomInputVerts));
1902 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcGeom, Graphic3d_TOS_GEOMETRY, aUniforms, aStageInOuts, "geomIn", "geomOut", aNbGeomInputVerts));
1903 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts, "", "", aNbGeomInputVerts));
1904 TCollection_AsciiString aKey;
1905 if (!Create (aProgramSrc, aKey, theProgram))
1907 theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1908 return Standard_False;
1910 return Standard_True;
1913 // =======================================================================
1914 // function : pointSpriteShadingSrc
1916 // =======================================================================
1917 TCollection_AsciiString OpenGl_ShaderManager::pointSpriteShadingSrc (const TCollection_AsciiString& theBaseColorSrc,
1918 Standard_Integer theBits)
1920 TCollection_AsciiString aSrcFragGetColor;
1921 if ((theBits & OpenGl_PO_PointSpriteA) == OpenGl_PO_PointSpriteA)
1923 aSrcFragGetColor = pointSpriteAlphaSrc (theBits) +
1924 EOL"vec4 getColor(void)"
1926 EOL" vec4 aColor = " + theBaseColorSrc + ";"
1927 EOL" aColor.a = getAlpha();"
1928 EOL" if (aColor.a <= 0.1) discard;"
1929 EOL" return aColor;"
1932 else if ((theBits & OpenGl_PO_PointSprite) == OpenGl_PO_PointSprite)
1934 aSrcFragGetColor = TCollection_AsciiString() +
1935 EOL"vec4 getColor(void)"
1937 EOL" vec4 aColor = " + theBaseColorSrc + ";"
1938 EOL" aColor = occTexture2D(occSamplerPointSprite, " THE_VEC2_glPointCoord ") * aColor;"
1939 EOL" if (aColor.a <= 0.1) discard;"
1940 EOL" return aColor;"
1944 return aSrcFragGetColor;
1947 // =======================================================================
1948 // function : stdComputeLighting
1950 // =======================================================================
1951 TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (Standard_Integer& theNbLights,
1952 Standard_Boolean theHasVertColor)
1954 TCollection_AsciiString aLightsFunc, aLightsLoop;
1956 const Handle(Graphic3d_LightSet)& aLights = myLightSourceState.LightSources();
1957 if (!aLights.IsNull())
1959 theNbLights = aLights->NbEnabled();
1960 if (theNbLights <= THE_NB_UNROLLED_LIGHTS_MAX)
1962 Standard_Integer anIndex = 0;
1963 for (Graphic3d_LightSet::Iterator aLightIter (aLights, Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient);
1964 aLightIter.More(); aLightIter.Next(), ++anIndex)
1966 switch (aLightIter.Value()->Type())
1968 case Graphic3d_TOLS_AMBIENT:
1970 break; // skip ambient
1971 case Graphic3d_TOLS_DIRECTIONAL:
1972 aLightsLoop = aLightsLoop + EOL" directionalLight (" + anIndex + ", theNormal, theView, theIsFront);";
1974 case Graphic3d_TOLS_POSITIONAL:
1975 aLightsLoop = aLightsLoop + EOL" pointLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);";
1977 case Graphic3d_TOLS_SPOT:
1978 aLightsLoop = aLightsLoop + EOL" spotLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);";
1985 theNbLights = roundUpMaxLightSources (theNbLights);
1986 bool isFirstInLoop = true;
1987 aLightsLoop = aLightsLoop +
1988 EOL" for (int anIndex = 0; anIndex < occLightSourcesCount; ++anIndex)"
1990 EOL" int aType = occLight_Type (anIndex);";
1991 if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_DIRECTIONAL) > 0)
1993 isFirstInLoop = false;
1995 EOL" if (aType == OccLightType_Direct)"
1997 EOL" directionalLight (anIndex, theNormal, theView, theIsFront);"
2000 if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_POSITIONAL) > 0)
2004 aLightsLoop += EOL" else ";
2006 isFirstInLoop = false;
2008 EOL" if (aType == OccLightType_Point)"
2010 EOL" pointLight (anIndex, theNormal, theView, aPoint, theIsFront);"
2013 if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_SPOT) > 0)
2017 aLightsLoop += EOL" else ";
2019 isFirstInLoop = false;
2021 EOL" if (aType == OccLightType_Spot)"
2023 EOL" spotLight (anIndex, theNormal, theView, aPoint, theIsFront);"
2026 aLightsLoop += EOL" }";
2028 if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_DIRECTIONAL) == 1
2029 && theNbLights == 1)
2031 // use the version with hard-coded first index
2032 aLightsLoop = EOL" directionalLightFirst(theNormal, theView, theIsFront);";
2033 aLightsFunc += THE_FUNC_directionalLightFirst;
2035 else if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_DIRECTIONAL) > 0)
2037 aLightsFunc += THE_FUNC_directionalLight;
2039 if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_POSITIONAL) > 0)
2041 aLightsFunc += THE_FUNC_pointLight;
2043 if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_SPOT) > 0)
2045 aLightsFunc += THE_FUNC_spotLight;
2049 TCollection_AsciiString aGetMatAmbient = "theIsFront ? occFrontMaterial_Ambient() : occBackMaterial_Ambient();";
2050 TCollection_AsciiString aGetMatDiffuse = "theIsFront ? occFrontMaterial_Diffuse() : occBackMaterial_Diffuse();";
2051 if (theHasVertColor)
2053 aGetMatAmbient = "getVertColor();";
2054 aGetMatDiffuse = "getVertColor();";
2057 return TCollection_AsciiString()
2061 EOL"vec4 computeLighting (in vec3 theNormal,"
2062 EOL" in vec3 theView,"
2063 EOL" in vec4 thePoint,"
2064 EOL" in bool theIsFront)"
2066 EOL" Ambient = occLightAmbient.rgb;"
2067 EOL" Diffuse = vec3 (0.0);"
2068 EOL" Specular = vec3 (0.0);"
2069 EOL" vec3 aPoint = thePoint.xyz / thePoint.w;"
2071 + EOL" vec4 aMatAmbient = " + aGetMatAmbient
2072 + EOL" vec4 aMatDiffuse = " + aGetMatDiffuse
2073 + EOL" vec4 aMatSpecular = theIsFront ? occFrontMaterial_Specular() : occBackMaterial_Specular();"
2074 EOL" vec4 aMatEmission = theIsFront ? occFrontMaterial_Emission() : occBackMaterial_Emission();"
2075 EOL" vec3 aColor = Ambient * aMatAmbient.rgb"
2076 EOL" + Diffuse * aMatDiffuse.rgb"
2077 EOL" + Specular * aMatSpecular.rgb"
2078 EOL" + aMatEmission.rgb;"
2079 EOL" return vec4 (aColor, aMatDiffuse.a);"
2083 // =======================================================================
2084 // function : prepareStdProgramGouraud
2086 // =======================================================================
2087 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_ShaderProgram)& theProgram,
2088 const Standard_Integer theBits)
2090 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
2091 TCollection_AsciiString aSrcVert, aSrcVertColor, aSrcVertExtraMain;
2092 TCollection_AsciiString aSrcFrag, aSrcFragExtraMain;
2093 TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return gl_FrontFacing ? FrontColor : BackColor; }";
2094 OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
2096 if ((theBits & OpenGl_PO_IsPoint) != 0)
2098 #if defined(GL_ES_VERSION_2_0)
2099 aSrcVertExtraMain += EOL" gl_PointSize = occPointSize;";
2102 if ((theBits & OpenGl_PO_PointSprite) != 0)
2104 #if !defined(GL_ES_VERSION_2_0)
2105 if (myContext->core11 != NULL
2106 && myContext->IsGlGreaterEqual (2, 1))
2108 aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
2112 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerPointSprite", Graphic3d_TOS_FRAGMENT));
2113 aSrcFragGetColor = pointSpriteShadingSrc ("gl_FrontFacing ? FrontColor : BackColor", theBits);
2116 if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB
2117 && (theBits & OpenGl_PO_VertColor) == 0)
2119 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_VERTEX));
2120 aSrcVertColor = EOL"vec4 getVertColor(void) { return occTexture2D (occSamplerBaseColor, occTexCoord.xy); }";
2125 if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB)
2127 aUniforms .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_FRAGMENT));
2128 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 TexCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
2129 aSrcVertExtraMain += THE_VARY_TexCoord_Trsf;
2132 EOL"vec4 getColor(void)"
2134 EOL" vec4 aColor = gl_FrontFacing ? FrontColor : BackColor;"
2135 EOL" return occTexture2D(occSamplerBaseColor, TexCoord.st / TexCoord.w) * aColor;"
2140 if ((theBits & OpenGl_PO_VertColor) != 0)
2142 aSrcVertColor = EOL"vec4 getVertColor(void) { return occVertColor; }";
2145 int aNbClipPlanes = 0;
2146 if ((theBits & OpenGl_PO_ClipPlanesN) != 0)
2148 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 PositionWorld", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
2149 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 Position", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
2150 aSrcVertExtraMain +=
2151 EOL" PositionWorld = aPositionWorld;"
2152 EOL" Position = aPosition;";
2154 if ((theBits & OpenGl_PO_ClipPlanesN) == OpenGl_PO_ClipPlanesN)
2156 aNbClipPlanes = Graphic3d_ShaderProgram::THE_MAX_CLIP_PLANES_DEFAULT;
2157 aSrcFragExtraMain += (theBits & OpenGl_PO_ClipChains) != 0
2158 ? THE_FRAG_CLIP_CHAINS_N
2159 : THE_FRAG_CLIP_PLANES_N;
2161 else if ((theBits & OpenGl_PO_ClipPlanes1) != 0)
2164 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_1;
2166 else if ((theBits & OpenGl_PO_ClipPlanes2) != 0)
2169 aSrcFragExtraMain += (theBits & OpenGl_PO_ClipChains) != 0
2170 ? THE_FRAG_CLIP_CHAINS_2
2171 : THE_FRAG_CLIP_PLANES_2;
2174 if ((theBits & OpenGl_PO_WriteOit) != 0)
2176 aProgramSrc->SetNbFragmentOutputs (2);
2177 aProgramSrc->SetWeightOitOutput (true);
2180 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 FrontColor", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
2181 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 BackColor", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
2183 Standard_Integer aNbLights = 0;
2184 const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, !aSrcVertColor.IsEmpty());
2185 aSrcVert = TCollection_AsciiString()
2186 + THE_FUNC_transformNormal
2192 EOL" vec4 aPositionWorld = occModelWorldMatrix * occVertex;"
2193 EOL" vec4 aPosition = occWorldViewMatrix * aPositionWorld;"
2194 EOL" vec3 aNormal = transformNormal (occNormal);"
2195 EOL" vec3 aView = vec3 (0.0, 0.0, 1.0);"
2196 EOL" FrontColor = computeLighting (normalize (aNormal), normalize (aView), aPosition, true);"
2197 EOL" BackColor = computeLighting (normalize (aNormal), normalize (aView), aPosition, false);"
2199 + THE_VERT_gl_Position
2202 TCollection_AsciiString aSrcGeom = prepareGeomMainSrc (aUniforms, aStageInOuts, theBits);
2203 aSrcFragGetColor += (theBits & OpenGl_PO_MeshEdges) != 0
2204 ? THE_FRAG_WIREFRAME_COLOR
2205 : EOL"#define getFinalColor getColor";
2207 aSrcFrag = TCollection_AsciiString()
2212 + EOL" occSetFragColor (getFinalColor());"
2215 const TCollection_AsciiString aProgId = TCollection_AsciiString ("gouraud-") + genLightKey (myLightSourceState.LightSources()) + "-";
2216 defaultGlslVersion (aProgramSrc, aProgId, theBits);
2217 aProgramSrc->SetDefaultSampler (false);
2218 aProgramSrc->SetNbLightsMax (aNbLights);
2219 aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
2220 aProgramSrc->SetAlphaTest ((theBits & OpenGl_PO_AlphaTest) != 0);
2221 const Standard_Integer aNbGeomInputVerts = !aSrcGeom.IsEmpty() ? 3 : 0;
2222 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts, "", "", aNbGeomInputVerts));
2223 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcGeom, Graphic3d_TOS_GEOMETRY, aUniforms, aStageInOuts, "geomIn", "geomOut", aNbGeomInputVerts));
2224 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts, "", "", aNbGeomInputVerts));
2225 TCollection_AsciiString aKey;
2226 if (!Create (aProgramSrc, aKey, theProgram))
2228 theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
2229 return Standard_False;
2231 return Standard_True;
2234 // =======================================================================
2235 // function : prepareStdProgramPhong
2237 // =======================================================================
2238 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram,
2239 const Standard_Integer theBits,
2240 const Standard_Boolean theIsFlatNormal)
2242 #define thePhongCompLight "computeLighting (normalize (Normal), normalize (View), Position, gl_FrontFacing)"
2243 const bool isFlatNormal = theIsFlatNormal
2244 && myContext->hasFlatShading != OpenGl_FeatureNotAvailable;
2245 const char* aDFdxSignReversion = "";
2246 #if defined(GL_ES_VERSION_2_0)
2247 if (isFlatNormal != theIsFlatNormal)
2249 myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
2250 GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
2251 "Warning: flat shading requires OpenGL ES 3.0+ or GL_OES_standard_derivatives extension.");
2253 else if (isFlatNormal
2254 && myContext->Vendor().Search("qualcomm") != -1)
2256 // workaround Adreno driver bug computing reversed normal using dFdx/dFdy
2257 aDFdxSignReversion = "-";
2258 myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
2259 "Warning: applied workaround for flat shading normal computation using dFdx/dFdy on Adreno");
2262 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
2263 TCollection_AsciiString aSrcVert, aSrcVertExtraFunc, aSrcVertExtraMain;
2264 TCollection_AsciiString aSrcFrag, aSrcFragExtraOut, aSrcFragGetVertColor, aSrcFragExtraMain;
2265 TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return " thePhongCompLight "; }";
2266 OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
2267 if ((theBits & OpenGl_PO_IsPoint) != 0)
2269 #if defined(GL_ES_VERSION_2_0)
2270 aSrcVertExtraMain += EOL" gl_PointSize = occPointSize;";
2273 if ((theBits & OpenGl_PO_PointSprite) != 0)
2275 #if !defined(GL_ES_VERSION_2_0)
2276 if (myContext->core11 != NULL
2277 && myContext->IsGlGreaterEqual (2, 1))
2279 aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
2283 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerPointSprite", Graphic3d_TOS_FRAGMENT));
2284 aSrcFragGetColor = pointSpriteShadingSrc (thePhongCompLight, theBits);
2287 if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB
2288 && (theBits & OpenGl_PO_VertColor) == 0)
2290 aUniforms .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_VERTEX));
2291 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 VertColor", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
2293 aSrcVertExtraMain += EOL" VertColor = occTexture2D (occSamplerBaseColor, occTexCoord.xy);";
2294 aSrcFragGetVertColor = EOL"vec4 getVertColor(void) { return VertColor; }";
2299 if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB)
2301 aUniforms .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_FRAGMENT));
2302 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 TexCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
2303 aSrcVertExtraMain += THE_VARY_TexCoord_Trsf;
2306 EOL"vec4 getColor(void)"
2308 EOL" vec4 aColor = " thePhongCompLight ";"
2309 EOL" return occTexture2D(occSamplerBaseColor, TexCoord.st / TexCoord.w) * aColor;"
2314 if ((theBits & OpenGl_PO_VertColor) != 0)
2316 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 VertColor", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
2317 aSrcVertExtraMain += EOL" VertColor = occVertColor;";
2318 aSrcFragGetVertColor = EOL"vec4 getVertColor(void) { return VertColor; }";
2321 int aNbClipPlanes = 0;
2322 if ((theBits & OpenGl_PO_ClipPlanesN) != 0)
2324 if ((theBits & OpenGl_PO_ClipPlanesN) == OpenGl_PO_ClipPlanesN)
2326 aNbClipPlanes = Graphic3d_ShaderProgram::THE_MAX_CLIP_PLANES_DEFAULT;
2327 aSrcFragExtraMain += (theBits & OpenGl_PO_ClipChains) != 0
2328 ? THE_FRAG_CLIP_CHAINS_N
2329 : THE_FRAG_CLIP_PLANES_N;
2331 else if ((theBits & OpenGl_PO_ClipPlanes1) != 0)
2334 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_1;
2336 else if ((theBits & OpenGl_PO_ClipPlanes2) != 0)
2339 aSrcFragExtraMain += (theBits & OpenGl_PO_ClipChains) != 0
2340 ? THE_FRAG_CLIP_CHAINS_2
2341 : THE_FRAG_CLIP_PLANES_2;
2344 if ((theBits & OpenGl_PO_WriteOit) != 0)
2346 aProgramSrc->SetNbFragmentOutputs (2);
2347 aProgramSrc->SetWeightOitOutput (true);
2352 aSrcFragExtraOut += EOL"vec3 Normal;";
2353 aSrcFragExtraMain += TCollection_AsciiString()
2354 + EOL" Normal = " + aDFdxSignReversion + "normalize (cross (dFdx (Position.xyz / Position.w), dFdy (Position.xyz / Position.w)));"
2355 EOL" if (!gl_FrontFacing) { Normal = -Normal; }";
2359 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec3 Normal", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
2360 aSrcVertExtraFunc += THE_FUNC_transformNormal;
2361 aSrcVertExtraMain += EOL" Normal = transformNormal (occNormal);";
2364 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 PositionWorld", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
2365 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 Position", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
2366 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec3 View", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
2368 aSrcVert = TCollection_AsciiString()
2372 EOL" PositionWorld = occModelWorldMatrix * occVertex;"
2373 EOL" Position = occWorldViewMatrix * PositionWorld;"
2374 + EOL" View = vec3 (0.0, 0.0, 1.0);"
2376 + THE_VERT_gl_Position
2379 TCollection_AsciiString aSrcGeom = prepareGeomMainSrc (aUniforms, aStageInOuts, theBits);
2380 aSrcFragGetColor += (theBits & OpenGl_PO_MeshEdges) != 0
2381 ? THE_FRAG_WIREFRAME_COLOR
2382 : EOL"#define getFinalColor getColor";
2384 Standard_Integer aNbLights = 0;
2385 const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, !aSrcFragGetVertColor.IsEmpty());
2386 aSrcFrag = TCollection_AsciiString()
2389 + aSrcFragGetVertColor
2396 + EOL" occSetFragColor (getFinalColor());"
2399 const TCollection_AsciiString aProgId = TCollection_AsciiString (theIsFlatNormal ? "flat-" : "phong-") + genLightKey (myLightSourceState.LightSources()) + "-";
2400 defaultGlslVersion (aProgramSrc, aProgId, theBits, isFlatNormal);
2401 aProgramSrc->SetDefaultSampler (false);
2402 aProgramSrc->SetNbLightsMax (aNbLights);
2403 aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
2404 aProgramSrc->SetAlphaTest ((theBits & OpenGl_PO_AlphaTest) != 0);
2405 const Standard_Integer aNbGeomInputVerts = !aSrcGeom.IsEmpty() ? 3 : 0;
2406 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts, "", "", aNbGeomInputVerts));
2407 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcGeom, Graphic3d_TOS_GEOMETRY, aUniforms, aStageInOuts, "geomIn", "geomOut", aNbGeomInputVerts));
2408 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts, "", "", aNbGeomInputVerts));
2409 TCollection_AsciiString aKey;
2410 if (!Create (aProgramSrc, aKey, theProgram))
2412 theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
2413 return Standard_False;
2415 return Standard_True;
2418 // =======================================================================
2419 // function : prepareStdProgramStereo
2421 // =======================================================================
2422 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_ShaderProgram)& theProgram,
2423 const Graphic3d_StereoMode theStereoMode)
2425 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
2426 OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
2428 aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec2 TexCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
2429 TCollection_AsciiString aSrcVert =
2432 EOL" TexCoord = occVertex.zw;"
2433 EOL" gl_Position = vec4(occVertex.x, occVertex.y, 0.0, 1.0);"
2436 TCollection_AsciiString aSrcFrag;
2437 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D uLeftSampler", Graphic3d_TOS_FRAGMENT));
2438 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D uRightSampler", Graphic3d_TOS_FRAGMENT));
2439 const char* aName = "stereo";
2440 switch (theStereoMode)
2442 case Graphic3d_StereoMode_Anaglyph:
2445 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("mat4 uMultL", Graphic3d_TOS_FRAGMENT));
2446 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("mat4 uMultR", Graphic3d_TOS_FRAGMENT));
2448 EOL"const vec4 THE_POW_UP = vec4 (2.2, 2.2, 2.2, 1.0);"
2449 EOL"const vec4 THE_POW_DOWN = 1.0 / vec4 (2.2, 2.2, 2.2, 1.0);"
2453 EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
2454 EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
2455 EOL" aColorL = pow (aColorL, THE_POW_UP);" // normalize
2456 EOL" aColorR = pow (aColorR, THE_POW_UP);"
2457 EOL" vec4 aColor = uMultR * aColorR + uMultL * aColorL;"
2458 EOL" occSetFragColor (pow (aColor, THE_POW_DOWN));"
2462 case Graphic3d_StereoMode_RowInterlaced:
2464 aName = "row-interlaced";
2468 EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
2469 EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
2470 EOL" if (int (mod (gl_FragCoord.y - 1023.5, 2.0)) != 1)"
2472 EOL" occSetFragColor (aColorL);"
2476 EOL" occSetFragColor (aColorR);"
2481 case Graphic3d_StereoMode_ColumnInterlaced:
2483 aName = "column-interlaced";
2487 EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
2488 EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
2489 EOL" if (int (mod (gl_FragCoord.x - 1023.5, 2.0)) == 1)"
2491 EOL" occSetFragColor (aColorL);"
2495 EOL" occSetFragColor (aColorR);"
2500 case Graphic3d_StereoMode_ChessBoard:
2502 aName = "chessboard";
2506 EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
2507 EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
2508 EOL" bool isEvenX = int(mod(floor(gl_FragCoord.x - 1023.5), 2.0)) != 1;"
2509 EOL" bool isEvenY = int(mod(floor(gl_FragCoord.y - 1023.5), 2.0)) == 1;"
2510 EOL" if ((isEvenX && isEvenY) || (!isEvenX && !isEvenY))"
2512 EOL" occSetFragColor (aColorL);"
2516 EOL" occSetFragColor (aColorR);"
2521 case Graphic3d_StereoMode_SideBySide:
2523 aName = "sidebyside";
2527 EOL" vec2 aTexCoord = vec2 (TexCoord.x * 2.0, TexCoord.y);"
2528 EOL" if (TexCoord.x > 0.5)"
2530 EOL" aTexCoord.x -= 1.0;"
2532 EOL" vec4 aColorL = occTexture2D (uLeftSampler, aTexCoord);"
2533 EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoord);"
2534 EOL" if (TexCoord.x <= 0.5)"
2536 EOL" occSetFragColor (aColorL);"
2540 EOL" occSetFragColor (aColorR);"
2545 case Graphic3d_StereoMode_OverUnder:
2547 aName = "overunder";
2551 EOL" vec2 aTexCoord = vec2 (TexCoord.x, TexCoord.y * 2.0);"
2552 EOL" if (TexCoord.y > 0.5)"
2554 EOL" aTexCoord.y -= 1.0;"
2556 EOL" vec4 aColorL = occTexture2D (uLeftSampler, aTexCoord);"
2557 EOL" vec4 aColorR = occTexture2D (uRightSampler, aTexCoord);"
2558 EOL" if (TexCoord.y <= 0.5)"
2560 EOL" occSetFragColor (aColorL);"
2564 EOL" occSetFragColor (aColorR);"
2569 case Graphic3d_StereoMode_QuadBuffer:
2570 case Graphic3d_StereoMode_SoftPageFlip:
2573 /*const Handle(OpenGl_ShaderProgram)& aProgram = myStereoPrograms[Graphic3d_StereoMode_QuadBuffer];
2574 if (!aProgram.IsNull())
2576 return aProgram->IsValid();
2581 EOL" vec4 aColorL = occTexture2D (uLeftSampler, TexCoord);"
2582 EOL" vec4 aColorR = occTexture2D (uRightSampler, TexCoord);"
2583 EOL" aColorL.b = 0.0;"
2584 EOL" aColorL.g = 0.0;"
2585 EOL" aColorR.r = 0.0;"
2586 EOL" occSetFragColor (aColorL + aColorR);"
2592 defaultGlslVersion (aProgramSrc, aName, 0);
2593 aProgramSrc->SetDefaultSampler (false);
2594 aProgramSrc->SetNbLightsMax (0);
2595 aProgramSrc->SetNbClipPlanesMax (0);
2596 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
2597 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
2598 TCollection_AsciiString aKey;
2599 if (!Create (aProgramSrc, aKey, theProgram))
2601 theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
2602 return Standard_False;
2605 myContext->BindProgram (theProgram);
2606 theProgram->SetSampler (myContext, "uLeftSampler", Graphic3d_TextureUnit_0);
2607 theProgram->SetSampler (myContext, "uRightSampler", Graphic3d_TextureUnit_1);
2608 myContext->BindProgram (NULL);
2609 return Standard_True;
2612 // =======================================================================
2613 // function : prepareStdProgramBoundBox
2615 // =======================================================================
2616 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramBoundBox()
2618 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
2620 OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
2621 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("vec3 occBBoxCenter", Graphic3d_TOS_VERTEX));
2622 aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("vec3 occBBoxSize", Graphic3d_TOS_VERTEX));
2624 TCollection_AsciiString aSrcVert =
2627 EOL" vec4 aCenter = vec4(occVertex.xyz * occBBoxSize + occBBoxCenter, 1.0);"
2628 EOL" vec4 aPos = vec4(occVertex.xyz * occBBoxSize + occBBoxCenter, 1.0);"
2629 EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * aPos;"
2632 TCollection_AsciiString aSrcFrag =
2635 EOL" occSetFragColor (occColor);"
2638 defaultGlslVersion (aProgramSrc, "bndbox", 0);
2639 aProgramSrc->SetDefaultSampler (false);
2640 aProgramSrc->SetNbLightsMax (0);
2641 aProgramSrc->SetNbClipPlanesMax (0);
2642 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
2643 aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
2644 TCollection_AsciiString aKey;
2645 if (!Create (aProgramSrc, aKey, myBoundBoxProgram))
2647 myBoundBoxProgram = new OpenGl_ShaderProgram(); // just mark as invalid
2648 return Standard_False;
2651 const OpenGl_Vec4 aMin (-0.5f, -0.5f, -0.5f, 1.0f);
2652 const OpenGl_Vec4 anAxisShifts[3] =
2654 OpenGl_Vec4 (1.0f, 0.0f, 0.0f, 0.0f),
2655 OpenGl_Vec4 (0.0f, 1.0f, 0.0f, 0.0f),
2656 OpenGl_Vec4 (0.0f, 0.0f, 1.0f, 0.0f)
2659 const OpenGl_Vec4 aLookup1 (0.0f, 1.0f, 0.0f, 1.0f);
2660 const OpenGl_Vec4 aLookup2 (0.0f, 0.0f, 1.0f, 1.0f);
2661 OpenGl_Vec4 aLinesVertices[24];
2662 for (int anAxis = 0, aVertex = 0; anAxis < 3; ++anAxis)
2664 for (int aCompIter = 0; aCompIter < 4; ++aCompIter)
2666 aLinesVertices[aVertex++] = aMin
2667 + anAxisShifts[(anAxis + 1) % 3] * aLookup1[aCompIter]
2668 + anAxisShifts[(anAxis + 2) % 3] * aLookup2[aCompIter];
2670 aLinesVertices[aVertex++] = aMin
2671 + anAxisShifts[anAxis]
2672 + anAxisShifts[(anAxis + 1) % 3] * aLookup1[aCompIter]
2673 + anAxisShifts[(anAxis + 2) % 3] * aLookup2[aCompIter];
2676 if (myContext->ToUseVbo())
2678 myBoundBoxVertBuffer = new OpenGl_VertexBuffer();
2679 if (myBoundBoxVertBuffer->Init (myContext, 4, 24, aLinesVertices[0].GetData()))
2681 myContext->ShareResource ("OpenGl_ShaderManager_BndBoxVbo", myBoundBoxVertBuffer);
2682 return Standard_True;
2685 myBoundBoxVertBuffer = new OpenGl_VertexBufferCompat();
2686 myBoundBoxVertBuffer->Init (myContext, 4, 24, aLinesVertices[0].GetData());
2687 myContext->ShareResource ("OpenGl_ShaderManager_BndBoxVbo", myBoundBoxVertBuffer);
2688 return Standard_True;
2691 // =======================================================================
2692 // function : bindProgramWithState
2694 // =======================================================================
2695 Standard_Boolean OpenGl_ShaderManager::bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram)
2697 const Standard_Boolean isBound = myContext->BindProgram (theProgram);
2699 && !theProgram.IsNull())
2701 theProgram->ApplyVariables (myContext);
2703 PushState (theProgram);
2707 // =======================================================================
2708 // function : BindMarkerProgram
2710 // =======================================================================
2711 Standard_Boolean OpenGl_ShaderManager::BindMarkerProgram (const Handle(OpenGl_TextureSet)& theTextures,
2712 Graphic3d_TypeOfShadingModel theShadingModel,
2713 Graphic3d_AlphaMode theAlphaMode,
2714 Standard_Boolean theHasVertColor,
2715 const Handle(OpenGl_ShaderProgram)& theCustomProgram)
2717 if (!theCustomProgram.IsNull()
2718 || myContext->caps->ffpEnable)
2720 return bindProgramWithState (theCustomProgram);
2723 Standard_Integer aBits = getProgramBits (theTextures, theAlphaMode, Aspect_IS_SOLID, theHasVertColor, false, false);
2724 if (!theTextures.IsNull()
2725 && theTextures->HasPointSprite())
2727 aBits |= theTextures->Last()->IsAlpha() ? OpenGl_PO_PointSpriteA : OpenGl_PO_PointSprite;
2731 aBits |= OpenGl_PO_PointSimple;
2733 Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (theShadingModel, aBits);
2734 return bindProgramWithState (aProgram);