gfxGLShader.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929
  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/gl/gfxGLShader.h"
  24. #include "core/frameAllocator.h"
  25. #include "core/stream/fileStream.h"
  26. #include "core/strings/stringFunctions.h"
  27. #include "math/mPoint2.h"
  28. #include "gfx/gfxStructs.h"
  29. #include "console/console.h"
  30. class GFXGLShaderConstHandle : public GFXShaderConstHandle
  31. {
  32. friend class GFXGLShader;
  33. public:
  34. GFXGLShaderConstHandle( GFXGLShader *shader );
  35. GFXGLShaderConstHandle( GFXGLShader *shader, const GFXShaderConstDesc &desc, GLuint loc, S32 samplerNum );
  36. virtual ~GFXGLShaderConstHandle();
  37. void reinit( const GFXShaderConstDesc &desc, GLuint loc, S32 samplerNum );
  38. const String& getName() const { return mDesc.name; }
  39. GFXShaderConstType getType() const { return mDesc.constType; }
  40. U32 getArraySize() const { return mDesc.arraySize; }
  41. U32 getSize() const;
  42. void setValid( bool valid ) { mValid = valid; }
  43. /// @warning This will always return the value assigned when the shader was
  44. /// initialized. If the value is later changed this method won't reflect that.
  45. S32 getSamplerRegister() const { return mSamplerNum; }
  46. GFXShaderConstDesc mDesc;
  47. GFXGLShader* mShader;
  48. GLuint mLocation;
  49. U32 mOffset;
  50. U32 mSize;
  51. S32 mSamplerNum;
  52. };
  53. GFXGLShaderConstHandle::GFXGLShaderConstHandle( GFXGLShader *shader )
  54. : mShader( shader ), mSamplerNum(-1)
  55. {
  56. mValid = false;
  57. }
  58. static U32 shaderConstTypeSize(GFXShaderConstType type)
  59. {
  60. switch(type)
  61. {
  62. case GFXSCT_Float:
  63. case GFXSCT_Int:
  64. case GFXSCT_Sampler:
  65. case GFXSCT_SamplerCube:
  66. return 4;
  67. case GFXSCT_Float2:
  68. case GFXSCT_Int2:
  69. return 8;
  70. case GFXSCT_Float3:
  71. case GFXSCT_Int3:
  72. return 12;
  73. case GFXSCT_Float4:
  74. case GFXSCT_Int4:
  75. return 16;
  76. case GFXSCT_Float2x2:
  77. return 16;
  78. case GFXSCT_Float3x3:
  79. return 36;
  80. case GFXSCT_Float4x4:
  81. return 64;
  82. default:
  83. AssertFatal(false,"shaderConstTypeSize - Unrecognized constant type");
  84. return 0;
  85. }
  86. }
  87. GFXGLShaderConstHandle::GFXGLShaderConstHandle( GFXGLShader *shader, const GFXShaderConstDesc &desc, GLuint loc, S32 samplerNum )
  88. : mShader(shader)
  89. {
  90. reinit(desc, loc, samplerNum);
  91. }
  92. void GFXGLShaderConstHandle::reinit( const GFXShaderConstDesc& desc, GLuint loc, S32 samplerNum )
  93. {
  94. mDesc = desc;
  95. mLocation = loc;
  96. mSamplerNum = samplerNum;
  97. mOffset = 0;
  98. U32 elemSize = shaderConstTypeSize(mDesc.constType);
  99. AssertFatal(elemSize, "GFXGLShaderConst::GFXGLShaderConst - elemSize is 0");
  100. mSize = mDesc.arraySize * elemSize;
  101. mValid = true;
  102. }
  103. U32 GFXGLShaderConstHandle::getSize() const
  104. {
  105. return mSize;
  106. }
  107. GFXGLShaderConstHandle::~GFXGLShaderConstHandle()
  108. {
  109. }
  110. GFXGLShaderConstBuffer::GFXGLShaderConstBuffer(GFXGLShader* shader, U32 bufSize, U8* existingConstants)
  111. {
  112. mShader = shader;
  113. mBuffer = new U8[bufSize];
  114. mWasLost = true;
  115. // Copy the existing constant buffer to preserve sampler numbers
  116. /// @warning This preserves a lot more than sampler numbers, obviously. If there
  117. /// is any code that assumes a new constant buffer will have everything set to
  118. /// 0, it will break.
  119. dMemcpy(mBuffer, existingConstants, bufSize);
  120. }
  121. GFXGLShaderConstBuffer::~GFXGLShaderConstBuffer()
  122. {
  123. delete[] mBuffer;
  124. if ( mShader )
  125. mShader->_unlinkBuffer( this );
  126. }
  127. template<typename ConstType>
  128. void GFXGLShaderConstBuffer::internalSet(GFXShaderConstHandle* handle, const ConstType& param)
  129. {
  130. AssertFatal(handle, "GFXGLShaderConstBuffer::internalSet - Handle is NULL!" );
  131. AssertFatal(handle->isValid(), "GFXGLShaderConstBuffer::internalSet - Handle is not valid!" );
  132. AssertFatal(dynamic_cast<GFXGLShaderConstHandle*>(handle), "GFXGLShaderConstBuffer::set - Incorrect const buffer type");
  133. GFXGLShaderConstHandle* _glHandle = static_cast<GFXGLShaderConstHandle*>(handle);
  134. AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
  135. dMemcpy(mBuffer + _glHandle->mOffset, &param, sizeof(ConstType));
  136. }
  137. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const F32 fv)
  138. {
  139. internalSet(handle, fv);
  140. }
  141. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point2F& fv)
  142. {
  143. internalSet(handle, fv);
  144. }
  145. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point3F& fv)
  146. {
  147. internalSet(handle, fv);
  148. }
  149. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point4F& fv)
  150. {
  151. internalSet(handle, fv);
  152. }
  153. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const PlaneF& fv)
  154. {
  155. internalSet(handle, fv);
  156. }
  157. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const ColorF& fv)
  158. {
  159. internalSet(handle, fv);
  160. }
  161. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const S32 fv)
  162. {
  163. internalSet(handle, fv);
  164. }
  165. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point2I& fv)
  166. {
  167. internalSet(handle, fv);
  168. }
  169. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point3I& fv)
  170. {
  171. internalSet(handle, fv);
  172. }
  173. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point4I& fv)
  174. {
  175. internalSet(handle, fv);
  176. }
  177. template<typename ConstType>
  178. void GFXGLShaderConstBuffer::internalSet(GFXShaderConstHandle* handle, const AlignedArray<ConstType>& fv)
  179. {
  180. AssertFatal(handle, "GFXGLShaderConstBuffer::internalSet - Handle is NULL!" );
  181. AssertFatal(handle->isValid(), "GFXGLShaderConstBuffer::internalSet - Handle is not valid!" );
  182. AssertFatal(dynamic_cast<GFXGLShaderConstHandle*>(handle), "GFXGLShaderConstBuffer::set - Incorrect const buffer type");
  183. GFXGLShaderConstHandle* _glHandle = static_cast<GFXGLShaderConstHandle*>(handle);
  184. AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
  185. const U8* fvBuffer = static_cast<const U8*>(fv.getBuffer());
  186. for(U32 i = 0; i < fv.size(); ++i)
  187. {
  188. dMemcpy(mBuffer + _glHandle->mOffset + i * sizeof(ConstType), fvBuffer, sizeof(ConstType));
  189. fvBuffer += fv.getElementSize();
  190. }
  191. }
  192. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<F32>& fv)
  193. {
  194. internalSet(handle, fv);
  195. }
  196. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point2F>& fv)
  197. {
  198. internalSet(handle, fv);
  199. }
  200. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point3F>& fv)
  201. {
  202. internalSet(handle, fv);
  203. }
  204. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point4F>& fv)
  205. {
  206. internalSet(handle, fv);
  207. }
  208. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<S32>& fv)
  209. {
  210. internalSet(handle, fv);
  211. }
  212. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point2I>& fv)
  213. {
  214. internalSet(handle, fv);
  215. }
  216. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point3I>& fv)
  217. {
  218. internalSet(handle, fv);
  219. }
  220. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point4I>& fv)
  221. {
  222. internalSet(handle, fv);
  223. }
  224. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF& mat, const GFXShaderConstType matType)
  225. {
  226. AssertFatal(handle, "GFXGLShaderConstBuffer::set - Handle is NULL!" );
  227. AssertFatal(handle->isValid(), "GFXGLShaderConstBuffer::set - Handle is not valid!" );
  228. AssertFatal(dynamic_cast<GFXGLShaderConstHandle*>(handle), "GFXGLShaderConstBuffer::set - Incorrect const buffer type");
  229. GFXGLShaderConstHandle* _glHandle = static_cast<GFXGLShaderConstHandle*>(handle);
  230. AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
  231. switch(matType)
  232. {
  233. case GFXSCT_Float2x2:
  234. reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[0] = mat[0];
  235. reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[1] = mat[1];
  236. reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[2] = mat[4];
  237. reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[3] = mat[5];
  238. break;
  239. case GFXSCT_Float3x3:
  240. reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[0] = mat[0];
  241. reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[1] = mat[1];
  242. reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[2] = mat[2];
  243. reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[3] = mat[4];
  244. reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[4] = mat[5];
  245. reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[5] = mat[6];
  246. reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[6] = mat[8];
  247. reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[7] = mat[9];
  248. reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[8] = mat[10];
  249. break;
  250. case GFXSCT_Float4x4:
  251. dMemcpy(mBuffer + _glHandle->mOffset, (const F32*)mat, sizeof(MatrixF));
  252. break;
  253. default:
  254. AssertFatal(false, "GFXGLShaderConstBuffer::set - Invalid matrix type");
  255. break;
  256. }
  257. }
  258. void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType)
  259. {
  260. AssertFatal(handle, "GFXGLShaderConstBuffer::set - Handle is NULL!" );
  261. AssertFatal(handle->isValid(), "GFXGLShaderConstBuffer::set - Handle is not valid!" );
  262. GFXGLShaderConstHandle* _glHandle = static_cast<GFXGLShaderConstHandle*>(handle);
  263. AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
  264. switch (matrixType) {
  265. case GFXSCT_Float4x4:
  266. dMemcpy(mBuffer + _glHandle->mOffset, (F32*)mat, _glHandle->getSize());
  267. break;
  268. default:
  269. AssertFatal(false, "GFXGLShaderConstBuffer::set - setting array of non 4x4 matrices!");
  270. break;
  271. }
  272. }
  273. void GFXGLShaderConstBuffer::activate()
  274. {
  275. mShader->setConstantsFromBuffer(this);
  276. mWasLost = false;
  277. }
  278. const String GFXGLShaderConstBuffer::describeSelf() const
  279. {
  280. return String();
  281. }
  282. void GFXGLShaderConstBuffer::onShaderReload( GFXGLShader *shader )
  283. {
  284. AssertFatal( shader == mShader, "GFXGLShaderConstBuffer::onShaderReload, mismatched shaders!" );
  285. delete[] mBuffer;
  286. mBuffer = new U8[mShader->mConstBufferSize];
  287. dMemset(mBuffer, 0, mShader->mConstBufferSize);
  288. mWasLost = true;
  289. }
  290. GFXGLShader::GFXGLShader() :
  291. mVertexShader(0),
  292. mPixelShader(0),
  293. mProgram(0),
  294. mConstBufferSize(0),
  295. mConstBuffer(NULL)
  296. {
  297. }
  298. GFXGLShader::~GFXGLShader()
  299. {
  300. clearShaders();
  301. for(HandleMap::Iterator i = mHandles.begin(); i != mHandles.end(); i++)
  302. delete i->value;
  303. delete[] mConstBuffer;
  304. }
  305. void GFXGLShader::clearShaders()
  306. {
  307. glDeleteProgram(mProgram);
  308. glDeleteShader(mVertexShader);
  309. glDeleteShader(mPixelShader);
  310. mProgram = 0;
  311. mVertexShader = 0;
  312. mPixelShader = 0;
  313. }
  314. bool GFXGLShader::_init()
  315. {
  316. // Don't initialize empty shaders.
  317. if ( mVertexFile.isEmpty() && mPixelFile.isEmpty() )
  318. return false;
  319. clearShaders();
  320. mProgram = glCreateProgram();
  321. // Set the macros and add the global ones.
  322. Vector<GFXShaderMacro> macros;
  323. macros.merge( mMacros );
  324. macros.merge( smGlobalMacros );
  325. // Add the shader version to the macros.
  326. const U32 mjVer = (U32)mFloor( mPixVersion );
  327. const U32 mnVer = (U32)( ( mPixVersion - F32( mjVer ) ) * 10.01f );
  328. macros.increment();
  329. macros.last().name = "TORQUE_SM";
  330. macros.last().value = String::ToString( mjVer * 10 + mnVer );
  331. // Default to true so we're "successful" if a vertex/pixel shader wasn't specified.
  332. bool compiledVertexShader = true;
  333. bool compiledPixelShader = true;
  334. // Compile the vertex and pixel shaders if specified.
  335. if(!mVertexFile.isEmpty())
  336. compiledVertexShader = initShader(mVertexFile, true, macros);
  337. if(!mPixelFile.isEmpty())
  338. compiledPixelShader = initShader(mPixelFile, false, macros);
  339. // If either shader was present and failed to compile, bail.
  340. if(!compiledVertexShader || !compiledPixelShader)
  341. return false;
  342. // Link it!
  343. glLinkProgram( mProgram );
  344. GLint linkStatus;
  345. glGetProgramiv( mProgram, GL_LINK_STATUS, &linkStatus );
  346. // Dump the info log to the console
  347. U32 logLength = 0;
  348. glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, (GLint*)&logLength);
  349. if ( logLength )
  350. {
  351. FrameAllocatorMarker fam;
  352. char* log = (char*)fam.alloc( logLength );
  353. glGetProgramInfoLog( mProgram, logLength, NULL, log );
  354. if ( linkStatus == GL_FALSE )
  355. {
  356. if ( smLogErrors )
  357. {
  358. Con::errorf( "GFXGLShader::init - Error linking shader!" );
  359. Con::errorf( "Program %s / %s: %s",
  360. mVertexFile.getFullPath().c_str(), mPixelFile.getFullPath().c_str(), log);
  361. }
  362. }
  363. else if ( smLogWarnings )
  364. {
  365. Con::warnf( "Program %s / %s: %s",
  366. mVertexFile.getFullPath().c_str(), mPixelFile.getFullPath().c_str(), log);
  367. }
  368. }
  369. // If we failed to link, bail.
  370. if ( linkStatus == GL_FALSE )
  371. return false;
  372. initConstantDescs();
  373. initHandles();
  374. // Notify Buffers we might have changed in size.
  375. // If this was our first init then we won't have any activeBuffers
  376. // to worry about unnecessarily calling.
  377. Vector<GFXShaderConstBuffer*>::iterator biter = mActiveBuffers.begin();
  378. for ( ; biter != mActiveBuffers.end(); biter++ )
  379. ((GFXGLShaderConstBuffer*)(*biter))->onShaderReload( this );
  380. return true;
  381. }
  382. void GFXGLShader::initConstantDescs()
  383. {
  384. mConstants.clear();
  385. GLint numUniforms;
  386. glGetProgramiv(mProgram, GL_ACTIVE_UNIFORMS, &numUniforms);
  387. GLint maxNameLength;
  388. glGetProgramiv(mProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength);
  389. FrameTemp<GLchar> uniformName(maxNameLength);
  390. for(U32 i = 0; i < numUniforms; i++)
  391. {
  392. GLint size;
  393. GLenum type;
  394. glGetActiveUniform(mProgram, i, maxNameLength, NULL, &size, &type, uniformName);
  395. GFXShaderConstDesc desc;
  396. desc.name = String((char*)uniformName);
  397. // Remove array brackets from the name
  398. desc.name = desc.name.substr(0, desc.name.find('['));
  399. // Insert $ to match D3D behavior of having a $ prepended to parameters to main.
  400. desc.name.insert(0, '$');
  401. desc.arraySize = size;
  402. switch(type)
  403. {
  404. case GL_FLOAT:
  405. desc.constType = GFXSCT_Float;
  406. break;
  407. case GL_FLOAT_VEC2:
  408. desc.constType = GFXSCT_Float2;
  409. break;
  410. case GL_FLOAT_VEC3:
  411. desc.constType = GFXSCT_Float3;
  412. break;
  413. case GL_FLOAT_VEC4:
  414. desc.constType = GFXSCT_Float4;
  415. break;
  416. case GL_INT:
  417. desc.constType = GFXSCT_Int;
  418. break;
  419. case GL_INT_VEC2:
  420. desc.constType = GFXSCT_Int2;
  421. break;
  422. case GL_INT_VEC3:
  423. desc.constType = GFXSCT_Int3;
  424. break;
  425. case GL_INT_VEC4:
  426. desc.constType = GFXSCT_Int4;
  427. break;
  428. case GL_FLOAT_MAT2:
  429. desc.constType = GFXSCT_Float2x2;
  430. break;
  431. case GL_FLOAT_MAT3:
  432. desc.constType = GFXSCT_Float3x3;
  433. break;
  434. case GL_FLOAT_MAT4:
  435. desc.constType = GFXSCT_Float4x4;
  436. break;
  437. case GL_SAMPLER_1D:
  438. case GL_SAMPLER_2D:
  439. case GL_SAMPLER_3D:
  440. case GL_SAMPLER_1D_SHADOW:
  441. case GL_SAMPLER_2D_SHADOW:
  442. desc.constType = GFXSCT_Sampler;
  443. break;
  444. case GL_SAMPLER_CUBE:
  445. desc.constType = GFXSCT_SamplerCube;
  446. break;
  447. default:
  448. AssertFatal(false, "GFXGLShader::initConstantDescs - unrecognized uniform type");
  449. // If we don't recognize the constant don't add its description.
  450. continue;
  451. }
  452. mConstants.push_back(desc);
  453. }
  454. }
  455. void GFXGLShader::initHandles()
  456. {
  457. // Mark all existing handles as invalid.
  458. // Those that are found when parsing the descriptions will then be marked valid again.
  459. for ( HandleMap::Iterator iter = mHandles.begin(); iter != mHandles.end(); ++iter )
  460. (iter->value)->setValid( false );
  461. mValidHandles.clear();
  462. // Loop through all ConstantDescriptions,
  463. // if they aren't in the HandleMap add them, if they are reinitialize them.
  464. S32 assignedSamplerNum = 0;
  465. for ( U32 i = 0; i < mConstants.size(); i++ )
  466. {
  467. GFXShaderConstDesc &desc = mConstants[i];
  468. // Index element 1 of the name to skip the '$' we inserted earier.
  469. U32 loc = glGetUniformLocation(mProgram, &desc.name.c_str()[1]);
  470. HandleMap::Iterator handle = mHandles.find(desc.name);
  471. S32 sampler = (desc.constType == GFXSCT_Sampler || desc.constType == GFXSCT_SamplerCube) ?
  472. assignedSamplerNum++ : -1;
  473. if ( handle != mHandles.end() )
  474. {
  475. handle->value->reinit( desc, loc, sampler );
  476. }
  477. else
  478. {
  479. mHandles[desc.name] = new GFXGLShaderConstHandle( this, desc, loc, sampler );
  480. }
  481. }
  482. // Loop through handles once more to set their offset and calculate our
  483. // constBuffer size.
  484. if ( mConstBuffer )
  485. delete[] mConstBuffer;
  486. mConstBufferSize = 0;
  487. for ( HandleMap::Iterator iter = mHandles.begin(); iter != mHandles.end(); ++iter )
  488. {
  489. GFXGLShaderConstHandle* handle = iter->value;
  490. if ( handle->isValid() )
  491. {
  492. mValidHandles.push_back(handle);
  493. handle->mOffset = mConstBufferSize;
  494. mConstBufferSize += handle->getSize();
  495. }
  496. }
  497. mConstBuffer = new U8[mConstBufferSize];
  498. dMemset(mConstBuffer, 0, mConstBufferSize);
  499. // Set our program so uniforms are assigned properly.
  500. glUseProgram(mProgram);
  501. // Iterate through uniforms to set sampler numbers.
  502. for (HandleMap::Iterator iter = mHandles.begin(); iter != mHandles.end(); ++iter)
  503. {
  504. GFXGLShaderConstHandle* handle = iter->value;
  505. if(handle->isValid() && (handle->getType() == GFXSCT_Sampler || handle->getType() == GFXSCT_SamplerCube))
  506. {
  507. // Set sampler number on our program.
  508. glUniform1i(handle->mLocation, handle->mSamplerNum);
  509. // Set sampler in constant buffer so it does not get unset later.
  510. dMemcpy(mConstBuffer + handle->mOffset, &handle->mLocation, handle->getSize());
  511. }
  512. }
  513. glUseProgram(0);
  514. }
  515. GFXShaderConstHandle* GFXGLShader::getShaderConstHandle(const String& name)
  516. {
  517. HandleMap::Iterator i = mHandles.find(name);
  518. if(i != mHandles.end())
  519. return i->value;
  520. else
  521. {
  522. GFXGLShaderConstHandle* handle = new GFXGLShaderConstHandle( this );
  523. mHandles[ name ] = handle;
  524. return handle;
  525. }
  526. }
  527. void GFXGLShader::setConstantsFromBuffer(GFXGLShaderConstBuffer* buffer)
  528. {
  529. for(Vector<GFXGLShaderConstHandle*>::iterator i = mValidHandles.begin(); i != mValidHandles.end(); ++i)
  530. {
  531. GFXGLShaderConstHandle* handle = *i;
  532. AssertFatal(handle, "GFXGLShader::setConstantsFromBuffer - Null handle");
  533. // Don't set if the value has not be changed.
  534. if(dMemcmp(mConstBuffer + handle->mOffset, buffer->mBuffer + handle->mOffset, handle->getSize()) == 0)
  535. continue;
  536. // Copy new value into our const buffer and set in GL.
  537. dMemcpy(mConstBuffer + handle->mOffset, buffer->mBuffer + handle->mOffset, handle->getSize());
  538. switch(handle->mDesc.constType)
  539. {
  540. case GFXSCT_Float:
  541. glUniform1fv(handle->mLocation, handle->mDesc.arraySize, (GLfloat*)(mConstBuffer + handle->mOffset));
  542. break;
  543. case GFXSCT_Float2:
  544. glUniform2fv(handle->mLocation, handle->mDesc.arraySize, (GLfloat*)(mConstBuffer + handle->mOffset));
  545. break;
  546. case GFXSCT_Float3:
  547. glUniform3fv(handle->mLocation, handle->mDesc.arraySize, (GLfloat*)(mConstBuffer + handle->mOffset));
  548. break;
  549. case GFXSCT_Float4:
  550. glUniform4fv(handle->mLocation, handle->mDesc.arraySize, (GLfloat*)(mConstBuffer + handle->mOffset));
  551. break;
  552. case GFXSCT_Int:
  553. case GFXSCT_Sampler:
  554. case GFXSCT_SamplerCube:
  555. glUniform1iv(handle->mLocation, handle->mDesc.arraySize, (GLint*)(mConstBuffer + handle->mOffset));
  556. break;
  557. case GFXSCT_Int2:
  558. glUniform2iv(handle->mLocation, handle->mDesc.arraySize, (GLint*)(mConstBuffer + handle->mOffset));
  559. break;
  560. case GFXSCT_Int3:
  561. glUniform3iv(handle->mLocation, handle->mDesc.arraySize, (GLint*)(mConstBuffer + handle->mOffset));
  562. break;
  563. case GFXSCT_Int4:
  564. glUniform4iv(handle->mLocation, handle->mDesc.arraySize, (GLint*)(mConstBuffer + handle->mOffset));
  565. break;
  566. case GFXSCT_Float2x2:
  567. glUniformMatrix2fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset));
  568. break;
  569. case GFXSCT_Float3x3:
  570. glUniformMatrix3fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset));
  571. break;
  572. case GFXSCT_Float4x4:
  573. glUniformMatrix4fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset));
  574. break;
  575. }
  576. }
  577. }
  578. GFXShaderConstBufferRef GFXGLShader::allocConstBuffer()
  579. {
  580. GFXGLShaderConstBuffer* buffer = new GFXGLShaderConstBuffer(this, mConstBufferSize, mConstBuffer);
  581. buffer->registerResourceWithDevice(getOwningDevice());
  582. mActiveBuffers.push_back( buffer );
  583. return buffer;
  584. }
  585. void GFXGLShader::useProgram()
  586. {
  587. glUseProgram(mProgram);
  588. }
  589. void GFXGLShader::zombify()
  590. {
  591. clearShaders();
  592. dMemset(mConstBuffer, 0, mConstBufferSize);
  593. }
  594. char* GFXGLShader::_handleIncludes( const Torque::Path& path, FileStream *s )
  595. {
  596. // TODO: The #line pragma on GLSL takes something called a
  597. // "source-string-number" which it then never explains.
  598. //
  599. // Until i resolve this mystery i disabled this.
  600. //
  601. //String linePragma = String::ToString( "#line 1 \r\n");
  602. //U32 linePragmaLen = linePragma.length();
  603. U32 shaderLen = s->getStreamSize();
  604. char* buffer = (char*)dMalloc(shaderLen + 1);
  605. //dStrncpy( buffer, linePragma.c_str(), linePragmaLen );
  606. s->read(shaderLen, buffer);
  607. buffer[shaderLen] = 0;
  608. char* p = dStrstr(buffer, "#include");
  609. while(p)
  610. {
  611. char* q = p;
  612. p += 8;
  613. if(dIsspace(*p))
  614. {
  615. U32 n = 0;
  616. while(dIsspace(*p)) ++p;
  617. AssertFatal(*p == '"', "Bad #include directive");
  618. ++p;
  619. static char includeFile[256];
  620. while(*p != '"')
  621. {
  622. AssertFatal(*p != 0, "Bad #include directive");
  623. includeFile[n++] = *p++;
  624. AssertFatal(n < sizeof(includeFile), "#include directive too long");
  625. }
  626. ++p;
  627. includeFile[n] = 0;
  628. // First try it as a local file.
  629. Torque::Path includePath = Torque::Path::Join(path.getPath(), '/', includeFile);
  630. includePath = Torque::Path::CompressPath(includePath);
  631. FileStream includeStream;
  632. if ( !includeStream.open( includePath, Torque::FS::File::Read ) )
  633. {
  634. // Try again assuming the path is absolute
  635. // and/or relative.
  636. includePath = String( includeFile );
  637. includePath = Torque::Path::CompressPath(includePath);
  638. if ( !includeStream.open( includePath, Torque::FS::File::Read ) )
  639. {
  640. AssertISV(false, avar("failed to open include '%s'.", includePath.getFullPath().c_str()));
  641. if ( smLogErrors )
  642. Con::errorf( "GFXGLShader::_handleIncludes - Failed to open include '%s'.",
  643. includePath.getFullPath().c_str() );
  644. // Fail... don't return the buffer.
  645. dFree(buffer);
  646. return NULL;
  647. }
  648. }
  649. char* includedText = _handleIncludes(includePath, &includeStream);
  650. // If a sub-include fails... cleanup and return.
  651. if ( !includedText )
  652. {
  653. dFree(buffer);
  654. return NULL;
  655. }
  656. // TODO: Disabled till this is fixed correctly.
  657. //
  658. // Count the number of lines in the file
  659. // before the include.
  660. /*
  661. U32 includeLine = 0;
  662. {
  663. char* nl = dStrstr( buffer, "\n" );
  664. while ( nl )
  665. {
  666. includeLine++;
  667. nl = dStrstr( nl, "\n" );
  668. if(nl) ++nl;
  669. }
  670. }
  671. */
  672. String manip(buffer);
  673. manip.erase(q-buffer, p-q);
  674. String sItx(includedText);
  675. // TODO: Disabled till this is fixed correctly.
  676. //
  677. // Add a new line pragma to restore the proper
  678. // file and line number after the include.
  679. //sItx += String::ToString( "\r\n#line %d \r\n", includeLine );
  680. dFree(includedText);
  681. manip.insert(q-buffer, sItx);
  682. char* manipBuf = dStrdup(manip.c_str());
  683. p = manipBuf + (p - buffer);
  684. dFree(buffer);
  685. buffer = manipBuf;
  686. }
  687. p = dStrstr(p, "#include");
  688. }
  689. return buffer;
  690. }
  691. bool GFXGLShader::_loadShaderFromStream( GLuint shader,
  692. const Torque::Path &path,
  693. FileStream *s,
  694. const Vector<GFXShaderMacro> &macros )
  695. {
  696. Vector<char*> buffers;
  697. Vector<U32> lengths;
  698. // The GLSL version declaration must go first!
  699. const char *versionDecl = "#version 120\r\n\r\n";
  700. buffers.push_back( dStrdup( versionDecl ) );
  701. lengths.push_back( dStrlen( versionDecl ) );
  702. // Now add all the macros.
  703. for( U32 i = 0; i < macros.size(); i++ )
  704. {
  705. String define = String::ToString( "#define %s %s\n", macros[i].name.c_str(), macros[i].value.c_str() );
  706. buffers.push_back( dStrdup( define.c_str() ) );
  707. lengths.push_back( define.length() );
  708. }
  709. // Now finally add the shader source.
  710. U32 shaderLen = s->getStreamSize();
  711. char *buffer = _handleIncludes(path, s);
  712. if ( !buffer )
  713. return false;
  714. buffers.push_back(buffer);
  715. lengths.push_back(shaderLen);
  716. glShaderSource(shader, buffers.size(), (const GLchar**)const_cast<const char**>(buffers.address()), NULL);
  717. // Cleanup the shader source buffer.
  718. for ( U32 i=0; i < buffers.size(); i++ )
  719. dFree( buffers[i] );
  720. glCompileShader(shader);
  721. return true;
  722. }
  723. bool GFXGLShader::initShader( const Torque::Path &file,
  724. bool isVertex,
  725. const Vector<GFXShaderMacro> &macros )
  726. {
  727. GLuint activeShader = glCreateShader(isVertex ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER);
  728. if(isVertex)
  729. mVertexShader = activeShader;
  730. else
  731. mPixelShader = activeShader;
  732. glAttachShader(mProgram, activeShader);
  733. // Ok it's not in the shader gen manager, so ask Torque for it
  734. FileStream stream;
  735. if ( !stream.open( file, Torque::FS::File::Read ) )
  736. {
  737. AssertISV(false, avar("GFXGLShader::initShader - failed to open shader '%s'.", file.getFullPath().c_str()));
  738. if ( smLogErrors )
  739. Con::errorf( "GFXGLShader::initShader - Failed to open shader file '%s'.",
  740. file.getFullPath().c_str() );
  741. return false;
  742. }
  743. if ( !_loadShaderFromStream( activeShader, file, &stream, macros ) )
  744. return false;
  745. GLint compile;
  746. glGetShaderiv(activeShader, GL_COMPILE_STATUS, &compile);
  747. // Dump the info log to the console
  748. U32 logLength = 0;
  749. glGetShaderiv(activeShader, GL_INFO_LOG_LENGTH, (GLint*)&logLength);
  750. GLint compileStatus = GL_TRUE;
  751. if ( logLength )
  752. {
  753. FrameAllocatorMarker fam;
  754. char* log = (char*)fam.alloc(logLength);
  755. glGetShaderInfoLog(activeShader, logLength, NULL, log);
  756. // Always print errors
  757. glGetShaderiv( activeShader, GL_COMPILE_STATUS, &compileStatus );
  758. if ( compileStatus == GL_FALSE )
  759. {
  760. if ( smLogErrors )
  761. {
  762. Con::errorf( "GFXGLShader::initShader - Error compiling shader!" );
  763. Con::errorf( "Program %s: %s", file.getFullPath().c_str(), log );
  764. }
  765. }
  766. else if ( smLogWarnings )
  767. Con::warnf( "Program %s: %s", file.getFullPath().c_str(), log );
  768. }
  769. return compileStatus != GL_FALSE;
  770. }
  771. /// Returns our list of shader constants, the material can get this and just set the constants it knows about
  772. const Vector<GFXShaderConstDesc>& GFXGLShader::getShaderConstDesc() const
  773. {
  774. return mConstants;
  775. }
  776. /// Returns the alignment value for constType
  777. U32 GFXGLShader::getAlignmentValue(const GFXShaderConstType constType) const
  778. {
  779. // Alignment is the same thing as size for us.
  780. return shaderConstTypeSize(constType);
  781. }
  782. const String GFXGLShader::describeSelf() const
  783. {
  784. String ret;
  785. ret = String::ToString(" Program: %i", mProgram);
  786. ret += String::ToString(" Vertex Path: %s", mVertexFile.getFullPath().c_str());
  787. ret += String::ToString(" Pixel Path: %s", mPixelFile.getFullPath().c_str());
  788. return ret;
  789. }