[vtkusers] vtkUniformVariables memory leak
eternallite2
cdavid.tran at gmail.com
Mon Aug 18 15:07:01 EDT 2014
Hello, here is a basic example demonstrating the process' memory usage
increasing every second when the uniform variable, "timer" is incremented by
0.01 every frame and sent to the actor's propProgram (vtkShaderProgram2)
Interestingly, if I set timer to a static value like 0.5 the memory used
shown in the Task Manager doesn't change. It is only when I increment the
timer variable (a float) by 0.01 every frame that the memory use increases.
I've attached the .cxx and .frag (shader file) with a Visual Studio 2013
solution file in this post (along with the compiled binary)
BasicVTK.zip <http://vtk.1045678.n5.nabble.com/file/n5728259/BasicVTK.zip>
But here is the code as well for convenience:
//++++++++++++++++++++ shader.frag +++++++++++++++++++++++++++++++++
//++++++++++++++++++++ main.cpp +++++++++++++++++++++++++++++++++
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkInteractionStyle)
VTK_MODULE_INIT(vtkRenderingOpenGL)
#include <vtkActor.h>
#include <vtkPolyDataMapper.h>
#include <vtkSphereSource.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkCommand.h>
#include <vtkSmartPointer.h>
#include <vtkOpenGLProperty.h>
#include <vtkShader2Collection.h>
#include <vtkShaderProgram2.h>
#include <vtkShader2.h>
#include <vtkUniformVariables.h>
#include <iostream>
#include <sstream>
// Set up a vector of vtkActors to render
std::vector<vtkSmartPointer<vtkActor>> actors;
// vtkRenderWindow
vtkSmartPointer<vtkRenderWindow> renWin;
// ***************** Timer callback *************************************
class vtkTimerCallback : public vtkCommand
{
public:
static vtkTimerCallback *New()
{
vtkTimerCallback *cb = new vtkTimerCallback;
return cb;
}
virtual void Execute(vtkObject *vtkNotUsed(caller), unsigned long eventId,
void *vtkNotUsed(callData))
{
// Update timer uniform variable (this line causes memory used by process
in Task Manager to increase every second)
timer += 0.01;
// timer = 0.5; // Interestingly if you don't increment the variable,
memory used by the process doesn't increase
// Update the timer uniform variable for every vtkActor in the scene
for (int i = 0; i < actors.size(); i++)
{
vtkOpenGLProperty::SafeDownCast(actors[i]->GetProperty())->GetPropProgram()->GetUniformVariables()->SetUniformf
("timer", 1, &timer);
}
renWin->Render();
}
private:
float timer;
};
// ************ Return a sphere with a vtkShaderProgram2 attached
********************
vtkSmartPointer<vtkActor> createSphere()
{
vtkSmartPointer<vtkSphereSource> sphere =
vtkSmartPointer<vtkSphereSource>::New();
sphere->SetRadius(1);
sphere->SetThetaResolution(3); // Use low resolution (since we'll be making
50)
sphere->SetPhiResolution(3);
sphere->Update();
vtkSmartPointer<vtkPolyDataMapper> sphereMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
sphereMapper->SetInputData(sphere->GetOutput());
vtkSmartPointer<vtkActor> sphereActor = vtkSmartPointer<vtkActor>::New();
sphereActor->SetMapper(sphereMapper);
// ------- Add Shader to Actor ---------
std::ifstream file("shader.frag");
std::stringstream buffer;
buffer << file.rdbuf();
vtkSmartPointer<vtkShader2> shader = vtkSmartPointer<vtkShader2>::New();
shader->SetSourceCode(buffer.str().c_str());
shader->SetType(VTK_SHADER_TYPE_FRAGMENT);
vtkSmartPointer<vtkShaderProgram2> shaderProgram =
vtkSmartPointer<vtkShaderProgram2>::New();
shaderProgram->GetShaders()->AddItem(shader);
vtkOpenGLProperty::SafeDownCast(sphereActor->GetProperty())->SetPropProgram(shaderProgram);
sphereActor->GetProperty()->ShadingOn();
// --------------------------------------
return sphereActor;
}
// ********** Main Function ************************************
void main()
{
renWin = vtkSmartPointer<vtkRenderWindow>::New();
vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindowInteractor> iren =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renWin);
iren->Initialize();
renWin->SetSize(640, 480);
renWin->SetWindowName("Setting Uniforms in Shaders");
renWin->AddRenderer(ren);
// Add 50 sphere actors (each with a shader program attached)
for (int i = 0; i < 50; i++)
{
vtkSmartPointer<vtkActor> actor = createSphere();
actor->SetPosition(i, 0, 0);
actors.push_back(actor);
ren->AddActor(actor);
}
// Set up timer callback for updating uniform
vtkSmartPointer<vtkTimerCallback> cb =
vtkSmartPointer<vtkTimerCallback>::New();
iren->AddObserver(vtkCommand::TimerEvent, cb);
iren->CreateRepeatingTimer(1000.0 / 60.0); // Executes 60 times per second
renWin->Render();
iren->Start();
}
--
View this message in context: http://vtk.1045678.n5.nabble.com/vtkUniformVariables-memory-leak-tp5728234p5728259.html
Sent from the VTK - Users mailing list archive at Nabble.com.
More information about the vtkusers
mailing list