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.6.1