0024452: TKOpenGl - Memory leak in OpenGl_ShaderManager
[occt.git] / src / OpenGl / OpenGl_ShaderManager.cxx
index 97b0fbb..d5ad6b9 100644 (file)
@@ -27,6 +27,7 @@
 #include <OpenGl_Context.hxx>
 #include <OpenGl_ShaderManager.hxx>
 #include <OpenGl_ShaderProgram.hxx>
+#include <OpenGl_Workspace.hxx>
 
 IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderManager, Standard_Transient)
 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager, Standard_Transient)
@@ -55,35 +56,59 @@ OpenGl_ShaderManager::~OpenGl_ShaderManager()
 // function : Create
 // purpose  : Creates new shader program
 // =======================================================================
-Handle(OpenGl_ShaderProgram) OpenGl_ShaderManager::Create (const Handle(Graphic3d_ShaderProgram)& theProxyProgram)
+void OpenGl_ShaderManager::Create (const Handle(Graphic3d_ShaderProgram)& theProxy,
+                                   TCollection_AsciiString&               theShareKey,
+                                   Handle(OpenGl_ShaderProgram)&          theProgram)
 {
-  if (theProxyProgram.IsNull())
+  theProgram.Nullify();
+  if (theProxy.IsNull())
   {
-    return NULL;
+    return;
   }
-  
-  Handle(OpenGl_ShaderProgram) aProgram = new OpenGl_ShaderProgram (theProxyProgram);
-  if (!aProgram->Initialize (myContext, theProxyProgram->ShaderObjects()))
+
+  theShareKey = theProxy->GetId();
+  if (myContext->GetResource<Handle(OpenGl_ShaderProgram)> (theShareKey, theProgram))
   {
-    return NULL;
+    if (theProgram->Share())
+    {
+      myProgramList.Append (theProgram);
+    }
+    return;
   }
-  
-  myProgramList.Append (aProgram);
 
-  return aProgram;
+  theProgram = new OpenGl_ShaderProgram (theProxy);
+  if (!theProgram->Initialize (myContext, theProxy->ShaderObjects()))
+  {
+    theProgram->Release (myContext);
+    theShareKey.Clear();
+    theProgram.Nullify();
+    return;
+  }
+
+  myProgramList.Append (theProgram);
+  myContext->ShareResource (theShareKey, theProgram);
 }
 
 // =======================================================================
 // function : Unregister
 // purpose  : Removes specified shader program from the manager
 // =======================================================================
-void OpenGl_ShaderManager::Unregister (Handle(OpenGl_ShaderProgram)& theProgram)
+void OpenGl_ShaderManager::Unregister (TCollection_AsciiString&      theShareKey,
+                                       Handle(OpenGl_ShaderProgram)& theProgram)
 {
   for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
   {
     if (anIt.Value() == theProgram)
     {
+      if (!theProgram->UnShare())
+      {
+        theShareKey.Clear();
+        theProgram.Nullify();
+        return;
+      }
+
       myProgramList.Remove (anIt);
+      myMaterialStates.UnBind (theProgram);
       break;
     }
   }
@@ -97,7 +122,7 @@ void OpenGl_ShaderManager::Unregister (Handle(OpenGl_ShaderProgram)& theProgram)
   else
   {
     theProgram.Nullify();
-    myContext->ReleaseResource (anID);
+    myContext->ReleaseResource (anID, Standard_True);
   }
 }
 
@@ -225,94 +250,125 @@ const OpenGl_WorldViewState& OpenGl_ShaderManager::WorldViewState() const
   return myWorldViewState;
 }
 
