0030748: Visualization - Marker displayed in immediate layer ruins QT Quick view...
[occt.git] / src / OpenGl / OpenGl_ShaderManager.cxx
index 3e8be7f..9dcdbc2 100644 (file)
@@ -22,6 +22,7 @@
 #include <OpenGl_ShaderManager.hxx>
 #include <OpenGl_ShaderProgram.hxx>
 #include <OpenGl_VertexBufferCompat.hxx>
+#include <OpenGl_PointSprite.hxx>
 #include <OpenGl_Workspace.hxx>
 
 #include <TCollection_ExtendedString.hxx>
@@ -627,16 +628,11 @@ void OpenGl_ShaderManager::UpdateWorldViewStateTo (const OpenGl_Mat4& theWorldVi
 }
 
 // =======================================================================
-// function : PushLightSourceState
-// purpose  : Pushes state of OCCT light sources to the program
+// function : pushLightSourceState
+// purpose  :
 // =======================================================================
-void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+void OpenGl_ShaderManager::pushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
 {
-  if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE))
-  {
-    return;
-  }
-
   theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
   if (theProgram == myFfpProgram)
   {
@@ -799,16 +795,11 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
 }
 
 // =======================================================================
-// function : PushProjectionState
-// purpose  : Pushes state of OCCT projection transform to the program
+// function : pushProjectionState
+// purpose  :
 // =======================================================================
