shaderCompGLSL.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  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 "shaderGen/GLSL/shaderCompGLSL.h"
  24. #include "shaderGen/shaderComp.h"
  25. #include "shaderGen/langElement.h"
  26. #include "gfx/gfxDevice.h"
  27. #include "gfx/gl/gfxGLVertexAttribLocation.h"
  28. Var * AppVertConnectorGLSL::getElement( RegisterType type,
  29. U32 numElements,
  30. U32 numRegisters )
  31. {
  32. switch( type )
  33. {
  34. case RT_POSITION:
  35. {
  36. Var *newVar = new Var;
  37. mElementList.push_back( newVar );
  38. newVar->setConnectName( "vPosition" );
  39. return newVar;
  40. }
  41. case RT_NORMAL:
  42. {
  43. Var *newVar = new Var;
  44. mElementList.push_back( newVar );
  45. newVar->setConnectName( "vNormal" );
  46. return newVar;
  47. }
  48. case RT_BINORMAL:
  49. {
  50. Var *newVar = new Var;
  51. mElementList.push_back( newVar );
  52. newVar->setConnectName( "vBinormal" );
  53. return newVar;
  54. }
  55. case RT_COLOR:
  56. {
  57. Var *newVar = new Var;
  58. mElementList.push_back( newVar );
  59. newVar->setConnectName( "vColor" );
  60. return newVar;
  61. }
  62. case RT_TANGENT:
  63. {
  64. Var *newVar = new Var;
  65. mElementList.push_back( newVar );
  66. newVar->setConnectName( "vTangent" );
  67. return newVar;
  68. }
  69. case RT_TANGENTW:
  70. {
  71. Var *newVar = new Var;
  72. mElementList.push_back( newVar );
  73. newVar->setConnectName( "vTangentW" );
  74. return newVar;
  75. }
  76. case RT_TEXCOORD:
  77. {
  78. Var *newVar = new Var;
  79. mElementList.push_back( newVar );
  80. char out[32];
  81. dSprintf( (char*)out, sizeof(out), "vTexCoord%d", mCurTexElem );
  82. newVar->setConnectName( out );
  83. newVar->constNum = mCurTexElem;
  84. newVar->arraySize = numElements;
  85. if ( numRegisters != -1 )
  86. mCurTexElem += numRegisters;
  87. else
  88. mCurTexElem += numElements;
  89. return newVar;
  90. }
  91. case RT_BLENDINDICES:
  92. {
  93. Var *newVar = new Var;
  94. newVar->constNum = mCurBlendIndicesElem;
  95. mElementList.push_back(newVar);
  96. char out[32];
  97. const U32 blendIndicesOffset = Torque::GL_VertexAttrib_BlendIndex0 - Torque::GL_VertexAttrib_TexCoord0;
  98. dSprintf((char*)out, sizeof(out), "vTexCoord%d", blendIndicesOffset + mCurBlendIndicesElem);
  99. mCurBlendIndicesElem += 1;
  100. newVar->setConnectName(out);
  101. return newVar;
  102. }
  103. case RT_BLENDWEIGHT:
  104. {
  105. Var *newVar = new Var;
  106. newVar->constNum = mCurBlendWeightsElem;
  107. mElementList.push_back(newVar);
  108. char out[32];
  109. const U32 blendWeightsOffset = Torque::GL_VertexAttrib_BlendWeight0 - Torque::GL_VertexAttrib_TexCoord0;
  110. dSprintf((char*)out, sizeof(out), "vTexCoord%d", blendWeightsOffset + mCurBlendWeightsElem);
  111. mCurBlendWeightsElem += 1;
  112. newVar->setConnectName(out);
  113. return newVar;
  114. }
  115. default:
  116. break;
  117. }
  118. return NULL;
  119. }
  120. void AppVertConnectorGLSL::sortVars()
  121. {
  122. // Not required in GLSL
  123. }
  124. void AppVertConnectorGLSL::setName( const char *newName )
  125. {
  126. dStrcpy( (char*)mName, newName, 32 );
  127. }
  128. void AppVertConnectorGLSL::reset()
  129. {
  130. for( U32 i=0; i<mElementList.size(); i++ )
  131. {
  132. mElementList[i] = NULL;
  133. }
  134. mElementList.setSize( 0 );
  135. mCurTexElem = 0;
  136. }
  137. void AppVertConnectorGLSL::print( Stream &stream, bool isVertexShader )
  138. {
  139. if(!isVertexShader)
  140. return;
  141. U8 output[256];
  142. // print struct
  143. dSprintf( (char*)output, sizeof(output), "struct VertexData\r\n" );
  144. stream.write( dStrlen((char*)output), output );
  145. dSprintf( (char*)output, sizeof(output), "{\r\n" );
  146. stream.write( dStrlen((char*)output), output );
  147. for( U32 i=0; i<mElementList.size(); i++ )
  148. {
  149. Var *var = mElementList[i];
  150. if( var->arraySize == 1)
  151. {
  152. dSprintf( (char*)output, sizeof(output), " %s %s;\r\n", var->type, (char*)var->name );
  153. stream.write( dStrlen((char*)output), output );
  154. }
  155. else
  156. {
  157. dSprintf( (char*)output, sizeof(output), " %s %s[%d];\r\n", var->type, (char*)var->name, var->arraySize );
  158. stream.write( dStrlen((char*)output), output );
  159. }
  160. }
  161. dSprintf( (char*)output, sizeof(output), "} IN;\r\n\r\n" );
  162. stream.write( dStrlen((char*)output), output );
  163. // print in elements
  164. for( U32 i=0; i<mElementList.size(); i++ )
  165. {
  166. Var *var = mElementList[i];
  167. for(int j = 0; j < var->arraySize; ++j)
  168. {
  169. const char *name = j == 0 ? var->connectName : avar("vTexCoord%d", var->constNum + j) ;
  170. dSprintf( (char*)output, sizeof(output), "in %s %s;\r\n", var->type, name );
  171. stream.write( dStrlen((char*)output), output );
  172. }
  173. dSprintf( (char*)output, sizeof(output), "#define IN_%s IN.%s\r\n", var->name, var->name ); // TODO REMOVE
  174. stream.write( dStrlen((char*)output), output );
  175. }
  176. const char* newLine ="\r\n";
  177. stream.write( dStrlen((char*)newLine), newLine );
  178. }
  179. Var * VertPixelConnectorGLSL::getElement( RegisterType type,
  180. U32 numElements,
  181. U32 numRegisters )
  182. {
  183. switch( type )
  184. {
  185. case RT_POSITION:
  186. {
  187. Var *newVar = new Var;
  188. mElementList.push_back( newVar );
  189. newVar->setConnectName( "POSITION" );
  190. return newVar;
  191. }
  192. case RT_NORMAL:
  193. {
  194. Var *newVar = new Var;
  195. mElementList.push_back( newVar );
  196. newVar->setConnectName( "NORMAL" );
  197. return newVar;
  198. }
  199. case RT_COLOR:
  200. {
  201. Var *newVar = new Var;
  202. mElementList.push_back( newVar );
  203. newVar->setConnectName( "COLOR" );
  204. return newVar;
  205. }
  206. /*case RT_BINORMAL:
  207. {
  208. Var *newVar = new Var;
  209. mElementList.push_back( newVar );
  210. newVar->setConnectName( "BINORMAL" );
  211. return newVar;
  212. }
  213. case RT_TANGENT:
  214. {
  215. Var *newVar = new Var;
  216. mElementList.push_back( newVar );
  217. newVar->setConnectName( "TANGENT" );
  218. return newVar;
  219. } */
  220. case RT_TEXCOORD:
  221. case RT_BINORMAL:
  222. case RT_TANGENT:
  223. {
  224. Var *newVar = new Var;
  225. newVar->arraySize = numElements;
  226. char out[32];
  227. dSprintf( (char*)out, sizeof(out), "TEXCOORD%d", mCurTexElem );
  228. newVar->setConnectName( out );
  229. if ( numRegisters != -1 )
  230. mCurTexElem += numRegisters;
  231. else
  232. mCurTexElem += numElements;
  233. mElementList.push_back( newVar );
  234. return newVar;
  235. }
  236. default:
  237. break;
  238. }
  239. return NULL;
  240. }
  241. void VertPixelConnectorGLSL::sortVars()
  242. {
  243. // Not needed in GLSL
  244. }
  245. void VertPixelConnectorGLSL::setName( const char *newName )
  246. {
  247. dStrcpy( (char*)mName, newName, 32 );
  248. }
  249. void VertPixelConnectorGLSL::reset()
  250. {
  251. for( U32 i=0; i<mElementList.size(); i++ )
  252. {
  253. mElementList[i] = NULL;
  254. }
  255. mElementList.setSize( 0 );
  256. mCurTexElem = 0;
  257. }
  258. void VertPixelConnectorGLSL::print( Stream &stream, bool isVerterShader )
  259. {
  260. // print out elements
  261. for( U32 i=0; i<mElementList.size(); i++ )
  262. {
  263. U8 output[256];
  264. Var *var = mElementList[i];
  265. if(!String::compare((const char*)var->name, "gl_Position"))
  266. continue;
  267. if(var->arraySize <= 1)
  268. dSprintf((char*)output, sizeof(output), "%s %s _%s_;\r\n", (isVerterShader ? "out" : "in"), var->type, var->connectName);
  269. else
  270. dSprintf((char*)output, sizeof(output), "%s %s _%s_[%d];\r\n", (isVerterShader ? "out" : "in"),var->type, var->connectName, var->arraySize);
  271. stream.write( dStrlen((char*)output), output );
  272. }
  273. printStructDefines(stream, !isVerterShader);
  274. }
  275. void VertPixelConnectorGLSL::printOnMain( Stream &stream, bool isVerterShader )
  276. {
  277. if(isVerterShader)
  278. return;
  279. const char *newLine = "\r\n";
  280. const char *header = " //-------------------------\r\n";
  281. stream.write( dStrlen((char*)newLine), newLine );
  282. stream.write( dStrlen((char*)header), header );
  283. // print out elements
  284. for( U32 i=0; i<mElementList.size(); i++ )
  285. {
  286. U8 output[256];
  287. Var *var = mElementList[i];
  288. if(!String::compare((const char*)var->name, "gl_Position"))
  289. continue;
  290. dSprintf((char*)output, sizeof(output), " %s IN_%s = _%s_;\r\n", var->type, var->name, var->connectName);
  291. stream.write( dStrlen((char*)output), output );
  292. }
  293. stream.write( dStrlen((char*)header), header );
  294. stream.write( dStrlen((char*)newLine), newLine );
  295. }
  296. void AppVertConnectorGLSL::printOnMain( Stream &stream, bool isVerterShader )
  297. {
  298. if(!isVerterShader)
  299. return;
  300. const char *newLine = "\r\n";
  301. const char *header = " //-------------------------\r\n";
  302. stream.write( dStrlen((char*)newLine), newLine );
  303. stream.write( dStrlen((char*)header), header );
  304. // print out elements
  305. for( U32 i=0; i<mElementList.size(); i++ )
  306. {
  307. Var *var = mElementList[i];
  308. U8 output[256];
  309. if(var->arraySize <= 1)
  310. {
  311. dSprintf((char*)output, sizeof(output), " IN.%s = %s;\r\n", var->name, var->connectName);
  312. stream.write( dStrlen((char*)output), output );
  313. }
  314. else
  315. {
  316. for(int j = 0; j < var->arraySize; ++j)
  317. {
  318. const char *name = j == 0 ? var->connectName : avar("vTexCoord%d", var->constNum + j) ;
  319. dSprintf((char*)output, sizeof(output), " IN.%s[%d] = %s;\r\n", var->name, j, name );
  320. stream.write( dStrlen((char*)output), output );
  321. }
  322. }
  323. }
  324. stream.write( dStrlen((char*)header), header );
  325. stream.write( dStrlen((char*)newLine), newLine );
  326. }
  327. Vector<String> initDeprecadedDefines()
  328. {
  329. Vector<String> vec;
  330. vec.push_back( "isBack");
  331. return vec;
  332. }
  333. void VertPixelConnectorGLSL::printStructDefines( Stream &stream, bool in )
  334. {
  335. const char* connectionDir = in ? "IN" : "OUT";
  336. static Vector<String> deprecatedDefines = initDeprecadedDefines();
  337. const char *newLine = "\r\n";
  338. const char *header = "// Struct defines\r\n";
  339. stream.write( dStrlen((char*)newLine), newLine );
  340. stream.write( dStrlen((char*)header), header );
  341. // print out elements
  342. for( U32 i=0; i<mElementList.size(); i++ )
  343. {
  344. U8 output[256];
  345. Var *var = mElementList[i];
  346. if(!String::compare((const char*)var->name, "gl_Position"))
  347. continue;
  348. if(!in)
  349. {
  350. dSprintf((char*)output, sizeof(output), "#define %s_%s _%s_\r\n", connectionDir, var->name, var->connectName);
  351. stream.write( dStrlen((char*)output), output );
  352. continue;
  353. }
  354. }
  355. stream.write( dStrlen((char*)newLine), newLine );
  356. }
  357. void VertexParamsDefGLSL::print( Stream &stream, bool isVerterShader )
  358. {
  359. // find all the uniform variables and print them out
  360. for( U32 i=0; i<LangElement::elementList.size(); i++)
  361. {
  362. Var *var = dynamic_cast<Var*>(LangElement::elementList[i]);
  363. if( var )
  364. {
  365. if( var->uniform )
  366. {
  367. U8 output[256];
  368. if(var->arraySize <= 1)
  369. dSprintf((char*)output, sizeof(output), "uniform %-8s %-15s;\r\n", var->type, var->name);
  370. else
  371. dSprintf((char*)output, sizeof(output), "uniform %-8s %-15s[%d];\r\n", var->type, var->name, var->arraySize);
  372. stream.write( dStrlen((char*)output), output );
  373. }
  374. }
  375. }
  376. const char *closer = "\r\n\r\nvoid main()\r\n{\r\n";
  377. stream.write( dStrlen(closer), closer );
  378. }
  379. void PixelParamsDefGLSL::print( Stream &stream, bool isVerterShader )
  380. {
  381. // find all the uniform variables and print them out
  382. for( U32 i=0; i<LangElement::elementList.size(); i++)
  383. {
  384. Var *var = dynamic_cast<Var*>(LangElement::elementList[i]);
  385. if( var )
  386. {
  387. if( var->uniform )
  388. {
  389. U8 output[256];
  390. if(var->arraySize <= 1)
  391. dSprintf((char*)output, sizeof(output), "uniform %-8s %-15s;\r\n", var->type, var->name);
  392. else
  393. dSprintf((char*)output, sizeof(output), "uniform %-8s %-15s[%d];\r\n", var->type, var->name, var->arraySize);
  394. stream.write( dStrlen((char*)output), output );
  395. }
  396. }
  397. }
  398. const char *closer = "\r\nvoid main()\r\n{\r\n";
  399. stream.write( dStrlen(closer), closer );
  400. for( U32 i=0; i<LangElement::elementList.size(); i++)
  401. {
  402. Var *var = dynamic_cast<Var*>(LangElement::elementList[i]);
  403. if( var )
  404. {
  405. if( var->uniform && !var->sampler)
  406. {
  407. U8 output[256];
  408. if(var->arraySize <= 1)
  409. dSprintf((char*)output, sizeof(output), " %s %s = %s;\r\n", var->type, var->name, var->name);
  410. else
  411. dSprintf((char*)output, sizeof(output), " %s %s[%d] = %s;\r\n", var->type, var->name, var->arraySize, var->name);
  412. stream.write( dStrlen((char*)output), output );
  413. }
  414. }
  415. }
  416. }