1 /*
2  * Copyright (C) Freespace Open 2013.  All rights reserved.
3  *
4  * All source code herein is the property of Freespace Open. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 #ifndef _MODELRENDER_H
11 #define _MODELRENDER_H
12 
13 #include "graphics/material.h"
14 #include "lighting/lighting.h"
15 #include "math/vecmat.h"
16 #include "model/model.h"
17 #include "mission/missionparse.h"
18 #include "graphics/util/UniformBuffer.h"
19 
20 extern SCP_vector<light> Lights;
21 extern int Num_lights;
22 
23 extern bool Rendering_to_shadow_map;
24 
25 extern matrix Object_matrix;
26 extern vec3d Object_position;
27 
28 extern color Wireframe_color;
29 
in_box(vec3d * min,vec3d * max,vec3d * pos,vec3d * view_position)30 inline int in_box(vec3d *min, vec3d *max, vec3d *pos, vec3d *view_position)
31 {
32 	vec3d point;
33 
34 	vm_vec_sub(&point, view_position, pos);
35 
36 	if ( (point.xyz.x >= min->xyz.x) && (point.xyz.x <= max->xyz.x)
37 		&& (point.xyz.y >= min->xyz.y) && (point.xyz.y <= max->xyz.y)
38 		&& (point.xyz.z >= min->xyz.z) && (point.xyz.z <= max->xyz.z) )
39 	{
40 		return 1;
41 	}
42 
43 	return -1;
44 }
45 
in_sphere(vec3d * pos,float radius,vec3d * view_position)46 inline int in_sphere(vec3d *pos, float radius, vec3d *view_position)
47 {
48 	if ( vm_vec_dist(view_position, pos) <= radius )
49 		return 1;
50 	else
51 		return -1;
52 }
53 
54 extern int model_interp_get_texture(texture_info *tinfo, fix base_frametime);
55 
56 class model_render_params
57 {
58 	uint Model_flags;
59 	uint Debug_flags;
60 
61 	int Objnum;
62 
63 	int Detail_level_locked;
64 
65 	float Depth_scale;
66 
67 	int Warp_bitmap;
68 	float Warp_alpha;
69 	vec3d Warp_scale;
70 
71 	color Color;
72 
73 	float Xparent_alpha;
74 
75 	int Forced_bitmap;
76 
77 	int Insignia_bitmap;
78 
79 	int *Replacement_textures;
80 	bool Manage_replacement_textures; // This is set when we are rendering a model without an associated ship object;
81 									  // in that case, model_render_params is responsible for allocating and destroying
82 									  // the Replacement_textures array (this is handled elsewhere otherwise)
83 
84 	bool Team_color_set;
85 	team_color Current_team_color;
86 
87 	bool Clip_plane_set;
88 	vec3d Clip_normal;
89 	vec3d Clip_pos;
90 
91 	int Animated_effect;
92 	float Animated_timer;
93 
94 	mst_info Thruster_info;
95 
96 	bool Normal_alpha;
97 	float Normal_alpha_min;
98 	float Normal_alpha_max;
99 
100 	float Outline_thickness = -1.0f;
101 
102 	model_render_params(const model_render_params&) = delete;
103 	model_render_params& operator=(const model_render_params&) = delete;
104 public:
105 	model_render_params();
106 	~model_render_params();
107 
108 	void set_flags(uint flags);
109 	void set_debug_flags(uint flags);
110 	void set_object_number(int num);
111 	void set_detail_level_lock(int detail_level_lock);
112 	void set_depth_scale(float scale);
113 	void set_warp_params(int bitmap, float alpha, vec3d &scale);
114 	void set_color(color &clr);
115 	void set_color(int r, int g, int b);
116 	void set_alpha(float alpha);
117 	void set_forced_bitmap(int bitmap);
118 	void set_insignia_bitmap(int bitmap);
119 	void set_replacement_textures(int *textures);
120 	void set_replacement_textures(int modelnum, SCP_vector<texture_replace>& replacement_textures);
121 	void set_team_color(team_color &clr);
122 	void set_team_color(const SCP_string &team, const SCP_string &secondaryteam, fix timestamp, int fadetime);
123 	void set_clip_plane(vec3d &pos, vec3d &normal);
124 	void set_animated_effect(int effect_num, float timer);
125 	void set_thruster_info(mst_info &info);
126 	void set_normal_alpha(float min, float max);
127 	void set_outline_thickness(float thick);
128 
129 	bool is_clip_plane_set();
130 	bool is_team_color_set();
131 	bool is_normal_alpha_set();
132 	bool uses_thick_outlines();
133 
134 	uint get_model_flags();
135 	uint get_debug_flags();
136 	int get_object_number();
137 	int get_detail_level_lock();
138 	float get_depth_scale();
139 	int get_warp_bitmap();
140 	float get_warp_alpha();
141 	const vec3d& get_warp_scale();
142 	const color& get_color();
143 	float get_alpha();
144 	int get_forced_bitmap();
145 	int get_insignia_bitmap();
146 	const int* get_replacement_textures();
147 	const team_color& get_team_color();
148 	const vec3d& get_clip_plane_pos();
149 	const vec3d& get_clip_plane_normal();
150 	int get_animated_effect_num();
151 	float get_animated_effect_timer();
152 	const mst_info& get_thruster_info();
153 	float get_normal_alpha_min();
154 	float get_normal_alpha_max();
155 	float get_outline_thickness();
156 };
157 
158 struct arc_effect
159 {
160 	matrix4 transform;
161 	vec3d v1;
162 	vec3d v2;
163 	color primary;
164 	color secondary;
165 	float width;
166 };
167 
168 struct insignia_draw_data
169 {
170 	matrix4 transform;
171 	polymodel *pm;
172 	int detail_level;
173 	int bitmap_num;
174 
175 	// if there's a clip plane
176 	bool clip;
177 	vec3d clip_normal;
178 	vec3d clip_position;
179 };
180 
181 struct queued_buffer_draw
182 {
183 	size_t transform_buffer_offset = 0;
184 	size_t uniform_buffer_offset = 0;
185 
186 	model_material render_material;
187 
188 	matrix4 transform;
189 	vec3d scale;
190 
191 	indexed_vertex_source *vert_src;
192 	vertex_buffer *buffer;
193 	size_t texi;
194 	int flags;
195 	int sdr_flags;
196 
197 	light_indexing_info lights;
198 
queued_buffer_drawqueued_buffer_draw199 	queued_buffer_draw()
200 	{
201 	}
202 };
203 
204 struct outline_draw
205 {
206 	vertex* vert_array;
207 	int n_verts;
208 
209 	matrix4 transform;
210 	color clr;
211 };
212 
213 class model_batch_buffer
214 {
215 	SCP_vector<matrix4> Submodel_matrices;
216 	void* Mem_alloc;
217 	size_t Mem_alloc_size;
218 
219 	size_t Current_offset;
220 
221 	void allocate_memory();
222 public:
model_batch_buffer()223 	model_batch_buffer() : Mem_alloc(NULL), Mem_alloc_size(0), Current_offset(0) {};
224 
225 	void reset();
226 
227 	size_t get_buffer_offset();
228 	void set_num_models(int n_models);
229 	void set_model_transform(matrix4 &transform, int model_id);
230 
231 	void submit_buffer_data();
232 
233 	void add_matrix(matrix4 &mat);
234 };
235 
236 class model_draw_list
237 {
238 	vec3d Current_scale;
239 	transform_stack Transformations;
240 
241 	scene_lights Scene_light_handler;
242 	light_indexing_info Current_lights_set;
243 
244 	void render_arc(arc_effect &arc);
245 	void render_insignia(insignia_draw_data &insignia_info);
246 	void render_outline(outline_draw &outline_info);
247 	void render_buffer(queued_buffer_draw &render_elements);
248 
249 	SCP_vector<queued_buffer_draw> Render_elements;
250 	SCP_vector<int> Render_keys;
251 
252 	SCP_vector<arc_effect> Arcs;
253 	SCP_vector<insignia_draw_data> Insignias;
254 	SCP_vector<outline_draw> Outlines;
255 
256 	graphics::util::UniformBuffer _dataBuffer;
257 
258 	bool Render_initialized = false; //!< A flag for checking if init_render has been called before a render_all call
259 
260 	static bool sort_draw_pair(model_draw_list* target, const int a, const int b);
261 	void sort_draws();
262 
263 	void build_uniform_buffer();
264 public:
265 	model_draw_list();
266 	~model_draw_list();
267 
268 	model_draw_list(const model_draw_list&) = delete;
269 	model_draw_list& operator=(const model_draw_list&) = delete;
270 
271 	void init();
272 
273 	void add_submodel_to_batch(int model_num);
274 	void start_model_batch(int n_models);
275 
276 	void add_buffer_draw(model_material *render_material, indexed_vertex_source *vert_src, vertex_buffer *buffer, size_t texi, uint tmap_flags);
277 
278 	vec3d get_view_position();
279 	void push_transform(vec3d* pos, matrix* orient);
280 	void pop_transform();
281 	void set_scale(vec3d *scale = NULL);
282 
283 	void add_arc(vec3d *v1, vec3d *v2, color *primary, color *secondary, float arc_width);
284 	void render_arcs();
285 
286 	void add_insignia(model_render_params *params, polymodel *pm, int detail_level, int bitmap_num);
287 	void render_insignias();
288 
289 	void add_outline(vertex* vert_array, int n_verts, color *clr);
290 	void render_outlines();
291 
292 	void set_light_filter(int objnum, vec3d *pos, float rad);
293 
294 	void init_render(bool sort = true);
295 	void render_all(gr_zbuffer_type depth_mode = ZBUFFER_TYPE_DEFAULT);
296 	void reset();
297 };
298 
299 void model_render_immediate(model_render_params* render_info, int model_num, matrix* orient, vec3d* pos, int render = MODEL_RENDER_ALL, bool sort = true);
300 void model_render_immediate(model_render_params* render_info, int model_num, int model_instance_num, matrix* orient, vec3d* pos, int render = MODEL_RENDER_ALL, bool sort = true);
301 void model_render_queue(model_render_params* render_info, model_draw_list* scene, int model_num, matrix* orient, vec3d* pos);
302 void model_render_queue(model_render_params* render_info, model_draw_list* scene, int model_num, int model_instance_num, matrix* orient, vec3d* pos);
303 void submodel_render_immediate(model_render_params *render_info, polymodel *pm, polymodel_instance *pmi, int submodel_num, matrix *orient, vec3d * pos);
304 void submodel_render_queue(model_render_params *render_info, model_draw_list *scene, polymodel *pm, polymodel_instance *pmi, int submodel_num, matrix *orient, vec3d * pos);
305 void model_render_buffers(model_draw_list* scene, model_material *rendering_material, model_render_params* interp, vertex_buffer *buffer, polymodel *pm, int mn, int detail_level, uint tmap_flags);
306 fix model_render_determine_base_frametime(int objnum, uint flags);
307 bool model_render_check_detail_box(vec3d *view_pos, polymodel *pm, int submodel_num, uint flags);
308 void model_render_arc(vec3d *v1, vec3d *v2, color *primary, color *secondary, float arc_width);
309 void model_render_insignias(insignia_draw_data *insignia);
310 void model_render_set_wireframe_color(color* clr);
311 
312 void model_render_determine_color(color *clr, float alpha, gr_alpha_blend blend_mode, bool no_texturing, bool desaturate);
313 gr_alpha_blend model_render_determine_blend_mode(int base_bitmap, bool blending);
314 
315 #endif
316