shaderCompGLSL.cpp 14 KB

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