-void OpenGl_ShaderManager::PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+void OpenGl_ShaderManager::pushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const
 {
-  if (myProjectionState.Index() == theProgram->ActiveState (OpenGl_PROJECTION_STATE))
-  {
-    return;
-  }
-
   theProgram->UpdateState (OpenGl_PROJECTION_STATE, myProjectionState.Index());
   if (theProgram == myFfpProgram)
   {
@@ -844,16 +835,11 @@ void OpenGl_ShaderManager::PushProjectionState (const Handle(OpenGl_ShaderProgra
 }
 
 // =======================================================================
-// function : PushModelWorldState
-// purpose  : Pushes state of OCCT model-world transform to the program
+// function : pushModelWorldState
+// purpose  :
 // =======================================================================
-void OpenGl_ShaderManager::PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+void OpenGl_ShaderManager::pushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const
 {
-  if (myModelWorldState.Index() == theProgram->ActiveState (OpenGl_MODEL_WORLD_STATE))
-  {
-    return;
-  }
-
   theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
   if (theProgram == myFfpProgram)
   {
@@ -891,10 +877,10 @@ void OpenGl_ShaderManager::PushModelWorldState (const Handle(OpenGl_ShaderProgra
 }
 
 // =======================================================================
-// function : PushWorldViewState
-// purpose  : Pushes state of OCCT world-view transform to the program
+// function : pushWorldViewState
+// purpose  :
 // =======================================================================
-void OpenGl_ShaderManager::PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+void OpenGl_ShaderManager::pushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const
 {
   if (myWorldViewState.Index() == theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE))
   {
@@ -956,16 +942,11 @@ void OpenGl_ShaderManager::RevertClippingState()
 }
 
 // =======================================================================
-// function : PushClippingState
-// purpose  : Pushes state of OCCT clipping planes to the program
+// function : pushClippingState
+// purpose  :
 // =======================================================================
-void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+void OpenGl_ShaderManager::pushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const
 {
-  if (myClippingState.Index() == theProgram->ActiveState (OpenGl_CLIP_PLANES_STATE))
-  {
-    return;
-  }
-
   theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index());
   if (theProgram == myFfpProgram)
   {
@@ -1135,16 +1116,11 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)
 }
 
 // =======================================================================
-// function : PushMaterialState
+// function : pushMaterialState
 // purpose  :
 // =======================================================================
-void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+void OpenGl_ShaderManager::pushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
 {
-  if (myMaterialState.Index() == theProgram->ActiveState (OpenGl_MATERIAL_STATE))
-  {
-    return;
-  }
-
   const OpenGl_Material& aFrontMat = myMaterialState.FrontMaterial();
   const OpenGl_Material& aBackMat  = myMaterialState.BackMaterial();
   theProgram->UpdateState (OpenGl_MATERIAL_STATE, myMaterialState.Index());
@@ -1207,21 +1183,11 @@ void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)
 }
 
 // =======================================================================
-// function : PushOitState
-// purpose  : Pushes state of OIT uniforms to the specified program
+// function : pushOitState
+// purpose  :
 // =======================================================================
-void OpenGl_ShaderManager::PushOitState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+void OpenGl_ShaderManager::pushOitState (const Handle(OpenGl_ShaderProgram)& theProgram) const
 {
-  if (!theProgram->IsValid())
-  {
-    return;
-  }
-
-  if (myOitState.Index() == theProgram->ActiveState (OpenGL_OIT_STATE))
-  {
-    return;
-  }
-
   const GLint aLocOutput = theProgram->GetStateLocation (OpenGl_OCCT_OIT_OUTPUT);
   if (aLocOutput != OpenGl_ShaderProgram::INVALID_LOCATION)
   {
@@ -1248,10 +1214,6 @@ void OpenGl_ShaderManager::PushInteriorState (const Handle(OpenGl_ShaderProgram)
     return;
   }
 
-  if (const OpenGl_ShaderUniformLocation aLocViewPort = theProgram->GetStateLocation (OpenGl_OCCT_VIEWPORT))
-  {
-    theProgram->SetUniform (myContext, aLocViewPort, OpenGl_Vec4 ((float )myContext->Viewport()[0], (float )myContext->Viewport()[1], (float )myContext->Viewport()[2], (float )myContext->Viewport()[3]));
-  }
   if (const OpenGl_ShaderUniformLocation aLocLineWidth = theProgram->GetStateLocation (OpenGl_OCCT_LINE_WIDTH))
   {
     theProgram->SetUniform (myContext, aLocLineWidth, theAspect->EdgeWidth() * myContext->LineWidthScale());
@@ -1288,6 +1250,15 @@ void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& thePro
   PushLightSourceState (aProgram);
   PushMaterialState    (aProgram);
   PushOitState         (aProgram);
+
+  if (!theProgram.IsNull())
+  {
+    if (const OpenGl_ShaderUniformLocation& aLocViewPort = theProgram->GetStateLocation (OpenGl_OCCT_VIEWPORT))
+    {
+      theProgram->SetUniform (myContext, aLocViewPort, OpenGl_Vec4 ((float )myContext->Viewport()[0], (float )myContext->Viewport()[1],
+                                                                    (float )myContext->Viewport()[2], (float )myContext->Viewport()[3]));
+    }
+  }
 }
 
 // =======================================================================
@@ -1297,6 +1268,7 @@ void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& thePro
 Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFont()
 {
   OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
+  aUniforms   .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_FRAGMENT));
   aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec2 TexCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
 
   TCollection_AsciiString aSrcVert = TCollection_AsciiString()
@@ -1327,6 +1299,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFont()
 
   Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
   defaultGlslVersion (aProgramSrc, "font", 0);
+  aProgramSrc->SetDefaultSampler (false);
   aProgramSrc->SetNbLightsMax (0);
   aProgramSrc->SetNbClipPlanesMax (0);
   aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX,   aUniforms, aStageInOuts));
@@ -1392,6 +1365,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFboBlit()
   }
 #endif
   aProgramSrc->SetId ("occt_blit");
+  aProgramSrc->SetDefaultSampler (false);
   aProgramSrc->SetNbLightsMax (0);
   aProgramSrc->SetNbClipPlanesMax (0);
   aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX,   aUniforms, aStageInOuts));
@@ -1483,6 +1457,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramOitCompositing (const St
   }
 
   aProgramSrc->SetId (theMsaa ? "occt_weight-oit-msaa" : "occt_weight-oit");
+  aProgramSrc->SetDefaultSampler (false);
   aProgramSrc->SetNbLightsMax (0);
   aProgramSrc->SetNbClipPlanesMax (0);
   aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX,   aUniforms, aStageInOuts));
