csgfx/shadervar.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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