gfxShader.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "gfx/gfxShader.h"
  24. #include "shaderGen/conditionerFeature.h"
  25. #include "core/volume.h"
  26. #include "console/engineAPI.h"
  27. Vector<GFXShaderMacro> GFXShader::smGlobalMacros;
  28. bool GFXShader::smLogErrors = true;
  29. bool GFXShader::smLogWarnings = true;
  30. GFXShader::GFXShader()
  31. : mPixVersion( 0.0f ),
  32. mReloadKey( 0 )
  33. {
  34. }
  35. GFXShader::~GFXShader()
  36. {
  37. Torque::FS::RemoveChangeNotification( mVertexFile, this, &GFXShader::_onFileChanged );
  38. Torque::FS::RemoveChangeNotification( mPixelFile, this, &GFXShader::_onFileChanged );
  39. }
  40. #ifndef TORQUE_OPENGL
  41. bool GFXShader::init( const Torque::Path &vertFile,
  42. const Torque::Path &pixFile,
  43. F32 pixVersion,
  44. const Vector<GFXShaderMacro> &macros )
  45. {
  46. Vector<String> samplerNames;
  47. return init( vertFile, pixFile, pixVersion, macros, samplerNames );
  48. }
  49. #endif
  50. bool GFXShader::init( const Torque::Path &vertFile,
  51. const Torque::Path &pixFile,
  52. F32 pixVersion,
  53. const Vector<GFXShaderMacro> &macros,
  54. const Vector<String> &samplerNames)
  55. {
  56. // Store the inputs for use in reloading.
  57. mVertexFile = vertFile;
  58. mPixelFile = pixFile;
  59. mPixVersion = pixVersion;
  60. mMacros = macros;
  61. mSamplerNamesOrdered = samplerNames;
  62. // Before we compile the shader make sure the
  63. // conditioner features have been updated.
  64. ConditionerFeature::updateConditioners();
  65. // Now do the real initialization.
  66. if ( !_init() )
  67. return false;
  68. _updateDesc();
  69. // Add file change notifications for reloads.
  70. Torque::FS::AddChangeNotification( mVertexFile, this, &GFXShader::_onFileChanged );
  71. Torque::FS::AddChangeNotification( mPixelFile, this, &GFXShader::_onFileChanged );
  72. return true;
  73. }
  74. bool GFXShader::reload()
  75. {
  76. // Before we compile the shader make sure the
  77. // conditioner features have been updated.
  78. ConditionerFeature::updateConditioners();
  79. mReloadKey++;
  80. // Init does the work.
  81. bool success = _init();
  82. if ( success )
  83. _updateDesc();
  84. // Let anything that cares know that
  85. // this shader has reloaded
  86. mReloadSignal.trigger();
  87. return success;
  88. }
  89. void GFXShader::_updateDesc()
  90. {
  91. mDescription = String::ToString( "Files: %s, %s Pix Version: %0.2f\nMacros: ",
  92. mVertexFile.getFullPath().c_str(), mPixelFile.getFullPath().c_str(), mPixVersion );
  93. GFXShaderMacro::stringize( smGlobalMacros, &mDescription );
  94. GFXShaderMacro::stringize( mMacros, &mDescription );
  95. }
  96. void GFXShader::addGlobalMacro( const String &name, const String &value )
  97. {
  98. // Check to see if we already have this macro.
  99. Vector<GFXShaderMacro>::iterator iter = smGlobalMacros.begin();
  100. for ( ; iter != smGlobalMacros.end(); iter++ )
  101. {
  102. if ( iter->name == name )
  103. {
  104. if ( iter->value != value )
  105. iter->value = value;
  106. return;
  107. }
  108. }
  109. // Add a new macro.
  110. smGlobalMacros.increment();
  111. smGlobalMacros.last().name = name;
  112. smGlobalMacros.last().value = value;
  113. }
  114. bool GFXShader::removeGlobalMacro( const String &name )
  115. {
  116. Vector<GFXShaderMacro>::iterator iter = smGlobalMacros.begin();
  117. for ( ; iter != smGlobalMacros.end(); iter++ )
  118. {
  119. if ( iter->name == name )
  120. {
  121. smGlobalMacros.erase( iter );
  122. return true;
  123. }
  124. }
  125. return false;
  126. }
  127. void GFXShader::_unlinkBuffer( GFXShaderConstBuffer *buf )
  128. {
  129. Vector<GFXShaderConstBuffer*>::iterator iter = mActiveBuffers.begin();
  130. for ( ; iter != mActiveBuffers.end(); iter++ )
  131. {
  132. if ( *iter == buf )
  133. {
  134. mActiveBuffers.erase_fast( iter );
  135. return;
  136. }
  137. }
  138. AssertFatal( false, "GFXShader::_unlinkBuffer - buffer was not found?" );
  139. }
  140. DefineEngineFunction( addGlobalShaderMacro, void,
  141. ( const char *name, const char *value ), ( NULL ),
  142. "Adds a global shader macro which will be merged with the script defined "
  143. "macros on every shader. The macro will replace the value of an existing "
  144. "macro of the same name. For the new macro to take effect all the shaders "
  145. "in the system need to be reloaded.\n"
  146. "@see resetLightManager, removeGlobalShaderMacro\n"
  147. "@ingroup Rendering\n" )
  148. {
  149. GFXShader::addGlobalMacro( name, value );
  150. }
  151. DefineEngineFunction( removeGlobalShaderMacro, void, ( const char *name ),,
  152. "Removes an existing global macro by name.\n"
  153. "@see addGlobalShaderMacro\n"
  154. "@ingroup Rendering\n" )
  155. {
  156. GFXShader::removeGlobalMacro( name );
  157. }