17 #define SR_INFO MITK_INFO("shader.repository")
18 #define SR_WARN MITK_WARN("shader.repository")
19 #define SR_ERROR MITK_ERROR("shader.repository")
29 #include <vtkOpenGLRenderWindow.h>
30 #include <vtkProperty.h>
31 #include <vtkShader2.h>
32 #include <vtkShader2Collection.h>
33 #include <vtkShaderProgram2.h>
34 #include <vtkSmartPointer.h>
35 #include <vtkUniformVariables.h>
36 #include <vtkVersionMacros.h>
37 #include <vtkXMLDataElement.h>
42 #include <itkDirectory.h>
43 #include <itksys/SystemTools.hxx>
45 int mitk::VtkShaderRepository::shaderId = 0;
46 const bool mitk::VtkShaderRepository::debug =
false;
67 std::string dirPath =
"./vtk_shader";
69 if (dir->Load(dirPath.c_str()))
71 int n = dir->GetNumberOfFiles();
72 for (
int r = 0; r < n; r++)
74 const char *
filename = dir->GetFile(r);
76 std::string extension = itksys::SystemTools::GetFilenameExtension(filename);
78 if (extension.compare(
".xml") == 0)
82 element->SetName(itksys::SystemTools::GetFilenameWithoutExtension(filename));
83 std::string filePath = dirPath + std::string(
"/") + element->GetName() + std::string(
".xml");
85 SR_INFO(debug) <<
"found shader '" << element->GetName() <<
"'";
87 std::ifstream fileStream(filePath.c_str());
88 element->LoadXmlShader(fileStream);
90 shaders.push_back(element);
98 std::list<Shader::Pointer>::const_iterator i = shaders.begin();
100 while (i != shaders.end())
102 if ((*i)->GetName() == name)
114 element->SetName(filename);
115 element->SetId(shaderId++);
116 element->LoadXmlShader(stream);
117 shaders.push_back(element);
118 SR_INFO(debug) <<
"found shader '" << element->GetName() <<
"'";
119 return element->GetId();
124 for (std::list<Shader::Pointer>::iterator i = shaders.begin(); i != shaders.end(); ++i)
126 if ((*i)->GetId() == id)
145 this->m_VertexShaderCode = code;
150 return this->m_VertexShaderCode;
155 this->m_FragmentShaderCode = code;
160 return this->m_FragmentShaderCode;
165 this->m_GeometryShaderCode = code;
170 return this->m_GeometryShaderCode;
178 void mitk::VtkShaderRepository::Shader::LoadXmlShader(std::istream &stream)
181 content.reserve(2048);
183 while (stream.read(buffer,
sizeof(buffer)))
185 content.append(buffer,
sizeof(buffer));
187 content.append(buffer, static_cast<std::size_t>(stream.gcount()));
192 this->SetMaterialXml(content);
197 parser->
Parse(content.c_str());
199 if (material == NULL)
207 SetVertexShaderCode(s->
GetCode());
208 vtkXMLDataElement *x = s->GetRootElement();
209 int n = x->GetNumberOfNestedElements();
210 for (
int r = 0; r < n; r++)
212 vtkXMLDataElement *y = x->GetNestedElement(r);
213 if (strcmp(y->GetName(),
"ApplicationUniform") == 0 || strcmp(y->GetName(),
"Uniform") == 0)
216 element->LoadFromXML(y);
217 uniforms.push_back(element);
228 SetFragmentShaderCode(s->
GetCode());
229 vtkXMLDataElement *x = s->GetRootElement();
230 int n = x->GetNumberOfNestedElements();
231 for (
int r = 0; r < n; r++)
233 vtkXMLDataElement *y = x->GetNestedElement(r);
234 if (strcmp(y->GetName(),
"ApplicationUniform") == 0 || strcmp(y->GetName(),
"Uniform") == 0)
237 element->LoadFromXML(y);
238 uniforms.push_back(element);
249 SetGeometryShaderCode(s->
GetCode());
250 vtkXMLDataElement *x = s->GetRootElement();
251 int n = x->GetNumberOfNestedElements();
252 for (
int r = 0; r < n; r++)
254 vtkXMLDataElement *y = x->GetNestedElement(r);
255 if (strcmp(y->GetName(),
"ApplicationUniform") == 0 || strcmp(y->GetName(),
"Uniform") == 0)
258 element->LoadFromXML(y);
259 uniforms.push_back(element);
280 name = y->GetAttribute(
"name");
282 const char *sType = y->GetAttribute(
"type");
284 if (!strcmp(sType,
"float"))
286 else if (!strcmp(sType,
"vec2"))
288 else if (!strcmp(sType,
"vec3"))
290 else if (!strcmp(sType,
"vec4"))
292 else if (!strcmp(sType,
"int"))
294 else if (!strcmp(sType,
"ivec2"))
296 else if (!strcmp(sType,
"ivec3"))
298 else if (!strcmp(sType,
"ivec4"))
303 SR_WARN <<
"unknown type for uniform '" << name <<
"'";
306 defaultFloat[0] = defaultFloat[1] = defaultFloat[2] = defaultFloat[3] = 0;
308 const char *sDefault = y->GetAttribute(
"value");
315 sscanf(sDefault,
"%f", &defaultFloat[0]);
319 sscanf(sDefault,
"%f %f", &defaultFloat[0], &defaultFloat[1]);
323 sscanf(sDefault,
"%f %f %f", &defaultFloat[0], &defaultFloat[1], &defaultFloat[2]);
327 sscanf(sDefault,
"%f %f %f %f", &defaultFloat[0], &defaultFloat[1], &defaultFloat[2], &defaultFloat[3]);
331 sscanf(sDefault,
"%d", &defaultInt[0]);
335 sscanf(sDefault,
"%d %d", &defaultInt[0], &defaultInt[1]);
339 sscanf(sDefault,
"%d %d %d", &defaultInt[0], &defaultInt[1], &defaultInt[2]);
343 sscanf(sDefault,
"%d %d %d %d", &defaultInt[0], &defaultInt[1], &defaultInt[2], &defaultInt[3]);
354 bool overwrite)
const
358 std::list<Shader::Pointer>::const_iterator i = shaders.begin();
360 while (i != shaders.end())
362 std::list<Shader::Uniform::Pointer> uniforms = (*i)->GetUniforms();
364 std::string shaderName = (*i)->GetName();
366 std::list<Shader::Uniform::Pointer>::const_iterator j = uniforms.begin();
368 while (j != uniforms.end())
370 std::string propertyName =
"shader." + shaderName +
"." + (*j)->name;
374 case Shader::Uniform::glsl_float:
378 case Shader::Uniform::glsl_vec2:
385 case Shader::Uniform::glsl_vec3:
394 case Shader::Uniform::glsl_vec4:
405 case Shader::Uniform::glsl_int:
409 case Shader::Uniform::glsl_ivec2:
416 case Shader::Uniform::glsl_ivec3:
425 case Shader::Uniform::glsl_ivec4:
436 case Shader::Uniform::glsl_none:
449 std::list<mitk::IShaderRepository::Shader::Pointer> result;
450 for (std::list<Shader::Pointer>::const_iterator i = shaders.begin(); i != shaders.end(); ++i)
452 result.push_back(i->GetPointer());
459 for (std::list<Shader::Pointer>::const_iterator i = shaders.begin(); i != shaders.end(); ++i)
461 if ((*i)->GetName() == name)
462 return i->GetPointer();
469 for (std::list<Shader::Pointer>::const_iterator i = shaders.begin(); i != shaders.end(); ++i)
471 if ((*i)->GetId() == id)
472 return i->GetPointer();
502 #if ((VTK_MAJOR_VERSION < 6) || ((VTK_MAJOR_VERSION == 6) && (VTK_MINOR_VERSION == 0)))
503 program->SetContext(dynamic_cast<vtkOpenGLRenderWindow *>(renderer->
GetRenderWindow()));
509 shader->SetType(VTK_SHADER_TYPE_VERTEX);
510 shader->SetSourceCode(s->GetVertexShaderCode().c_str());
511 #if ((VTK_MAJOR_VERSION < 6) || ((VTK_MAJOR_VERSION == 6) && (VTK_MINOR_VERSION == 0)))
512 shader->SetContext(dynamic_cast<vtkOpenGLRenderWindow *>(renderer->
GetRenderWindow()));
516 program->GetShaders()->AddItem(shader);
521 shader->SetType(VTK_SHADER_TYPE_FRAGMENT);
522 shader->SetSourceCode(s->GetFragmentShaderCode().c_str());
523 #if ((VTK_MAJOR_VERSION < 6) || ((VTK_MAJOR_VERSION == 6) && (VTK_MINOR_VERSION == 0)))
524 shader->SetContext(dynamic_cast<vtkOpenGLRenderWindow *>(renderer->
GetRenderWindow()));
528 program->GetShaders()->AddItem(shader);
531 if (s->GetGeometryShaderCode().size() > 0)
535 shader->SetType(VTK_SHADER_TYPE_GEOMETRY);
536 shader->SetSourceCode(s->GetGeometryShaderCode().c_str());
537 #if ((VTK_MAJOR_VERSION < 6) || ((VTK_MAJOR_VERSION == 6) && (VTK_MINOR_VERSION == 0)))
538 shader->SetContext(dynamic_cast<vtkOpenGLRenderWindow *>(renderer->
GetRenderWindow()));
542 program->GetShaders()->AddItem(shader);
562 std::list<Shader::Uniform::Pointer>::const_iterator j = s->uniforms.begin();
564 while (j != s->uniforms.end())
566 std::string propertyName =
"shader." + s->GetName() +
"." + (*j)->name;
581 case Shader::Uniform::glsl_float:
583 p->GetUniformVariables()->SetUniformf((*j)->name.c_str(), 1, fval);
586 case Shader::Uniform::glsl_vec2:
589 p->GetUniformVariables()->SetUniformf((*j)->name.c_str(), 2, fval);
592 case Shader::Uniform::glsl_vec3:
597 p->GetUniformVariables()->SetUniformf((*j)->name.c_str(), 3, fval);
600 case Shader::Uniform::glsl_vec4:
605 p->GetUniformVariables()->SetUniformf((*j)->name.c_str(), 4, fval);
608 case Shader::Uniform::glsl_int:
610 p->GetUniformVariables()->SetUniformi((*j)->name.c_str(), 1, ival);
613 case Shader::Uniform::glsl_ivec2:
614 node->
GetIntProperty((propertyName +
".x").c_str(), ival[0], renderer);
615 node->
GetIntProperty((propertyName +
".y").c_str(), ival[1], renderer);
616 p->GetUniformVariables()->SetUniformi((*j)->name.c_str(), 2, ival);
619 case Shader::Uniform::glsl_ivec3:
620 node->
GetIntProperty((propertyName +
".x").c_str(), ival[0], renderer);
621 node->
GetIntProperty((propertyName +
".y").c_str(), ival[1], renderer);
622 node->
GetIntProperty((propertyName +
".z").c_str(), ival[2], renderer);
624 p->GetUniformVariables()->SetUniformi((*j)->name.c_str(), 3, ival);
627 case Shader::Uniform::glsl_ivec4:
628 node->
GetIntProperty((propertyName +
".x").c_str(), ival[0], renderer);
629 node->
GetIntProperty((propertyName +
".y").c_str(), ival[1], renderer);
630 node->
GetIntProperty((propertyName +
".z").c_str(), ival[2], renderer);
631 node->
GetIntProperty((propertyName +
".w").c_str(), ival[3], renderer);
632 p->GetUniformVariables()->SetUniformi((*j)->name.c_str(), 4, ival);
635 case Shader::Uniform::glsl_none:
void AddDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer, bool overwrite) const override
Adds all parsed shader uniforms to property list of the given DataNode; used by mappers.
virtual std::string GetValueAsString() const override
itk::SmartPointer< Self > Pointer
IShaderRepository::Shader::Pointer GetShader(const std::string &name) const override
Return the named shader.
bool GetIntProperty(const char *propertyKey, int &intValue, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for int properties (instances of IntProperty)
void SetVertexShaderCode(const std::string &code)
Organizes the rendering process.
vtkXMLShader * GetVertexShader(int id=0)
void SetMaterial(vtkXMLMaterial *)
void UpdateShaderProgram(mitk::IShaderRepository::ShaderProgram *shaderProgram, DataNode *node, BaseRenderer *renderer) const override
Applies shader and shader specific variables of the specified DataNode to the VTK object by updating ...
mitk::BaseProperty * GetProperty(const char *propertyKey, const mitk::BaseRenderer *renderer=nullptr) const
Get the property (instance of BaseProperty) with key propertyKey from the PropertyList of the rendere...
std::string GetFragmentShaderCode() const
ShaderProgram::Pointer CreateShaderProgram() override
static vtkXMLMaterial * New()
vtkXMLShader * GetGeometryShader(int id=0)
Shader::Pointer GetShaderImpl(const std::string &name) const
void AddProperty(const char *propertyKey, BaseProperty *property, const mitk::BaseRenderer *renderer=nullptr, bool overwrite=false)
Add the property (instance of BaseProperty) if it does not exist (or always ifoverwrite istrue) with ...
static const std::string filename
void SetGeometryShaderCode(const std::string &code)
bool GetFloatProperty(const char *propertyKey, float &floatValue, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for float properties (instances of FloatProperty)
std::list< Uniform::Pointer > GetUniforms() const
virtual int Parse() override
std::list< IShaderRepository::Shader::Pointer > GetShaders() const override
int LoadShader(std::istream &stream, const std::string &name) override
Applies shader and shader specific variables of the specified DataNode to the VTK object by updating ...
vtkXMLShader * GetFragmentShader(int id=0)
itk::SmartPointer< Self > Pointer
bool UnloadShader(int id) override
Unload a previously loaded shader.
static vtkXMLMaterialParser * New()
itk::TimeStamp & GetShaderTimestampUpdate()
std::string GetVertexShaderCode() const
void SetVtkShaderProgram(vtkSmartPointer< vtkShaderProgram2 > p)
vtkRenderWindow * GetRenderWindow() const
Access the RenderWindow into which this renderer renders.
vtkSmartPointer< vtkShaderProgram2 > GetVtkShaderProgram() const
Class for nodes of the DataTree.
void SetFragmentShaderCode(const std::string &code)
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.
std::string GetGeometryShaderCode() const