+//! Packed properties of light source
+class OpenGl_ShaderLightParameters
+{
+public:
+
+  OpenGl_Vec4 Color;
+  OpenGl_Vec4 Position;
+  OpenGl_Vec4 Direction;
+  OpenGl_Vec4 Parameters;
+
+  //! Returns packed (serialized) representation of light source properties
+  const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
+  static Standard_Integer NbOfVec4() { return 4; }
+
+};
+
+//! Packed light source type information
+class OpenGl_ShaderLightType
+{
+public:
+
+  Standard_Integer Type;
+  Standard_Integer IsHeadlight;
+
+  //! Returns packed (serialized) representation of light source type
+  const OpenGl_Vec2i* Packed() const { return reinterpret_cast<const OpenGl_Vec2i*> (this); }
+  static Standard_Integer NbOfVec2i() { return 1; }
+
+};
+
 // =======================================================================
 // function : PushLightSourceState
 // purpose  : Pushes state of OCCT light sources to the program
 // =======================================================================
 void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
 {
-  if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE))
+  if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE)
+   || !theProgram->IsValid())
   {
     return;
   }
-  
-  theProgram->SetUniform (myContext, theProgram->GetStateLocation (
-    OpenGl_OCC_LIGHT_SOURCE_COUNT), myLightSourceState.LightSources()->Size());
 
-  OpenGl_ListOfLight::Iterator anIter (*myLightSourceState.LightSources());
-  for (unsigned int anIndex = 0; anIter.More(); anIter.Next())
+  OpenGl_ShaderLightType* aLightTypeArray = new OpenGl_ShaderLightType[OpenGLMaxLights];
+  for (Standard_Integer aLightIt = 0; aLightIt < OpenGLMaxLights; ++aLightIt)
   {
-    if (anIndex >= OpenGLMaxLights)
-    {
-      break;
-    }
-
-    const OpenGl_Light& aLight = anIter.Value();
-    if (aLight.type == TLightAmbient)
-    {
-      OpenGl_Vec3 anAmbient (aLight.col.rgb[0],
-                             aLight.col.rgb[1],
-                             aLight.col.rgb[2]);
-
-      theProgram->SetUniform (myContext,
-        theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_AMBIENT + anIndex), anAmbient);
-
-      anIter.Next();
-      if (!anIter.More())
-      {
-        theProgram->SetUniform (myContext,
-          theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_TYPE + anIndex), int (aLight.type));
-        break;
-      }
-    }
-
-    OpenGl_Vec3 aDiffuse (aLight.col.rgb[0],
-                          aLight.col.rgb[1],
-                          aLight.col.rgb[2]);
-
-    OpenGl_Vec3 aPosition (aLight.type == TLightDirectional ? -aLight.dir[0] : aLight.pos[0],
-                           aLight.type == TLightDirectional ? -aLight.dir[1] : aLight.pos[1],
-                           aLight.type == TLightDirectional ? -aLight.dir[2] : aLight.pos[2]);
-
-    theProgram->SetUniform (myContext,
-      theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_TYPE + anIndex), int (aLight.type));
-
-    theProgram->SetUniform (myContext,
-      theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_HEAD + anIndex), aLight.HeadLight);
+    aLightTypeArray[aLightIt].Type = -1;
+  }
 
+  const Standard_Integer aLightsDefNb = Min (myLightSourceState.LightSources()->Size(), OpenGLMaxLights);
+  if (aLightsDefNb < 1)
+  {
     theProgram->SetUniform (myContext,
-      theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_DIFFUSE + anIndex), aDiffuse);
-
+                            theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
+                            0);
     theProgram->SetUniform (myContext,
-      theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPECULAR + anIndex), aDiffuse);
-
+                            theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT),
+                            OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
     theProgram->SetUniform (myContext,
-      theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_POSITION + anIndex), aPosition);
-
-    theProgram->SetUniform (myContext,
-      theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_CONST_ATTENUATION + anIndex), aLight.atten[0]);
+                            theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
+                            OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
+                            aLightTypeArray[0].Packed());
+    theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
+    delete[] aLightTypeArray;
+    return;
+  }
 
-    theProgram->SetUniform (myContext,
-      theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_LINEAR_ATTENUATION + anIndex), aLight.atten[1]);
+  OpenGl_ShaderLightParameters* aLightParamsArray = new OpenGl_ShaderLightParameters[aLightsDefNb];
 
