CrystalSpace

Public API Reference

csgfx/shadervar.h
Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2003 by Mat Sutcliffe <oktal@gmx.co.uk>
00003                   2003-2008 by Marten Svanfeldt
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public
00016     License along with this library; if not, write to the Free
00017     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 */
00019 
00020 #ifndef __CS_GFX_SHADERVAR_H__
00021 #define __CS_GFX_SHADERVAR_H__
00022 
00027 #include "csextern.h"
00028 
00029 #include "csgeom/math.h"
00030 #include "csgeom/quaternion.h"
00031 #include "csgeom/transfrm.h"
00032 #include "csgeom/vector2.h"
00033 #include "csgeom/vector3.h"
00034 #include "csgeom/vector4.h"
00035 #include "csgfx/rgbpixel.h"
00036 #include "csutil/blockallocator.h"
00037 #include "csutil/cscolor.h"
00038 #include "csutil/leakguard.h"
00039 #include "csutil/refarr.h"
00040 #include "csutil/refcount.h"
00041 #include "csutil/strset.h"
00042 
00043 #include "iengine/texture.h"
00044 #include "ivideo/texture.h"
00045 #include "ivideo/rndbuf.h"
00046 
00047 struct iTextureHandle;
00048 struct iTextureWrapper;
00049 struct csShaderVariableWrapper;
00050 
00051 class csShaderVariable;
00052 
00053 namespace CS
00054 {
00055   namespace StringSetTag
00056   {
00057     struct ShaderVar;
00058   } // namespace StringSetTag
00059   
00061   typedef StringID<StringSetTag::ShaderVar> ShaderVarStringID;
00063   ShaderVarStringID const InvalidShaderVarStringID =
00064     InvalidStringID<StringSetTag::ShaderVar> ();
00065 } // namespace CS
00066 
00068 struct iShaderVarStringSet :
00069   public iStringSetBase<CS::StringSetTag::ShaderVar>
00070 {
00071   CS_ISTRINGSSET_SCF_VERSION(iShaderVarStringSet);
00072 };
00073 
00082 struct iShaderVariableAccessor : public virtual iBase
00083 {
00084   SCF_INTERFACE (iShaderVariableAccessor, 2, 0, 0);
00085 
00087   virtual void PreGetValue (csShaderVariable *variable) = 0;
00088 };
00089 
00095 class CS_CRYSTALSPACE_EXPORT csShaderVariable : public csRefCount
00096 {
00097 public:
00103   enum VariableType
00104   {
00106     UNKNOWN = 0,
00108     INT = 1,
00110     FLOAT,
00112     TEXTURE,
00114     RENDERBUFFER,
00116     VECTOR2,
00118     VECTOR3,
00120     VECTOR4,
00122     MATRIX3X3,
00123     MATRIX = MATRIX3X3,
00125     TRANSFORM,
00127     ARRAY,
00129     MATRIX4X4,
00130     
00135     COLOR = VECTOR4
00136   };
00137 
00138 
00143   csShaderVariable ();
00145   csShaderVariable (CS::ShaderVarStringID name);
00146 
00147   csShaderVariable (const csShaderVariable& other);
00148 
00149   virtual ~csShaderVariable ();  
00150 
00151   csShaderVariable& operator= (const csShaderVariable& copyFrom);
00152 
00154   VariableType GetType() 
00155   { 
00156     /* The accessor should be called at least once so the var has a proper
00157      * type set */
00158     if ((GetTypeI() == UNKNOWN) && accessor && accessor->obj) 
00159       accessor->obj->PreGetValue (this);
00160     return GetTypeI(); 
00161   }
00163   void SetType (VariableType t) 
00164   {
00165     NewType (t);
00166   }
00167 
00169   void SetAccessor (iShaderVariableAccessor* a, intptr_t extraData = 0) 
00170   { 
00171     if (accessor == 0) AllocAccessor ();
00172     accessor->obj = a;
00173     accessor->data = extraData;
00174   }
00175 
00181   void SetName (CS::ShaderVarStringID newName)
00182   {
00183     CS_ASSERT((newName == CS::InvalidShaderVarStringID)
00184       || (uint(newName) < nameMask));
00185     nameAndType &= ~nameMask;
00186     nameAndType |= uint (newName) & nameMask;
00187   }
00188   
00190   CS::ShaderVarStringID GetName () const
00191   { 
00192     CS::ShaderVarStringID namePart =
00193       static_cast<CS::ShaderVarStringID>(nameAndType & nameMask);
00194     return namePart == nameMask ? CS::InvalidShaderVarStringID : namePart;
00195   }
00196 
00198   iShaderVariableAccessor* GetAccessor () const
00199   {
00200     return accessor ? accessor->obj : 0;
00201   }
00202 
00204   intptr_t GetAccessorData () const
00205   {
00206     return accessor? accessor->data : 0;
00207   }
00208 
00210   bool GetValue (int& value)
00211   { 
00212     if (accessor && accessor->obj)
00213       accessor->obj->PreGetValue (this);
00214 
00215     if (GetTypeI() == INT)
00216       value = Int;
00217     else
00218       value = int (Vector[0]); 
00219     return true; 
00220   }
00221 
00223   bool GetValue (float& value)
00224   { 
00225     if (accessor && accessor->obj)
00226       accessor->obj->PreGetValue (this);
00227 
00228     if (GetTypeI() == INT)
00229       value = Int;
00230     else
00231       value = Vector[0]; 
00232     return true; 
00233   }
00234 
00236   bool GetValue (csRGBpixel& value)
00237   {
00238     if (accessor && accessor->obj)
00239       accessor->obj->PreGetValue (this);
00240 
00241     if (GetTypeI() == INT)
00242     {
00243       value.red = (unsigned char) csClamp (Int, 255, 0);
00244       value.green = (unsigned char) csClamp (Int, 255, 0);
00245       value.blue = (unsigned char) csClamp (Int, 255, 0);
00246       value.alpha = (unsigned char) csClamp (Int, 255, 0);
00247     }
00248     else
00249     {
00250       value.red = 
00251         (unsigned char) csClamp (int (Vector[0] * 255.0f), 255, 0);
00252       value.green = 
00253         (unsigned char) csClamp (int (Vector[1] * 255.0f), 255, 0);
00254       value.blue = 
00255         (unsigned char) csClamp (int (Vector[2] * 255.0f), 255, 0);
00256       value.alpha = 
00257         (unsigned char) csClamp (int (Vector[3] * 255.0f), 255, 0);
00258     }
00259     return true;
00260   }
00261 
00263   bool GetValue (iTextureHandle*& value)
00264   {
00265     if (accessor && accessor->obj)
00266       accessor->obj->PreGetValue (this);
00267 
00268     if (GetTypeI() != TEXTURE)
00269     {
00270       value = 0;
00271       return false;
00272     }
00273 
00274     value = texture.HandValue;
00275     if (!value && texture.WrapValue)
00276     {
00277       value = texture.HandValue = texture.WrapValue->GetTextureHandle ();
00278       if(value)
00279         value->IncRef();
00280     }
00281     return true;
00282   }
00283 
00285   bool GetValue (iTextureWrapper*& value)
00286   {
00287     if (accessor && accessor->obj)
00288       accessor->obj->PreGetValue (this);
00289 
00290     if (GetTypeI() != TEXTURE)
00291     {
00292       value = 0;
00293       return false;
00294     }
00295 
00296     value = texture.WrapValue;
00297     return true;
00298   }
00299 
00301   bool GetValue (iRenderBuffer*& value)
00302   {
00303     if (accessor && accessor->obj)
00304       accessor->obj->PreGetValue (this);
00305 
00306     value = RenderBuffer;
00307     return true;
00308   }
00309 
00311   bool GetValue (csVector2& value)
00312   {
00313     if (accessor && accessor->obj)
00314       accessor->obj->PreGetValue (this);
00315 
00316     if (GetTypeI() == INT)
00317       value.Set (Int, Int);
00318     else
00319       value.Set (Vector[0], Vector[1]);
00320     return true;
00321   }
00322 
00324   bool GetValue (csVector3& value)
00325   { 
00326     if (accessor && accessor->obj)
00327       accessor->obj->PreGetValue (this);
00328 
00329     if (GetTypeI() == INT)
00330       value.Set (Int, Int, Int);
00331     else
00332       value.Set (Vector[0], Vector[1], Vector[2]);
00333     return true; 
00334   }
00335 
00337   bool GetValue (csColor& value)
00338   { 
00339     if (accessor && accessor->obj)
00340       accessor->obj->PreGetValue (this);
00341 
00342     if (GetTypeI() == INT)
00343       value.Set (Int, Int, Int);
00344     else
00345       value.Set (Vector[0], Vector[1], Vector[2]);
00346     return true; 
00347   }
00348 
00350   bool GetValue (csVector4& value)
00351   { 
00352     if (accessor && accessor->obj)
00353       accessor->obj->PreGetValue (this);
00354 
00355     if (GetTypeI() == INT)
00356       value.Set (Int, Int, Int, Int);
00357     else
00358     {
00359       value.x = Vector[0]; 
00360       value.y = Vector[1]; 
00361       value.z = Vector[2]; 
00362       value.w = Vector[3]; 
00363     }
00364     return true; 
00365   }
00366 
00368   bool GetValue (csQuaternion& value)
00369   { 
00370     if (accessor && accessor->obj)
00371       accessor->obj->PreGetValue (this);
00372 
00373     if (GetTypeI() == INT)
00374       value.Set (Int, Int, Int, Int);
00375     else
00376       value.Set (Vector[0], Vector[1], Vector[2], Vector[3]);
00377     return true; 
00378   }
00379 
00381   bool GetValue (csMatrix3& value)
00382   {
00383     if (accessor && accessor->obj)
00384       accessor->obj->PreGetValue (this);
00385 
00386     if (GetTypeI() == MATRIX)
00387     {
00388       value = *MatrixValuePtr;
00389       return true;
00390     }
00391     
00392     value = csMatrix3();    
00393     return false;
00394   }
00395 
00397   bool GetValue (csReversibleTransform& value)
00398   {
00399     if (accessor && accessor->obj)
00400       accessor->obj->PreGetValue (this);
00401 
00402     if (GetTypeI() == TRANSFORM)
00403     {
00404       value = *TransformPtr;
00405       return true;
00406     }
00407     
00408     value = csReversibleTransform();    
00409     return false;
00410   }
00411 
00413   bool GetValue (CS::Math::Matrix4& value)
00414   {
00415     if (accessor && accessor->obj)
00416       accessor->obj->PreGetValue (this);
00417 
00418     if (GetTypeI() == MATRIX4X4)
00419     {
00420       value = *Matrix4ValuePtr;
00421       return true;
00422     }
00423     else if (GetTypeI() == MATRIX3X3)
00424     {
00425       value = *MatrixValuePtr;
00426       return true;
00427     }
00428     else if (GetTypeI() == TRANSFORM)
00429     {
00430       value = *TransformPtr;
00431       return true;
00432     }
00433     
00434     value = CS::Math::Matrix4();    
00435     return false;
00436   }
00437 
00438 
00440   bool SetValue (int value) 
00441   { 
00442     if (GetTypeI() != INT)
00443       NewType (INT);
00444 
00445     Int = value; 
00446     return true; 
00447   }
00448 
00450   bool SetValue (float value)
00451   { 
00452     if (GetTypeI() != FLOAT)
00453       NewType (FLOAT);
00454 
00455     Vector[0] = value;
00456     Vector[1] = value;
00457     Vector[2] = value;
00458     Vector[3] = value;
00459     return true; 
00460   }
00461 
00463   bool SetValue (const csRGBpixel &value)
00464   {    
00465     if (GetTypeI() != COLOR)
00466       NewType (COLOR);
00467 
00468     Vector[0] = (float)value.red / 255.0f;
00469     Vector[1] = (float)value.green / 255.0f;
00470     Vector[2] = (float)value.blue / 255.0f;
00471     Vector[3] = (float)value.alpha / 255.0f;
00472     return true;
00473   }
00474 
00476   bool SetValue (iTextureHandle* value)
00477   {    
00478     if (GetTypeI() != TEXTURE)
00479     {
00480       NewType (TEXTURE);
00481       texture.WrapValue = 0;
00482     }
00483     else
00484     {
00485       if (texture.HandValue)
00486         texture.HandValue->DecRef();
00487     }
00488     texture.HandValue = value;
00489     
00490     if (value)
00491       value->IncRef ();
00492     return true;
00493   }
00494 
00496   bool SetValue (iTextureWrapper* value)
00497   {    
00498     if (GetTypeI() != TEXTURE)
00499     {
00500       NewType (TEXTURE);
00501       texture.HandValue = 0;
00502     }
00503     else
00504     {
00505       if (texture.WrapValue)
00506         texture.WrapValue->DecRef();
00507     }
00508     
00509     texture.WrapValue = value;
00510     
00511     if (value)
00512       value->IncRef ();
00513     return true;
00514   }
00515 
00517   bool SetValue (iRenderBuffer* value)
00518   {    
00519     if (GetTypeI() != RENDERBUFFER)
00520       NewType (RENDERBUFFER);
00521     else
00522     {
00523       if (RenderBuffer)
00524         RenderBuffer ->DecRef();
00525     }
00526     RenderBuffer = value;
00527     
00528     if (value)
00529       value->IncRef ();
00530     return true;
00531   }
00532 
00534   bool SetValue (const csVector2 &value)
00535   {
00536     if (GetTypeI() != VECTOR2)
00537       NewType (VECTOR2);
00538     
00539     Vector[0] = value.x;
00540     Vector[1] = value.y;
00541     Vector[2] = 0.0f;
00542     Vector[3] = 1.0f;
00543     return true;
00544   }
00545 
00547   bool SetValue (const csVector3 &value)
00548   { 
00549     if (GetTypeI() != VECTOR3)
00550       NewType (VECTOR3);
00551 
00552     Vector[0] = value.x;
00553     Vector[1] = value.y;
00554     Vector[2] = value.z;
00555     Vector[3] = 1.0f;
00556     return true; 
00557   }
00558 
00560   bool SetValue (const csColor& value)
00561   { 
00562     if (GetTypeI() != VECTOR3)
00563       NewType (VECTOR3);
00564 
00565     Vector[0] = value.red;
00566     Vector[1] = value.green;
00567     Vector[2] = value.blue;
00568     Vector[3] = 1.0f;
00569     return true; 
00570   }
00571 
00573   bool SetValue (const csColor4& value)
00574   { 
00575     if (GetTypeI() != VECTOR4)
00576       NewType (VECTOR4);
00577 
00578     Vector[0] = value.red;
00579     Vector[1] = value.green;
00580     Vector[2] = value.blue;
00581     Vector[3] = value.alpha;
00582     return true; 
00583   }
00584 
00586   bool SetValue (const csVector4 &value)
00587   { 
00588     if (GetTypeI() != VECTOR4)
00589       NewType (VECTOR4);
00590 
00591     Vector[0] = value.x;
00592     Vector[1] = value.y;
00593     Vector[2] = value.z;
00594     Vector[3] = value.w;
00595     return true; 
00596   }
00597 
00598   bool SetValue (const csQuaternion& value)
00599   {
00600     if (GetTypeI() != VECTOR4)
00601       NewType (VECTOR4);
00602 
00603     Vector[0] = value.v.x;
00604     Vector[1] = value.v.y;
00605     Vector[2] = value.v.z;
00606     Vector[3] = value.w;
00607     return true;
00608   }
00609 
00611   bool SetValue (const csMatrix3 &value)
00612   {
00613     if (GetTypeI() != MATRIX)
00614       NewType (MATRIX);
00615 
00616     *MatrixValuePtr = value;
00617         
00618     return true;
00619   }
00620 
00622   bool SetValue (const csReversibleTransform &value)
00623   {
00624     if (GetTypeI() != TRANSFORM)
00625       NewType (TRANSFORM);
00626 
00627     *TransformPtr = value;
00628    
00629     return true;
00630   }
00631 
00633   bool SetValue (const CS::Math::Matrix4& value)
00634   {
00635     if (GetTypeI() != MATRIX4X4)
00636       NewType (MATRIX4X4);
00637 
00638     *Matrix4ValuePtr = value;
00639         
00640     return true;
00641   }
00642   
00643   void AddVariableToArray (csShaderVariable *variable)
00644   {
00645     if (GetTypeI() == ARRAY) 
00646       ShaderVarArray->Push (variable);
00647   }
00648 
00649   void RemoveFromArray (size_t element)
00650   {
00651     if (GetTypeI() == ARRAY) 
00652       ShaderVarArray->DeleteIndex (element);
00653   }
00654 
00656   void SetArraySize (size_t size)
00657   {
00658     if (GetTypeI() != ARRAY)
00659       NewType (ARRAY);
00660 
00661     ShaderVarArray->SetSize (size);
00662   }
00663 
00665   size_t GetArraySize ()
00666   {
00667     return (GetTypeI() == ARRAY) ? ShaderVarArray->GetSize () : 0;
00668   }
00669 
00675   csShaderVariable *GetArrayElement (size_t element)
00676   {
00677     if (GetTypeI() == ARRAY && element < ShaderVarArray->GetSize ())
00678     {
00679       return ShaderVarArray->Get (element);
00680     }
00681     return 0;
00682   }
00683 
00687   void SetArrayElement (size_t element, csShaderVariable *variable)
00688   {
00689     if (GetTypeI() != ARRAY) NewType (ARRAY);
00690     ShaderVarArray->Put (element, variable);
00691   }
00692 
00697   size_t FindArrayElement (const csRef<csShaderVariable>& sv) 
00698   { 
00699     if ((GetTypeI() != ARRAY) || (ShaderVarArray == 0))
00700       return csArrayItemNotFound; 
00701     else 
00702       return ShaderVarArray->Find (sv); 
00703   } 
00704 
00705 private:
00706   enum { nameMask = 0xffffff, typeShift = 24 };
00707   uint32 nameAndType;
00708   VariableType GetTypeI() const
00709   { return (VariableType)(nameAndType >> typeShift); }
00710 
00711   // Storage for types that can be combined..
00712   typedef csRefArray<csShaderVariable,
00713     CS::Memory::LocalBufferAllocatorUnchecked<csShaderVariable*, 8,
00714       CS::Memory::AllocatorMalloc, true>,
00715     csArrayCapacityFixedGrow<8> > SvArrayType;
00716   union
00717   {
00718     // Refcounted
00719     struct
00720     {
00721       iTextureHandle* HandValue;
00722       iTextureWrapper* WrapValue;
00723     } texture;    
00724     iRenderBuffer* RenderBuffer;
00725 
00726     int Int;
00727     float Vector[4];
00728     csMatrix3* MatrixValuePtr;
00729     CS::Math::Matrix4* Matrix4ValuePtr;
00730     csReversibleTransform* TransformPtr;
00731     SvArrayType* ShaderVarArray;
00732   };
00733 
00734   struct AccessorValues
00735   {
00736     csRef<iShaderVariableAccessor> obj;
00737     intptr_t data;
00738 
00739     AccessorValues() : data (0) {}
00740   };
00741   AccessorValues* accessor;
00742 
00743   CS_DECLARE_STATIC_CLASSVAR (matrixAlloc, MatrixAlloc,
00744     CS::Memory::BlockAllocatorSafe<csMatrix3>)
00745   CS_DECLARE_STATIC_CLASSVAR (matrix4Alloc, Matrix4Alloc,
00746     CS::Memory::BlockAllocatorSafe<CS::Math::Matrix4>)
00747   CS_DECLARE_STATIC_CLASSVAR (transformAlloc, TransformAlloc,
00748     CS::Memory::BlockAllocatorSafe<csReversibleTransform>)
00749   CS_DECLARE_STATIC_CLASSVAR (arrayAlloc, ShaderVarArrayAlloc,
00750     CS::Memory::BlockAllocatorSafe<SvArrayType>)
00751   CS_DECLARE_STATIC_CLASSVAR (accessorAlloc, AccessorValuesAlloc,
00752     CS::Memory::BlockAllocatorSafe<AccessorValues>)
00753 
00754   virtual void NewType (VariableType nt);
00755   virtual void AllocAccessor (const AccessorValues& other = AccessorValues());
00756   virtual void FreeAccessor ();
00757 };
00758 
00759 namespace CS
00760 {
00762   struct ShaderVarName
00763   {
00764     ShaderVarStringID name;
00765     
00766     ShaderVarName() : name (InvalidShaderVarStringID) {}
00767     ShaderVarName (iStringSetBase<StringSetTag::ShaderVar>* strings,
00768       const char* name) : name (strings->Request (name)) { }
00769     
00770     operator ShaderVarStringID () const { return name; }
00771   };
00772   
00773 } // namespace CS
00774 
00777 #endif

Generated for Crystal Space 2.0 by doxygen 1.7.6.1