@@ -1505,14 +1480,14 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramOitCompositing (const St
 // function : pointSpriteAlphaSrc
 // purpose  :
 // =======================================================================
-TCollection_AsciiString OpenGl_ShaderManager::pointSpriteAlphaSrc (const Standard_Integer theBits)
+TCollection_AsciiString OpenGl_ShaderManager::pointSpriteAlphaSrc (Standard_Integer theBits)
 {
-  TCollection_AsciiString aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occSamplerBaseColor, " THE_VEC2_glPointCoord ").a; }";
+  TCollection_AsciiString aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occSamplerPointSprite, " THE_VEC2_glPointCoord ").a; }";
 #if !defined(GL_ES_VERSION_2_0)
   if (myContext->core11 == NULL
-   && (theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureA)
+   && (theBits & OpenGl_PO_PointSpriteA) == OpenGl_PO_PointSpriteA)
   {
-    aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occSamplerBaseColor, " THE_VEC2_glPointCoord ").r; }";
+    aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occSamplerPointSprite, " THE_VEC2_glPointCoord ").r; }";
   }
 #else
   (void )theBits;
@@ -1545,7 +1520,9 @@ int OpenGl_ShaderManager::defaultGlslVersion (const Handle(Graphic3d_ShaderProgr
       }
       else if (myContext->CheckExtension ("GL_EXT_gpu_shader4"))
       {
-        theProgram->SetHeader ("#extension GL_EXT_gpu_shader4 : enable");
+        // GL_EXT_gpu_shader4 defines GLSL type "unsigned int", while core GLSL specs define type "uint"
+        theProgram->SetHeader ("#extension GL_EXT_gpu_shader4 : enable\n"
+                               "#define uint unsigned int");
       }
       else
       {
@@ -1699,18 +1676,29 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramUnlit (Handle(OpenGl_Sha
   TCollection_AsciiString aSrcFragMainGetColor = EOL"  occSetFragColor (getFinalColor());";
   OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
 
-  if ((theBits & OpenGl_PO_Point) != 0)
+  if ((theBits & OpenGl_PO_IsPoint) != 0)
   {
   #if defined(GL_ES_VERSION_2_0)
     aSrcVertExtraMain += EOL"  gl_PointSize = occPointSize;";
   #endif
 
-    if ((theBits & OpenGl_PO_HasTextures) != 0)
+    if ((theBits & OpenGl_PO_PointSprite) != 0)
     {
-      if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB)
+      aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerPointSprite", Graphic3d_TOS_FRAGMENT));
+      if ((theBits & OpenGl_PO_PointSpriteA) != OpenGl_PO_PointSpriteA)
+      {
+        aSrcFragGetColor =
+          EOL"vec4 getColor(void) { return occTexture2D(occSamplerPointSprite, " THE_VEC2_glPointCoord "); }";
+      }
+      else if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB
+            && (theBits & OpenGl_PO_VertColor) == 0)
       {
+        aUniforms   .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_VERTEX));
+        aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 VertColor", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
+        aSrcVertExtraMain +=
+          EOL"  VertColor = occTexture2D (occSamplerBaseColor, occTexCoord.xy);";
         aSrcFragGetColor =
-          EOL"vec4 getColor(void) { return occTexture2D(occSamplerBaseColor, " THE_VEC2_glPointCoord "); }";
+          EOL"vec4 getColor(void) { return VertColor; }";
       }
 
       aSrcGetAlpha = pointSpriteAlphaSrc (theBits);
@@ -1731,6 +1719,17 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramUnlit (Handle(OpenGl_Sha
     }
     else
     {
+      if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB
+       && (theBits & OpenGl_PO_VertColor) == 0)
+      {
+        aUniforms   .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_VERTEX));
+        aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 VertColor", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
+        aSrcVertExtraMain +=
+          EOL"  VertColor = occTexture2D (occSamplerBaseColor, occTexCoord.xy);";
+        aSrcFragGetColor =
+          EOL"vec4 getColor(void) { return VertColor; }";
+      }
+
       aSrcFragMainGetColor =
         EOL"  vec4 aColor = getColor();"
         EOL"  if (aColor.a <= 0.1) discard;"
@@ -1741,6 +1740,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramUnlit (Handle(OpenGl_Sha
   {
     if ((theBits & OpenGl_PO_TextureRGB) != 0 || (theBits & OpenGl_PO_TextureEnv) != 0)
     {
+      aUniforms   .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_FRAGMENT));
       aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 TexCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
     }
 
@@ -1821,12 +1821,23 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramUnlit (Handle(OpenGl_Sha
     {
       aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("int   uPattern", Graphic3d_TOS_FRAGMENT));
       aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("float uFactor",  Graphic3d_TOS_FRAGMENT));
+      aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 occViewport", Graphic3d_TOS_VERTEX));
       aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec2 ScreenSpaceCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
       aSrcVertEndMain =
-        EOL"  ScreenSpaceCoord = gl_Position.xy / gl_Position.w;";
+        EOL"  vec2 aPosition   = gl_Position.xy / gl_Position.w;"
+        EOL"  aPosition        = aPosition * 0.5 + 0.5;"
+        EOL"  ScreenSpaceCoord = aPosition.xy * occViewport.zw + occViewport.xy;";
       aSrcFragMainGetColor =
-        EOL"  float anAngle      = atan (dFdx (ScreenSpaceCoord.x), dFdy (ScreenSpaceCoord.y));"
-        EOL"  float aRotatePoint = gl_FragCoord.x * sin (anAngle) + gl_FragCoord.y * cos (anAngle);"
+        EOL"  vec2 anAxis = vec2 (0.0);"
+        EOL"  if (abs (dFdx (ScreenSpaceCoord.x)) - abs (dFdy (ScreenSpaceCoord.y)) > 0.001)" 
+        EOL"  {"
+        EOL"    anAxis = vec2 (1.0, 0.0);"
+        EOL"  }"
+        EOL"  else"
+        EOL"  {"
+        EOL"    anAxis = vec2 (0.0, 1.0);"
+        EOL"  }"
+        EOL"  float aRotatePoint = dot (gl_FragCoord.xy, anAxis);"
         EOL"  uint  aBit         = uint (floor (aRotatePoint / uFactor + 0.5)) & 15U;"
         EOL"  if ((uint (uPattern) & (1U << aBit)) == 0U) discard;"
         EOL"  vec4 aColor = getFinalColor();"
@@ -1863,6 +1874,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramUnlit (Handle(OpenGl_Sha
     + EOL"}";
 
   defaultGlslVersion (aProgramSrc, theIsOutline ? "outline" : "unlit", theBits);
+  aProgramSrc->SetDefaultSampler (false);
   aProgramSrc->SetNbLightsMax (0);
   aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
   aProgramSrc->SetAlphaTest ((theBits & OpenGl_PO_AlphaTest) != 0);
@@ -1883,11 +1895,11 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramUnlit (Handle(OpenGl_Sha
 // function : pointSpriteShadingSrc
 // purpose  :
 // =======================================================================
-TCollection_AsciiString OpenGl_ShaderManager::pointSpriteShadingSrc (const TCollection_AsciiString theBaseColorSrc,
-                                                                     const Standard_Integer theBits)
+TCollection_AsciiString OpenGl_ShaderManager::pointSpriteShadingSrc (const TCollection_AsciiString& theBaseColorSrc,
+                                                                     Standard_Integer theBits)
 {
   TCollection_AsciiString aSrcFragGetColor;
-  if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureA)
+  if ((theBits & OpenGl_PO_PointSpriteA) == OpenGl_PO_PointSpriteA)
   {
     aSrcFragGetColor = pointSpriteAlphaSrc (theBits) +
       EOL"vec4 getColor(void)"
@@ -1898,13 +1910,13 @@ TCollection_AsciiString OpenGl_ShaderManager::pointSpriteShadingSrc (const TColl
       EOL"  return aColor;"
       EOL"}";
   }
-  else if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB)
+  else if ((theBits & OpenGl_PO_PointSprite) == OpenGl_PO_PointSprite)
   {
     aSrcFragGetColor = TCollection_AsciiString() +
       EOL"vec4 getColor(void)"
       EOL"{"
       EOL"  vec4 aColor = " + theBaseColorSrc + ";"
-      EOL"  aColor = occTexture2D(occSamplerBaseColor, " THE_VEC2_glPointCoord ") * aColor;"
+      EOL"  aColor = occTexture2D(occSamplerPointSprite, " THE_VEC2_glPointCoord ") * aColor;"
       EOL"  if (aColor.a <= 0.1) discard;"
       EOL"  return aColor;"
       EOL"}";
@@ -2062,29 +2074,38 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
   TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return gl_FrontFacing ? FrontColor : BackColor; }";
   OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
 
-  if ((theBits & OpenGl_PO_Point) != 0)
+  if ((theBits & OpenGl_PO_IsPoint) != 0)
   {
   #if defined(GL_ES_VERSION_2_0)
     aSrcVertExtraMain += EOL"  gl_PointSize = occPointSize;";
   #endif
 
-    if ((theBits & OpenGl_PO_HasTextures) != 0)
+    if ((theBits & OpenGl_PO_PointSprite) != 0)
     {
-      #if !defined(GL_ES_VERSION_2_0)
-        if (myContext->core11 != NULL
-         && myContext->IsGlGreaterEqual (2, 1))
-        {
-          aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
-        }
-      #endif
+    #if !defined(GL_ES_VERSION_2_0)
+      if (myContext->core11 != NULL
+        && myContext->IsGlGreaterEqual (2, 1))
+      {
+        aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
+      }
+    #endif
 
+      aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerPointSprite", Graphic3d_TOS_FRAGMENT));
       aSrcFragGetColor = pointSpriteShadingSrc ("gl_FrontFacing ? FrontColor : BackColor", theBits);
     }
+
+    if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB
+     && (theBits & OpenGl_PO_VertColor) == 0)
+    {
+      aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_VERTEX));
+      aSrcVertColor = EOL"vec4 getVertColor(void) { return occTexture2D (occSamplerBaseColor, occTexCoord.xy); }";
+    }
   }
   else
   {
     if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB)
     {
+      aUniforms   .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_FRAGMENT));
       aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 TexCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
       aSrcVertExtraMain += THE_VARY_TexCoord_Trsf;
 
@@ -2141,7 +2162,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
   aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 BackColor",  Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
 
   Standard_Integer aNbLights = 0;
-  const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, (theBits & OpenGl_PO_VertColor) != 0);
+  const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, !aSrcVertColor.IsEmpty());
   aSrcVert = TCollection_AsciiString()
     + THE_FUNC_transformNormal
     + EOL
@@ -2174,6 +2195,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
 
   const TCollection_AsciiString aProgId = TCollection_AsciiString ("gouraud-") + genLightKey (myLightSourceState.LightSources()) + "-";
   defaultGlslVersion (aProgramSrc, aProgId, theBits);
+  aProgramSrc->SetDefaultSampler (false);
   aProgramSrc->SetNbLightsMax (aNbLights);
   aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
   aProgramSrc->SetAlphaTest ((theBits & OpenGl_PO_AlphaTest) != 0);
@@ -2223,29 +2245,41 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
   TCollection_AsciiString aSrcFrag, aSrcFragExtraOut, aSrcFragGetVertColor, aSrcFragExtraMain;
   TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return " thePhongCompLight "; }";
   OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
