0024452: TKOpenGl - Memory leak in OpenGl_ShaderManager
[occt.git] / src / OpenGl / OpenGl_ShaderManager.cxx
index 4092769..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)
@@ -260,8 +261,8 @@ public:
   OpenGl_Vec4 Parameters;
 
   //! Returns packed (serialized) representation of light source properties
-  const OpenGl_Vec4* Packed()  { return reinterpret_cast<OpenGl_Vec4*> (this); }
-  static Standard_Size NbOfVec4() { return 4; }
+  const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
+  static Standard_Integer NbOfVec4() { return 4; }
 
 };
 
@@ -274,8 +275,8 @@ public:
   Standard_Integer IsHeadlight;
 
   //! Returns packed (serialized) representation of light source type
-  const OpenGl_Vec2i* Packed() { return reinterpret_cast<OpenGl_Vec2i*> (this); }
-  static Standard_Size NbOfVec2i() { return 1; }
+  const OpenGl_Vec2i* Packed() const { return reinterpret_cast<const OpenGl_Vec2i*> (this); }
+  static Standard_Integer NbOfVec2i() { return 1; }
 
 };
 
@@ -291,6 +292,12 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
     return;
   }
 
+  OpenGl_ShaderLightType* aLightTypeArray = new OpenGl_ShaderLightType[OpenGLMaxLights];
+  for (Standard_Integer aLightIt = 0; aLightIt < OpenGLMaxLights; ++aLightIt)
+  {
+    aLightTypeArray[aLightIt].Type = -1;
+  }
+
   const Standard_Integer aLightsDefNb = Min (myLightSourceState.LightSources()->Size(), OpenGLMaxLights);
   if (aLightsDefNb < 1)
   {
@@ -300,12 +307,16 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
     theProgram->SetUniform (myContext,
                             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_TYPES),
+                            OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
+                            aLightTypeArray[0].Packed());
     theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
+    delete[] aLightTypeArray;
     return;
   }
 
   OpenGl_ShaderLightParameters* aLightParamsArray = new OpenGl_ShaderLightParameters[aLightsDefNb];
-  OpenGl_ShaderLightType*       aLightTypeArray   = new OpenGl_ShaderLightType[aLightsDefNb];
 
   OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f);
   Standard_Integer aLightsNb = 0;
@@ -345,12 +356,12 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
   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_TYPES),
-                            aLightsNb * OpenGl_ShaderLightType::NbOfVec2i(),
-                            aLightTypeArray[0].Packed());
     theProgram->SetUniform (myContext,
                             theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_PARAMS),
                             aLightsNb * OpenGl_ShaderLightParameters::NbOfVec4(),
@@ -503,7 +514,7 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)
   }
 
   GLuint aPlanesNb = 0;
-  for (Graphic3d_SetOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
+  for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
        anIter.More(); anIter.Next())
   {
     const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
@@ -522,7 +533,7 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)
   OpenGl_Vec4* anEquations = new OpenGl_Vec4[aPlanesNb];
   GLint*       aSpaces     = new GLint      [aPlanesNb];
   GLuint aPlaneId = 0;
-  for (Graphic3d_SetOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
+  for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
        anIter.More(); anIter.Next())
   {
     const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
@@ -612,7 +623,7 @@ static void PushAspectFace (const Handle(OpenGl_Context)&       theCtx,
                           theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
                           theAspect->DistinguishingMode());
 
-  OpenGl_Vec4 aParams[5];
+  OpenGl_Material aParams;
   for (Standard_Integer anIndex = 0; anIndex < 2; ++anIndex)
   {
     const GLint aLoc = theProgram->GetStateLocation (anIndex == 0
@@ -623,30 +634,9 @@ static void PushAspectFace (const Handle(OpenGl_Context)&       theCtx,
       continue;
     }
 
-    const OPENGL_SURF_PROP& aProps = (anIndex == 0) ? theAspect->IntFront() : theAspect->IntBack();
-    const OpenGl_Vec4 anEmission (aProps.emscol.rgb[0] * aProps.emsv,
-                                  aProps.emscol.rgb[1] * aProps.emsv,
-                                  aProps.emscol.rgb[2] * aProps.emsv,
-                                  aProps.emscol.rgb[3] * aProps.emsv);
-    const OpenGl_Vec4 anAmbient  (aProps.ambcol.rgb[0] * aProps.amb,
-                                  aProps.ambcol.rgb[1] * aProps.amb,
-                                  aProps.ambcol.rgb[2] * aProps.amb,
-                                  aProps.ambcol.rgb[3] * aProps.amb);
-    const OpenGl_Vec4 aDiffuse   (aProps.difcol.rgb[0] * aProps.diff,
-                                  aProps.difcol.rgb[1] * aProps.diff,
-                                  aProps.difcol.rgb[2] * aProps.diff,
-                                  aProps.difcol.rgb[3] * aProps.diff);
-    const OpenGl_Vec4 aSpecular  (aProps.speccol.rgb[0] * aProps.spec,
-                                  aProps.speccol.rgb[1] * aProps.spec,
-                                  aProps.speccol.rgb[2] * aProps.spec,
-                                  aProps.speccol.rgb[3] * aProps.spec);
-    aParams[0] = anEmission;
-    aParams[1] = anAmbient;
-    aParams[2] = aDiffuse;
-    aParams[3] = aSpecular;
-    aParams[4].x() = aProps.shine;
-    aParams[4].y() = aProps.trans;
-    theProgram->SetUniform (theCtx, aLoc, 5, aParams);
+    aParams.Init (anIndex == 0 ? theAspect->IntFront() : theAspect->IntBack());
+    theProgram->SetUniform (theCtx, aLoc, OpenGl_Material::NbOfVec4(),
+                            aParams.Packed());
   }
 }