00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #define SR_INFO MITK_INFO("shader.repository")
00019 #define SR_WARN MITK_WARN("shader.repository")
00020 #define SR_ERROR MITK_ERROR("shader.repository")
00021
00022 #include "mitkShaderRepository.h"
00023 #include "mitkShaderProperty.h"
00024 #include "mitkProperties.h"
00025
00026 #include <vtkProperty.h>
00027 #include <vtkXMLMaterial.h>
00028 #include <vtkXMLShader.h>
00029 #include <vtkXMLDataElement.h>
00030
00031 #include <itkDirectory.h>
00032 #include <itksys/SystemTools.hxx>
00033
00034 #include "mitkStandardFileLocations.h"
00035
00036 mitk::ShaderRepository::ShaderRepository()
00037 {
00038 LoadShaders();
00039 }
00040
00041 mitk::ShaderRepository::~ShaderRepository()
00042 {
00043 }
00044
00045 mitk::ShaderRepository *mitk::ShaderRepository::GetGlobalShaderRepository()
00046 {
00047 static mitk::ShaderRepository::Pointer i;
00048
00049 if(i.IsNull())
00050 {
00051 i=mitk::ShaderRepository::New();
00052 }
00053
00054 return i;
00055 }
00056
00057
00058 void mitk::ShaderRepository::LoadShaders()
00059 {
00060 itk::Directory::Pointer dir = itk::Directory::New();
00061
00062 std::string mitkLighting = mitk::StandardFileLocations::GetInstance()->FindFile("mitkShaderLighting.xml", "Core/Code/Rendering");
00063
00064 std::string dirPath = "./vtk_shader";
00065
00066
00067 if(mitkLighting.size() > 0)
00068 {
00069
00070 dirPath = itksys::SystemTools::GetFilenamePath( mitkLighting );
00071
00072 SR_INFO << "found default mitk shader at '" << dirPath << "'";
00073 }
00074
00075
00076
00077 if( dir->Load( dirPath.c_str() ) )
00078 {
00079 int n = dir->GetNumberOfFiles();
00080 for(int r=0;r<n;r++)
00081 {
00082 const char *filename = dir->GetFile( r );
00083
00084 std::string extension = itksys::SystemTools::GetFilenameExtension(filename);
00085
00086 if(extension.compare(".xml")==0)
00087 {
00088 Shader::Pointer element=Shader::New();
00089
00090 element->name = itksys::SystemTools::GetFilenameWithoutExtension(filename);
00091 element->path = dirPath + std::string("/") + element->name + std::string(".xml");
00092
00093 SR_INFO << "found shader '" << element->name << "'";
00094
00095 element->LoadPropertiesFromPath();
00096
00097 shaders.push_back(element);
00098 }
00099 }
00100 }
00101 }
00102
00103 void mitk::ShaderRepository::LoadShader(std::string filename)
00104 {
00105 std::string extension = itksys::SystemTools::GetFilenameExtension(filename);
00106 if (extension.compare(".xml")==0)
00107 {
00108 Shader::Pointer element=Shader::New();
00109 element->name = itksys::SystemTools::GetFilenameWithoutExtension(filename);
00110 element->path = filename;
00111 element->LoadPropertiesFromPath();
00112 shaders.push_back(element);
00113 SR_INFO << "found shader '" << element->name << "'";
00114 }
00115
00116 else
00117 {
00118 SR_INFO << "Error: no xml shader file!";
00119 }
00120 }
00121
00122 mitk::ShaderRepository::Shader::Shader()
00123 {
00124 }
00125
00126 mitk::ShaderRepository::Shader::~Shader()
00127 {
00128 }
00129
00130 void mitk::ShaderRepository::Shader::LoadPropertiesFromPath()
00131 {
00132 vtkProperty *p;
00133
00134 p = vtkProperty::New();
00135
00136 p->LoadMaterial(path.c_str());
00137
00138 vtkXMLMaterial *m=p->GetMaterial();
00139
00140
00141 {
00142 vtkXMLShader *s=m->GetVertexShader();
00143 vtkXMLDataElement *x=s->GetRootElement();
00144 int n=x->GetNumberOfNestedElements();
00145 for(int r=0;r<n;r++)
00146 {
00147 vtkXMLDataElement *y=x->GetNestedElement(r);
00148 if(!strcmp(y->GetName(),"ApplicationUniform"))
00149 {
00150 Uniform::Pointer element=Uniform::New();
00151 element->LoadFromXML(y);
00152 uniforms.push_back(element);
00153 }
00154 }
00155 }
00156
00157
00158 {
00159 vtkXMLShader *s=m->GetFragmentShader();
00160 vtkXMLDataElement *x=s->GetRootElement();
00161 int n=x->GetNumberOfNestedElements();
00162 for(int r=0;r<n;r++)
00163 {
00164 vtkXMLDataElement *y=x->GetNestedElement(r);
00165 if(!strcmp(y->GetName(),"ApplicationUniform"))
00166 {
00167 Uniform::Pointer element=Uniform::New();
00168 element->LoadFromXML(y);
00169 uniforms.push_back(element);
00170 }
00171 }
00172 }
00173
00174 p->Delete();
00175 }
00176
00177
00178
00179
00180 mitk::ShaderRepository::Shader::Uniform::Uniform()
00181 {
00182 }
00183
00184 mitk::ShaderRepository::Shader::Uniform::~Uniform()
00185 {
00186 }
00187
00188 mitk::ShaderRepository::Shader *mitk::ShaderRepository::GetShader(const char *id)
00189 {
00190 std::list<Shader::Pointer>::const_iterator i = shaders.begin();
00191
00192 while( i != shaders.end() )
00193 {
00194 if( (*i)->name.compare(id) == 0)
00195 return (*i);
00196
00197 i++;
00198 }
00199
00200 return 0;
00201 }
00202
00203
00204 void mitk::ShaderRepository::Shader::Uniform::LoadFromXML(vtkXMLDataElement *y)
00205 {
00206
00207
00208 name = y->GetAttribute("name");
00209
00210 const char *sType=y->GetAttribute("type");
00211
00212 if(!strcmp(sType,"float"))
00213 type=glsl_float;
00214 else if(!strcmp(sType,"vec2"))
00215 type=glsl_vec2;
00216 else if(!strcmp(sType,"vec3"))
00217 type=glsl_vec3;
00218 else if(!strcmp(sType,"vec4"))
00219 type=glsl_vec4;
00220 else if(!strcmp(sType,"int"))
00221 type=glsl_int;
00222 else if(!strcmp(sType,"ivec2"))
00223 type=glsl_ivec2;
00224 else if(!strcmp(sType,"ivec3"))
00225 type=glsl_ivec3;
00226 else if(!strcmp(sType,"ivec4"))
00227 type=glsl_ivec4;
00228 else
00229 {
00230 type=glsl_none;
00231 SR_WARN << "unknown type for uniform '" << name << "'" ;
00232 }
00233
00234
00235 defaultFloat[0]=defaultFloat[1]=defaultFloat[2]=defaultFloat[3]=0;
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 }
00259
00260
00261
00262 void mitk::ShaderRepository::AddDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
00263 {
00264 node->AddProperty( "shader", mitk::ShaderProperty::New(), renderer, overwrite );
00265
00266 std::list<Shader::Pointer>::const_iterator i = shaders.begin();
00267
00268 while( i != shaders.end() )
00269 {
00270 std::list<Shader::Uniform::Pointer> *l = (*i)->GetUniforms();
00271
00272 std::string shaderName = (*i)->name;
00273
00274 std::list<Shader::Uniform::Pointer>::const_iterator j = l->begin();
00275
00276 while( j != l->end() )
00277 {
00278 std::string propertyName = "shader." + shaderName + "." + (*j)->name;
00279
00280 switch( (*j)->type )
00281 {
00282 case Shader::Uniform::glsl_float:
00283 node->AddProperty( propertyName.c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite );
00284 break;
00285
00286 case Shader::Uniform::glsl_vec2:
00287 node->AddProperty( (propertyName+".x").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite );
00288 node->AddProperty( (propertyName+".y").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[1] ), renderer, overwrite );
00289 break;
00290
00291 case Shader::Uniform::glsl_vec3:
00292 node->AddProperty( (propertyName+".x").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite );
00293 node->AddProperty( (propertyName+".y").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[1] ), renderer, overwrite );
00294 node->AddProperty( (propertyName+".z").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[2] ), renderer, overwrite );
00295 break;
00296
00297 case Shader::Uniform::glsl_vec4:
00298 node->AddProperty( (propertyName+".x").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite );
00299 node->AddProperty( (propertyName+".y").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[1] ), renderer, overwrite );
00300 node->AddProperty( (propertyName+".z").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[2] ), renderer, overwrite );
00301 node->AddProperty( (propertyName+".w").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[3] ), renderer, overwrite );
00302 break;
00303
00304 default:
00305 break;
00306
00307 }
00308
00309 j++;
00310
00311 }
00312
00313 i++;
00314 }
00315
00316
00317 }
00318
00319 void mitk::ShaderRepository::ApplyProperties(mitk::DataNode* node, vtkActor *actor, mitk::BaseRenderer* renderer,itk::TimeStamp &MTime)
00320 {
00321 bool setMTime = false;
00322
00323 vtkProperty* property = actor->GetProperty();
00324
00325 unsigned long ts = MTime.GetMTime();
00326
00327 mitk::ShaderProperty *sep=(mitk::ShaderProperty *)node->GetProperty("shader",renderer);
00328
00329 if(!sep)
00330 {
00331 property->ShadingOff();
00332 return;
00333 }
00334
00335 std::string shader=sep->GetValueAsString();
00336
00337
00338 if(sep->GetMTime() > ts)
00339 {
00340 if(shader.compare("fixed")==0)
00341 {
00342
00343 property->ShadingOff();
00344 }
00345 else
00346 {
00347 Shader *s=GetShader(shader.c_str());
00348 if(s)
00349 {
00350
00351 property->ShadingOn();
00352 property->LoadMaterial(s->path.c_str());
00353 }
00354 }
00355 setMTime = true;
00356 }
00357
00358 if(shader.compare("fixed")!=0)
00359 {
00360 Shader *s=GetShader(shader.c_str());
00361
00362 if(!s)
00363 return;
00364
00365 std::list<Shader::Uniform::Pointer>::const_iterator j = s->uniforms.begin();
00366
00367 while( j != s->uniforms.end() )
00368 {
00369 std::string propertyName = "shader." + s->name + "." + (*j)->name;
00370
00371
00372
00373
00374
00375
00376 {
00377 float fval[4];
00378
00379
00380
00381
00382 switch( (*j)->type )
00383 {
00384 case Shader::Uniform::glsl_float:
00385 node->GetFloatProperty( propertyName.c_str(), fval[0], renderer );
00386 property->AddShaderVariable( (*j)->name.c_str(), 1 , fval );
00387 break;
00388
00389 case Shader::Uniform::glsl_vec2:
00390 node->GetFloatProperty( (propertyName+".x").c_str(), fval[0], renderer );
00391 node->GetFloatProperty( (propertyName+".y").c_str(), fval[1], renderer );
00392 property->AddShaderVariable( (*j)->name.c_str(), 2 , fval );
00393 break;
00394
00395 case Shader::Uniform::glsl_vec3:
00396 node->GetFloatProperty( (propertyName+".x").c_str(), fval[0], renderer );
00397 node->GetFloatProperty( (propertyName+".y").c_str(), fval[1], renderer );
00398 node->GetFloatProperty( (propertyName+".z").c_str(), fval[2], renderer );
00399
00400 property->AddShaderVariable( (*j)->name.c_str(), 3 , fval );
00401 break;
00402
00403 case Shader::Uniform::glsl_vec4:
00404 node->GetFloatProperty( (propertyName+".x").c_str(), fval[0], renderer );
00405 node->GetFloatProperty( (propertyName+".y").c_str(), fval[1], renderer );
00406 node->GetFloatProperty( (propertyName+".z").c_str(), fval[2], renderer );
00407 node->GetFloatProperty( (propertyName+".w").c_str(), fval[3], renderer );
00408 property->AddShaderVariable( (*j)->name.c_str(), 4 , fval );
00409 break;
00410
00411 default:
00412 break;
00413
00414 }
00415
00416
00417 }
00418
00419 j++;
00420 }
00421 }
00422
00423 if(setMTime)
00424 MTime.Modified();
00425 }
00426