-  if ((theBits & OpenGl_PO_Point) != 0)
+  if ((theBits & OpenGl_PO_IsPoint) != 0)
   {
   #if defined(GL_ES_VERSION_2_0)
     aSrcVertExtraMain += EOL"  gl_PointSize = occPointSize;";
   #endif
 
-    if ((theBits & OpenGl_PO_HasTextures) != 0)
+    if ((theBits & OpenGl_PO_PointSprite) != 0)
     {
-      #if !defined(GL_ES_VERSION_2_0)
-        if (myContext->core11 != NULL
-         && myContext->IsGlGreaterEqual (2, 1))
-        {
-          aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
-        }
-      #endif
+    #if !defined(GL_ES_VERSION_2_0)
+      if (myContext->core11 != NULL
+        && myContext->IsGlGreaterEqual (2, 1))
+      {
+        aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
+      }
+    #endif
 
+      aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerPointSprite", Graphic3d_TOS_FRAGMENT));
       aSrcFragGetColor = pointSpriteShadingSrc (thePhongCompLight, theBits);
     }
+
+    if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB
+     && (theBits & OpenGl_PO_VertColor) == 0)
+    {
+      aUniforms   .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_VERTEX));
+      aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 VertColor", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
+
+      aSrcVertExtraMain   += EOL"  VertColor = occTexture2D (occSamplerBaseColor, occTexCoord.xy);";
+      aSrcFragGetVertColor = EOL"vec4 getVertColor(void) { return VertColor; }";
+    }
   }
   else
   {
     if ((theBits & OpenGl_PO_HasTextures) == OpenGl_PO_TextureRGB)
     {
+      aUniforms   .Append (OpenGl_ShaderObject::ShaderVariable ("sampler2D occSamplerBaseColor", Graphic3d_TOS_FRAGMENT));
       aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable ("vec4 TexCoord", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
       aSrcVertExtraMain += THE_VARY_TexCoord_Trsf;
 
@@ -2329,7 +2363,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
     : EOL"#define getFinalColor getColor";
 
   Standard_Integer aNbLights = 0;
-  const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, (theBits & OpenGl_PO_VertColor) != 0);
+  const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, !aSrcFragGetVertColor.IsEmpty());
   aSrcFrag = TCollection_AsciiString()
     + EOL
     + aSrcFragExtraOut
@@ -2345,6 +2379,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
 
   const TCollection_AsciiString aProgId = TCollection_AsciiString (theIsFlatNormal ? "flat-" : "phong-") + genLightKey (myLightSourceState.LightSources()) + "-";
   defaultGlslVersion (aProgramSrc, aProgId, theBits, isFlatNormal);
+  aProgramSrc->SetDefaultSampler (false);
   aProgramSrc->SetNbLightsMax (aNbLights);
   aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
   aProgramSrc->SetAlphaTest ((theBits & OpenGl_PO_AlphaTest) != 0);
@@ -2536,6 +2571,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
   }
 
   defaultGlslVersion (aProgramSrc, aName, 0);
