00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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 }
00059
00061 typedef StringID<StringSetTag::ShaderVar> ShaderVarStringID;
00063 ShaderVarStringID const InvalidShaderVarStringID =
00064 InvalidStringID<StringSetTag::ShaderVar> ();
00065 }
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
00157
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
00712 typedef csRefArray<csShaderVariable,
00713 CS::Memory::LocalBufferAllocatorUnchecked<csShaderVariable*, 8,
00714 CS::Memory::AllocatorMalloc, true>,
00715 csArrayCapacityFixedGrow<8> > SvArrayType;
00716 union
00717 {
00718
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 }
00774
00777 #endif