gfxShader.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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. mInstancingFormat( NULL )
  34. {
  35. }
  36. GFXShader::~GFXShader()
  37. {
  38. Torque::FS::RemoveChangeNotification( mVertexFile, this, &GFXShader::_onFileChanged );
  39. Torque::FS::RemoveChangeNotification( mPixelFile, this, &GFXShader::_onFileChanged );
  40. SAFE_DELETE(mInstancingFormat);
  41. }
  42. #ifndef TORQUE_OPENGL
  43. bool GFXShader::init( const Torque::Path &vertFile,
  44. const Torque::Path &pixFile,
  45. F32 pixVersion,
  46. const Vector<GFXShaderMacro> &macros )
  47. {
  48. Vector<String> samplerNames;
  49. return init( vertFile, pixFile, pixVersion, macros, samplerNames );
  50. }
  51. #endif
  52. bool GFXShader::init( const Torque::Path &vertFile,
  53. const Torque::Path &pixFile,
  54. F32 pixVersion,
  55. const Vector<GFXShaderMacro> &macros,
  56. const Vector<String> &samplerNames,
  57. GFXVertexFormat *instanceFormat)
  58. {
  59. // Take care of instancing
  60. if (instanceFormat)
  61. {
  62. mInstancingFormat = new GFXVertexFormat;
  63. mInstancingFormat->copy(*instanceFormat);
  64. }
  65. // Store the inputs for use in reloading.
  66. mVertexFile = vertFile;
  67. mPixelFile = pixFile;
  68. mPixVersion = pixVersion;
  69. mMacros = macros;
  70. mSamplerNamesOrdered = samplerNames;
  71. // Before we compile the shader make sure the
  72. // conditioner features have been updated.
  73. ConditionerFeature::updateConditioners();
  74. // Now do the real initialization.
  75. if ( !_init() )
  76. return false;
  77. _updateDesc();
  78. // Add file change notifications for reloads.
  79. Torque::FS::AddChangeNotification( mVertexFile, this, &GFXShader::_onFileChanged );
  80. Torque::FS::AddChangeNotification( mPixelFile, this, &GFXShader::_onFileChanged );
  81. return true;
  82. }
  83. bool GFXShader::reload()
  84. {
  85. // Before we compile the shader make sure the
  86. // conditioner features have been updated.
  87. ConditionerFeature::updateConditioners();
  88. mReloadKey++;
  89. // Init does the work.
  90. bool success = _init();
  91. if ( success )
  92. _updateDesc();
  93. // Let anything that cares know that
  94. // this shader has reloaded
  95. mReloadSignal.trigger();
  96. return success;
  97. }
  98. void GFXShader::_updateDesc()
  99. {
  100. mDescription = String::ToString( "Files: %s, %s Pix Version: %0.2f\nMacros: ",
  101. mVertexFile.getFullPath().c_str(), mPixelFile.getFullPath().c_str(), mPixVersion );
  102. GFXShaderMacro::stringize( smGlobalMacros, &mDescription );
  103. GFXShaderMacro::stringize( mMacros, &mDescription );
  104. }
  105. void GFXShader::addGlobalMacro( const String &name, const String &value )
  106. {
  107. // Check to see if we already have this macro.
  108. Vector<GFXShaderMacro>::iterator iter = smGlobalMacros.begin();
  109. for ( ; iter != smGlobalMacros.end(); iter++ )
  110. {
  111. if ( iter->name == name )
  112. {
  113. if ( iter->value != value )
  114. iter->value = value;
  115. return;
  116. }
  117. }
  118. // Add a new macro.
  119. smGlobalMacros.increment();
  120. smGlobalMacros.last().name = name;
  121. smGlobalMacros.last().value = value;
  122. }
  123. bool GFXShader::removeGlobalMacro( const String &name )
  124. {
  125. Vector<GFXShaderMacro>::iterator iter = smGlobalMacros.begin();
  126. for ( ; iter != smGlobalMacros.end(); iter++ )
  127. {
  128. if ( iter->name == name )
  129. {
  130. smGlobalMacros.erase( iter );
  131. return true;
  132. }
  133. }
  134. return false;
  135. }
  136. void GFXShader::_unlinkBuffer( GFXShaderConstBuffer *buf )
  137. {
  138. Vector<GFXShaderConstBuffer*>::iterator iter = mActiveBuffers.begin();
  139. for ( ; iter != mActiveBuffers.end(); iter++ )
  140. {
  141. if ( *iter == buf )
  142. {
  143. mActiveBuffers.erase_fast( iter );
  144. return;
  145. }
  146. }
  147. AssertFatal( false, "GFXShader::_unlinkBuffer - buffer was not found?" );
  148. }
  149. DefineEngineFunction( addGlobalShaderMacro, void,
  150. ( const char *name, const char *value ), ( nullAsType<const char*>() ),
  151. "Adds a global shader macro which will be merged with the script defined "
  152. "macros on every shader. The macro will replace the value of an existing "
  153. "macro of the same name. For the new macro to take effect all the shaders "
  154. "in the system need to be reloaded.\n"
  155. "@see resetLightManager, removeGlobalShaderMacro\n"
  156. "@ingroup Rendering\n" )
  157. {
  158. GFXShader::addGlobalMacro( name, value );
  159. }
  160. DefineEngineFunction( removeGlobalShaderMacro, void, ( const char *name ),,
  161. "Removes an existing global macro by name.\n"
  162. "@see addGlobalShaderMacro\n"
  163. "@ingroup Rendering\n" )
  164. {
  165. GFXShader::removeGlobalMacro( name );
  166. }