Material.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. #include <string.h>
  2. #include "Material.h"
  3. #include "Resource.h"
  4. #include "Scanner.h"
  5. #include "parser.h"
  6. #include "Texture.h"
  7. #include "ShaderProg.h"
  8. #include "Renderer.h"
  9. #define MTL_ERROR( x ) ERROR( "Material (" << getRsrcPath() << getRsrcName() << "): " << x );
  10. /*
  11. =======================================================================================================================================
  12. Blending dtuff =
  13. =======================================================================================================================================
  14. */
  15. struct blend_param_t
  16. {
  17. int gl_enum;
  18. const char* str;
  19. };
  20. static blend_param_t bparams [] =
  21. {
  22. {GL_ZERO, "GL_ZERO"},
  23. {GL_ONE, "GL_ONE"},
  24. {GL_DST_COLOR, "GL_DST_COLOR"},
  25. {GL_ONE_MINUS_DST_COLOR, "GL_ONE_MINUS_DST_COLOR"},
  26. {GL_SRC_ALPHA, "GL_SRC_ALPHA"},
  27. {GL_ONE_MINUS_SRC_ALPHA, "GL_ONE_MINUS_SRC_ALPHA"},
  28. {GL_DST_ALPHA, "GL_DST_ALPHA"},
  29. {GL_ONE_MINUS_DST_ALPHA, "GL_ONE_MINUS_DST_ALPHA"},
  30. {GL_SRC_ALPHA_SATURATE, "GL_SRC_ALPHA_SATURATE"},
  31. {GL_SRC_COLOR, "GL_SRC_COLOR"},
  32. {GL_ONE_MINUS_SRC_COLOR, "GL_ONE_MINUS_SRC_COLOR"}
  33. };
  34. const int BLEND_PARAMS_NUM = 11;
  35. static bool SearchBlendEnum( const char* str, int& gl_enum )
  36. {
  37. for( int i=0; i<BLEND_PARAMS_NUM; i++ )
  38. {
  39. if( !strcmp( bparams[i].str, str) )
  40. {
  41. gl_enum = bparams[i].gl_enum;
  42. return true;
  43. }
  44. }
  45. return false;
  46. }
  47. /*
  48. =======================================================================================================================================
  49. load =
  50. =======================================================================================================================================
  51. */
  52. bool Material::load( const char* filename )
  53. {
  54. Scanner scanner;
  55. if( !scanner.loadFile( filename ) ) return false;
  56. const Scanner::Token* token;
  57. do
  58. {
  59. token = &scanner.getNextToken();
  60. //** SHADER_PROG **
  61. if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "SHADER_PROG" ) )
  62. {
  63. if( shaderProg ) ERROR( "Shader program already loaded" );
  64. token = &scanner.getNextToken();
  65. if( token->code != Scanner::TC_STRING )
  66. {
  67. PARSE_ERR_EXPECTED( "string" );
  68. return false;
  69. }
  70. shaderProg = rsrc::shaders.load( token->value.string );
  71. }
  72. /*//** DEPTH_SHADER_PROG **
  73. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "DEPTH_SHADER_PROG" ) )
  74. {
  75. if( depth.shaderProg ) ERROR( "Depth shader program already loaded" );
  76. token = &scanner.getNextToken();
  77. if( token->code != Scanner::TC_STRING )
  78. {
  79. PARSE_ERR_EXPECTED( "string" );
  80. return false;
  81. }
  82. depth.shaderProg = rsrc::shaders.load( token->value.string );
  83. }*/
  84. //** DEPTH_MATERIAL **
  85. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "DEPTH_PASS_MATERIAL" ) )
  86. {
  87. if( dpMtl ) ERROR( "Depth material already loaded" );
  88. token = &scanner.getNextToken();
  89. if( token->code != Scanner::TC_STRING )
  90. {
  91. PARSE_ERR_EXPECTED( "string" );
  92. return false;
  93. }
  94. dpMtl = rsrc::materials.load( token->value.string );
  95. }
  96. //** BLENDS **
  97. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "BLENDS" ) )
  98. {
  99. token = &scanner.getNextToken();
  100. if( token->code != Scanner::TC_NUMBER )
  101. {
  102. PARSE_ERR_EXPECTED( "number" );
  103. return false;
  104. }
  105. blends = token->value.int_;
  106. }
  107. //** REFRACTS **
  108. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "REFRACTS" ) )
  109. {
  110. token = &scanner.getNextToken();
  111. if( token->code != Scanner::TC_NUMBER )
  112. {
  113. PARSE_ERR_EXPECTED( "number" );
  114. return false;
  115. }
  116. refracts = token->value.int_;
  117. }
  118. //** BLENDING_SFACTOR **
  119. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "BLENDING_SFACTOR" ) )
  120. {
  121. token = &scanner.getNextToken();
  122. if( token->code != Scanner::TC_IDENTIFIER )
  123. {
  124. PARSE_ERR_EXPECTED( "identifier" );
  125. return false;
  126. }
  127. int gl_enum;
  128. if( !SearchBlendEnum(token->value.string, gl_enum) )
  129. {
  130. PARSE_ERR( "Incorrect blending factor \"" << token->value.string << "\"" );
  131. return false;
  132. }
  133. blendingSfactor = gl_enum;
  134. }
  135. //** BLENDING_DFACTOR **
  136. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "BLENDING_DFACTOR" ) )
  137. {
  138. token = &scanner.getNextToken();
  139. if( token->code != Scanner::TC_IDENTIFIER )
  140. {
  141. PARSE_ERR_EXPECTED( "identifier" );
  142. return false;
  143. }
  144. int gl_enum;
  145. if( !SearchBlendEnum(token->value.string, gl_enum) )
  146. {
  147. PARSE_ERR( "Incorrect blending factor \"" << token->value.string << "\"" );
  148. return false;
  149. }
  150. blendingDfactor = gl_enum;
  151. }
  152. //** DEPTH_TESTING **
  153. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "DEPTH_TESTING" ) )
  154. {
  155. token = &scanner.getNextToken();
  156. if( token->code != Scanner::TC_NUMBER )
  157. {
  158. PARSE_ERR_EXPECTED( "number" );
  159. return false;
  160. }
  161. depthTesting = token->value.int_;
  162. }
  163. //** GRASS_MAP **
  164. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "GRASS_MAP" ) )
  165. {
  166. token = &scanner.getNextToken();
  167. if( token->code != Scanner::TC_STRING )
  168. {
  169. PARSE_ERR_EXPECTED( "string" );
  170. return false;
  171. }
  172. grassMap = rsrc::textures.load( token->value.string );
  173. }
  174. //** WIREFRAME **
  175. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "WIREFRAME" ) )
  176. {
  177. token = &scanner.getNextToken();
  178. if( token->code != Scanner::TC_NUMBER )
  179. {
  180. PARSE_ERR_EXPECTED( "number" );
  181. return false;
  182. }
  183. wireframe = token->value.int_;
  184. }
  185. //** CASTS_SHADOW **
  186. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "CASTS_SHADOW" ) )
  187. {
  188. token = &scanner.getNextToken();
  189. if( token->code != Scanner::TC_NUMBER )
  190. {
  191. PARSE_ERR_EXPECTED( "number" );
  192. return false;
  193. }
  194. castsShadow = token->value.int_;
  195. }
  196. //** USER_DEFINED_VARS **
  197. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "USER_DEFINED_VARS" ) )
  198. {
  199. // read {
  200. token = &scanner.getNextToken();
  201. if( token->code != Scanner::TC_LBRACKET )
  202. {
  203. PARSE_ERR_EXPECTED( "{" );
  204. return false;
  205. }
  206. // loop all the vars
  207. do
  208. {
  209. // read var type
  210. UserDefinedVar::Type type;
  211. token = &scanner.getNextToken();
  212. if( token->code == Scanner::TC_RBRACKET )
  213. break;
  214. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "TEXTURE" ) )
  215. type = UserDefinedVar::VT_TEXTURE;
  216. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "FLOAT" ) )
  217. type = UserDefinedVar::VT_FLOAT;
  218. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "VEC3" ) )
  219. type = UserDefinedVar::VT_VEC3;
  220. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "VEC4" ) )
  221. type = UserDefinedVar::VT_VEC4;
  222. else
  223. {
  224. PARSE_ERR_EXPECTED( "TEXTURE or FLOAT or VEC3 or VEC4 or }" );
  225. return false;
  226. }
  227. userDefinedVars.push_back( UserDefinedVar() ); // create new var
  228. UserDefinedVar& var = userDefinedVars.back();
  229. var.type = type;
  230. // read the name
  231. token = &scanner.getNextToken();
  232. if( token->code == Scanner::TC_IDENTIFIER )
  233. var.name = token->value.string;
  234. else
  235. {
  236. PARSE_ERR_EXPECTED( "identifier" );
  237. return false;
  238. }
  239. // read the values
  240. switch( type )
  241. {
  242. // texture
  243. case UserDefinedVar::VT_TEXTURE:
  244. token = &scanner.getNextToken();
  245. if( token->code == Scanner::TC_STRING )
  246. {
  247. var.value.texture = rsrc::textures.load( token->value.string );
  248. }
  249. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "IS_FAI" ) )
  250. {
  251. var.value.texture = &R::Is::fai;
  252. }
  253. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "MS_NORMAL_FAI" ) )
  254. {
  255. var.value.texture = &R::Ms::normalFai;
  256. }
  257. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "MS_DEPTH_FAI" ) )
  258. {
  259. var.value.texture = &R::Ms::depthFai;
  260. }
  261. else if( token->code == Scanner::TC_IDENTIFIER && !strcmp( token->value.string, "PPS_FAI" ) )
  262. {
  263. var.value.texture = &R::Pps::fai;
  264. }
  265. else
  266. {
  267. PARSE_ERR_EXPECTED( "string or IS_FAI or MS_NORMAL_FAI or MS_DEPTH_FAI or PPS_FAI" );
  268. return false;
  269. }
  270. break;
  271. // float
  272. case UserDefinedVar::VT_FLOAT:
  273. token = &scanner.getNextToken();
  274. if( token->code == Scanner::TC_NUMBER && token->type == Scanner::DT_FLOAT )
  275. var.value.float_ = token->value.float_;
  276. else
  277. {
  278. PARSE_ERR_EXPECTED( "float" );
  279. return false;
  280. }
  281. break;
  282. // vec2
  283. case UserDefinedVar::VT_VEC2:
  284. ERROR( "Unimplemented" );
  285. break;
  286. // vec3
  287. case UserDefinedVar::VT_VEC3:
  288. if( !ParseArrOfNumbers<float>( scanner, true, true, 3, &var.value.vec3[0] ) ) return false;
  289. break;
  290. // vec4
  291. case UserDefinedVar::VT_VEC4:
  292. if( !ParseArrOfNumbers<float>( scanner, true, true, 4, &var.value.vec4[0] ) ) return false;
  293. break;
  294. };
  295. }while(true); // end loop for all the vars
  296. }
  297. // end of file
  298. else if( token->code == Scanner::TC_EOF )
  299. {
  300. break;
  301. }
  302. // other crap
  303. else
  304. {
  305. PARSE_ERR_UNEXPECTED();
  306. return false;
  307. }
  308. }while( true );
  309. return additionalInit();
  310. }
  311. //=====================================================================================================================================
  312. // additionalInit =
  313. //=====================================================================================================================================
  314. bool Material::additionalInit()
  315. {
  316. // sanity checks
  317. if( !shaderProg )
  318. {
  319. MTL_ERROR( "Without shader is like cake without sugar (missing SHADER_PROG)" );
  320. return false;
  321. }
  322. /*if( !depth.shaderProg )
  323. {
  324. MTL_ERROR( "Without depth shader is like cake without shadow (missing DEPTH_SHADER_PROG)" );
  325. return false;
  326. }*/
  327. // for all user defined vars get their location
  328. shaderProg->bind();
  329. for( uint i=0; i<userDefinedVars.size(); i++ )
  330. {
  331. int loc = shaderProg->getUniLoc( userDefinedVars[i].name.c_str() );
  332. if( loc == -1 )
  333. {
  334. MTL_ERROR( "Shader \"" << shaderProg->getRsrcName() << "\" and user defined var \"" << userDefinedVars[i].name <<
  335. "\" do not combine. Incorrect location" );
  336. return false;
  337. }
  338. userDefinedVars[i].uniLoc = loc;
  339. }
  340. shaderProg->unbind();
  341. // init the attribute locations
  342. attribLocs.tanget = shaderProg->getAttribLocSilently( "tangent" );
  343. attribLocs.position = shaderProg->getAttribLocSilently( "position" );
  344. attribLocs.normal = shaderProg->getAttribLocSilently( "normal" );
  345. attribLocs.texCoords = shaderProg->getAttribLocSilently( "texCoords" );
  346. // vertex weights
  347. attribLocs.vertWeightBonesNum = shaderProg->getAttribLocSilently( "vertWeightBonesNum" );
  348. if( attribLocs.vertWeightBonesNum != -1 )
  349. {
  350. attribLocs.vertWeightBoneIds = shaderProg->getAttribLoc( "vertWeightBoneIds" );
  351. attribLocs.vertWeightWeights = shaderProg->getAttribLoc( "vertWeightWeights" );
  352. uniLocs.skinningRotations = shaderProg->getUniLoc( "skinningRotations" );
  353. uniLocs.skinningTranslations = shaderProg->getUniLoc( "skinningTranslations" );
  354. }
  355. return true;
  356. }
  357. /*
  358. =======================================================================================================================================
  359. unload =
  360. =======================================================================================================================================
  361. */
  362. void Material::unload()
  363. {
  364. rsrc::shaders.unload( shaderProg );
  365. // loop all user defined vars and unload the textures
  366. for( uint i=0; i<userDefinedVars.size(); i++ )
  367. {
  368. if( userDefinedVars[i].type == UserDefinedVar::VT_TEXTURE )
  369. rsrc::textures.unload( userDefinedVars[i].value.texture );
  370. }
  371. // the grass map
  372. if( grassMap )
  373. rsrc::textures.unload( grassMap );
  374. }
  375. /*
  376. =======================================================================================================================================
  377. setToDefault =
  378. =======================================================================================================================================
  379. */
  380. void Material::setToDefault()
  381. {
  382. shaderProg = NULL;
  383. blends = false;
  384. blendingSfactor = GL_ONE;
  385. blendingDfactor = GL_ZERO;
  386. depthTesting = true;
  387. wireframe = false;
  388. grassMap = NULL;
  389. castsShadow = true;
  390. refracts = false;
  391. dpMtl = NULL;
  392. /*depth.shaderProg = NULL;
  393. depth.alpha_testing_map = NULL;*/
  394. }
  395. //=====================================================================================================================================
  396. // setup =
  397. //=====================================================================================================================================
  398. void Material::setup()
  399. {
  400. shaderProg->bind();
  401. if( blends )
  402. {
  403. glEnable( GL_BLEND );
  404. //glDisable( GL_BLEND );
  405. glBlendFunc( blendingSfactor, blendingDfactor );
  406. }
  407. else
  408. glDisable( GL_BLEND );
  409. if( depthTesting ) glEnable( GL_DEPTH_TEST );
  410. else glDisable( GL_DEPTH_TEST );
  411. if( wireframe ) glPolygonMode( GL_FRONT, GL_LINE );
  412. else glPolygonMode( GL_FRONT, GL_FILL );
  413. // now loop all the user defined vars and set them
  414. uint texture_unit = 0;
  415. Vec<UserDefinedVar>::iterator udv;
  416. for( udv=userDefinedVars.begin(); udv!=userDefinedVars.end(); udv++ )
  417. {
  418. switch( udv->type )
  419. {
  420. // texture
  421. case UserDefinedVar::VT_TEXTURE:
  422. shaderProg->locTexUnit( udv->uniLoc, *udv->value.texture, texture_unit++ );
  423. break;
  424. // float
  425. case UserDefinedVar::VT_FLOAT:
  426. glUniform1f( udv->uniLoc, udv->value.float_ );
  427. break;
  428. // vec2
  429. case UserDefinedVar::VT_VEC2:
  430. glUniform2fv( udv->uniLoc, 1, &udv->value.vec2[0] );
  431. break;
  432. // vec3
  433. case UserDefinedVar::VT_VEC3:
  434. glUniform3fv( udv->uniLoc, 1, &udv->value.vec3[0] );
  435. break;
  436. // vec4
  437. case UserDefinedVar::VT_VEC4:
  438. glUniform4fv( udv->uniLoc, 1, &udv->value.vec4[0] );
  439. break;
  440. }
  441. }
  442. }