1 #include "globalincs/pstypes.h"
2 #include "graphics/grinternal.h"
3 #include "graphics/2d.h"
4 #include "graphics/material.h"
5 #include "globalincs/systemvars.h"
6 #include "cmdline/cmdline.h"
7 
material_determine_blend_mode(int base_bitmap,bool blending)8 gr_alpha_blend material_determine_blend_mode(int base_bitmap, bool blending)
9 {
10 	if ( blending ) {
11 		if ( base_bitmap >= 0 && bm_has_alpha_channel(base_bitmap) ) {
12 			return ALPHA_BLEND_ALPHA_BLEND_ALPHA;
13 		}
14 
15 		return ALPHA_BLEND_ADDITIVE;
16 	}
17 
18 	return ALPHA_BLEND_ALPHA_BLEND_ALPHA;
19 }
20 
material_determine_depth_mode(bool depth_testing,bool blending)21 gr_zbuffer_type material_determine_depth_mode(bool depth_testing, bool blending)
22 {
23 	if ( depth_testing ) {
24 		if ( blending ) {
25 			return ZBUFFER_TYPE_READ;
26 		}
27 
28 		return ZBUFFER_TYPE_FULL;
29 	}
30 
31 	return ZBUFFER_TYPE_NONE;
32 }
33 
material_set_unlit(material * mat_info,int texture,float alpha,bool blending,bool depth_testing)34 void material_set_unlit(material* mat_info, int texture, float alpha, bool blending, bool depth_testing)
35 {
36 	mat_info->set_texture_map(TM_BASE_TYPE, texture);
37 
38 	gr_alpha_blend blend_mode = material_determine_blend_mode(texture, blending);
39 	gr_zbuffer_type depth_mode = material_determine_depth_mode(depth_testing, blending);
40 
41 	mat_info->set_blend_mode(blend_mode);
42 	mat_info->set_depth_mode(depth_mode);
43 	mat_info->set_cull_mode(false);
44 
45 	if ( blend_mode == ALPHA_BLEND_ADDITIVE ) {
46 		mat_info->set_color(alpha, alpha, alpha, 1.0f);
47 	} else {
48 		mat_info->set_color(1.0f, 1.0f, 1.0f, alpha);
49 	}
50 
51 	if ( texture >= 0 && bm_has_alpha_channel(texture) ) {
52 		mat_info->set_texture_type(material::TEX_TYPE_XPARENT);
53 	}
54 }
55 
material_set_unlit_emissive(material * mat_info,int texture,float alpha,float color_scale)56 void material_set_unlit_emissive(material* mat_info, int texture, float alpha, float color_scale)
57 {
58 	material_set_unlit(mat_info, texture, alpha, true, true);
59 
60 	mat_info->set_color_scale(color_scale);
61 }
62 
material_set_unlit_color(material * mat_info,int texture,color * clr,bool blending,bool depth_testing)63 void material_set_unlit_color(material* mat_info, int texture, color *clr, bool blending, bool depth_testing)
64 {
65 	mat_info->set_texture_map(TM_BASE_TYPE, texture);
66 
67 	gr_alpha_blend blend_mode = material_determine_blend_mode(texture, blending);
68 	gr_zbuffer_type depth_mode = material_determine_depth_mode(depth_testing, blending);
69 
70 	mat_info->set_blend_mode(blend_mode);
71 	mat_info->set_depth_mode(depth_mode);
72 	mat_info->set_cull_mode(false);
73 	mat_info->set_color(*clr);
74 }
75 
material_set_unlit_color(material * mat_info,int texture,color * clr,float alpha,bool blending,bool depth_testing)76 void material_set_unlit_color(material* mat_info, int texture, color *clr, float alpha, bool blending, bool depth_testing)
77 {
78 	color clr_with_alpha;
79 	gr_init_alphacolor(&clr_with_alpha, clr->red, clr->green, clr->blue, fl2i(alpha * 255.0f));
80 
81 	material_set_unlit_color(mat_info, texture, &clr_with_alpha, blending, depth_testing);
82 }
83 
material_set_interface(material * mat_info,int texture,bool blended,float alpha)84 void material_set_interface(material* mat_info, int texture, bool blended, float alpha)
85 {
86 	mat_info->set_texture_map(TM_BASE_TYPE, texture);
87 	mat_info->set_texture_type(material::TEX_TYPE_INTERFACE);
88 
89 	gr_alpha_blend blend_mode = material_determine_blend_mode(texture, blended);
90 
91 	mat_info->set_blend_mode(blend_mode);
92 	mat_info->set_depth_mode(ZBUFFER_TYPE_NONE);
93 	mat_info->set_cull_mode(false);
94 
95 	if ( blend_mode == ALPHA_BLEND_ADDITIVE ) {
96 		mat_info->set_color(alpha, alpha, alpha, 1.0f);
97 	} else {
98 		mat_info->set_color(1.0f, 1.0f, 1.0f, alpha);
99 	}
100 }
101 
material_set_unlit_volume(particle_material * mat_info,int texture,bool point_sprites)102 void material_set_unlit_volume(particle_material* mat_info, int texture, bool point_sprites)
103 {
104 	mat_info->set_point_sprite_mode(point_sprites);
105 	mat_info->set_depth_mode(ZBUFFER_TYPE_NONE);
106 
107 	mat_info->set_blend_mode(material_determine_blend_mode(texture, true));
108 
109 	mat_info->set_texture_map(TM_BASE_TYPE, texture);
110 	mat_info->set_cull_mode(false);
111 	mat_info->set_color(1.0f, 1.0f, 1.0f, 1.0f);
112 }
113 
material_set_distortion(distortion_material * mat_info,int texture,bool thruster)114 void material_set_distortion(distortion_material *mat_info, int texture, bool thruster)
115 {
116 	mat_info->set_thruster_rendering(thruster);
117 
118 	mat_info->set_depth_mode(ZBUFFER_TYPE_READ);
119 
120 	mat_info->set_blend_mode(ALPHA_BLEND_ALPHA_BLEND_ALPHA);
121 
122 	mat_info->set_texture_map(TM_BASE_TYPE, texture);
123 	mat_info->set_cull_mode(false);
124 	mat_info->set_color(1.0f, 1.0f, 1.0f, 1.0f);
125 }
material_set_rocket_interface(interface_material * mat_info,int texture,const vec2d & offset,float horizontal_swipe)126 void material_set_rocket_interface(interface_material* mat_info,
127 	int texture,
128 	const vec2d& offset,
129 	float horizontal_swipe)
130 {
131 	mat_info->set_texture_map(TM_BASE_TYPE, texture);
132 	mat_info->set_offset(offset);
133 	mat_info->set_horizontal_swipe(horizontal_swipe);
134 
135 	mat_info->set_cull_mode(false);
136 	mat_info->set_color(1.0f, 1.0f, 1.0f, 1.0f);
137 
138 	mat_info->set_depth_mode(ZBUFFER_TYPE_NONE);
139 
140 	mat_info->set_blend_mode(ALPHA_BLEND_ALPHA_BLEND_ALPHA);
141 
142 	mat_info->set_texture_type(material::TEX_TYPE_INTERFACE);
143 }
144 
material_set_movie(movie_material * mat_info,int y_bm,int u_bm,int v_bm)145 void material_set_movie(movie_material* mat_info, int y_bm, int u_bm, int v_bm) {
146 	mat_info->set_depth_mode(ZBUFFER_TYPE_NONE);
147 	mat_info->set_blend_mode(ALPHA_BLEND_ALPHA_BLEND_ALPHA);
148 
149 	mat_info->set_cull_mode(false);
150 	mat_info->set_color(1.0f, 1.0f, 1.0f, 1.0f);
151 
152 	mat_info->setYtex(y_bm);
153 	mat_info->setUtex(u_bm);
154 	mat_info->setVtex(v_bm);
155 
156 	mat_info->set_texture_type(material::TEX_TYPE_AABITMAP);
157 }
158 
material_set_batched_bitmap(batched_bitmap_material * mat_info,int base_tex,float alpha,float color_scale)159 void material_set_batched_bitmap(batched_bitmap_material* mat_info, int base_tex, float alpha, float color_scale) {
160 	material_set_unlit(mat_info, base_tex, alpha, true, true);
161 
162 	mat_info->set_color_scale(color_scale);
163 }
material_set_nanovg(nanovg_material * mat_info,int base_tex)164 void material_set_nanovg(nanovg_material* mat_info, int base_tex) {
165 	material_set_unlit(mat_info, base_tex, 1.0f, true, false);
166 
167 	mat_info->set_cull_mode(false);
168 
169 	mat_info->set_color_mask(true, true, true, true);
170 
171 	mat_info->set_blend_mode(ALPHA_BLEND_PREMULTIPLIED);
172 
173 	mat_info->set_stencil_mask(0xFFFFFFFF);
174 	mat_info->set_stencil_func(ComparisionFunction::Always, 0, 0xFFFFFFFF);
175 	mat_info->set_front_stencil_op(StencilOperation::Keep, StencilOperation::Keep, StencilOperation::Keep);
176 	mat_info->set_back_stencil_op(StencilOperation::Keep, StencilOperation::Keep, StencilOperation::Keep);
177 }
178 
material_set_decal(material * mat_info,int diffuse_tex,int glow_tex,int normal_tex)179 void material_set_decal(material* mat_info, int diffuse_tex, int glow_tex, int normal_tex) {
180 	mat_info->set_depth_mode(ZBUFFER_TYPE_READ);
181 
182 	mat_info->set_blend_mode(0, material_determine_blend_mode(diffuse_tex, true));
183 	mat_info->set_blend_mode(1, ALPHA_BLEND_ADDITIVE); // Normal blending must always be additive
184 	mat_info->set_blend_mode(2, material_determine_blend_mode(glow_tex, true));
185 
186 	mat_info->set_texture_map(TM_BASE_TYPE, diffuse_tex);
187 	mat_info->set_texture_map(TM_GLOW_TYPE, glow_tex);
188 	mat_info->set_texture_map(TM_NORMAL_TYPE, normal_tex);
189 	mat_info->set_cull_mode(false);
190 
191 	// Done't write the alpha channel in any case since that will cause changes to other material properties
192 	// TODO: If decals should be able to change more than just the material diffuse color then a solution with separate
193 	// blending equations must be used
194 	mat_info->set_color_mask(true, true, true, false);
195 }
196 
material()197 material::material():
198 Sdr_type(SDR_TYPE_DEFAULT_MATERIAL),
199 Tex_type(TEX_TYPE_NORMAL),
200 Texture_addressing(TMAP_ADDRESS_WRAP),
201 Depth_mode(ZBUFFER_TYPE_NONE),
202 Blend_mode(ALPHA_BLEND_ALPHA_BLEND_ALPHA),
203 Cull_mode(true),
204 Fill_mode(GR_FILL_MODE_SOLID),
205 Clr_scale(1.0f),
206 Depth_bias(0)
207 {
208 	Clr.xyzw.x = 1.0f;
209 	Clr.xyzw.y = 1.0f;
210 	Clr.xyzw.z = 1.0f;
211 	Clr.xyzw.w = 1.0f;
212 
213 	Texture_maps[TM_BASE_TYPE]		= -1;
214 	Texture_maps[TM_GLOW_TYPE]		= -1;
215 	Texture_maps[TM_SPECULAR_TYPE]	= -1;
216 	Texture_maps[TM_NORMAL_TYPE]	= -1;
217 	Texture_maps[TM_HEIGHT_TYPE]	= -1;
218 	Texture_maps[TM_MISC_TYPE]		= -1;
219 	Texture_maps[TM_SPEC_GLOSS_TYPE] = -1;
220 	Texture_maps[TM_AMBIENT_TYPE] = -1;
221 
222 	Clip_params.enabled = false;
223 
224 	Color_mask.x = true;
225 	Color_mask.y = true;
226 	Color_mask.z = true;
227 	Color_mask.w = true;
228 
229 	Buffer_blend_mode.fill(Blend_mode);
230 };
231 
set_shader_type(shader_type init_sdr_type)232 void material::set_shader_type(shader_type init_sdr_type)
233 {
234 	Sdr_type = init_sdr_type;
235 }
236 
get_shader_flags() const237 uint material::get_shader_flags() const
238 {
239 	return 0;
240 }
241 
get_shader_handle() const242 int material::get_shader_handle() const
243 {
244 	return gr_maybe_create_shader(Sdr_type, get_shader_flags());
245 }
246 
set_texture_map(int tex_type,int texture_num)247 void material::set_texture_map(int tex_type, int texture_num)
248 {
249 	Assert(tex_type > -1 && tex_type < TM_NUM_TYPES);
250 
251 	Texture_maps[tex_type] = texture_num;
252 }
253 
get_texture_map(int tex_type) const254 int material::get_texture_map(int tex_type) const
255 {
256 	Assert(tex_type > -1 && tex_type < TM_NUM_TYPES);
257 
258 	return Texture_maps[tex_type];
259 }
260 
is_textured() const261 bool material::is_textured() const
262 {
263 	return
264 	Texture_maps[TM_BASE_TYPE]		> -1 ||
265 	Texture_maps[TM_GLOW_TYPE]		> -1 ||
266 	Texture_maps[TM_SPECULAR_TYPE]	> -1 ||
267 	Texture_maps[TM_NORMAL_TYPE]	> -1 ||
268 	Texture_maps[TM_HEIGHT_TYPE]	> -1 ||
269 	Texture_maps[TM_MISC_TYPE]		> -1;
270 }
271 
set_texture_type(texture_type t_type)272 void material::set_texture_type(texture_type t_type)
273 {
274 	Tex_type = t_type;
275 }
276 
get_texture_type() const277 int material::get_texture_type() const
278 {
279 	switch ( Tex_type ) {
280 	default:
281 	case TEX_TYPE_NORMAL:
282 		return TCACHE_TYPE_NORMAL;
283 	case TEX_TYPE_XPARENT:
284 		return TCACHE_TYPE_XPARENT;
285 	case TEX_TYPE_INTERFACE:
286 		return TCACHE_TYPE_INTERFACE;
287 	case TEX_TYPE_AABITMAP:
288 		return TCACHE_TYPE_AABITMAP;
289 	}
290 }
291 
is_clipped() const292 bool material::is_clipped() const
293 {
294 	return Clip_params.enabled;
295 }
296 
set_clip_plane(const vec3d & normal,const vec3d & position)297 void material::set_clip_plane(const vec3d &normal, const vec3d &position)
298 {
299 	Clip_params.enabled = true;
300 	Clip_params.normal = normal;
301 	Clip_params.position = position;
302 }
303 
set_clip_plane()304 void material::set_clip_plane()
305 {
306 	Clip_params.enabled = false;
307 }
308 
get_clip_plane() const309 const material::clip_plane& material::get_clip_plane() const
310 {
311 	return Clip_params;
312 }
313 
set_texture_addressing(int addressing)314 void material::set_texture_addressing(int addressing)
315 {
316 	Texture_addressing = addressing;
317 }
318 
get_texture_addressing() const319 int material::get_texture_addressing() const
320 {
321 	return Texture_addressing;
322 }
323 
set_depth_mode(gr_zbuffer_type mode)324 void material::set_depth_mode(gr_zbuffer_type mode)
325 {
326 	Depth_mode = mode;
327 }
328 
get_depth_mode() const329 gr_zbuffer_type material::get_depth_mode() const
330 {
331 	return Depth_mode;
332 }
333 
set_cull_mode(bool mode)334 void material::set_cull_mode(bool mode)
335 {
336 	Cull_mode = mode;
337 }
338 
get_cull_mode() const339 bool material::get_cull_mode() const
340 {
341 	return Cull_mode;
342 }
343 
set_fill_mode(int mode)344 void material::set_fill_mode(int mode)
345 {
346 	Fill_mode = mode;
347 }
348 
get_fill_mode() const349 int material::get_fill_mode() const
350 {
351 	return Fill_mode;
352 }
353 
set_blend_mode(gr_alpha_blend mode)354 void material::set_blend_mode(gr_alpha_blend mode)
355 {
356 	Blend_mode = mode;
357 	Has_buffer_blends = false;
358 	Buffer_blend_mode.fill(mode);
359 }
360 
set_blend_mode(int buffer,gr_alpha_blend mode)361 void material::set_blend_mode(int buffer, gr_alpha_blend mode)
362 {
363 	Assertion(buffer >= 0 && buffer < (int) Buffer_blend_mode.size(), "Invalid buffer index %d found!", buffer);
364 
365 	Has_buffer_blends = true;
366 	Buffer_blend_mode[buffer] = mode;
367 }
368 
has_buffer_blend_modes() const369 bool material::has_buffer_blend_modes() const {
370 	return Has_buffer_blends;
371 }
372 
get_blend_mode(int buffer) const373 gr_alpha_blend material::get_blend_mode(int buffer) const
374 {
375 	if (!Has_buffer_blends) {
376 		return Blend_mode;
377 	}
378 
379 	Assertion(buffer >= 0 && buffer < (int) Buffer_blend_mode.size(), "Invalid buffer index %d found!", buffer);
380 
381 	return Buffer_blend_mode[buffer];
382 }
383 
set_depth_bias(int bias)384 void material::set_depth_bias(int bias)
385 {
386 	Depth_bias = bias;
387 }
388 
get_depth_bias() const389 int material::get_depth_bias() const
390 {
391 	return Depth_bias;
392 }
393 
set_color(float red,float green,float blue,float alpha)394 void material::set_color(float red, float green, float blue, float alpha)
395 {
396 	Clr.xyzw.x = red;
397 	Clr.xyzw.y = green;
398 	Clr.xyzw.z = blue;
399 	Clr.xyzw.w = alpha;
400 }
401 
set_color(int r,int g,int b,int a)402 void material::set_color(int r, int g, int b, int a)
403 {
404 	CLAMP(r, 0, 255);
405 	CLAMP(b, 0, 255);
406 	CLAMP(g, 0, 255);
407 	CLAMP(a, 0, 255);
408 
409 	Clr.xyzw.x = i2fl(r) / 255.0f;
410 	Clr.xyzw.y = i2fl(g) / 255.0f;
411 	Clr.xyzw.z = i2fl(b) / 255.0f;
412 	Clr.xyzw.w = i2fl(a) / 255.0f;
413 }
414 
set_color(color & clr_in)415 void material::set_color(color &clr_in)
416 {
417 	if ( clr_in.is_alphacolor ) {
418 		Clr.xyzw.x = i2fl(clr_in.red) / 255.0f;
419 		Clr.xyzw.y = i2fl(clr_in.green) / 255.0f;
420 		Clr.xyzw.z = i2fl(clr_in.blue) / 255.0f;
421 		Clr.xyzw.w = i2fl(clr_in.alpha) / 255.0f;
422 	} else {
423 		Clr.xyzw.x = i2fl(clr_in.red) / 255.0f;
424 		Clr.xyzw.y = i2fl(clr_in.green) / 255.0f;
425 		Clr.xyzw.z = i2fl(clr_in.blue) / 255.0f;
426 		Clr.xyzw.w = 1.0f;
427 	}
428 }
429 
get_color() const430 const vec4& material::get_color() const
431 {
432 	return Clr;
433 }
434 
set_color_scale(float scale)435 void material::set_color_scale(float scale)
436 {
437 	Clr_scale = scale;
438 }
439 
get_color_scale() const440 float material::get_color_scale() const
441 {
442 	return Clr_scale;
443 }
set_stencil_test(bool stencil)444 void material::set_stencil_test(bool stencil) {
445 	Stencil_test = stencil;
446 }
is_stencil_enabled() const447 bool material::is_stencil_enabled() const {
448 	return Stencil_test;
449 }
set_stencil_mask(uint32_t mask)450 void material::set_stencil_mask(uint32_t mask) {
451 	Stencil_mask = mask;
452 }
get_stencil_mask() const453 uint32_t material::get_stencil_mask() const {
454 	return Stencil_mask;
455 }
set_stencil_func(ComparisionFunction compare,int ref,uint32_t mask)456 void material::set_stencil_func(ComparisionFunction compare, int ref, uint32_t mask) {
457 	Stencil_func.compare = compare;
458 	Stencil_func.ref = ref;
459 	Stencil_func.mask = mask;
460 }
get_stencil_func() const461 const material::StencilFunc& material::get_stencil_func() const {
462 	return Stencil_func;
463 }
set_stencil_op(StencilOperation stencilFailOperation,StencilOperation depthFailOperation,StencilOperation successOperation)464 void material::set_stencil_op(StencilOperation stencilFailOperation,
465 							  StencilOperation depthFailOperation,
466 							  StencilOperation successOperation) {
467 	set_front_stencil_op(stencilFailOperation, depthFailOperation, successOperation);
468 	set_back_stencil_op(stencilFailOperation, depthFailOperation, successOperation);
469 }
set_front_stencil_op(StencilOperation stencilFailOperation,StencilOperation depthFailOperation,StencilOperation successOperation)470 void material::set_front_stencil_op(StencilOperation stencilFailOperation,
471 									StencilOperation depthFailOperation,
472 									StencilOperation successOperation) {
473 	Front_stencil_op.stencilFailOperation = stencilFailOperation;
474 	Front_stencil_op.depthFailOperation = depthFailOperation;
475 	Front_stencil_op.successOperation = successOperation;
476 }
get_front_stencil_op() const477 const material::StencilOp& material::get_front_stencil_op() const {
478 	return Front_stencil_op;
479 }
set_back_stencil_op(StencilOperation stencilFailOperation,StencilOperation depthFailOperation,StencilOperation successOperation)480 void material::set_back_stencil_op(StencilOperation stencilFailOperation,
481 								   StencilOperation depthFailOperation,
482 								   StencilOperation successOperation) {
483 	Back_stencil_op.stencilFailOperation = stencilFailOperation;
484 	Back_stencil_op.depthFailOperation = depthFailOperation;
485 	Back_stencil_op.successOperation = successOperation;
486 }
get_back_stencil_op() const487 const material::StencilOp& material::get_back_stencil_op() const {
488 	return Back_stencil_op;
489 }
set_color_mask(bool red,bool green,bool blue,bool alpha)490 void material::set_color_mask(bool red, bool green, bool blue, bool alpha) {
491 	Color_mask.x = red;
492 	Color_mask.y = green;
493 	Color_mask.z = blue;
494 	Color_mask.w = alpha;
495 }
get_color_mask() const496 const bvec4& material::get_color_mask() const {
497 	return Color_mask;
498 }
499 
model_material()500 model_material::model_material() : material() {
501 	set_shader_type(SDR_TYPE_MODEL);
502 }
503 
set_desaturation(bool enabled)504 void model_material::set_desaturation(bool enabled)
505 {
506 	Desaturate = enabled;
507 }
508 
is_desaturated() const509 bool model_material::is_desaturated() const
510 {
511 	return Desaturate;
512 }
513 
set_shadow_casting(bool enabled)514 void model_material::set_shadow_casting(bool enabled)
515 {
516 	Shadow_casting = enabled;
517 }
518 
is_shadow_casting() const519 bool model_material::is_shadow_casting() const {
520 	return Shadow_casting;
521 }
522 
set_shadow_receiving(bool enabled)523 void model_material::set_shadow_receiving(bool enabled) {
524 	Shadow_receiving = enabled;
525 }
526 
is_shadow_receiving() const527 bool model_material::is_shadow_receiving() const {
528 	return Shadow_receiving;
529 }
530 
set_light_factor(float factor)531 void model_material::set_light_factor(float factor)
532 {
533 	Light_factor = factor;
534 }
535 
get_light_factor() const536 float model_material::get_light_factor() const
537 {
538 	return Light_factor;
539 }
540 
set_lighting(bool mode)541 void model_material::set_lighting(bool mode)
542 {
543 	lighting = mode;
544 }
545 
is_lit() const546 bool model_material::is_lit() const
547 {
548 	return lighting;
549 }
550 
set_deferred_lighting(bool enabled)551 void model_material::set_deferred_lighting(bool enabled)
552 {
553 	Deferred = enabled;
554 }
555 
set_high_dynamic_range(bool enabled)556 void model_material::set_high_dynamic_range(bool enabled)
557 {
558 	HDR = enabled;
559 }
560 
set_center_alpha(int c_alpha)561 void model_material::set_center_alpha(int c_alpha)
562 {
563 	Center_alpha = c_alpha;
564 }
565 
get_center_alpha() const566 int model_material::get_center_alpha() const
567 {
568 	return Center_alpha;
569 }
570 
set_thrust_scale(float scale)571 void model_material::set_thrust_scale(float scale)
572 {
573 	Thrust_scale = scale;
574 }
575 
get_thrust_scale() const576 float model_material::get_thrust_scale() const
577 {
578 	return Thrust_scale;
579 }
580 
set_team_color(const team_color & team_clr)581 void model_material::set_team_color(const team_color &team_clr)
582 {
583 	Team_color_set = true;
584 	Tm_color = team_clr;
585 }
586 
set_team_color()587 void model_material::set_team_color()
588 {
589 	Team_color_set = false;
590 }
591 
get_team_color() const592 const team_color& model_material::get_team_color() const
593 {
594 	return Tm_color;
595 }
596 
set_animated_effect(int effect,float time)597 void model_material::set_animated_effect(int effect, float time)
598 {
599 	Animated_effect = effect;
600 	Animated_timer = time;
601 }
602 
set_animated_effect()603 void model_material::set_animated_effect()
604 {
605 	Animated_effect = 0;
606 	Animated_timer = 0.0f;
607 }
608 
get_animated_effect() const609 int model_material::get_animated_effect() const
610 {
611 	return Animated_effect;
612 }
613 
get_animated_effect_time() const614 float model_material::get_animated_effect_time() const
615 {
616 	return Animated_timer;
617 }
618 
set_batching(bool enabled)619 void model_material::set_batching(bool enabled)
620 {
621 	Batched = enabled;
622 }
623 
is_batched() const624 bool model_material::is_batched() const
625 {
626 	return Batched;
627 }
628 
set_normal_alpha(float min,float max)629 void model_material::set_normal_alpha(float min, float max)
630 {
631 	Normal_alpha = true;
632 	Normal_alpha_min = min;
633 	Normal_alpha_max = max;
634 }
635 
set_normal_alpha()636 void model_material::set_normal_alpha()
637 {
638 	Normal_alpha = false;
639 }
640 
is_normal_alpha_active() const641 bool model_material::is_normal_alpha_active() const
642 {
643 	return Normal_alpha;
644 }
645 
get_normal_alpha_min() const646 float model_material::get_normal_alpha_min() const
647 {
648 	return Normal_alpha_min;
649 }
650 
get_normal_alpha_max() const651 float model_material::get_normal_alpha_max() const
652 {
653 	return Normal_alpha_max;
654 }
655 
set_fog(int r,int g,int b,float _near,float _far)656 void model_material::set_fog(int r, int g, int b, float _near, float _far)
657 {
658 	Fog_params.enabled = true;
659 	Fog_params.r = r;
660 	Fog_params.g = g;
661 	Fog_params.b = b;
662 	Fog_params.dist_near = _near;
663 	Fog_params.dist_far = _far;
664 }
665 
set_fog()666 void model_material::set_fog()
667 {
668 	Fog_params.enabled = false;
669 }
670 
is_fogged() const671 bool model_material::is_fogged() const
672 {
673 	return Fog_params.enabled;
674 }
675 
get_fog() const676 const model_material::fog& model_material::get_fog() const
677 {
678 	return Fog_params;
679 }
680 
set_outline_thickness(float thickness)681 void model_material::set_outline_thickness(float thickness) {
682 	Outline_thickness = thickness;
683 }
get_outline_thickness() const684 float model_material::get_outline_thickness() const {
685 	return Outline_thickness;
686 }
uses_thick_outlines() const687 bool model_material::uses_thick_outlines() const {
688 	return Outline_thickness > 0.0f;
689 }
690 
get_shader_flags() const691 uint model_material::get_shader_flags() const
692 {
693 	uint Shader_flags = 0;
694 
695 	if ( is_clipped() ) {
696 		Shader_flags |= SDR_FLAG_MODEL_CLIP;
697 	}
698 
699 	if ( is_batched() ) {
700 		Shader_flags |= SDR_FLAG_MODEL_TRANSFORM;
701 	}
702 
703 	if ( Shadow_casting ) {
704 		// if we're building the shadow map, we likely only need the flags here and above so bail
705 		Shader_flags |= SDR_FLAG_MODEL_SHADOW_MAP;
706 
707 		return Shader_flags;
708 	}
709 
710 	if ( is_fogged() ) {
711 		Shader_flags |= SDR_FLAG_MODEL_FOG;
712 	}
713 
714 	if ( Animated_effect >= 0 ) {
715 		Shader_flags |= SDR_FLAG_MODEL_ANIMATED;
716 	}
717 
718 	if ( get_texture_map(TM_BASE_TYPE) > 0 && !Basemap_override ) {
719 		Shader_flags |= SDR_FLAG_MODEL_DIFFUSE_MAP;
720 	}
721 
722 	if ( get_texture_map(TM_GLOW_TYPE) > 0 ) {
723 		Shader_flags |= SDR_FLAG_MODEL_GLOW_MAP;
724 	}
725 
726 	if ( (get_texture_map(TM_SPECULAR_TYPE) > 0 || get_texture_map(TM_SPEC_GLOSS_TYPE) > 0) && !Specmap_override ) {
727 		Shader_flags |= SDR_FLAG_MODEL_SPEC_MAP;
728 
729 		if ( (ENVMAP > 0) && !Envmap_override ) {
730 			Shader_flags |= SDR_FLAG_MODEL_ENV_MAP;
731 		}
732 	}
733 
734 	if ( (get_texture_map(TM_NORMAL_TYPE) > 0) && !Normalmap_override ) {
735 		Shader_flags |= SDR_FLAG_MODEL_NORMAL_MAP;
736 	}
737 
738 	if ( (get_texture_map(TM_HEIGHT_TYPE) > 0) && !Heightmap_override ) {
739 		Shader_flags |= SDR_FLAG_MODEL_HEIGHT_MAP;
740 	}
741 
742 	if ( get_texture_map(TM_AMBIENT_TYPE) > 0) {
743 		Shader_flags |= SDR_FLAG_MODEL_AMBIENT_MAP;
744 	}
745 
746 	if ( lighting ) {
747 		Shader_flags |= SDR_FLAG_MODEL_LIGHT;
748 
749 		if ( Shadow_receiving && !Shadow_override ) {
750 			Shader_flags |= SDR_FLAG_MODEL_SHADOWS;
751 		}
752 	}
753 
754 	if ( get_texture_map(TM_MISC_TYPE) > 0 ) {
755 		Shader_flags |= SDR_FLAG_MODEL_MISC_MAP;
756 
757 		if ( Team_color_set ) {
758 			Shader_flags |= SDR_FLAG_MODEL_TEAMCOLOR;
759 		}
760 	}
761 
762 	if ( Deferred ) {
763 		Shader_flags |= SDR_FLAG_MODEL_DEFERRED;
764 	}
765 
766 	if ( HDR ) {
767 		Shader_flags |= SDR_FLAG_MODEL_HDR;
768 	}
769 
770 	if ( Thrust_scale > 0.0f ) {
771 		Shader_flags |= SDR_FLAG_MODEL_THRUSTER;
772 	}
773 
774 	if ( Normal_alpha ) {
775 		Shader_flags |= SDR_FLAG_MODEL_NORMAL_ALPHA;
776 	}
777 
778 	if ( uses_thick_outlines() ) {
779 		Shader_flags |= SDR_FLAG_MODEL_THICK_OUTLINES;
780 	}
781 
782 	return Shader_flags;
783 }
784 
particle_material()785 particle_material::particle_material():
786 material()
787 {
788 	set_shader_type(SDR_TYPE_EFFECT_PARTICLE);
789 }
790 
set_point_sprite_mode(bool enabled)791 void particle_material::set_point_sprite_mode(bool enabled)
792 {
793 	Point_sprite = enabled;
794 }
795 
get_point_sprite_mode()796 bool particle_material::get_point_sprite_mode()
797 {
798 	return Point_sprite;
799 }
800 
get_shader_flags() const801 uint particle_material::get_shader_flags() const
802 {
803 	uint flags = 0;
804 
805 	if ( Point_sprite ) {
806 		flags |= SDR_FLAG_PARTICLE_POINT_GEN;
807 	}
808 
809 	return flags;
810 }
811 
distortion_material()812 distortion_material::distortion_material():
813 material()
814 {
815 	set_shader_type(SDR_TYPE_EFFECT_DISTORTION);
816 }
817 
set_thruster_rendering(bool enabled)818 void distortion_material::set_thruster_rendering(bool enabled)
819 {
820 	Thruster_render = enabled;
821 }
822 
get_thruster_rendering()823 bool distortion_material::get_thruster_rendering()
824 {
825 	return Thruster_render;
826 }
827 
shield_material()828 shield_material::shield_material() :
829 	material()
830 {
831 	set_shader_type(SDR_TYPE_SHIELD_DECAL);
832 
833 	vm_set_identity(&Impact_orient);
834 
835 	Impact_pos.xyz.x = 0.0f;
836 	Impact_pos.xyz.y = 0.0f;
837 	Impact_pos.xyz.z = 0.0f;
838 
839 	Impact_radius = 1.0f;
840 }
841 
set_impact_transform(matrix & orient,vec3d & pos)842 void shield_material::set_impact_transform(matrix &orient, vec3d &pos)
843 {
844 	Impact_orient = orient;
845 	Impact_pos = pos;
846 }
847 
set_impact_radius(float radius)848 void shield_material::set_impact_radius(float radius)
849 {
850 	Impact_radius = radius;
851 }
852 
get_impact_orient()853 const matrix& shield_material::get_impact_orient()
854 {
855 	return Impact_orient;
856 }
857 
get_impact_pos()858 const vec3d& shield_material::get_impact_pos()
859 {
860 	return Impact_pos;
861 }
862 
get_impact_radius()863 float shield_material::get_impact_radius()
864 {
865 	return Impact_radius;
866 }
867 
movie_material()868 movie_material::movie_material() : material() {
869 	set_shader_type(SDR_TYPE_VIDEO_PROCESS);
870 }
getYtex() const871 int movie_material::getYtex() const {
872 	return Ytex;
873 }
getUtex() const874 int movie_material::getUtex() const {
875 	return Utex;
876 }
getVtex() const877 int movie_material::getVtex() const {
878 	return Vtex;
879 }
setYtex(int _Ytex)880 void movie_material::setYtex(int _Ytex) {
881 	this->Ytex = _Ytex;
882 }
setUtex(int _Utex)883 void movie_material::setUtex(int _Utex) {
884 	this->Utex = _Utex;
885 }
setVtex(int _Vtex)886 void movie_material::setVtex(int _Vtex) {
887 	movie_material::Vtex = _Vtex;
888 }
889 
batched_bitmap_material()890 batched_bitmap_material::batched_bitmap_material() {
891 	set_shader_type(SDR_TYPE_BATCHED_BITMAP);
892 }
893 
nanovg_material()894 nanovg_material::nanovg_material() {
895 	set_shader_type(SDR_TYPE_NANOVG);
896 }
897 
decal_material()898 decal_material::decal_material() {
899 	set_shader_type(SDR_TYPE_DECAL);
900 }
get_shader_flags() const901 uint decal_material::get_shader_flags() const {
902 	uint flags = 0;
903 
904 	if (get_texture_map(TM_NORMAL_TYPE) == -1) {
905 		// If we don't write to the normal map then we can use the existing normal map for better normal accuracy
906 		flags |= SDR_FLAG_DECAL_USE_NORMAL_MAP;
907 	}
908 
909 	return flags;
910 }
911 
interface_material()912 interface_material::interface_material()
913 {
914 	set_shader_type(SDR_TYPE_ROCKET_UI);
915 
916 	offset.x = 0;
917 	offset.y = 0;
918 }
set_offset(const vec2d & new_offset)919 void interface_material::set_offset(const vec2d& new_offset) { this->offset = new_offset; }
get_offset() const920 vec2d interface_material::get_offset() const { return offset; }
set_horizontal_swipe(float hor_offset)921 void interface_material::set_horizontal_swipe(float hor_offset) { this->horizontalSwipeOff = hor_offset; }
get_horizontal_swipe() const922 float interface_material::get_horizontal_swipe() const { return this->horizontalSwipeOff; }
923