-    if (aLight.type == TLightSpot)
+  OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f);
+  Standard_Integer aLightsNb = 0;
+  for (OpenGl_ListOfLight::Iterator anIter (*myLightSourceState.LightSources()); anIter.More(); anIter.Next())
+  {
+    const OpenGl_Light& aLight = anIter.Value();
+    if (aLight.Type == Visual3d_TOLS_AMBIENT)
     {
-      OpenGl_Vec3 aDirection (aLight.dir[0],
-                              aLight.dir[1],
-                              aLight.dir[2]);
-
-      theProgram->SetUniform (myContext,
-        theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPOT_CUTOFF + anIndex), aLight.angle);
+      anAmbient += aLight.Color;
+      continue;
+    }
+    else if (aLightsNb >= OpenGLMaxLights)
+    {
+      continue;
+    }
 
-      theProgram->SetUniform (myContext,
-        theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPOT_EXPONENT + anIndex), aLight.shine);
+    OpenGl_ShaderLightType& aLightType = aLightTypeArray[aLightsNb];
+    aLightType.Type        = aLight.Type;
+    aLightType.IsHeadlight = aLight.IsHeadlight;
 
-      theProgram->SetUniform (myContext,
-        theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPOT_DIRECTION + anIndex), aDirection);
+    OpenGl_ShaderLightParameters& aLightParams = aLightParamsArray[aLightsNb];
+    aLightParams.Color    = aLight.Color;
+    aLightParams.Position = aLight.Type == Visual3d_TOLS_DIRECTIONAL
+                         ? -aLight.Direction
+                         :  aLight.Position;
+    if (aLight.Type == Visual3d_TOLS_SPOT)
+    {
+      aLightParams.Direction = aLight.Direction;
     }
+    aLightParams.Parameters = aLight.Params;
+    ++aLightsNb;
+  }
 
-    ++anIndex;
+  theProgram->SetUniform (myContext,
+                          theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
+                          aLightsNb);
+  theProgram->SetUniform (myContext,
+                          theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT),
+                          anAmbient);
+  theProgram->SetUniform (myContext,
+                          theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
+                          OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
+                          aLightTypeArray[0].Packed());
+  if (aLightsNb > 0)
+  {
+    theProgram->SetUniform (myContext,
+                            theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_PARAMS),
+                            aLightsNb * OpenGl_ShaderLightParameters::NbOfVec4(),
+                            aLightParamsArray[0].Packed());
   }
+  delete[] aLightParamsArray;
+  delete[] aLightTypeArray;
 
   theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
 }
@@ -448,8 +504,18 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)
     return;
   }
 
-  Graphic3d_SetOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
-  for (GLuint anIndex = 0; anIter.More(); anIter.Next())
+  theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index());
+  const GLint aLocEquations = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_EQUATIONS);
+  const GLint aLocSpaces    = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_SPACES);
+  if (aLocEquations == OpenGl_ShaderProgram::INVALID_LOCATION
+   && aLocSpaces    == OpenGl_ShaderProgram::INVALID_LOCATION)
+  {
+    return;
+  }
+
+  GLuint aPlanesNb = 0;
+  for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
+       anIter.More(); anIter.Next())
   {
     const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
     if (!myContext->Clipping().IsEnabled (aPlane))
@@ -457,23 +523,38 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)
       continue;
     }
 
-    GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_0_EQUATION + anIndex);
-    if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
+    ++aPlanesNb;
+  }
+  if (aPlanesNb < 1)
+  {
+    return;
+  }
+
+  OpenGl_Vec4* anEquations = new OpenGl_Vec4[aPlanesNb];
+  GLint*       aSpaces     = new GLint      [aPlanesNb];
+  GLuint aPlaneId = 0;
+  for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
+       anIter.More(); anIter.Next())
+  {
+    const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
+    if (!myContext->Clipping().IsEnabled (aPlane))
     {
-      const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
-      theProgram->SetUniform (myContext, aLocation, OpenGl_Vec4 ((float) anEquation.x(),
-                                                                 (float) anEquation.y(),
-                                                                 (float) anEquation.z(),
-                                                                 (float) anEquation.w()));
+      continue;
     }
 
-    theProgram->SetUniform (myContext,
-                            theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_0_SPACE + anIndex),
-                            myContext->Clipping().GetEquationSpace (aPlane));
-    ++anIndex;
+    const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
+    anEquations[aPlaneId] = OpenGl_Vec4 ((float) anEquation.x(),
+                                         (float) anEquation.y(),
+                                         (float) anEquation.z(),
+                                         (float) anEquation.w());
+    aSpaces[aPlaneId] = myContext->Clipping().GetEquationSpace (aPlane);
+    ++aPlaneId;
   }
