material.cpp 15 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 "shader_prog.h"
  8. #include "renderer.h"
  9. #define MTL_ERROR( x ) ERROR( "Material (" << GetPath() << GetName() << "): " << 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_t::Load( const char* filename )
  53. {
  54. scanner_t scanner;
  55. if( !scanner.LoadFile( filename ) ) return false;
  56. const scanner_t::token_t* token;
  57. do
  58. {
  59. token = &scanner.GetNextToken();
  60. //** SHADER_PROG **
  61. if( token->code == scanner_t::TC_IDENTIFIER && !strcmp( token->value.string, "SHADER_PROG" ) )
  62. {
  63. if( shader_prog ) ERROR( "Shader program allready loaded" );
  64. token = &scanner.GetNextToken();
  65. if( token->code != scanner_t::TC_STRING )
  66. {
  67. PARSE_ERR_EXPECTED( "string" );
  68. return false;
  69. }
  70. shader_prog = rsrc::shaders.Load( token->value.string );
  71. }
  72. /*//** DEPTH_SHADER_PROG **
  73. else if( token->code == scanner_t::TC_IDENTIFIER && !strcmp( token->value.string, "DEPTH_SHADER_PROG" ) )
  74. {
  75. if( depth.shader_prog ) ERROR( "Depth shader program allready loaded" );
  76. token = &scanner.GetNextToken();
  77. if( token->code != scanner_t::TC_STRING )
  78. {
  79. PARSE_ERR_EXPECTED( "string" );
  80. return false;
  81. }
  82. depth.shader_prog = rsrc::shaders.Load( token->value.string );
  83. }*/
  84. //** DEPTH_MATERIAL **
  85. else if( token->code == scanner_t::TC_IDENTIFIER && !strcmp( token->value.string, "DEPTH_PASS_MATERIAL" ) )
  86. {
  87. if( dp_mtl ) ERROR( "Depth material already loaded" );
  88. token = &scanner.GetNextToken();
  89. if( token->code != scanner_t::TC_STRING )
  90. {
  91. PARSE_ERR_EXPECTED( "string" );
  92. return false;
  93. }
  94. dp_mtl = rsrc::materials.Load( token->value.string );
  95. }
  96. //** BLENDS **
  97. else if( token->code == scanner_t::TC_IDENTIFIER && !strcmp( token->value.string, "BLENDS" ) )
  98. {
  99. token = &scanner.GetNextToken();
  100. if( token->code != scanner_t::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_t::TC_IDENTIFIER && !strcmp( token->value.string, "REFRACTS" ) )
  109. {
  110. token = &scanner.GetNextToken();
  111. if( token->code != scanner_t::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_t::TC_IDENTIFIER && !strcmp( token->value.string, "BLENDING_SFACTOR" ) )
  120. {
  121. token = &scanner.GetNextToken();
  122. if( token->code != scanner_t::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. blending_sfactor = gl_enum;
  134. }
  135. //** BLENDING_DFACTOR **
  136. else if( token->code == scanner_t::TC_IDENTIFIER && !strcmp( token->value.string, "BLENDING_DFACTOR" ) )
  137. {
  138. token = &scanner.GetNextToken();
  139. if( token->code != scanner_t::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. blending_dfactor = gl_enum;
  151. }
  152. //** DEPTH_TESTING **
  153. else if( token->code == scanner_t::TC_IDENTIFIER && !strcmp( token->value.string, "DEPTH_TESTING" ) )
  154. {
  155. token = &scanner.GetNextToken();
  156. if( token->code != scanner_t::TC_NUMBER )
  157. {
  158. PARSE_ERR_EXPECTED( "number" );
  159. return false;
  160. }
  161. depth_testing = token->value.int_;
  162. }
  163. //** GRASS_MAP **
  164. else if( token->code == scanner_t::TC_IDENTIFIER && !strcmp( token->value.string, "GRASS_MAP" ) )
  165. {
  166. token = &scanner.GetNextToken();
  167. if( token->code != scanner_t::TC_STRING )
  168. {
  169. PARSE_ERR_EXPECTED( "string" );
  170. return false;
  171. }
  172. grass_map = rsrc::textures.Load( token->value.string );
  173. }
  174. //** WIREFRAME **
  175. else if( token->code == scanner_t::TC_IDENTIFIER && !strcmp( token->value.string, "WIREFRAME" ) )
  176. {
  177. token = &scanner.GetNextToken();
  178. if( token->code != scanner_t::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_t::TC_IDENTIFIER && !strcmp( token->value.string, "CASTS_SHADOW" ) )
  187. {
  188. token = &scanner.GetNextToken();
  189. if( token->code != scanner_t::TC_NUMBER )
  190. {
  191. PARSE_ERR_EXPECTED( "number" );
  192. return false;
  193. }
  194. casts_shadow = token->value.int_;
  195. }
  196. //** USER_DEFINED_VARS **
  197. else if( token->code == scanner_t::TC_IDENTIFIER && !strcmp( token->value.string, "USER_DEFINED_VARS" ) )
  198. {
  199. // read {
  200. token = &scanner.GetNextToken();
  201. if( token->code != scanner_t::TC_LBRACKET )
  202. {
  203. PARSE_ERR_EXPECTED( "{" );
  204. return false;
  205. }
  206. // loop all the vars
  207. do
  208. {
  209. // read var type
  210. user_defined_var_t::type_e type;
  211. token = &scanner.GetNextToken();
  212. if( token->code == scanner_t::TC_RBRACKET )
  213. break;
  214. else if( token->code == scanner_t::TC_IDENTIFIER && !strcmp( token->value.string, "TEXTURE" ) )
  215. type = user_defined_var_t::VT_TEXTURE;
  216. else if( token->code == scanner_t::TC_IDENTIFIER && !strcmp( token->value.string, "FLOAT" ) )
  217. type = user_defined_var_t::VT_FLOAT;
  218. else if( token->code == scanner_t::TC_IDENTIFIER && !strcmp( token->value.string, "VEC3" ) )
  219. type = user_defined_var_t::VT_VEC3;
  220. else if( token->code == scanner_t::TC_IDENTIFIER && !strcmp( token->value.string, "VEC4" ) )
  221. type = user_defined_var_t::VT_VEC4;
  222. else
  223. {
  224. PARSE_ERR_EXPECTED( "TEXTURE or FLOAT or VEC3 or VEC4 or }" );
  225. return false;
  226. }
  227. user_defined_vars.push_back( user_defined_var_t() ); // create new var
  228. user_defined_var_t& var = user_defined_vars.back();
  229. var.type = type;
  230. // read the name
  231. token = &scanner.GetNextToken();
  232. if( token->code == scanner_t::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 user_defined_var_t::VT_TEXTURE:
  244. token = &scanner.GetNextToken();
  245. if( token->code == scanner_t::TC_STRING )
  246. {
  247. var.value.texture = rsrc::textures.Load( token->value.string );
  248. }
  249. else if( token->code == scanner_t::TC_IDENTIFIER && !strcmp( token->value.string, "IS_FAI" ) )
  250. {
  251. var.value.texture = &r::is::fai;
  252. }
  253. else if( token->code == scanner_t::TC_IDENTIFIER && !strcmp( token->value.string, "MS_NORMAL_FAI" ) )
  254. {
  255. var.value.texture = &r::ms::normal_fai;
  256. }
  257. else if( token->code == scanner_t::TC_IDENTIFIER && !strcmp( token->value.string, "MS_DEPTH_FAI" ) )
  258. {
  259. var.value.texture = &r::ms::depth_fai;
  260. }
  261. else if( token->code == scanner_t::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 user_defined_var_t::VT_FLOAT:
  273. token = &scanner.GetNextToken();
  274. if( token->code == scanner_t::TC_NUMBER && token->type == scanner_t::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 user_defined_var_t::VT_VEC2:
  284. ERROR( "Unimplemented" );
  285. break;
  286. // vec3
  287. case user_defined_var_t::VT_VEC3:
  288. if( !ParseArrOfNumbers<float>( scanner, true, true, 3, &var.value.vec3[0] ) ) return false;
  289. break;
  290. // vec4
  291. case user_defined_var_t::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_t::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_t::AdditionalInit()
  315. {
  316. // sanity checks
  317. if( !shader_prog )
  318. {
  319. MTL_ERROR( "Without shader is like cake without sugar (missing SHADER_PROG)" );
  320. return false;
  321. }
  322. /*if( !depth.shader_prog )
  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. shader_prog->Bind();
  329. for( uint i=0; i<user_defined_vars.size(); i++ )
  330. {
  331. int loc = shader_prog->GetUniformLocation( user_defined_vars[i].name.c_str() );
  332. if( loc == -1 )
  333. {
  334. MTL_ERROR( "Shader \"" << shader_prog->GetName() << "\" and user defined var \"" << user_defined_vars[i].name <<
  335. "\" do not combine. Incorrect location" );
  336. return false;
  337. }
  338. user_defined_vars[i].uniform_location = loc;
  339. }
  340. shader_prog->Unbind();
  341. // init the attribute locations
  342. attrib_locs.tanget = shader_prog->GetAttributeLocationSilently( "tangent" );
  343. attrib_locs.position = shader_prog->GetAttributeLocationSilently( "position" );
  344. attrib_locs.normal = shader_prog->GetAttributeLocationSilently( "normal" );
  345. attrib_locs.tex_coords = shader_prog->GetAttributeLocationSilently( "tex_coords" );
  346. // vertex weights
  347. attrib_locs.vert_weight_bones_num = shader_prog->GetAttributeLocationSilently( "vert_weight_bones_num" );
  348. if( attrib_locs.vert_weight_bones_num != -1 )
  349. {
  350. attrib_locs.vert_weight_bone_ids = shader_prog->GetAttributeLocation( "vert_weight_bone_ids" );
  351. attrib_locs.vert_weight_weights = shader_prog->GetAttributeLocation( "vert_weight_weights" );
  352. uni_locs.skinning_rotations = shader_prog->GetUniformLocation( "skinning_rotations" );
  353. uni_locs.skinning_translations = shader_prog->GetUniformLocation( "skinning_translations" );
  354. }
  355. return true;
  356. }
  357. /*
  358. =======================================================================================================================================
  359. Unload =
  360. =======================================================================================================================================
  361. */
  362. void material_t::Unload()
  363. {
  364. rsrc::shaders.Unload( shader_prog );
  365. // loop all user defined vars and unload the textures
  366. for( uint i=0; i<user_defined_vars.size(); i++ )
  367. {
  368. if( user_defined_vars[i].type == user_defined_var_t::VT_TEXTURE )
  369. rsrc::textures.Unload( user_defined_vars[i].value.texture );
  370. }
  371. // the grass map
  372. if( grass_map )
  373. rsrc::textures.Unload( grass_map );
  374. }
  375. /*
  376. =======================================================================================================================================
  377. SetToDefault =
  378. =======================================================================================================================================
  379. */
  380. void material_t::SetToDefault()
  381. {
  382. shader_prog = NULL;
  383. blends = false;
  384. blending_sfactor = GL_ONE;
  385. blending_dfactor = GL_ZERO;
  386. depth_testing = true;
  387. wireframe = false;
  388. grass_map = NULL;
  389. casts_shadow = true;
  390. refracts = false;
  391. dp_mtl = NULL;
  392. /*depth.shader_prog = NULL;
  393. depth.alpha_testing_map = NULL;*/
  394. }
  395. //=====================================================================================================================================
  396. // Setup =
  397. //=====================================================================================================================================
  398. void material_t::Setup()
  399. {
  400. shader_prog->Bind();
  401. if( blends )
  402. {
  403. glEnable( GL_BLEND );
  404. //glDisable( GL_BLEND );
  405. glBlendFunc( blending_sfactor, blending_dfactor );
  406. }
  407. else
  408. glDisable( GL_BLEND );
  409. if( depth_testing ) 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_t<user_defined_var_t>::iterator udv;
  416. for( udv=user_defined_vars.begin(); udv!=user_defined_vars.end(); udv++ )
  417. {
  418. switch( udv->type )
  419. {
  420. // texture
  421. case user_defined_var_t::VT_TEXTURE:
  422. shader_prog->LocTexUnit( udv->uniform_location, *udv->value.texture, texture_unit++ );
  423. break;
  424. // float
  425. case user_defined_var_t::VT_FLOAT:
  426. glUniform1f( udv->uniform_location, udv->value.float_ );
  427. break;
  428. // vec2
  429. case user_defined_var_t::VT_VEC2:
  430. glUniform2fv( udv->uniform_location, 1, &udv->value.vec2[0] );
  431. break;
  432. // vec3
  433. case user_defined_var_t::VT_VEC3:
  434. glUniform3fv( udv->uniform_location, 1, &udv->value.vec3[0] );
  435. break;
  436. // vec4
  437. case user_defined_var_t::VT_VEC4:
  438. glUniform4fv( udv->uniform_location, 1, &udv->value.vec4[0] );
  439. break;
  440. }
  441. }
  442. }