+  aProgramSrc->SetDefaultSampler (false);
   aProgramSrc->SetNbLightsMax (0);
   aProgramSrc->SetNbClipPlanesMax (0);
   aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX,   aUniforms, aStageInOuts));
@@ -2581,6 +2617,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramBoundBox()
     EOL"}";
 
   defaultGlslVersion (aProgramSrc, "bndbox", 0);
+  aProgramSrc->SetDefaultSampler (false);
   aProgramSrc->SetNbLightsMax (0);
   aProgramSrc->SetNbClipPlanesMax (0);
   aProgramSrc->AttachShader (OpenGl_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX,   aUniforms, aStageInOuts));
@@ -2647,3 +2684,33 @@ Standard_Boolean OpenGl_ShaderManager::bindProgramWithState (const Handle(OpenGl
   PushState (theProgram);
   return isBound;
 }
+
+// =======================================================================
+// function : BindMarkerProgram
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_ShaderManager::BindMarkerProgram (const Handle(OpenGl_TextureSet)& theTextures,
+                                                          Graphic3d_TypeOfShadingModel theShadingModel,
+                                                          Graphic3d_AlphaMode theAlphaMode,
+                                                          Standard_Boolean theHasVertColor,
+                                                          const Handle(OpenGl_ShaderProgram)& theCustomProgram)
+{
+  if (!theCustomProgram.IsNull()
+    || myContext->caps->ffpEnable)
+  {
+    return bindProgramWithState (theCustomProgram);
+  }
+
+  Standard_Integer aBits = getProgramBits (theTextures, theAlphaMode, Aspect_IS_SOLID, theHasVertColor, false, false);
+  if (!theTextures.IsNull()
+    && theTextures->HasPointSprite())
+  {
+    aBits |= theTextures->Last()->IsAlpha() ? OpenGl_PO_PointSpriteA : OpenGl_PO_PointSprite;
+  }
+  else
+  {
+    aBits |= OpenGl_PO_PointSimple;
+  }
+  Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (theShadingModel, aBits);
+  return bindProgramWithState (aProgram);
+}