+  theProgram->SetUniform (myContext, aLocEquations, aPlanesNb, anEquations[0].GetData());
+  theProgram->SetUniform (myContext, aLocSpaces,    aPlanesNb, aSpaces);
 
-  theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index());
+  delete[] anEquations;
+  delete[] aSpaces;
 }
 
 // =======================================================================
@@ -535,65 +616,27 @@ static void PushAspectFace (const Handle(OpenGl_Context)&       theCtx,
   theProgram->SetUniform (theCtx,
                           theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),
                           theAspect->DoTextureMap());
-
   theProgram->SetUniform (theCtx,
                           theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER),
                           0 /* GL_TEXTURE0 */);
-
   theProgram->SetUniform (theCtx,
                           theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
                           theAspect->DistinguishingMode());
 
-  for (int anIndex = 0; anIndex < 2; ++anIndex)
+  OpenGl_Material aParams;
+  for (Standard_Integer anIndex = 0; anIndex < 2; ++anIndex)
   {
-    const OPENGL_SURF_PROP& aProperties = (anIndex == 0) ? theAspect->IntFront() : theAspect->IntBack();
-    GLint aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT + anIndex);
-    if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
+    const GLint aLoc = theProgram->GetStateLocation (anIndex == 0
+                                                   ? OpenGl_OCCT_FRONT_MATERIAL
+                                                   : OpenGl_OCCT_BACK_MATERIAL);
+    if (aLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
     {
-      OpenGl_Vec4 anAmbient (aProperties.ambcol.rgb[0] * aProperties.amb,
-                             aProperties.ambcol.rgb[1] * aProperties.amb,
-                             aProperties.ambcol.rgb[2] * aProperties.amb,
-                             aProperties.ambcol.rgb[3] * aProperties.amb);
-      theProgram->SetUniform (theCtx, aLocation, anAmbient);
-    }
-
-    aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE + anIndex);
-    if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
-    {
-      OpenGl_Vec4 aDiffuse (aProperties.difcol.rgb[0] * aProperties.diff,
-                            aProperties.difcol.rgb[1] * aProperties.diff,
-                            aProperties.difcol.rgb[2] * aProperties.diff,
-                            aProperties.difcol.rgb[3] * aProperties.diff);
-      theProgram->SetUniform (theCtx, aLocation, aDiffuse);
-    }
-
-    aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR + anIndex);
-    if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
-    {
-      OpenGl_Vec4 aSpecular (aProperties.speccol.rgb[0] * aProperties.spec,
-                             aProperties.speccol.rgb[1] * aProperties.spec,
-                             aProperties.speccol.rgb[2] * aProperties.spec,
-                             aProperties.speccol.rgb[3] * aProperties.spec);
-      theProgram->SetUniform (theCtx, aLocation, aSpecular);
-    }
-
-    aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION + anIndex);
-    if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
-    {
-      OpenGl_Vec4 anEmission (aProperties.emscol.rgb[0] * aProperties.emsv,
-                              aProperties.emscol.rgb[1] * aProperties.emsv,
-                              aProperties.emscol.rgb[2] * aProperties.emsv,
-                              aProperties.emscol.rgb[3] * aProperties.emsv);
-      theProgram->SetUniform (theCtx, aLocation, anEmission);
+      continue;
     }
-    
-    theProgram->SetUniform (theCtx,
-                            theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SHININESS + anIndex),
-                            aProperties.shine);
 
-    theProgram->SetUniform (theCtx,
-                            theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY + anIndex),
-                            aProperties.trans);
+    aParams.Init (anIndex == 0 ? theAspect->IntFront() : theAspect->IntBack());
+    theProgram->SetUniform (theCtx, aLoc, OpenGl_Material::NbOfVec4(),
+                            aParams.Packed());
   }
 }
 
