You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1170 lines
27 KiB
C++
1170 lines
27 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkUniformVariables.cxx
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
|
|
#include "vtkUniformVariables.h"
|
|
#include "vtkgl.h"
|
|
#include <cassert>
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkOpenGLError.h"
|
|
|
|
#include <map>
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkStandardNewMacro(vtkUniformVariables);
|
|
|
|
class ltstr
|
|
{
|
|
public:
|
|
bool operator()(const char* s1, const char* s2) const
|
|
{
|
|
return strcmp(s1, s2) < 0;
|
|
}
|
|
};
|
|
|
|
class vtkUniform
|
|
{
|
|
public:
|
|
|
|
// just because dynamic__cast is forbidden in VTK. Sucks.
|
|
enum
|
|
{
|
|
ClassTypeVectorInt=0,
|
|
ClassTypeVectorFloat=1,
|
|
ClassTypeMatrix=2,
|
|
ClassTypeArrayInt=3,
|
|
ClassTypeArrayFloat=4
|
|
};
|
|
|
|
int GetClassType() const
|
|
{
|
|
return this->ClassType;
|
|
}
|
|
|
|
vtkUniform()
|
|
{
|
|
this->ClassType=-1;
|
|
this->Name=0;
|
|
}
|
|
|
|
const char *GetName() const
|
|
{
|
|
return this->Name;
|
|
}
|
|
|
|
void SetName(const char *n)
|
|
{
|
|
if(this->Name==0 && n==0)
|
|
{
|
|
return;
|
|
}
|
|
if(this->Name!=0 && n!=0 && strcmp(this->Name,n)==0)
|
|
{
|
|
return;
|
|
}
|
|
delete[] this->Name;
|
|
if(n!=0) // copy
|
|
{
|
|
size_t l=strlen(n)+1;
|
|
this->Name=new char[l];
|
|
strncpy(this->Name,n,l);
|
|
}
|
|
else
|
|
{
|
|
this->Name=0;
|
|
}
|
|
}
|
|
|
|
virtual ~vtkUniform()
|
|
{
|
|
delete[] Name;
|
|
}
|
|
|
|
virtual void Send(int location)=0;
|
|
|
|
virtual void PrintSelf(ostream &os, vtkIndent indent)=0;
|
|
|
|
virtual vtkUniform *Clone() const=0;
|
|
|
|
protected:
|
|
char *Name;
|
|
|
|
int ClassType; // just because dynamic__cast is forbidden in VTK. Sucks.
|
|
};
|
|
|
|
class vtkUniformVectorInt : public vtkUniform
|
|
{
|
|
public:
|
|
vtkUniformVectorInt(int size,
|
|
int *values)
|
|
{
|
|
this->ClassType=ClassTypeVectorInt;
|
|
this->Size=size;
|
|
this->Values=new int[size];
|
|
int i=0;
|
|
while(i<size)
|
|
{
|
|
this->Values[i]=values[i];
|
|
++i;
|
|
}
|
|
}
|
|
virtual ~vtkUniformVectorInt()
|
|
{
|
|
delete[] this->Values;
|
|
}
|
|
|
|
int GetSize()
|
|
{
|
|
return this->Size;
|
|
}
|
|
|
|
void SetValues(int *values)
|
|
{
|
|
int i=0;
|
|
while(i<this->Size)
|
|
{
|
|
this->Values[i]=values[i];
|
|
++i;
|
|
}
|
|
}
|
|
|
|
const int *GetValues()
|
|
{
|
|
return this->Values;
|
|
}
|
|
|
|
virtual void Send(int location)
|
|
{
|
|
switch(this->Size)
|
|
{
|
|
case 1:
|
|
vtkgl::Uniform1i(location,this->Values[0]);
|
|
break;
|
|
case 2:
|
|
vtkgl::Uniform2i(location,this->Values[0],this->Values[1]);
|
|
break;
|
|
case 3:
|
|
vtkgl::Uniform3i(location,this->Values[0],this->Values[1],
|
|
this->Values[2]);
|
|
break;
|
|
case 4:
|
|
vtkgl::Uniform4i(location,this->Values[0],this->Values[1],
|
|
this->Values[2],this->Values[3]);
|
|
break;
|
|
}
|
|
vtkOpenGLStaticCheckErrorMacro("failed at glUniform*i");
|
|
}
|
|
|
|
virtual void PrintSelf(ostream &os, vtkIndent indent)
|
|
{
|
|
os << indent << this->Name << " (uniform" << this->Size << "i): ";
|
|
int i=0;
|
|
while(i<this->Size)
|
|
{
|
|
os << this->Values[i];
|
|
if(i<(this->Size-1))
|
|
{
|
|
os <<",";
|
|
}
|
|
++i;
|
|
}
|
|
os << endl;
|
|
}
|
|
|
|
virtual vtkUniform *Clone() const
|
|
{
|
|
vtkUniformVectorInt *result=new vtkUniformVectorInt(this->Size,
|
|
this->Values);
|
|
result->SetName(this->Name);
|
|
return result;
|
|
}
|
|
|
|
protected:
|
|
int Size;
|
|
int *Values;
|
|
};
|
|
|
|
class vtkUniformVectorFloat : public vtkUniform
|
|
{
|
|
public:
|
|
vtkUniformVectorFloat(int size,
|
|
float *values)
|
|
{
|
|
this->ClassType=ClassTypeVectorFloat;
|
|
this->Size=size;
|
|
this->Values=new float[size];
|
|
int i=0;
|
|
while(i<size)
|
|
{
|
|
this->Values[i]=values[i];
|
|
++i;
|
|
}
|
|
}
|
|
|
|
virtual ~vtkUniformVectorFloat()
|
|
{
|
|
delete[] this->Values;
|
|
}
|
|
|
|
int GetSize()
|
|
{
|
|
return this->Size;
|
|
}
|
|
|
|
void SetValues(float *values)
|
|
{
|
|
int i=0;
|
|
while(i<this->Size)
|
|
{
|
|
this->Values[i]=values[i];
|
|
++i;
|
|
}
|
|
}
|
|
|
|
const float *GetValues()
|
|
{
|
|
return this->Values;
|
|
}
|
|
|
|
virtual void Send(int location)
|
|
{
|
|
switch(this->Size)
|
|
{
|
|
case 1:
|
|
vtkgl::Uniform1f(location,this->Values[0]);
|
|
break;
|
|
case 2:
|
|
vtkgl::Uniform2f(location,this->Values[0],this->Values[1]);
|
|
break;
|
|
case 3:
|
|
vtkgl::Uniform3f(location,this->Values[0],this->Values[1],
|
|
this->Values[2]);
|
|
break;
|
|
case 4:
|
|
vtkgl::Uniform4f(location,this->Values[0],this->Values[1],
|
|
this->Values[2],this->Values[3]);
|
|
break;
|
|
}
|
|
vtkOpenGLStaticCheckErrorMacro("failed at glUniform*f");
|
|
}
|
|
|
|
virtual void PrintSelf(ostream &os, vtkIndent indent)
|
|
{
|
|
os << indent << this->Name << " (uniform" << this->Size << "f): ";
|
|
int i=0;
|
|
while(i<this->Size)
|
|
{
|
|
os << this->Values[i];
|
|
if(i<(this->Size-1))
|
|
{
|
|
os <<",";
|
|
}
|
|
++i;
|
|
}
|
|
os << endl;
|
|
}
|
|
|
|
virtual vtkUniform *Clone() const
|
|
{
|
|
vtkUniformVectorFloat *result=new vtkUniformVectorFloat(this->Size,
|
|
this->Values);
|
|
result->SetName(this->Name);
|
|
return result;
|
|
}
|
|
|
|
protected:
|
|
int Size;
|
|
float *Values;
|
|
};
|
|
|
|
class vtkUniformArrayInt : public vtkUniform
|
|
{
|
|
public:
|
|
vtkUniformArrayInt(int size,
|
|
int arraySize,
|
|
int *values)
|
|
{
|
|
this->ClassType=ClassTypeArrayInt;
|
|
this->Size=size;
|
|
this->ArraySize=arraySize;
|
|
this->Values=new GLint[size*arraySize];
|
|
int i=0;
|
|
while(i<this->Size*this->ArraySize)
|
|
{
|
|
this->Values[i]=values[i];
|
|
++i;
|
|
}
|
|
}
|
|
|
|
// this constructor is used inside Clone()
|
|
// It is required because GLint is long on Mac, not int.
|
|
vtkUniformArrayInt(int size,
|
|
int arraySize,
|
|
const GLint *values)
|
|
{
|
|
this->ClassType=ClassTypeArrayInt;
|
|
this->Size=size;
|
|
this->ArraySize=arraySize;
|
|
this->Values=new GLint[size*arraySize];
|
|
int i=0;
|
|
while(i<this->Size*this->ArraySize)
|
|
{
|
|
this->Values[i]=values[i];
|
|
++i;
|
|
}
|
|
}
|
|
|
|
virtual ~vtkUniformArrayInt()
|
|
{
|
|
delete[] this->Values;
|
|
}
|
|
|
|
int GetSize()
|
|
{
|
|
return this->Size;
|
|
}
|
|
|
|
int GetArraySize()
|
|
{
|
|
return this->ArraySize;
|
|
}
|
|
|
|
void SetValues(int *values)
|
|
{
|
|
int i=0;
|
|
while(i<this->Size*this->ArraySize)
|
|
{
|
|
this->Values[i]=values[i];
|
|
++i;
|
|
}
|
|
}
|
|
|
|
const GLint *GetValues()
|
|
{
|
|
return this->Values;
|
|
}
|
|
|
|
virtual void Send(int location)
|
|
{
|
|
switch(this->Size)
|
|
{
|
|
case 1:
|
|
vtkgl::Uniform1iv(location,this->ArraySize,this->Values);
|
|
break;
|
|
case 2:
|
|
vtkgl::Uniform2iv(location,this->ArraySize,this->Values);
|
|
break;
|
|
case 3:
|
|
vtkgl::Uniform3iv(location,this->ArraySize,this->Values);
|
|
break;
|
|
case 4:
|
|
vtkgl::Uniform4iv(location,this->ArraySize,this->Values);
|
|
break;
|
|
}
|
|
vtkOpenGLStaticCheckErrorMacro("failed at glUniform*iv");
|
|
}
|
|
|
|
virtual void PrintSelf(ostream &os, vtkIndent indent)
|
|
{
|
|
os << indent << this->Name << " (uniform" << this->Size << "iv[" << this->ArraySize << "]): ";
|
|
int j=0;
|
|
while(j<this->ArraySize)
|
|
{
|
|
os << "(";
|
|
int i=0;
|
|
while(i<this->Size)
|
|
{
|
|
os << this->Values[i];
|
|
if(i<(this->Size-1))
|
|
{
|
|
os <<",";
|
|
}
|
|
++i;
|
|
}
|
|
os << endl;
|
|
++j;
|
|
}
|
|
}
|
|
|
|
virtual vtkUniform *Clone() const
|
|
{
|
|
vtkUniformArrayInt *result=new vtkUniformArrayInt(this->Size,
|
|
this->ArraySize,
|
|
this->Values);
|
|
result->SetName(this->Name);
|
|
return result;
|
|
}
|
|
|
|
protected:
|
|
int Size; // size of element (eq. to float, vec2, vec2, vec4)
|
|
int ArraySize; // number of elements
|
|
GLint *Values; // GLint is long on Mac
|
|
};
|
|
|
|
class vtkUniformArrayFloat : public vtkUniform
|
|
{
|
|
public:
|
|
vtkUniformArrayFloat(int size,
|
|
int arraySize,
|
|
float *values)
|
|
{
|
|
this->ClassType=ClassTypeArrayFloat;
|
|
this->Size=size;
|
|
this->ArraySize=arraySize;
|
|
this->Values=new float[size*arraySize];
|
|
int i=0;
|
|
while(i<this->Size*this->ArraySize)
|
|
{
|
|
this->Values[i]=values[i];
|
|
++i;
|
|
}
|
|
}
|
|
|
|
virtual ~vtkUniformArrayFloat()
|
|
{
|
|
delete[] this->Values;
|
|
}
|
|
|
|
int GetSize()
|
|
{
|
|
return this->Size;
|
|
}
|
|
|
|
int GetArraySize()
|
|
{
|
|
return this->ArraySize;
|
|
}
|
|
|
|
void SetValues(float *values)
|
|
{
|
|
int i=0;
|
|
while(i<this->Size*this->ArraySize)
|
|
{
|
|
this->Values[i]=values[i];
|
|
++i;
|
|
}
|
|
}
|
|
|
|
const float *GetValues()
|
|
{
|
|
return this->Values;
|
|
}
|
|
|
|
virtual void Send(int location)
|
|
{
|
|
switch(this->Size)
|
|
{
|
|
case 1:
|
|
vtkgl::Uniform1fv(location,this->ArraySize,this->Values);
|
|
break;
|
|
case 2:
|
|
vtkgl::Uniform2fv(location,this->ArraySize,this->Values);
|
|
break;
|
|
case 3:
|
|
vtkgl::Uniform3fv(location,this->ArraySize,this->Values);
|
|
break;
|
|
case 4:
|
|
vtkgl::Uniform4fv(location,this->ArraySize,this->Values);
|
|
break;
|
|
}
|
|
vtkOpenGLStaticCheckErrorMacro("failed at glUniform*fv");
|
|
}
|
|
|
|
virtual void PrintSelf(ostream &os, vtkIndent indent)
|
|
{
|
|
os << indent << this->Name << " (uniform" << this->Size << "fv[" << this->ArraySize << "]): ";
|
|
int j=0;
|
|
while(j<this->ArraySize)
|
|
{
|
|
os << "(";
|
|
int i=0;
|
|
while(i<this->Size)
|
|
{
|
|
os << this->Values[i];
|
|
if(i<(this->Size-1))
|
|
{
|
|
os <<",";
|
|
}
|
|
++i;
|
|
}
|
|
os << endl;
|
|
++j;
|
|
}
|
|
}
|
|
|
|
virtual vtkUniform *Clone() const
|
|
{
|
|
vtkUniformArrayFloat *result=new vtkUniformArrayFloat(this->Size,
|
|
this->ArraySize,
|
|
this->Values);
|
|
result->SetName(this->Name);
|
|
return result;
|
|
}
|
|
|
|
protected:
|
|
int Size; // size of element (eq. to float, vec2, vec2, vec4)
|
|
int ArraySize; // number of elements
|
|
float *Values;
|
|
};
|
|
|
|
// rows or columns are 2,3,4.
|
|
class vtkUniformMatrix : public vtkUniform
|
|
{
|
|
public:
|
|
vtkUniformMatrix(int rows,
|
|
int columns,
|
|
float *values)
|
|
{
|
|
this->ClassType=ClassTypeMatrix;
|
|
this->Rows=rows;
|
|
this->Columns=columns;
|
|
this->Values=new float[rows*columns];
|
|
int i=0;
|
|
while(i<rows)
|
|
{
|
|
int j=0;
|
|
while(j<columns)
|
|
{
|
|
int index=i*columns+j;
|
|
this->Values[index]=values[index];
|
|
++j;
|
|
}
|
|
++i;
|
|
}
|
|
}
|
|
|
|
~vtkUniformMatrix()
|
|
{
|
|
delete[] this->Values;
|
|
}
|
|
|
|
int GetRows()
|
|
{
|
|
return this->Rows;
|
|
}
|
|
|
|
int GetColumns()
|
|
{
|
|
return this->Columns;
|
|
}
|
|
|
|
void SetValues(float *values)
|
|
{
|
|
int i=0;
|
|
while(i<this->Rows)
|
|
{
|
|
int j=0;
|
|
while(j<this->Columns)
|
|
{
|
|
int index=i*this->Columns+j;
|
|
this->Values[index]=values[index];
|
|
++j;
|
|
}
|
|
++i;
|
|
}
|
|
}
|
|
|
|
const float* GetValues()
|
|
{
|
|
return this->Values;
|
|
}
|
|
|
|
virtual void Send(int location)
|
|
{
|
|
switch(this->Rows)
|
|
{
|
|
case 2:
|
|
switch(this->Columns)
|
|
{
|
|
case 2:
|
|
vtkgl::UniformMatrix2fv(location,1,GL_FALSE,this->Values);
|
|
break;
|
|
case 3:
|
|
vtkgl::UniformMatrix2x3fv(location,1,GL_FALSE,this->Values);
|
|
break;
|
|
case 4:
|
|
vtkgl::UniformMatrix2x4fv(location,1,GL_FALSE,this->Values);
|
|
break;
|
|
}
|
|
break;
|
|
case 3:
|
|
switch(this->Columns)
|
|
{
|
|
case 2:
|
|
vtkgl::UniformMatrix3x2fv(location,1,GL_FALSE,this->Values);
|
|
break;
|
|
case 3:
|
|
vtkgl::UniformMatrix3fv(location,1,GL_FALSE,this->Values);
|
|
break;
|
|
case 4:
|
|
vtkgl::UniformMatrix3x4fv(location,1,GL_FALSE,this->Values);
|
|
break;
|
|
}
|
|
break;
|
|
case 4:
|
|
switch(this->Columns)
|
|
{
|
|
case 2:
|
|
vtkgl::UniformMatrix4x2fv(location,1,GL_FALSE,this->Values);
|
|
break;
|
|
case 3:
|
|
vtkgl::UniformMatrix4x3fv(location,1,GL_FALSE,this->Values);
|
|
break;
|
|
case 4:
|
|
vtkgl::UniformMatrix4fv(location,1,GL_FALSE,this->Values);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
vtkOpenGLStaticCheckErrorMacro("failed at glUniformMatrix*fv");
|
|
}
|
|
|
|
virtual void PrintSelf(ostream &os, vtkIndent indent)
|
|
{
|
|
os << indent << this->Name << " (matrix " << this->Rows << "x"
|
|
<< this->Columns << "): ";
|
|
|
|
int i=0;
|
|
while(i<this->Rows)
|
|
{
|
|
int j=0;
|
|
while(j<this->Columns)
|
|
{
|
|
int index=i*this->Columns+j;
|
|
os << this->Values[index];
|
|
if(j<(this->Columns-1))
|
|
os << ",";
|
|
++j;
|
|
}
|
|
os << endl;
|
|
++i;
|
|
}
|
|
}
|
|
|
|
virtual vtkUniform *Clone() const
|
|
{
|
|
vtkUniformMatrix *result=new vtkUniformMatrix(this->Rows,this->Columns,
|
|
this->Values);
|
|
result->SetName(this->Name);
|
|
return result;
|
|
}
|
|
|
|
protected:
|
|
float *Values;
|
|
int Rows;
|
|
int Columns;
|
|
};
|
|
|
|
typedef std::map<const char *, vtkUniform *, ltstr> UniformMap;
|
|
typedef std::map<const char *, vtkUniform *, ltstr>::iterator UniformMapIt;
|
|
|
|
class vtkUniformVariablesMap
|
|
{
|
|
public:
|
|
UniformMap Map;
|
|
UniformMapIt It; // used for external iteration.
|
|
|
|
~vtkUniformVariablesMap()
|
|
{
|
|
UniformMapIt i=this->Map.begin();
|
|
UniformMapIt e=this->Map.end();
|
|
while(i!=e)
|
|
{
|
|
vtkUniform *u=(*i).second;
|
|
delete u;
|
|
++i;
|
|
}
|
|
}
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
vtkUniformVariables::vtkUniformVariables()
|
|
{
|
|
this->Map=new vtkUniformVariablesMap;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
vtkUniformVariables::~vtkUniformVariables()
|
|
{
|
|
delete this->Map;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
void vtkUniformVariables::SetUniformi(const char *name,
|
|
int numberOfComponents,
|
|
int *value)
|
|
{
|
|
assert("pre: name_exists" && name!=0);
|
|
assert("pre: value_exists" && value!=0);
|
|
assert("pre: valid_numberOfComponents" && numberOfComponents>=1 && numberOfComponents<=4);
|
|
|
|
UniformMapIt cur=this->Map->Map.find(name);
|
|
|
|
if(cur!=this->Map->Map.end())
|
|
{
|
|
vtkUniform *u=(*cur).second;
|
|
vtkUniformVectorInt *ui=0;
|
|
if(u->GetClassType()==vtkUniform::ClassTypeVectorInt)
|
|
{
|
|
ui=static_cast<vtkUniformVectorInt *>(u);
|
|
}
|
|
if(ui==0)
|
|
{
|
|
vtkErrorMacro(<<"try to overwrite a value with different type.");
|
|
}
|
|
else
|
|
{
|
|
if(ui->GetSize()!=numberOfComponents)
|
|
{
|
|
vtkErrorMacro(<<"try to overwrite a value of same type but different number of components.");
|
|
}
|
|
else
|
|
{
|
|
bool changed=false;
|
|
int i=0;
|
|
while(!changed && i<numberOfComponents)
|
|
{
|
|
changed=value[i]!=ui->GetValues()[i];
|
|
++i;
|
|
}
|
|
if(changed)
|
|
{
|
|
ui->SetValues(value);
|
|
this->Modified();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vtkUniform *u=0;
|
|
u=new vtkUniformVectorInt(numberOfComponents,value);
|
|
u->SetName(name);
|
|
|
|
std::pair<const char *, vtkUniform *> p;
|
|
p.first=u->GetName(); // cannot be `name' because
|
|
// we don't manage this pointer.
|
|
p.second=u;
|
|
|
|
this->Map->Map.insert(p);
|
|
this->Modified();
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
void vtkUniformVariables::SetUniformf(const char *name,
|
|
int numberOfComponents,
|
|
float *value)
|
|
{
|
|
assert("pre: name_exists" && name!=0);
|
|
assert("pre: value_exists" && value!=0);
|
|
assert("pre: valid_numberOfComponents" && numberOfComponents>=1 && numberOfComponents<=4);
|
|
|
|
UniformMapIt cur=this->Map->Map.find(name);
|
|
|
|
if(cur!=this->Map->Map.end())
|
|
{
|
|
vtkUniform *u=(*cur).second;
|
|
vtkUniformVectorFloat *uf=0;
|
|
if(u->GetClassType()==vtkUniform::ClassTypeVectorFloat)
|
|
{
|
|
uf=static_cast<vtkUniformVectorFloat *>(u);
|
|
}
|
|
if(uf==0)
|
|
{
|
|
vtkErrorMacro(<<"try to overwrite a value with different type.");
|
|
}
|
|
else
|
|
{
|
|
if(uf->GetSize()!=numberOfComponents)
|
|
{
|
|
vtkErrorMacro(<<"try to overwrite a value of same type but different number of components.");
|
|
}
|
|
else
|
|
{
|
|
bool changed=false;
|
|
int i=0;
|
|
while(!changed && i<numberOfComponents)
|
|
{
|
|
changed=value[i]!=uf->GetValues()[i];
|
|
++i;
|
|
}
|
|
if(changed)
|
|
{
|
|
uf->SetValues(value);
|
|
this->Modified();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vtkUniform *u=0;
|
|
u=new vtkUniformVectorFloat(numberOfComponents,value);
|
|
u->SetName(name);
|
|
|
|
std::pair<const char *, vtkUniform *> p;
|
|
p.first=u->GetName(); // cannot be `name' because
|
|
// we don't manage this pointer.
|
|
p.second=u;
|
|
|
|
this->Map->Map.insert(p);
|
|
this->Modified();
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
void vtkUniformVariables::SetUniformiv(const char *name,
|
|
int numberOfComponents,
|
|
int numberOfElements,
|
|
int *value)
|
|
{
|
|
assert("pre: name_exists" && name!=0);
|
|
assert("pre: value_exists" && value!=0);
|
|
assert("pre: valid_numberOfComponents" && numberOfComponents>=1 && numberOfComponents<=4);
|
|
assert("pre: valid_numberOfElements" && numberOfElements>=1);
|
|
|
|
UniformMapIt cur=this->Map->Map.find(name);
|
|
|
|
if(cur!=this->Map->Map.end())
|
|
{
|
|
vtkUniform *u=(*cur).second;
|
|
vtkUniformArrayInt *ui=0;
|
|
if(u->GetClassType()==vtkUniform::ClassTypeArrayInt)
|
|
{
|
|
ui=static_cast<vtkUniformArrayInt *>(u);
|
|
}
|
|
if(ui==0)
|
|
{
|
|
vtkErrorMacro(<<"try to overwrite a value with different type.");
|
|
}
|
|
else
|
|
{
|
|
if(ui->GetSize()!=numberOfComponents)
|
|
{
|
|
vtkErrorMacro(<<"try to overwrite a value of same type but different number of components.");
|
|
}
|
|
if(ui->GetArraySize()!=numberOfElements)
|
|
{
|
|
vtkErrorMacro(<<"try to overwrite a value of same type but different number of elements.");
|
|
}
|
|
else
|
|
{
|
|
bool changed=false;
|
|
int i=0;
|
|
while(!changed && i<numberOfComponents*numberOfElements)
|
|
{
|
|
changed=value[i]!=ui->GetValues()[i];
|
|
++i;
|
|
}
|
|
if(changed)
|
|
{
|
|
ui->SetValues(value);
|
|
this->Modified();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vtkUniform *u=0;
|
|
u=new vtkUniformArrayInt(numberOfComponents,numberOfElements,value);
|
|
u->SetName(name);
|
|
|
|
std::pair<const char *, vtkUniform *> p;
|
|
p.first=u->GetName(); // cannot be `name' because
|
|
// we don't manage this pointer.
|
|
p.second=u;
|
|
|
|
this->Map->Map.insert(p);
|
|
this->Modified();
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
void vtkUniformVariables::SetUniformfv(const char *name,
|
|
int numberOfComponents,
|
|
int numberOfElements,
|
|
float *value)
|
|
{
|
|
assert("pre: name_exists" && name!=0);
|
|
assert("pre: value_exists" && value!=0);
|
|
assert("pre: valid_numberOfComponents" && numberOfComponents>=1 && numberOfComponents<=4);
|
|
assert("pre: valid_numberOfElements" && numberOfElements>=1);
|
|
|
|
UniformMapIt cur=this->Map->Map.find(name);
|
|
|
|
if(cur!=this->Map->Map.end())
|
|
{
|
|
vtkUniform *u=(*cur).second;
|
|
vtkUniformArrayFloat *uf=0;
|
|
if(u->GetClassType()==vtkUniform::ClassTypeArrayFloat)
|
|
{
|
|
uf=static_cast<vtkUniformArrayFloat *>(u);
|
|
}
|
|
if(uf==0)
|
|
{
|
|
vtkErrorMacro(<<"try to overwrite a value with different type.");
|
|
}
|
|
else
|
|
{
|
|
if(uf->GetSize()!=numberOfComponents)
|
|
{
|
|
vtkErrorMacro(<<"try to overwrite a value of same type but different number of components.");
|
|
}
|
|
if(uf->GetArraySize()!=numberOfElements)
|
|
{
|
|
vtkErrorMacro(<<"try to overwrite a value of same type but different number of elements.");
|
|
}
|
|
else
|
|
{
|
|
bool changed=false;
|
|
int i=0;
|
|
while(!changed && i<numberOfComponents*numberOfElements)
|
|
{
|
|
changed=value[i]!=uf->GetValues()[i];
|
|
++i;
|
|
}
|
|
if(changed)
|
|
{
|
|
uf->SetValues(value);
|
|
this->Modified();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vtkUniform *u=0;
|
|
u=new vtkUniformArrayFloat(numberOfComponents,numberOfElements,value);
|
|
u->SetName(name);
|
|
|
|
std::pair<const char *, vtkUniform *> p;
|
|
p.first=u->GetName(); // cannot be `name' because
|
|
// we don't manage this pointer.
|
|
p.second=u;
|
|
|
|
this->Map->Map.insert(p);
|
|
this->Modified();
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
void vtkUniformVariables::SetUniformMatrix(const char *name,
|
|
int rows,
|
|
int columns,
|
|
float *value)
|
|
{
|
|
assert("pre: name_exists" && name!=0);
|
|
assert("pre: value_exists" && value!=0);
|
|
assert("pre: valid_rows" && rows>=2 && rows<=4);
|
|
assert("pre: valid_columns" && columns>=2 && columns<=4);
|
|
|
|
UniformMapIt cur=this->Map->Map.find(name);
|
|
|
|
if(cur!=this->Map->Map.end())
|
|
{
|
|
vtkUniform *u=(*cur).second;
|
|
vtkUniformMatrix *um=0;
|
|
if(u->GetClassType()==vtkUniform::ClassTypeMatrix)
|
|
{
|
|
um=static_cast<vtkUniformMatrix *>(u);
|
|
}
|
|
if(um==0)
|
|
{
|
|
vtkErrorMacro(<<"try to overwrite a value with different type.");
|
|
}
|
|
else
|
|
{
|
|
if(um->GetRows()!=rows || um->GetColumns()!=columns)
|
|
{
|
|
vtkErrorMacro(<<"try to overwrite a value of same type but different number of components.");
|
|
}
|
|
else
|
|
{
|
|
bool changed=false;
|
|
int i=0;
|
|
while(!changed && i<rows*columns)
|
|
{
|
|
changed=value[i]!=um->GetValues()[i];
|
|
++i;
|
|
}
|
|
if(changed)
|
|
{
|
|
um->SetValues(value);
|
|
this->Modified();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vtkUniform *u=new vtkUniformMatrix(rows,columns,value);
|
|
u->SetName(name);
|
|
std::pair<const char *, vtkUniform *> p;
|
|
p.first=u->GetName(); // cannot be `name' because
|
|
// we don't manage this pointer.
|
|
p.second=u;
|
|
this->Map->Map.insert(p);
|
|
this->Modified();
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Description:
|
|
// Remove uniform `name' from the list.
|
|
void vtkUniformVariables::RemoveUniform(const char *name)
|
|
{
|
|
UniformMapIt cur=this->Map->Map.find(name);
|
|
if(cur!=this->Map->Map.end())
|
|
{
|
|
this->Map->Map.erase(cur);
|
|
this->Modified();
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Description:
|
|
// \pre need a valid OpenGL context and a shader program in use.
|
|
void vtkUniformVariables::Send(const char *name,
|
|
int uniformIndex)
|
|
{
|
|
UniformMapIt cur=this->Map->Map.find(name);
|
|
(*cur).second->Send(uniformIndex);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Description:
|
|
// Place the internal cursor on the first uniform.
|
|
void vtkUniformVariables::Start()
|
|
{
|
|
this->Map->It=this->Map->Map.begin();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Description:
|
|
// Is the iteration done?
|
|
bool vtkUniformVariables::IsAtEnd()
|
|
{
|
|
return this->Map->It==this->Map->Map.end();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Description:
|
|
// Name of the uniform at the current cursor position.
|
|
// \pre not_done: !this->IsAtEnd()
|
|
const char *vtkUniformVariables::GetCurrentName()
|
|
{
|
|
assert("pre: not_done" && !this->IsAtEnd());
|
|
return (*this->Map->It).first;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Description:
|
|
// \pre need a valid OpenGL context and a shader program in use.
|
|
// \pre not_done: !this->IsAtEnd()
|
|
void vtkUniformVariables::SendCurrentUniform(int uniformIndex)
|
|
{
|
|
assert("pre: not_done" && !this->IsAtEnd());
|
|
(*this->Map->It).second->Send(uniformIndex);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Description:
|
|
// Move the cursor to the next uniform.
|
|
// \pre not_done: !this->IsAtEnd()
|
|
void vtkUniformVariables::Next()
|
|
{
|
|
assert("pre: not_done" && !this->IsAtEnd());
|
|
++this->Map->It;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Description:
|
|
// Copy all the variables from `other'. Any existing variable will be
|
|
// overwritten.
|
|
// \pre other_exists: other!=0
|
|
// \pre not_self: other!=this
|
|
void vtkUniformVariables::Merge(vtkUniformVariables *other)
|
|
{
|
|
assert("pre: other_exists" && other != 0);
|
|
assert("pre: not_self" && other != this);
|
|
|
|
other->Start();
|
|
while (!other->IsAtEnd())
|
|
{
|
|
const char *name = other->GetCurrentName();
|
|
UniformMapIt prev = this->Map->Map.find(name);
|
|
if (prev != this->Map->Map.end())
|
|
{
|
|
delete prev->second;
|
|
this->Map->Map.erase(prev);
|
|
}
|
|
vtkUniform* clone = other->Map->It->second->Clone();
|
|
this->Map->Map[clone->GetName()] = clone;
|
|
|
|
other->Next();
|
|
}
|
|
if (other->Map->Map.size() > 0)
|
|
{
|
|
this->Modified();
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Description:
|
|
// Copy all the variables from `other'. Any existing variable will be
|
|
// deleted first.
|
|
// \pre other_exists: other!=0
|
|
// \pre not_self: other!=this
|
|
void vtkUniformVariables::DeepCopy(vtkUniformVariables *other)
|
|
{
|
|
assert("pre: other_exists" && other!=0);
|
|
assert("pre: not_self" && other!=this);
|
|
|
|
if(this->Map->Map.size()>0)
|
|
{
|
|
delete this->Map;
|
|
this->Map=new vtkUniformVariablesMap;
|
|
this->Modified();
|
|
}
|
|
this->Merge(other);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
void vtkUniformVariables::RemoveAllUniforms()
|
|
{
|
|
if(this->Map->Map.size()>0)
|
|
{
|
|
delete this->Map;
|
|
this->Map=new vtkUniformVariablesMap;
|
|
this->Modified();
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
void vtkUniformVariables::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
|
|
this->Start();
|
|
while(!this->IsAtEnd())
|
|
{
|
|
const char *name=this->GetCurrentName();
|
|
UniformMapIt cur=this->Map->Map.find(name);
|
|
(*cur).second->PrintSelf(os,indent);
|
|
this->Next();
|
|
}
|
|
}
|