diff --git a/Core/Code/Interfaces/mitkIShaderRepository.h b/Core/Code/Interfaces/mitkIShaderRepository.h index 96dbafada9..3ccee656cd 100644 --- a/Core/Code/Interfaces/mitkIShaderRepository.h +++ b/Core/Code/Interfaces/mitkIShaderRepository.h @@ -1,142 +1,144 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKISHADERREPOSITORY_H #define MITKISHADERREPOSITORY_H #include #include "mitkCommon.h" #include "usServiceInterface.h" #include class vtkActor; +class vtkShaderProgram2; namespace mitk { class DataNode; class BaseRenderer; -class vtkShaderProgram2; /** * \brief Management class for vtkShader XML descriptions. * * Loads XML shader files from std::istream objects and adds default properties * for each shader object (shader uniforms) to the specified mitk::DataNode. * * Additionally, it provides a utility function for applying properties for shaders * in mappers. */ struct MITK_CORE_EXPORT IShaderRepository { struct ShaderPrivate; - class MITK_CORE_EXPORT Shader : public itk::LightObject + class MITK_CORE_EXPORT Shader : public itk::Object { public: mitkClassMacro( Shader, itk::Object ) itkFactorylessNewMacro( Self ) ~Shader(); int GetId() const; std::string GetName() const; std::string GetMaterialXml() const; protected: Shader(); void SetId(int id); void SetName(const std::string& name); void SetMaterialXml(const std::string& xml); private: // not implemented Shader(const Shader&); Shader& operator=(const Shader&); ShaderPrivate* d; }; class MITK_CORE_EXPORT ShaderProgram : public itk::LightObject { public: + virtual void Activate() = 0; + virtual void Deactivate() = 0; mitkClassMacro( ShaderProgram, itk::LightObject ) }; virtual ~IShaderRepository(); virtual std::list GetShaders() const = 0; /** * \brief Return the named shader. * * \param name The shader name. * \return A Shader object. * * Names might not be unique. Use the shader id to uniquely identify a shader. */ virtual Shader::Pointer GetShader(const std::string& name) const = 0; virtual ShaderProgram::Pointer CreateShaderProgram() = 0; /** * \brief Return the shader identified by the given id. * @param id The shader id. * @return The shader object or null if the id is unknown. */ virtual Shader::Pointer GetShader(int id) const = 0; /** \brief Adds all parsed shader uniforms to property list of the given DataNode; * used by mappers. */ virtual void AddDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) const = 0; /** \brief Applies shader and shader specific variables of the specified DataNode * to the VTK object by updating the shader variables of its vtkProperty. */ - virtual ShaderProgram::Pointer UpdateShaderProgram(mitk::IShaderRepository::ShaderProgram::Pointer shaderProgram, mitk::DataNode* node, - mitk::BaseRenderer* renderer, const itk::TimeStamp& MTime) const = 0; + virtual void UpdateShaderProgram(mitk::IShaderRepository::ShaderProgram* shaderProgram, mitk::DataNode* node, + mitk::BaseRenderer* renderer) const = 0; /** \brief Loads a shader from a given file. Make sure that this stream is in the XML shader format. * * \return A unique id for the loaded shader which can be used to unload it. */ virtual int LoadShader(std::istream& stream, const std::string& name) = 0; /** * \brief Unload a previously loaded shader. * \param id The unique shader id returned by LoadShader. * \return \c true if the shader id was found and the shader was successfully unloaded, * \c false otherwise. */ virtual bool UnloadShader(int id) = 0; }; } US_DECLARE_SERVICE_INTERFACE(mitk::IShaderRepository, "org.mitk.services.IShaderRepository/1.0") #endif // MITKISHADERREPOSITORY_H diff --git a/Core/Code/Rendering/mitkVtkMapper.cpp b/Core/Code/Rendering/mitkVtkMapper.cpp index ce1b81b292..d254730a0a 100644 --- a/Core/Code/Rendering/mitkVtkMapper.cpp +++ b/Core/Code/Rendering/mitkVtkMapper.cpp @@ -1,145 +1,142 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkVtkMapper.h" mitk::VtkMapper::VtkMapper() { } mitk::VtkMapper::~VtkMapper() { } void mitk::VtkMapper::MitkRender(mitk::BaseRenderer* renderer, mitk::VtkPropRenderer::RenderType type){ - - switch(type) - { - case mitk::VtkPropRenderer::Opaque: this->MitkRenderOpaqueGeometry(renderer); break; - case mitk::VtkPropRenderer::Translucent: this->MitkRenderTranslucentGeometry(renderer); break; - case mitk::VtkPropRenderer::Overlay: this->MitkRenderOverlay(renderer); break; - case mitk::VtkPropRenderer::Volumetric: this->MitkRenderVolumetricGeometry(renderer); break; - } + VtkMapperLocalStorage* ls = m_VtkMapperLSH.GetLocalStorage(renderer); + ls->m_ShaderProgram->Activate(); + switch(type) + { + case mitk::VtkPropRenderer::Opaque: this->MitkRenderOpaqueGeometry(renderer); break; + case mitk::VtkPropRenderer::Translucent: this->MitkRenderTranslucentGeometry(renderer); break; + case mitk::VtkPropRenderer::Overlay: this->MitkRenderOverlay(renderer); break; + case mitk::VtkPropRenderer::Volumetric: this->MitkRenderVolumetricGeometry(renderer); break; + } + ls->m_ShaderProgram->Deactivate(); } bool mitk::VtkMapper::IsVtkBased() const { return true; } void mitk::VtkMapper::MitkRenderOverlay(BaseRenderer* renderer) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if ( !visible) return; if ( this->GetVtkProp(renderer)->GetVisibility() ) { -// repository->act //SHADERTODO GetVtkProp(renderer)->RenderOverlay(renderer->GetVtkRenderer()); } } void mitk::VtkMapper::MitkRenderOpaqueGeometry(BaseRenderer* renderer) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if ( !visible) return; if ( this->GetVtkProp(renderer)->GetVisibility() ) { - //activate shader (set uniforms + call use) SHADERTODO GetVtkProp(renderer)->RenderOpaqueGeometry( renderer->GetVtkRenderer() ); - //deactivate shader } } void mitk::VtkMapper::MitkRenderTranslucentGeometry(BaseRenderer* renderer) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if ( !visible) return; if ( this->GetVtkProp(renderer)->GetVisibility() ) { GetVtkProp(renderer)->RenderTranslucentPolygonalGeometry(renderer->GetVtkRenderer()); } } void mitk::VtkMapper::ApplyShaderProperties(mitk::BaseRenderer* renderer) { - VtkMapperLocalStorage *ls = m_LSH.GetLocalStorage(renderer); + VtkMapperLocalStorage *ls = m_VtkMapperLSH.GetLocalStorage(renderer); CoreServicePointer shaderRepo(CoreServices::GetShaderRepository()); -// shaderRepo->( ) + shaderRepo->UpdateShaderProgram(ls->m_ShaderProgram,this->GetDataNode(),renderer); - shaderRepo->UpdateShaderProgram(ls->m_ShaderProgram,this->GetDataNode(),renderer, GetTimeStamp()); //SHADERTODO - // } void mitk::VtkMapper::MitkRenderVolumetricGeometry(BaseRenderer* renderer) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if ( !visible) return; if ( GetVtkProp(renderer)->GetVisibility() ) { GetVtkProp(renderer)->RenderVolumetricGeometry(renderer->GetVtkRenderer()); } } bool mitk::VtkMapper::HasVtkProp( const vtkProp *prop, BaseRenderer *renderer ) { vtkProp *myProp = this->GetVtkProp( renderer ); // TODO: check if myProp is a vtkAssembly and if so, check if prop is contained in its leafs return ( prop == myProp ); } void mitk::VtkMapper::SetVtkMapperImmediateModeRendering(vtkMapper *mapper) { if(mapper) mapper->SetImmediateModeRendering(mitk::VtkPropRenderer::useImmediateModeRendering()); } void mitk::VtkMapper::UpdateVtkTransform(mitk::BaseRenderer *renderer) { vtkLinearTransform * vtktransform = GetDataNode()->GetVtkTransform(this->GetTimestep()); vtkProp3D *prop = dynamic_cast( GetVtkProp(renderer) ); if(prop) prop->SetUserTransform(vtktransform); } void mitk::VtkMapper::ApplyColorAndOpacityProperties(BaseRenderer* renderer, vtkActor* actor) { float rgba[4]={1.0f,1.0f,1.0f,1.0f}; DataNode * node = GetDataNode(); // check for color prop and use it for rendering if it exists node->GetColor(rgba, renderer, "color"); // check for opacity prop and use it for rendering if it exists node->GetOpacity(rgba[3], renderer, "opacity"); double drgba[4]={rgba[0],rgba[1],rgba[2],rgba[3]}; actor->GetProperty()->SetColor(drgba); actor->GetProperty()->SetOpacity(drgba[3]); } diff --git a/Core/Code/Rendering/mitkVtkMapper.h b/Core/Code/Rendering/mitkVtkMapper.h index 29d8786d42..0eb46d9c8a 100644 --- a/Core/Code/Rendering/mitkVtkMapper.h +++ b/Core/Code/Rendering/mitkVtkMapper.h @@ -1,177 +1,178 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // change number #ifndef VTKMAPPER_H_HEADER_INCLUDED_C1C5453B #define VTKMAPPER_H_HEADER_INCLUDED_C1C5453B #include #include "mitkMapper.h" #include "mitkBaseRenderer.h" #include "mitkDataNode.h" #include "mitkVtkPropRenderer.h" #include "mitkLocalStorageHandler.h" #include "mitkIShaderRepository.h" #include #include #include #include #include #include #include #include #include class vtkProp; class vtkProp3D; class vtkActor; namespace mitk { /** \brief Base class of all Vtk Mappers in order to display primitives * by exploiting Vtk functionality. * * Rendering of opaque, translucent or volumetric geometry and overlays * is done in consecutive render passes. * * \ingroup Mapper */ class MITK_CORE_EXPORT VtkMapper : public Mapper { public: mitkClassMacro(VtkMapper,Mapper); virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer) = 0; /** \brief Re-issues all drawing commands required to describe * the entire scene each time a new frame is required, * regardless of actual changes. */ static void SetVtkMapperImmediateModeRendering(vtkMapper *mapper); /** * \brief Returns whether this is an vtk-based mapper * \deprecatedSince{2013_03} All mappers of superclass VTKMapper are vtk based, use a dynamic_cast instead */ DEPRECATED( virtual bool IsVtkBased() const ); /** \brief Determines which geometry should be rendered * (opaque, translucent, volumetric, overlay) * and calls the appropriate function. * * Called by mitk::VtkPropRenderer::Render */ void MitkRender(mitk::BaseRenderer* renderer, mitk::VtkPropRenderer::RenderType type); /** \brief Checks visibility and renders the overlay */ virtual void MitkRenderOverlay(BaseRenderer* renderer); /** \brief Checks visibility and renders untransparent geometry */ virtual void MitkRenderOpaqueGeometry(BaseRenderer* renderer); /** \brief Checks visiblity and renders transparent geometry */ virtual void MitkRenderTranslucentGeometry(BaseRenderer* renderer); /** \brief Checks visibility and renders volumes */ virtual void MitkRenderVolumetricGeometry(BaseRenderer* renderer); /** \brief Returns true if this mapper owns the specified vtkProp for * the given BaseRenderer. * * Note: returns false by default; should be implemented for VTK-based * Mapper subclasses. */ virtual bool HasVtkProp( const vtkProp *prop, BaseRenderer *renderer ); /** \brief Set the vtkTransform of the m_Prop3D for * the current time step of \a renderer * * Called by mitk::VtkPropRenderer::Update before rendering */ virtual void UpdateVtkTransform(mitk::BaseRenderer *renderer); /** * \brief Apply color and opacity properties read from the PropertyList * \deprecatedSince{2013_03} Use ApplyColorAndOpacityProperties(mitk::BaseRenderer* renderer, vtkActor * actor) instead */ DEPRECATED(inline virtual void ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer)) { ApplyColorAndOpacityProperties(renderer, actor); } /** * \brief SHADERTODO */ void ApplyShaderProperties( mitk::BaseRenderer* renderer); /** * \brief Apply color and opacity properties read from the PropertyList. * Called by mapper subclasses. */ virtual void ApplyColorAndOpacityProperties(mitk::BaseRenderer* renderer, vtkActor * actor); /** * \brief Release vtk-based graphics resources that are being consumed by this mapper. * * Method called by mitk::VtkPropRenderer. The parameter renderer could be used to * determine which graphic resources to release. The local storage is accessible * by the parameter renderer. Should be overwritten in subclasses. */ virtual void ReleaseGraphicsResources(mitk::BaseRenderer* /*renderer*/) { }; class VtkMapperLocalStorage : public mitk::Mapper::BaseLocalStorage { public: mitk::IShaderRepository::ShaderProgram::Pointer m_ShaderProgram; + itk::TimeStamp m_ModifiedTimeStamp; VtkMapperLocalStorage() { CoreServicePointer shaderRepo(CoreServices::GetShaderRepository()); m_ShaderProgram = shaderRepo->CreateShaderProgram(); } ~VtkMapperLocalStorage() { } }; - mitk::LocalStorageHandler m_LSH; + mitk::LocalStorageHandler m_VtkMapperLSH; protected: /** constructor */ VtkMapper(); /** virtual destructor in order to derive from this class */ virtual ~VtkMapper(); private: /** copy constructor */ VtkMapper( const VtkMapper &); /** assignment operator */ VtkMapper & operator=(const VtkMapper &); }; } // namespace mitk #endif /* VTKMAPPER_H_HEADER_INCLUDED_C1C5453B */ diff --git a/Modules/VtkShaders/mitkVtkShaderProgram.cpp b/Modules/VtkShaders/mitkVtkShaderProgram.cpp index f8b6fc34fd..4304155c85 100644 --- a/Modules/VtkShaders/mitkVtkShaderProgram.cpp +++ b/Modules/VtkShaders/mitkVtkShaderProgram.cpp @@ -1,25 +1,32 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkVtkShaderProgram.h" +#include "vtkShader2.h" mitk::VtkShaderProgram::VtkShaderProgram() { } mitk::VtkShaderProgram::~VtkShaderProgram() { } + +void mitk::VtkShaderProgram::SetVtkShaderProgram(vtkShaderProgram2* p) { m_VtkShaderProgram = p; } + +vtkShaderProgram2*mitk::VtkShaderProgram::GetVtkShaderProgram() const { return m_VtkShaderProgram; } + +itk::TimeStamp&mitk::VtkShaderProgram::GetShaderTimestampUpdate(){return m_ShaderTimestampUpdate;} diff --git a/Modules/VtkShaders/mitkVtkShaderProgram.h b/Modules/VtkShaders/mitkVtkShaderProgram.h index f033c4a040..043d5c33fd 100644 --- a/Modules/VtkShaders/mitkVtkShaderProgram.h +++ b/Modules/VtkShaders/mitkVtkShaderProgram.h @@ -1,53 +1,75 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef _MITKVTKSHADERPROGRAM_H_ #define _MITKVTKSHADERPROGRAM_H_ #include +#include #include +#include namespace mitk { /** * \brief SHADERTODO */ -class VtkShaderProgram : public IShaderRepository::ShaderProgram +class VtkShaders_EXPORT VtkShaderProgram : public IShaderRepository::ShaderProgram { public: mitkClassMacro( VtkShaderProgram, IShaderRepository::ShaderProgram ) itkFactorylessNewMacro( Self ) /** * Constructor */ VtkShaderProgram(); /** * Destructor */ virtual ~VtkShaderProgram(); + virtual void Activate() + { + if(m_VtkShaderProgram) + { + m_VtkShaderProgram->UseProgram(); + + } + } + virtual void Deactivate() + { + if(m_VtkShaderProgram) + { + m_VtkShaderProgram->UnuseProgram(); + } + } + + void SetVtkShaderProgram( vtkShaderProgram2 * p ); + vtkShaderProgram2 * GetVtkShaderProgram() const; + itk::TimeStamp& GetShaderTimestampUpdate(); + private: vtkShaderProgram2* m_VtkShaderProgram; itk::TimeStamp m_ShaderTimestampUpdate; }; } //end of namespace mitk #endif diff --git a/Modules/VtkShaders/mitkVtkShaderRepository.cpp b/Modules/VtkShaders/mitkVtkShaderRepository.cpp index 30e914ef0a..895e83f4d9 100644 --- a/Modules/VtkShaders/mitkVtkShaderRepository.cpp +++ b/Modules/VtkShaders/mitkVtkShaderRepository.cpp @@ -1,480 +1,477 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #define SR_INFO MITK_INFO("shader.repository") #define SR_WARN MITK_WARN("shader.repository") #define SR_ERROR MITK_ERROR("shader.repository") #include "mitkVtkShaderRepository.h" #include "mitkVtkShaderProgram.h" #include "mitkShaderProperty.h" #include "mitkProperties.h" #include "mitkDataNode.h" #include #include #include #include #include #include +#include +#include +#include +#include +#include #include #include int mitk::VtkShaderRepository::shaderId = 0; const bool mitk::VtkShaderRepository::debug = false; mitk::VtkShaderRepository::VtkShaderRepository() { LoadShaders(); } mitk::VtkShaderRepository::~VtkShaderRepository() { } mitk::IShaderRepository::ShaderProgram::Pointer mitk::VtkShaderRepository::CreateShaderProgram() { mitk::IShaderRepository::ShaderProgram::Pointer shaderProg = (mitk::VtkShaderProgram::New()).GetPointer(); return shaderProg; } void mitk::VtkShaderRepository::LoadShaders() { itk::Directory::Pointer dir = itk::Directory::New(); std::string dirPath = "./vtk_shader"; if( dir->Load( dirPath.c_str() ) ) { int n = dir->GetNumberOfFiles(); for(int r=0;rGetFile( r ); std::string extension = itksys::SystemTools::GetFilenameExtension(filename); if(extension.compare(".xml")==0) { Shader::Pointer element=Shader::New(); element->SetName(itksys::SystemTools::GetFilenameWithoutExtension(filename)); std::string filePath = dirPath + std::string("/") + element->GetName() + std::string(".xml"); SR_INFO(debug) << "found shader '" << element->GetName() << "'"; std::ifstream fileStream(filePath.c_str()); - element->LoadProperties(fileStream); + element->LoadXmlShader(fileStream); shaders.push_back(element); } } } } mitk::VtkShaderRepository::Shader::Pointer mitk::VtkShaderRepository::GetShaderImpl(const std::string &name) const { std::list::const_iterator i = shaders.begin(); while( i != shaders.end() ) { if( (*i)->GetName() == name) return (*i); i++; } return Shader::Pointer(); } int mitk::VtkShaderRepository::LoadShader(std::istream& stream, const std::string& filename) { Shader::Pointer element=Shader::New(); element->SetName(filename); element->SetId(shaderId++); - element->LoadProperties(stream); + element->LoadXmlShader(stream); shaders.push_back(element); SR_INFO(debug) << "found shader '" << element->GetName() << "'"; return element->GetId(); } bool mitk::VtkShaderRepository::UnloadShader(int id) { for (std::list::iterator i = shaders.begin(); i != shaders.end(); ++i) { if ((*i)->GetId() == id) { shaders.erase(i); return true; } } return false; } mitk::VtkShaderRepository::Shader::Shader() { } mitk::VtkShaderRepository::Shader::~Shader() { } -/*void mitk::VtkShaderRepository::Shader::LoadProperties(vtkPropertyXMLParser* p) +void mitk::VtkShaderRepository::Shader::LoadXmlShader(std::istream& stream) { - vtkXMLMaterial *m=p->GetMaterial(); - if (m == NULL) return; + std::string content; + content.reserve(2048); + char buffer[2048]; + while (stream.read(buffer, sizeof(buffer))) + { + content.append(buffer, sizeof(buffer)); + } + content.append(buffer, static_cast(stream.gcount())); + + if (content.empty()) return; + + this->SetMaterialXml(content); + + vtkXMLMaterialParser* parser = vtkXMLMaterialParser::New(); + vtkXMLMaterial* material = vtkXMLMaterial::New(); + parser->SetMaterial(material); + parser->Parse(content.c_str()); + parser->Delete(); + if (material == NULL) return; // Vertexshader uniforms { - vtkXMLShader *s=m->GetVertexShader(); + vtkXMLShader *s=material->GetVertexShader(); if (s) { + SetVertexShaderCode(s->GetCode()); vtkXMLDataElement *x=s->GetRootElement(); int n=x->GetNumberOfNestedElements(); for(int r=0;rGetNestedElement(r); if(!strcmp(y->GetName(),"ApplicationUniform")) { Uniform::Pointer element=Uniform::New(); element->LoadFromXML(y); uniforms.push_back(element); } } } } // Fragmentshader uniforms { - vtkXMLShader *s=m->GetFragmentShader(); + vtkXMLShader *s=material->GetFragmentShader(); if (s) { + SetFragmentShaderCode(s->GetCode()); vtkXMLDataElement *x=s->GetRootElement(); int n=x->GetNumberOfNestedElements(); for(int r=0;rGetNestedElement(r); if(!strcmp(y->GetName(),"ApplicationUniform")) { Uniform::Pointer element=Uniform::New(); element->LoadFromXML(y); uniforms.push_back(element); } } } } -}*/ - -void mitk::VtkShaderRepository::Shader::LoadProperties(std::istream& stream) -{ - std::string content; - content.reserve(2048); - char buffer[2048]; - while (stream.read(buffer, sizeof(buffer))) - { - content.append(buffer, sizeof(buffer)); - } - content.append(buffer, static_cast(stream.gcount())); - - if (content.empty()) return; + material->Delete(); - this->SetMaterialXml(content); - -// vtkPropertyXMLParser *p = vtkPropertyXMLParser::New(); SHADERTODO (move parsercode to here) -// p->LoadMaterialFromString(content.c_str()); -// LoadProperties(p); -// p->Delete(); } mitk::VtkShaderRepository::Shader::Uniform::Uniform() { } mitk::VtkShaderRepository::Shader::Uniform::~Uniform() { } void mitk::VtkShaderRepository::Shader::Uniform::LoadFromXML(vtkXMLDataElement *y) { //MITK_INFO << "found uniform '" << y->GetAttribute("name") << "' type=" << y->GetAttribute("type");// << " default=" << y->GetAttribute("value"); name = y->GetAttribute("name"); const char *sType=y->GetAttribute("type"); if(!strcmp(sType,"float")) type=glsl_float; else if(!strcmp(sType,"vec2")) type=glsl_vec2; else if(!strcmp(sType,"vec3")) type=glsl_vec3; else if(!strcmp(sType,"vec4")) type=glsl_vec4; else if(!strcmp(sType,"int")) type=glsl_int; else if(!strcmp(sType,"ivec2")) type=glsl_ivec2; else if(!strcmp(sType,"ivec3")) type=glsl_ivec3; else if(!strcmp(sType,"ivec4")) type=glsl_ivec4; else { type=glsl_none; SR_WARN << "unknown type for uniform '" << name << "'" ; } defaultFloat[0]=defaultFloat[1]=defaultFloat[2]=defaultFloat[3]=0; /* const char *sDefault=y->GetAttribute("value"); switch(type) { case glsl_float: sscanf(sDefault,"%f",&defaultFloat[0]); break; case glsl_vec2: sscanf(sDefault,"%f %f",&defaultFloat[0],&defaultFloat[1]); break; case glsl_vec3: sscanf(sDefault,"%f %f %f",&defaultFloat[0],&defaultFloat[1],&defaultFloat[2]); break; case glsl_vec4: sscanf(sDefault,"%f %f %f %f",&defaultFloat[0],&defaultFloat[1],&defaultFloat[2],&defaultFloat[3]); break; } */ } void mitk::VtkShaderRepository::AddDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) const { node->AddProperty( "shader", mitk::ShaderProperty::New(), renderer, overwrite ); std::list::const_iterator i = shaders.begin(); while( i != shaders.end() ) { std::list *l = (*i)->GetUniforms(); std::string shaderName = (*i)->GetName(); std::list::const_iterator j = l->begin(); while( j != l->end() ) { std::string propertyName = "shader." + shaderName + "." + (*j)->name; switch( (*j)->type ) { case Shader::Uniform::glsl_float: node->AddProperty( propertyName.c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite ); break; case Shader::Uniform::glsl_vec2: node->AddProperty( (propertyName+".x").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite ); node->AddProperty( (propertyName+".y").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[1] ), renderer, overwrite ); break; case Shader::Uniform::glsl_vec3: node->AddProperty( (propertyName+".x").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite ); node->AddProperty( (propertyName+".y").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[1] ), renderer, overwrite ); node->AddProperty( (propertyName+".z").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[2] ), renderer, overwrite ); break; case Shader::Uniform::glsl_vec4: node->AddProperty( (propertyName+".x").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite ); node->AddProperty( (propertyName+".y").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[1] ), renderer, overwrite ); node->AddProperty( (propertyName+".z").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[2] ), renderer, overwrite ); node->AddProperty( (propertyName+".w").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[3] ), renderer, overwrite ); break; default: break; } j++; } i++; } } -void mitk::VtkShaderRepository::ApplyShaderProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, vtkXMLMaterial* xmlMaterial, itk::TimeStamp& MTime) -{ - bool setMTime = false; - mitk::ShaderProperty *sep= dynamic_cast(node->GetProperty("shader",renderer)); - - std::string shader=sep->GetValueAsString(); - if(shader.compare("fixed")!=0) - { - Shader::Pointer s=GetShaderImpl(shader); - - if(s.IsNull()) - return; - - std::list::const_iterator j = s->uniforms.begin(); - - while( j != s->uniforms.end() ) - { - std::string propertyName = "shader." + s->GetName() + "." + (*j)->name; - - // MITK_INFO << "querying property: " << propertyName; - - // mitk::BaseProperty *p = node->GetProperty( propertyName.c_str(), renderer ); - - // if( p && p->GetMTime() > MTime.GetMTime() ) - { - float fval[4]; - - // MITK_INFO << "copying property " << propertyName << " ->->- " << (*j)->name << " type=" << (*j)->type ; - - - /* switch( (*j)->type ) - { - case Shader::Uniform::glsl_float: - node->GetFloatProperty( propertyName.c_str(), fval[0], renderer ); - property->AddShaderVariable( (*j)->name.c_str(), 1 , fval ); - break; - - case Shader::Uniform::glsl_vec2: - node->GetFloatProperty( (propertyName+".x").c_str(), fval[0], renderer ); - node->GetFloatProperty( (propertyName+".y").c_str(), fval[1], renderer ); - property->AddShaderVariable( (*j)->name.c_str(), 2 , fval ); - break; - - case Shader::Uniform::glsl_vec3: - node->GetFloatProperty( (propertyName+".x").c_str(), fval[0], renderer ); - node->GetFloatProperty( (propertyName+".y").c_str(), fval[1], renderer ); - node->GetFloatProperty( (propertyName+".z").c_str(), fval[2], renderer ); - - property->AddShaderVariable( (*j)->name.c_str(), 3 , fval ); - break; - - case Shader::Uniform::glsl_vec4: - node->GetFloatProperty( (propertyName+".x").c_str(), fval[0], renderer ); - node->GetFloatProperty( (propertyName+".y").c_str(), fval[1], renderer ); - node->GetFloatProperty( (propertyName+".z").c_str(), fval[2], renderer ); - node->GetFloatProperty( (propertyName+".w").c_str(), fval[3], renderer ); - property->AddShaderVariable( (*j)->name.c_str(), 4 , fval ); - break; - - default: - break; - - }*/ - - //setMTime=true; - } - - j++; - } - } - - if(setMTime) - MTime.Modified(); -} - -vtkXMLMaterial* mitk::VtkShaderRepository::GetXMLMaterial(mitk::DataNode* node, mitk::BaseRenderer* renderer, itk::TimeStamp& MTime) const -{ - /* SHADERTODO invoke parser here - bool setMTime = false; - - vtkPropertyXMLParser* property = new vtkPropertyXMLParser(); - - unsigned long ts = MTime.GetMTime(); - - mitk::ShaderProperty *sep= dynamic_cast(node->GetProperty("shader",renderer)); - - if(!sep) - { - property->ShadingOff(); - return 0; - } - - std::string shader=sep->GetValueAsString(); - - // Need update pipeline mode - if(sep->GetMTime() > ts) - { - if(shader.compare("fixed")==0) - { - //MITK_INFO << "disabling shader"; - property->ShadingOff(); - return 0; - } - else - { - Shader::Pointer s=GetShaderImpl(shader); - if(s.IsNotNull()) - { - //MITK_INFO << "enabling shader"; - property->ShadingOn(); - setMTime = true; - return property->LoadMaterialFromString(s->GetMaterialXml().c_str()); - } - } - setMTime = true; - return 0; - } -*/ -} - std::list mitk::VtkShaderRepository::GetShaders() const { std::list result; for (std::list::const_iterator i = shaders.begin(); i != shaders.end(); ++i) { result.push_back(i->GetPointer()); } return result; } mitk::IShaderRepository::Shader::Pointer mitk::VtkShaderRepository::GetShader(const std::string& name) const { for (std::list::const_iterator i = shaders.begin(); i != shaders.end(); ++i) { if ((*i)->GetName() == name) return i->GetPointer(); } return IShaderRepository::Shader::Pointer(); } mitk::IShaderRepository::Shader::Pointer mitk::VtkShaderRepository::GetShader(int id) const { for (std::list::const_iterator i = shaders.begin(); i != shaders.end(); ++i) { if ((*i)->GetId() == id) return i->GetPointer(); } return IShaderRepository::Shader::Pointer(); } -mitk::IShaderRepository::ShaderProgram::Pointer mitk::VtkShaderRepository::UpdateShaderProgram(mitk::IShaderRepository::ShaderProgram::Pointer shaderProgram, DataNode* node, BaseRenderer* renderer, const itk::TimeStamp& MTime) const +void +mitk::VtkShaderRepository::UpdateShaderProgram(ShaderProgram* shaderProgram, + DataNode* node, BaseRenderer* renderer) const { -// vtkXMLMaterial* xmlMaterial = GetXMLMaterial(node,renderer,MTime); - //SHADERTODO + VtkShaderProgram* mitkVtkShaderProgram = dynamic_cast(shaderProgram); + mitk::ShaderProperty *sep= dynamic_cast(node->GetProperty("shader",renderer)); + if(!sep) + { + mitkVtkShaderProgram->SetVtkShaderProgram(0); + return; + } + + Shader::Pointer s = GetShaderImpl(sep->GetValueAsString()); + + // Need update pipeline mode + if(sep->GetMTime() > mitkVtkShaderProgram->GetShaderTimestampUpdate().GetMTime()) + { + if( s.IsNull() ) + { + mitkVtkShaderProgram->SetVtkShaderProgram(0); + MITK_INFO << "disabling shader"; + mitkVtkShaderProgram->GetShaderTimestampUpdate().Modified(); + return; + } + + vtkSmartPointer program = vtkSmartPointer::New(); + program->SetContext(renderer->GetRenderWindow()); + + // The vertext shader + vtkShader2 *shader = vtkShader2::New(); + shader->SetType(VTK_SHADER_TYPE_VERTEX); + shader->SetSourceCode(s->GetVertexShaderCode().c_str()); + shader->SetContext(renderer->GetRenderWindow()); + program->GetShaders()->AddItem(shader); + shader->Delete(); + + // The fragment shader + shader = vtkShader2::New(); + shader->SetType(VTK_SHADER_TYPE_FRAGMENT); + shader->SetSourceCode(s->GetFragmentShaderCode().c_str()); + shader->SetContext(renderer->GetRenderWindow()); + program->GetShaders()->AddItem(shader); + shader->Delete(); + + program->Build(); + + mitkVtkShaderProgram->SetVtkShaderProgram(program); + + MITK_INFO << "enabling shader "; + mitkVtkShaderProgram->GetShaderTimestampUpdate().Modified(); + } + + if(s.IsNull()) + return; + + // update uniforms + vtkShaderProgram2 *p = mitkVtkShaderProgram->GetVtkShaderProgram(); + + if(!p) + return; + + std::list::const_iterator j = s->uniforms.begin(); + + while( j != s->uniforms.end() ) + { + std::string propertyName = "shader." + s->GetName() + "." + (*j)->name; + + // MITK_INFO << "querying property: " << propertyName; + + // mitk::BaseProperty *p = node->GetProperty( propertyName.c_str(), renderer ); + + // if( p && p->GetMTime() > MTime.GetMTime() ) + { + float fval[4]; + + // MITK_INFO << "copying property " << propertyName << " ->->- " << (*j)->name << " type=" << (*j)->type ; + + + switch( (*j)->type ) + { + case Shader::Uniform::glsl_float: + node->GetFloatProperty( propertyName.c_str(), fval[0], renderer ); + p->SetUniform1f( (*j)->name.c_str(), fval ); + break; + + case Shader::Uniform::glsl_vec2: + node->GetFloatProperty( (propertyName+".x").c_str(), fval[0], renderer ); + node->GetFloatProperty( (propertyName+".y").c_str(), fval[1], renderer ); + p->SetUniform2f( (*j)->name.c_str(), fval ); + break; + + case Shader::Uniform::glsl_vec3: + node->GetFloatProperty( (propertyName+".x").c_str(), fval[0], renderer ); + node->GetFloatProperty( (propertyName+".y").c_str(), fval[1], renderer ); + node->GetFloatProperty( (propertyName+".z").c_str(), fval[2], renderer ); + p->SetUniform3f( (*j)->name.c_str(), fval ); + break; + + case Shader::Uniform::glsl_vec4: + node->GetFloatProperty( (propertyName+".x").c_str(), fval[0], renderer ); + node->GetFloatProperty( (propertyName+".y").c_str(), fval[1], renderer ); + node->GetFloatProperty( (propertyName+".z").c_str(), fval[2], renderer ); + node->GetFloatProperty( (propertyName+".w").c_str(), fval[3], renderer ); + p->SetUniform4f( (*j)->name.c_str(), fval ); + break; + + default: + break; + + } + } + + j++; + } + + return; } diff --git a/Modules/VtkShaders/mitkVtkShaderRepository.h b/Modules/VtkShaders/mitkVtkShaderRepository.h index 84d700e233..c357a3fe02 100644 --- a/Modules/VtkShaders/mitkVtkShaderRepository.h +++ b/Modules/VtkShaders/mitkVtkShaderRepository.h @@ -1,169 +1,175 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef _MITKVTKSHADERREPOSITORY_H_ #define _MITKVTKSHADERREPOSITORY_H_ #include "mitkIShaderRepository.h" #include +#include class vtkXMLDataElement; class vtkXMLMaterial; class vtkProperty; namespace mitk { /** * \brief Management class for vtkShader XML descriptions. * * Looks for all XML shader files in a given directory and adds default properties * for each shader object (shader uniforms) to the specified mitk::DataNode. * * Additionally, it provides a utility function for applying properties for shaders * in mappers. */ class VtkShaderRepository : public IShaderRepository { protected: class Shader : public IShaderRepository::Shader { public: mitkClassMacro( Shader, itk::Object ) itkFactorylessNewMacro( Self ) + itkSetMacro(VertexShaderCode,std::string); + itkGetConstMacro(VertexShaderCode,std::string); + itkSetMacro(FragmentShaderCode,std::string); + itkGetConstMacro(FragmentShaderCode,std::string); + class Uniform : public itk::Object { public: mitkClassMacro( Uniform, itk::Object ) itkFactorylessNewMacro( Self ) enum Type { glsl_none, glsl_float, glsl_vec2, glsl_vec3, glsl_vec4, glsl_int, glsl_ivec2, glsl_ivec3, glsl_ivec4 }; /** * Constructor */ Uniform(); /** * Destructor */ ~Uniform(); Type type; std::string name; int defaultInt[4]; float defaultFloat[4]; void LoadFromXML(vtkXMLDataElement *e); }; std::list uniforms; /** * Constructor */ Shader(); /** * Destructor */ ~Shader(); Uniform *GetUniform(char * /*id*/) { return 0; } std::list *GetUniforms() { return &uniforms; } private: friend class VtkShaderRepository; -// void LoadProperties(vtkPropertyXMLParser* prop); - void LoadProperties(std::istream& stream); + std::string m_VertexShaderCode; + std::string m_FragmentShaderCode; + + void LoadXmlShader(std::istream& stream); }; void LoadShaders(); Shader::Pointer GetShaderImpl(const std::string& name) const; private: std::list shaders; static int shaderId; static const bool debug; public: /** * Constructor */ VtkShaderRepository(); /** * Destructor */ ~VtkShaderRepository(); ShaderProgram::Pointer CreateShaderProgram(); std::list GetShaders() const; IShaderRepository::Shader::Pointer GetShader(const std::string& name) const; IShaderRepository::Shader::Pointer GetShader(int id) const; /** \brief Adds all parsed shader uniforms to property list of the given DataNode; * used by mappers. */ void AddDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) const; /** \brief Applies shader and shader specific variables of the specified DataNode * to the VTK object by updating the shader variables of its vtkProperty. */ int LoadShader(std::istream& stream, const std::string& name); bool UnloadShader(int id); - vtkXMLMaterial* GetXMLMaterial(mitk::DataNode* node, mitk::BaseRenderer* renderer,itk::TimeStamp &MTime) const; - - void ApplyShaderProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, vtkXMLMaterial* xmlMaterial, itk::TimeStamp& MTime); - mitk::IShaderRepository::ShaderProgram::Pointer UpdateShaderProgram(mitk::IShaderRepository::ShaderProgram::Pointer shaderProgram, DataNode* node, BaseRenderer* renderer, const itk::TimeStamp& MTime) const; + void UpdateShaderProgram(mitk::IShaderRepository::ShaderProgram* shaderProgram, + DataNode* node, BaseRenderer* renderer) const; }; } //end of namespace mitk #endif