@@ -612,21 +655,15 @@ static void PushAspectLine (const Handle(OpenGl_Context)&       theCtx,
                               theAspect->Color().rgb[1],
                               theAspect->Color().rgb[2],
                               theAspect->Color().rgb[3]);
-  theProgram->SetUniform (theCtx,
-                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT),
-                          THE_COLOR_BLACK_VEC4);
-  theProgram->SetUniform (theCtx,
-                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE),
-                          aDiffuse);
-  theProgram->SetUniform (theCtx,
-                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR),
-                          THE_COLOR_BLACK_VEC4);
-  theProgram->SetUniform (theCtx,
-                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION),
-                          THE_COLOR_BLACK_VEC4);
-  theProgram->SetUniform (theCtx,
-                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY),
-                          0.0f);
+  OpenGl_Vec4 aParams[5];
+  aParams[0] = THE_COLOR_BLACK_VEC4;
+  aParams[1] = THE_COLOR_BLACK_VEC4;
+  aParams[2] = aDiffuse;
+  aParams[3] = THE_COLOR_BLACK_VEC4;
+  aParams[4].x() = 0.0f; // shininess
+  aParams[4].y() = 0.0f; // transparency
+  theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
+                          5, aParams);
 }
 
 // =======================================================================
@@ -654,21 +691,15 @@ static void PushAspectText (const Handle(OpenGl_Context)&       theCtx,
                             theAspect->SubtitleColor().rgb[3]);
   }
 
-  theProgram->SetUniform (theCtx,
-                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT),
-                          THE_COLOR_BLACK_VEC4);
-  theProgram->SetUniform (theCtx,
-                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE),
-                          aDiffuse);
-  theProgram->SetUniform (theCtx,
-                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR),
-                          THE_COLOR_BLACK_VEC4);
-  theProgram->SetUniform (theCtx,
-                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION),
-                          THE_COLOR_BLACK_VEC4);
-  theProgram->SetUniform (theCtx,
-                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY),
-                          0.0f);
+  OpenGl_Vec4 aParams[5];
+  aParams[0] = THE_COLOR_BLACK_VEC4;
+  aParams[1] = THE_COLOR_BLACK_VEC4;
+  aParams[2] = aDiffuse;
+  aParams[3] = THE_COLOR_BLACK_VEC4;
+  aParams[4].x() = 0.0f; // shininess
+  aParams[4].y() = 0.0f; // transparency
+  theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
+                          5, aParams);
 }
 
 // =======================================================================
@@ -687,22 +718,15 @@ static void PushAspectMarker (const Handle(OpenGl_Context)&       theCtx,
                               theAspect->Color().rgb[1],
                               theAspect->Color().rgb[2],
                               theAspect->Color().rgb[3]);
-
-  theProgram->SetUniform (theCtx,
-                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT),
-                          THE_COLOR_BLACK_VEC4);
-  theProgram->SetUniform (theCtx,
-                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE),
-                          aDiffuse);
-  theProgram->SetUniform (theCtx,
-                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR),
-                          THE_COLOR_BLACK_VEC4);
-  theProgram->SetUniform (theCtx,
-                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION),
-                          THE_COLOR_BLACK_VEC4);
-  theProgram->SetUniform (theCtx,
-                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY),
-                          0.0f);
+  OpenGl_Vec4 aParams[5];
+  aParams[0] = THE_COLOR_BLACK_VEC4;
+  aParams[1] = THE_COLOR_BLACK_VEC4;
+  aParams[2] = aDiffuse;
+  aParams[3] = THE_COLOR_BLACK_VEC4;
+  aParams[4].x() = 0.0f; // shininess
+  aParams[4].y() = 0.0f; // transparency
+  theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
+                          5, aParams);
 }
 
 }; // nameless namespace
@@ -756,4 +780,4 @@ void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& thePro
   PushModelWorldState  (theProgram);
   PushProjectionState  (theProgram);  
   PushLightSourceState (theProgram);
-}
\ No newline at end of file
+}