rasterizer.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. /*************************************************************************/
  2. /* rasterizer.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "rasterizer.h"
  31. #include "os/os.h"
  32. #include "print_string.h"
  33. Rasterizer *(*Rasterizer::_create_func)() = NULL;
  34. Rasterizer *Rasterizer::create() {
  35. return _create_func();
  36. }
  37. RasterizerStorage *RasterizerStorage::base_singleton = NULL;
  38. RasterizerStorage::RasterizerStorage() {
  39. base_singleton = this;
  40. }
  41. #if 0
  42. RID Rasterizer::create_default_material() {
  43. return material_create();
  44. }
  45. /* Fixed MAterial SHADER API */
  46. RID Rasterizer::_create_shader(const SpatialMaterialShaderKey& p_key) {
  47. ERR_FAIL_COND_V(!p_key.valid,RID());
  48. Map<SpatialMaterialShaderKey,SpatialMaterialShader>::Element *E=fixed_material_shaders.find(p_key);
  49. if (E) {
  50. E->get().refcount++;
  51. return E->get().shader;
  52. }
  53. uint64_t t = OS::get_singleton()->get_ticks_usec();
  54. SpatialMaterialShader fms;
  55. fms.refcount=1;
  56. fms.shader=shader_create();
  57. //create shader code
  58. int texcoords_used=0;
  59. String code;
  60. static const char* _uv_str[4]={"UV","uv_xform","UV2","uv_sphere"};
  61. #define _TEXUVSTR(m_idx) String(_uv_str[(p_key.texcoord_mask >> (m_idx * 2)) & 0x3])
  62. if (p_key.use_pointsize) {
  63. code+="UV=POINT_COORD;\n";
  64. }
  65. for(int i=0;i<VS::FIXED_MATERIAL_PARAM_MAX;i++) {
  66. if (p_key.texture_mask&(1<<i))
  67. texcoords_used|=(1<<((p_key.texcoord_mask>>(i*2))&0x3));
  68. }
  69. if (texcoords_used&(1<<VS::FIXED_MATERIAL_TEXCOORD_UV_TRANSFORM)) {
  70. code+="uniform mat4 fmp_uv_xform;\n";
  71. code+="vec2 uv_xform = (fmp_uv_xform * vec4(UV,0,1)).xy;\n";
  72. }
  73. /* HANDLE NORMAL MAPPING */
  74. if (p_key.texture_mask&(1<<VS::FIXED_MATERIAL_PARAM_NORMAL)) {
  75. String scode;
  76. scode+="uniform float fmp_normal;\n";
  77. scode+="uniform texture fmp_normal_tex;\n";
  78. String uv_str;
  79. if (((p_key.texcoord_mask>>(VS::FIXED_MATERIAL_PARAM_NORMAL*2))&0x3)==VS::FIXED_MATERIAL_TEXCOORD_SPHERE) {
  80. uv_str="uv"; //sorry not supported
  81. } else {
  82. uv_str=_TEXUVSTR(VS::FIXED_MATERIAL_PARAM_NORMAL);
  83. }
  84. if (p_key.use_xy_normalmap) {
  85. scode+="vec2 ywnormal=tex( fmp_normal_tex,"+uv_str+").wy * vec2(2.0,2.0) - vec2(1.0,1.0);\n";
  86. scode+="NORMALMAP=vec3(ywnormal,sqrt(1 - (ywnormal.x * ywnormal.x) - (ywnormal.y * ywnormal.y) ));\n";
  87. } else {
  88. scode+="NORMALMAP=tex( fmp_normal_tex,"+uv_str+").xyz * vec3(2.0,2.0,1.0) - vec3(1.0,1.0,0.0);\n";
  89. }
  90. scode+="NORMALMAP_DEPTH=fmp_normal;\n";
  91. code+=scode;
  92. }
  93. //handle sphere uv if used, do it here because it needs the normal, which may be transformed by a normal map
  94. if (texcoords_used&(1<<VS::FIXED_MATERIAL_TEXCOORD_SPHERE)) {
  95. String tcode;
  96. tcode="vec3 eye_normal = normalize(VERTEX);\n";
  97. tcode+="vec3 ref = (eye_normal - 2.0*dot(NORMAL, eye_normal)*NORMAL);\n";
  98. tcode+="ref.z+=1.0;\n";
  99. tcode+="vec2 uv_sphere = ref.xy*vec2(0.5,0.0-0.5)+vec2(0.5,0.0-0.5);\n";
  100. code+=tcode;
  101. }
  102. /* HANDLE DIFFUSE LIGHTING */
  103. code+="uniform color fmp_diffuse;\n";
  104. code+="color diffuse=fmp_diffuse;\n";
  105. if (p_key.use_color_array)
  106. code+="diffuse*=COLOR;\n";
  107. if (p_key.texture_mask&(1<<VS::FIXED_MATERIAL_PARAM_DIFFUSE)) {
  108. code+="uniform texture fmp_diffuse_tex;\n";
  109. code+="diffuse*=tex( fmp_diffuse_tex,"+_TEXUVSTR(VS::FIXED_MATERIAL_PARAM_DIFFUSE)+");\n";
  110. }
  111. if (p_key.texture_mask&(1<<VS::FIXED_MATERIAL_PARAM_DETAIL)) {
  112. String dcode;
  113. dcode+="uniform texture fmp_detail_tex;\n";
  114. dcode+="uniform float fmp_detail;\n";
  115. dcode+="color detail=tex( fmp_detail_tex,"+_TEXUVSTR(VS::FIXED_MATERIAL_PARAM_DETAIL)+");\n";
  116. //aways mix
  117. dcode+="diffuse=vec4(mix(diffuse.rgb,detail.rgb,detail.a*fmp_detail),diffuse.a);\n";
  118. code+=dcode;
  119. }
  120. if (p_key.use_alpha) {
  121. code+="DIFFUSE_ALPHA=diffuse;\n";
  122. if (p_key.discard_alpha) {
  123. code+="DISCARD=diffuse.a<0.5;\n";
  124. }
  125. } else {
  126. code+="DIFFUSE=diffuse.rgb;\n";
  127. }
  128. /* HANDLE SPECULAR LIGHTING */
  129. code+="uniform color fmp_specular;\n";
  130. code+="color specular=fmp_specular;\n";
  131. if (p_key.texture_mask&(1<<VS::FIXED_MATERIAL_PARAM_SPECULAR)) {
  132. String scode;
  133. scode+="uniform texture fmp_specular_tex;\n";
  134. scode+="specular*=tex( fmp_specular_tex,"+_TEXUVSTR(VS::FIXED_MATERIAL_PARAM_SPECULAR)+");\n";
  135. code+=scode;
  136. }
  137. code+="SPECULAR=specular.rgb;\n";
  138. code+="uniform float fmp_specular_exp;\n";
  139. code+="float specular_exp=fmp_specular_exp;\n";
  140. if (p_key.texture_mask&(1<<VS::FIXED_MATERIAL_PARAM_SPECULAR_EXP)) {
  141. String scode;
  142. scode+="uniform texture fmp_specular_exp_tex;\n";
  143. scode+="specular_exp*=tex( fmp_specular_exp_tex,"+_TEXUVSTR(VS::FIXED_MATERIAL_PARAM_SPECULAR_EXP)+").r;\n";
  144. code+=scode;
  145. }
  146. code+="SPEC_EXP=specular_exp;\n";
  147. /* HANDLE EMISSION LIGHTING */
  148. code+="uniform color fmp_emission;\n";
  149. code+="color emission=fmp_emission;\n";
  150. if (p_key.texture_mask&(1<<VS::FIXED_MATERIAL_PARAM_EMISSION)) {
  151. String scode;
  152. scode+="uniform texture fmp_emission_tex;\n";
  153. scode+="emission*=tex( fmp_emission_tex,"+_TEXUVSTR(VS::FIXED_MATERIAL_PARAM_EMISSION)+");\n";
  154. code+=scode;
  155. }
  156. code+="EMISSION=emission.rgb;\n";
  157. /* HANDLE GLOW */
  158. code+="uniform float fmp_glow;\n";
  159. code+="float glow=fmp_glow;\n";
  160. if (p_key.texture_mask&(1<<VS::FIXED_MATERIAL_PARAM_GLOW)) {
  161. String scode;
  162. scode+="uniform texture fmp_glow_tex;\n";
  163. scode+="glow*=tex( fmp_glow_tex,"+_TEXUVSTR(VS::FIXED_MATERIAL_PARAM_GLOW)+").r;\n";
  164. code+=scode;
  165. }
  166. code+="GLOW=glow;\n";
  167. if (p_key.texture_mask&(1<<VS::FIXED_MATERIAL_PARAM_SHADE_PARAM)) {
  168. String scode;
  169. scode+="uniform texture fmp_shade_param_tex;\n";
  170. scode+="SHADE_PARAM=tex( fmp_shade_param_tex,"+_TEXUVSTR(VS::FIXED_MATERIAL_PARAM_SHADE_PARAM)+").r;\n";
  171. code+=scode;
  172. } else {
  173. String scode;
  174. scode+="uniform float fmp_shade_param;\n";
  175. scode+="SHADE_PARAM=fmp_shade_param;\n";
  176. code+=scode;
  177. }
  178. //print_line("**FRAGMENT SHADER GENERATED code: \n"+code);
  179. String vcode;
  180. vcode="uniform float "+_fixed_material_param_names[VS::FIXED_MATERIAL_PARAM_SPECULAR_EXP]+";\n";
  181. vcode+="SPEC_EXP="+_fixed_material_param_names[VS::FIXED_MATERIAL_PARAM_SPECULAR_EXP]+";\n";
  182. if (p_key.use_pointsize) {
  183. vcode+="uniform float "+_fixed_material_point_size_name+";\n";
  184. vcode+="POINT_SIZE="+_fixed_material_point_size_name+";\n";
  185. //vcode+="POINT_SIZE=10.0;\n";
  186. }
  187. String lcode;
  188. switch(p_key.light_shader) {
  189. case VS::FIXED_MATERIAL_LIGHT_SHADER_LAMBERT: {
  190. //do nothing
  191. } break;
  192. case VS::FIXED_MATERIAL_LIGHT_SHADER_WRAP: {
  193. lcode+="float NdotL = max(0.0,((dot( NORMAL, LIGHT_DIR )+SHADE_PARAM)/(1.0+SHADE_PARAM)));";
  194. lcode+="vec3 half_vec = normalize(LIGHT_DIR + EYE_VEC);";
  195. lcode+="float eye_light = max(dot(NORMAL, half_vec),0.0);";
  196. lcode+="LIGHT = LIGHT_DIFFUSE * DIFFUSE * NdotL;";
  197. lcode+="if (NdotL > 0.0) {";
  198. lcode+="\tLIGHT+=LIGHT_SPECULAR * SPECULAR * pow( eye_light, SPECULAR_EXP );";
  199. lcode+="};";
  200. } break;
  201. case VS::FIXED_MATERIAL_LIGHT_SHADER_VELVET: {
  202. lcode+="float NdotL = max(0.0,dot( NORMAL, LIGHT_DIR ));";
  203. lcode+="vec3 half_vec = normalize(LIGHT_DIR + EYE_VEC);";
  204. lcode+="float eye_light = max(dot(NORMAL, half_vec),0.0);";
  205. lcode+="LIGHT = LIGHT_DIFFUSE * DIFFUSE * NdotL;";
  206. lcode+="float rim = (1.0-abs(dot(NORMAL,vec3(0,0,1))))*SHADE_PARAM;";
  207. lcode+="LIGHT += LIGHT_DIFFUSE * DIFFUSE * rim;";
  208. lcode+="if (NdotL > 0.0) {";
  209. lcode+="\tLIGHT+=LIGHT_SPECULAR * SPECULAR * pow( eye_light, SPECULAR_EXP );";
  210. lcode+="};";
  211. } break;
  212. case VS::FIXED_MATERIAL_LIGHT_SHADER_TOON: {
  213. lcode+="float NdotL = dot( NORMAL, LIGHT_DIR );";
  214. lcode+="vec3 light_ref = reflect( LIGHT_DIR, NORMAL );";
  215. lcode+="float eye_light = clamp( dot( light_ref, vec3(0,0,0)-EYE_VEC), 0.0, 1.0 );";
  216. lcode+="float NdotL_diffuse = smoothstep( max( SHADE_PARAM-0.05, 0.0-1.0), min( SHADE_PARAM+0.05, 1.0), NdotL );";
  217. lcode+="float spec_radius=clamp((1.0-(SPECULAR_EXP/64.0)),0.0,1.0);";
  218. lcode+="float NdotL_specular = smoothstep( max( spec_radius-0.05, 0.0), min( spec_radius+0.05, 1.0), eye_light )*max(NdotL,0);";
  219. lcode+="LIGHT = NdotL_diffuse * LIGHT_DIFFUSE*DIFFUSE + NdotL_specular * LIGHT_SPECULAR*SPECULAR;";
  220. } break;
  221. }
  222. //print_line("**VERTEX SHADER GENERATED code: \n"+vcode);
  223. shader_set_code(fms.shader,vcode,code,lcode,0,0);
  224. fixed_material_shaders[p_key]=fms;
  225. return fms.shader;
  226. }
  227. void Rasterizer::_free_shader(const SpatialMaterialShaderKey& p_key) {
  228. if (p_key.valid==0)
  229. return; //not a valid key
  230. Map<SpatialMaterialShaderKey,SpatialMaterialShader>::Element *E=fixed_material_shaders.find(p_key);
  231. ERR_FAIL_COND(!E);
  232. E->get().refcount--;
  233. if (E->get().refcount==0) {
  234. free(E->get().shader);
  235. fixed_material_shaders.erase(E);
  236. }
  237. }
  238. void Rasterizer::fixed_material_set_flag(RID p_material, VS::SpatialMaterialFlags p_flag, bool p_enabled) {
  239. Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
  240. ERR_FAIL_COND(!E);
  241. SpatialMaterial &fm=*E->get();
  242. switch(p_flag) {
  243. case VS::FIXED_MATERIAL_FLAG_USE_ALPHA: fm.use_alpha=p_enabled; break;
  244. case VS::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY: fm.use_color_array=p_enabled; break;
  245. case VS::FIXED_MATERIAL_FLAG_USE_POINT_SIZE: fm.use_pointsize=p_enabled; break;
  246. case VS::FIXED_MATERIAL_FLAG_DISCARD_ALPHA: fm.discard_alpha=p_enabled; break;
  247. case VS::FIXED_MATERIAL_FLAG_USE_XY_NORMALMAP: fm.use_xy_normalmap=p_enabled; break;
  248. }
  249. if (!fm.dirty_list.in_list())
  250. fixed_material_dirty_list.add( &fm.dirty_list );
  251. }
  252. bool Rasterizer::fixed_material_get_flag(RID p_material, VS::SpatialMaterialFlags p_flag) const{
  253. const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
  254. ERR_FAIL_COND_V(!E,false);
  255. const SpatialMaterial &fm=*E->get();
  256. switch(p_flag) {
  257. case VS::FIXED_MATERIAL_FLAG_USE_ALPHA: return fm.use_alpha;; break;
  258. case VS::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY: return fm.use_color_array;; break;
  259. case VS::FIXED_MATERIAL_FLAG_USE_POINT_SIZE: return fm.use_pointsize;; break;
  260. case VS::FIXED_MATERIAL_FLAG_DISCARD_ALPHA: return fm.discard_alpha;; break;
  261. case VS::FIXED_MATERIAL_FLAG_USE_XY_NORMALMAP: return fm.use_xy_normalmap;; break;
  262. }
  263. return false;
  264. }
  265. RID Rasterizer::fixed_material_create() {
  266. RID mat = material_create();
  267. fixed_materials[mat]=memnew( SpatialMaterial() );
  268. SpatialMaterial &fm=*fixed_materials[mat];
  269. fm.self=mat;
  270. fm.get_key();
  271. material_set_flag(mat,VS::MATERIAL_FLAG_COLOR_ARRAY_SRGB,true);
  272. for(int i=0;i<VS::FIXED_MATERIAL_PARAM_MAX;i++) {
  273. material_set_param(mat,_fixed_material_param_names[i],fm.param[i]); //must be there
  274. }
  275. fixed_material_dirty_list.add(&fm.dirty_list);
  276. //print_line("FMC: "+itos(mat.get_id()));
  277. return mat;
  278. }
  279. void Rasterizer::fixed_material_set_parameter(RID p_material, VS::SpatialMaterialParam p_parameter, const Variant& p_value){
  280. Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
  281. ERR_FAIL_COND(!E);
  282. SpatialMaterial &fm=*E->get();
  283. RID material=E->key();
  284. ERR_FAIL_INDEX(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX);
  285. if ((p_parameter==VS::FIXED_MATERIAL_PARAM_DIFFUSE || p_parameter==VS::FIXED_MATERIAL_PARAM_SPECULAR || p_parameter==VS::FIXED_MATERIAL_PARAM_EMISSION)) {
  286. if (p_value.get_type()!=Variant::COLOR) {
  287. ERR_EXPLAIN(String(_fixed_material_param_names[p_parameter])+" expects Color");
  288. ERR_FAIL();
  289. }
  290. } else {
  291. if (!p_value.is_num()) {
  292. ERR_EXPLAIN(String(_fixed_material_param_names[p_parameter])+" expects scalar");
  293. ERR_FAIL();
  294. }
  295. }
  296. fm.param[p_parameter]=p_value;
  297. VS::get_singleton()->material_set_param(material,_fixed_material_param_names[p_parameter],p_value);
  298. }
  299. Variant Rasterizer::fixed_material_get_parameter(RID p_material,VS::SpatialMaterialParam p_parameter) const{
  300. const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
  301. ERR_FAIL_COND_V(!E,Variant());
  302. const SpatialMaterial &fm=*E->get();
  303. ERR_FAIL_INDEX_V(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX,Variant());
  304. return fm.param[p_parameter];
  305. }
  306. void Rasterizer::fixed_material_set_texture(RID p_material,VS::SpatialMaterialParam p_parameter, RID p_texture){
  307. Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
  308. if (!E) {
  309. print_line("Not found: "+itos(p_material.get_id()));
  310. }
  311. ERR_FAIL_COND(!E);
  312. SpatialMaterial &fm=*E->get();
  313. ERR_FAIL_INDEX(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX);
  314. RID material=E->key();
  315. fm.texture[p_parameter]=p_texture;
  316. VS::get_singleton()->material_set_param(material,_fixed_material_tex_names[p_parameter],p_texture);
  317. if (!fm.dirty_list.in_list())
  318. fixed_material_dirty_list.add( &fm.dirty_list );
  319. }
  320. RID Rasterizer::fixed_material_get_texture(RID p_material,VS::SpatialMaterialParam p_parameter) const{
  321. const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
  322. ERR_FAIL_COND_V(!E,RID());
  323. const SpatialMaterial &fm=*E->get();
  324. ERR_FAIL_INDEX_V(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX,RID());
  325. return fm.texture[p_parameter];
  326. }
  327. void Rasterizer::fixed_material_set_texcoord_mode(RID p_material,VS::SpatialMaterialParam p_parameter, VS::SpatialMaterialTexCoordMode p_mode) {
  328. Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
  329. ERR_FAIL_COND(!E);
  330. SpatialMaterial &fm=*E->get();
  331. ERR_FAIL_INDEX(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX);
  332. fm.get_key();
  333. fm.texture_tc[p_parameter]=p_mode;
  334. if (!fm.dirty_list.in_list())
  335. fixed_material_dirty_list.add( &fm.dirty_list );
  336. }
  337. VS::SpatialMaterialTexCoordMode Rasterizer::fixed_material_get_texcoord_mode(RID p_material,VS::SpatialMaterialParam p_parameter) const {
  338. const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
  339. ERR_FAIL_COND_V(!E,VS::FIXED_MATERIAL_TEXCOORD_UV);
  340. const SpatialMaterial &fm=*E->get();
  341. ERR_FAIL_INDEX_V(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX,VS::FIXED_MATERIAL_TEXCOORD_UV);
  342. return fm.texture_tc[p_parameter];
  343. }
  344. void Rasterizer::fixed_material_set_uv_transform(RID p_material,const Transform& p_transform) {
  345. Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
  346. ERR_FAIL_COND(!E);
  347. SpatialMaterial &fm=*E->get();
  348. RID material=E->key();
  349. VS::get_singleton()->material_set_param(material,_fixed_material_uv_xform_name,p_transform);
  350. fm.uv_xform=p_transform;
  351. }
  352. Transform Rasterizer::fixed_material_get_uv_transform(RID p_material) const {
  353. const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
  354. ERR_FAIL_COND_V(!E,Transform());
  355. const SpatialMaterial &fm=*E->get();
  356. return fm.uv_xform;
  357. }
  358. void Rasterizer::fixed_material_set_light_shader(RID p_material,VS::SpatialMaterialLightShader p_shader) {
  359. Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
  360. ERR_FAIL_COND(!E);
  361. SpatialMaterial &fm=*E->get();
  362. fm.light_shader=p_shader;
  363. if (!fm.dirty_list.in_list())
  364. fixed_material_dirty_list.add( &fm.dirty_list );
  365. }
  366. VS::SpatialMaterialLightShader Rasterizer::fixed_material_get_light_shader(RID p_material) const {
  367. const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
  368. ERR_FAIL_COND_V(!E,VS::FIXED_MATERIAL_LIGHT_SHADER_LAMBERT);
  369. const SpatialMaterial &fm=*E->get();
  370. return fm.light_shader;
  371. }
  372. void Rasterizer::fixed_material_set_point_size(RID p_material,float p_size) {
  373. Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
  374. ERR_FAIL_COND(!E);
  375. SpatialMaterial &fm=*E->get();
  376. RID material=E->key();
  377. VS::get_singleton()->material_set_param(material,_fixed_material_point_size_name,p_size);
  378. fm.point_size=p_size;
  379. }
  380. float Rasterizer::fixed_material_get_point_size(RID p_material) const{
  381. const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
  382. ERR_FAIL_COND_V(!E,1.0);
  383. const SpatialMaterial &fm=*E->get();
  384. return fm.point_size;
  385. }
  386. void Rasterizer::_update_fixed_materials() {
  387. while(fixed_material_dirty_list.first()) {
  388. SpatialMaterial &fm=*fixed_material_dirty_list.first()->self();
  389. SpatialMaterialShaderKey new_key = fm.get_key();
  390. if (new_key.key!=fm.current_key.key) {
  391. _free_shader(fm.current_key);
  392. RID new_rid = _create_shader(new_key);
  393. fm.current_key=new_key;
  394. material_set_shader(fm.self,new_rid);
  395. if (fm.texture[VS::FIXED_MATERIAL_PARAM_DETAIL].is_valid()) {
  396. //send these again just in case.
  397. material_set_param(fm.self,_fixed_material_param_names[VS::FIXED_MATERIAL_PARAM_DETAIL],fm.param[VS::FIXED_MATERIAL_PARAM_DETAIL]);
  398. }
  399. if (fm.texture[VS::FIXED_MATERIAL_PARAM_NORMAL].is_valid()) {
  400. //send these again just in case.
  401. material_set_param(fm.self,_fixed_material_param_names[VS::FIXED_MATERIAL_PARAM_NORMAL],fm.param[VS::FIXED_MATERIAL_PARAM_NORMAL]);
  402. }
  403. material_set_param(fm.self,_fixed_material_uv_xform_name,fm.uv_xform);
  404. if (fm.use_pointsize) {
  405. material_set_param(fm.self,_fixed_material_point_size_name,fm.point_size);
  406. }
  407. }
  408. fixed_material_dirty_list.remove(fixed_material_dirty_list.first());
  409. }
  410. }
  411. void Rasterizer::_free_fixed_material(const RID& p_material) {
  412. Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
  413. if (E) {
  414. _free_shader(E->get()->current_key); //free shader
  415. if (E->get()->dirty_list.in_list())
  416. fixed_material_dirty_list.remove( &E->get()->dirty_list);
  417. memdelete(E->get());
  418. fixed_materials.erase(E); //free material
  419. }
  420. }
  421. void Rasterizer::flush_frame() {
  422. //not really necessary to implement
  423. }
  424. Rasterizer::Rasterizer() {
  425. static const char* fm_names[VS::FIXED_MATERIAL_PARAM_MAX]={
  426. "diffuse",
  427. "detail",
  428. "specular",
  429. "emission",
  430. "specular_exp",
  431. "glow",
  432. "normal",
  433. "shade_param"};
  434. for(int i=0;i<VS::FIXED_MATERIAL_PARAM_MAX;i++) {
  435. _fixed_material_param_names[i]=String("fmp_")+fm_names[i];
  436. _fixed_material_tex_names[i]=String("fmp_")+fm_names[i]+"_tex";
  437. }
  438. _fixed_material_uv_xform_name="fmp_uv_xform";
  439. _fixed_material_point_size_name="fmp_point_size";
  440. draw_viewport_func=NULL;
  441. ERR_FAIL_COND( sizeof(SpatialMaterialShaderKey)!=4);
  442. }
  443. RID Rasterizer::create_overdraw_debug_material() {
  444. RID mat = fixed_material_create();
  445. fixed_material_set_parameter( mat,VisualServer::FIXED_MATERIAL_PARAM_SPECULAR,Color(0,0,0) );
  446. fixed_material_set_parameter( mat,VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE,Color(0.1,0.1,0.2) );
  447. fixed_material_set_parameter( mat,VisualServer::FIXED_MATERIAL_PARAM_EMISSION,Color(0,0,0) );
  448. fixed_material_set_flag( mat, VS::FIXED_MATERIAL_FLAG_USE_ALPHA, true);
  449. material_set_flag( mat, VisualServer::MATERIAL_FLAG_UNSHADED, true );
  450. material_set_blend_mode( mat,VisualServer::MATERIAL_BLEND_MODE_ADD );
  451. return mat;
  452. }
  453. #endif