1 /*
2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
3 *
4 * All source code herein is the property of Volition, Inc. 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 _GRAPHICS_H
11 #define _GRAPHICS_H
12
13 #include "globalincs/flagset.h"
14 #include "globalincs/pstypes.h"
15
16 #include "bmpman/bmpman.h"
17 #include "cfile/cfile.h"
18 #include "graphics/grinternal.h"
19 #include "graphics/tmapper.h"
20 #include "io/cursor.h"
21 #include "math/vecmat.h"
22 #include "osapi/osapi.h"
23 #include "utils/id.h"
24
25 // Forward definition
26 namespace graphics {
27 namespace util {
28 class UniformBuffer;
29 class GPUMemoryHeap;
30 } // namespace util
31 } // namespace graphics
32 namespace scripting {
33 class OverridableHook;
34 }
35
36 extern const float Default_min_draw_distance;
37 extern const float Default_max_draw_distance;
38 extern float Min_draw_distance;
39 extern float Max_draw_distance;
40 extern int Gr_inited;
41
42 // z-buffering stuff
43 extern int gr_zbuffering, gr_zbuffering_mode;
44 extern int gr_global_zbuffering;
45
46 extern bool Gr_enable_soft_particles;
47
FLAG_LIST(FramebufferEffects)48 FLAG_LIST(FramebufferEffects){Thrusters = 0, Shockwaves, NUM_VALUES};
49 extern flagset<FramebufferEffects> Gr_framebuffer_effects;
50
51 enum class AntiAliasMode {
52 None = 0,
53
54 FXAA_Low = 1,
55 FXAA_Medium = 2,
56 FXAA_High = 3,
57
58 SMAA_Low = 4,
59 SMAA_Medium = 5,
60 SMAA_High = 6,
61 SMAA_Ultra = 7,
62 };
63 extern AntiAliasMode Gr_aa_mode;
64 extern AntiAliasMode Gr_aa_mode_last_frame;
65
66 bool gr_is_fxaa_mode(AntiAliasMode mode);
67 bool gr_is_smaa_mode(AntiAliasMode mode);
68
69 extern bool Gr_post_processing_enabled;
70
71 extern bool Gr_enable_vsync;
72
73 extern bool Deferred_lighting;
74 extern bool High_dynamic_range;
75
76 extern os::ViewportState Gr_configured_window_state;
77
78 extern const std::shared_ptr<scripting::OverridableHook> OnFrameHook;
79
80 class material;
81 class model_material;
82 class particle_material;
83 class distortion_material;
84 class shield_material;
85 class movie_material;
86 class batched_bitmap_material;
87 class nanovg_material;
88 class decal_material;
89 class interface_material;
90
91 class transform_stack {
92
93 matrix4 Current_transform;
94 SCP_vector<matrix4> Stack;
95 public:
transform_stack()96 transform_stack()
97 {
98 vm_matrix4_set_identity(&Current_transform);
99
100 Stack.clear();
101 Stack.push_back(Current_transform);
102 }
103
get_transform()104 matrix4 &get_transform()
105 {
106 return Current_transform;
107 }
108
clear()109 void clear()
110 {
111 vm_matrix4_set_identity(&Current_transform);
112
113 Stack.clear();
114 Stack.push_back(Current_transform);
115 }
116
push_and_replace(matrix4 new_transform)117 void push_and_replace(matrix4 new_transform)
118 {
119 Current_transform = new_transform;
120 Stack.push_back(Current_transform);
121 }
122
123 void push(const vec3d *pos, const matrix *orient, const vec3d *scale = NULL)
124 {
125 vec3d new_scale = SCALE_IDENTITY_VECTOR;
126 matrix new_orient = IDENTITY_MATRIX;
127 vec3d new_pos = ZERO_VECTOR;
128
129 matrix4 current_transform_copy = Current_transform;
130 matrix4 new_transform;
131
132 if ( pos != NULL ) {
133 new_pos = *pos;
134 }
135
136 if ( orient != NULL ) {
137 new_orient = *orient;
138 }
139
140 if ( scale != NULL ) {
141 new_scale = *scale;
142 }
143
144 vm_vec_scale(&new_orient.vec.rvec, new_scale.xyz.x);
145 vm_vec_scale(&new_orient.vec.uvec, new_scale.xyz.y);
146 vm_vec_scale(&new_orient.vec.fvec, new_scale.xyz.z);
147
148 vm_matrix4_set_transform(&new_transform, &new_orient, &new_pos);
149
150 vm_matrix4_x_matrix4(&Current_transform, ¤t_transform_copy, &new_transform);
151 Stack.push_back(Current_transform);
152 }
153
pop()154 void pop()
155 {
156 if ( Stack.size() > 1 ) {
157 Stack.pop_back();
158 }
159
160 Current_transform = Stack.back();
161 }
162
depth()163 size_t depth() {
164 return Stack.size();
165 }
166 };
167
168 enum primitive_type {
169 PRIM_TYPE_POINTS,
170 PRIM_TYPE_LINES,
171 PRIM_TYPE_LINESTRIP,
172 PRIM_TYPE_TRIS,
173 PRIM_TYPE_TRISTRIP,
174 PRIM_TYPE_TRIFAN,
175 };
176
177 enum shader_type {
178 SDR_TYPE_NONE = -1,
179 SDR_TYPE_MODEL,
180 SDR_TYPE_EFFECT_PARTICLE,
181 SDR_TYPE_EFFECT_DISTORTION,
182 SDR_TYPE_POST_PROCESS_MAIN,
183 SDR_TYPE_POST_PROCESS_BLUR,
184 SDR_TYPE_POST_PROCESS_BLOOM_COMP,
185 SDR_TYPE_POST_PROCESS_BRIGHTPASS,
186 SDR_TYPE_POST_PROCESS_FXAA,
187 SDR_TYPE_POST_PROCESS_FXAA_PREPASS,
188 SDR_TYPE_POST_PROCESS_LIGHTSHAFTS,
189 SDR_TYPE_POST_PROCESS_TONEMAPPING,
190 SDR_TYPE_DEFERRED_LIGHTING,
191 SDR_TYPE_DEFERRED_CLEAR,
192 SDR_TYPE_VIDEO_PROCESS,
193 SDR_TYPE_PASSTHROUGH_RENDER, //!< Shader for doing the old style fixed-function rendering. Only used internally, use
194 //!< SDR_TYPE_DEFAULT_MATERIAL.
195 SDR_TYPE_SHIELD_DECAL,
196 SDR_TYPE_BATCHED_BITMAP,
197 SDR_TYPE_DEFAULT_MATERIAL,
198 SDR_TYPE_NANOVG,
199 SDR_TYPE_DECAL,
200 SDR_TYPE_SCENE_FOG,
201 SDR_TYPE_ROCKET_UI,
202
203 SDR_TYPE_POST_PROCESS_SMAA_EDGE,
204 SDR_TYPE_POST_PROCESS_SMAA_BLENDING_WEIGHT,
205 SDR_TYPE_POST_PROCESS_SMAA_NEIGHBORHOOD_BLENDING,
206
207 NUM_SHADER_TYPES
208 };
209
210 // Shader flags
211 #define SDR_FLAG_MODEL_LIGHT (1<<0)
212 #define SDR_FLAG_MODEL_FOG (1<<1)
213 #define SDR_FLAG_MODEL_DIFFUSE_MAP (1<<2)
214 #define SDR_FLAG_MODEL_GLOW_MAP (1<<3)
215 #define SDR_FLAG_MODEL_SPEC_MAP (1<<4)
216 #define SDR_FLAG_MODEL_NORMAL_MAP (1<<5)
217 #define SDR_FLAG_MODEL_HEIGHT_MAP (1<<6)
218 #define SDR_FLAG_MODEL_ENV_MAP (1<<7)
219 #define SDR_FLAG_MODEL_ANIMATED (1<<8)
220 #define SDR_FLAG_MODEL_MISC_MAP (1<<9)
221 #define SDR_FLAG_MODEL_TEAMCOLOR (1<<10)
222 #define SDR_FLAG_MODEL_TRANSFORM (1<<11)
223 #define SDR_FLAG_MODEL_DEFERRED (1<<12)
224 #define SDR_FLAG_MODEL_SHADOW_MAP (1<<13)
225 #define SDR_FLAG_MODEL_GEOMETRY (1<<14)
226 #define SDR_FLAG_MODEL_SHADOWS (1<<15)
227 #define SDR_FLAG_MODEL_THRUSTER (1<<16)
228 #define SDR_FLAG_MODEL_CLIP (1<<17)
229 #define SDR_FLAG_MODEL_HDR (1<<18)
230 #define SDR_FLAG_MODEL_AMBIENT_MAP (1<<19)
231 #define SDR_FLAG_MODEL_NORMAL_ALPHA (1<<20)
232 #define SDR_FLAG_MODEL_THICK_OUTLINES (1<<21) // Renders the model geometry as an outline with configurable line width
233
234 #define SDR_FLAG_PARTICLE_POINT_GEN (1<<0)
235
236 #define SDR_FLAG_BLUR_HORIZONTAL (1<<0)
237 #define SDR_FLAG_BLUR_VERTICAL (1<<1)
238
239 #define SDR_FLAG_NANOVG_EDGE_AA (1<<0)
240
241 #define SDR_FLAG_DECAL_USE_NORMAL_MAP (1<<0)
242
243 enum class uniform_block_type {
244 Lights = 0,
245 ModelData = 1,
246 NanoVGData = 2,
247 DecalInfo = 3,
248 DecalGlobals = 4,
249 DeferredGlobals = 5,
250 Matrices = 6,
251 GenericData = 7,
252
253 NUM_BLOCK_TYPES
254 };
255
256 struct vertex_format_data
257 {
258 enum vertex_format {
259 POSITION4,
260 POSITION3,
261 POSITION2,
262 SCREEN_POS,
263 COLOR3,
264 COLOR4,
265 COLOR4F,
266 TEX_COORD2,
267 TEX_COORD3,
268 NORMAL,
269 TANGENT,
270 MODEL_ID,
271 RADIUS,
272 UVEC,
273 };
274
275 vertex_format format_type;
276 size_t stride;
277 size_t offset;
278
vertex_format_datavertex_format_data279 vertex_format_data(vertex_format i_format_type, size_t i_stride, size_t i_offset) :
280 format_type(i_format_type), stride(i_stride), offset(i_offset) {}
281
maskvertex_format_data282 static inline uint mask(vertex_format v_format) { return 1 << v_format; }
283
284 bool operator==(const vertex_format_data& other) const {
285 return format_type == other.format_type && stride == other.stride && offset == other.offset;
286 }
287 };
288 class vertex_layout
289 {
290 SCP_vector<vertex_format_data> Vertex_components;
291
292 uint Vertex_mask = 0;
293 size_t Vertex_stride = 0;
294 public:
vertex_layout()295 vertex_layout() {}
296
get_num_vertex_components()297 size_t get_num_vertex_components() const { return Vertex_components.size(); }
298
get_vertex_component(size_t index)299 const vertex_format_data* get_vertex_component(size_t index) const { return &Vertex_components[index]; }
300
301 bool resident_vertex_format(vertex_format_data::vertex_format format_type) const;
302
303 void add_vertex_component(vertex_format_data::vertex_format format_type, size_t stride, size_t offset);
304
get_vertex_stride()305 size_t get_vertex_stride() { return Vertex_stride; }
306
307 bool operator==(const vertex_layout& other) const;
308
309 size_t hash() const;
310 };
311 namespace std {
312 template<> struct hash<vertex_format_data> {
313 size_t operator()(const vertex_format_data& data) const;
314 };
315 template<> struct hash<vertex_layout> {
316 size_t operator()(const vertex_layout& data) const;
317 };
318 }
319
320 typedef enum gr_capability {
321 CAPABILITY_ENVIRONMENT_MAP,
322 CAPABILITY_NORMAL_MAP,
323 CAPABILITY_HEIGHT_MAP,
324 CAPABILITY_SOFT_PARTICLES,
325 CAPABILITY_DISTORTION,
326 CAPABILITY_POST_PROCESSING,
327 CAPABILITY_DEFERRED_LIGHTING,
328 CAPABILITY_SHADOWS,
329 CAPABILITY_BATCHED_SUBMODELS,
330 CAPABILITY_POINT_PARTICLES,
331 CAPABILITY_TIMESTAMP_QUERY,
332 CAPABILITY_SEPARATE_BLEND_FUNCTIONS,
333 CAPABILITY_PERSISTENT_BUFFER_MAPPING,
334 CAPABILITY_BPTC
335 } gr_capability;
336
337 enum class gr_property
338 {
339 UNIFORM_BUFFER_OFFSET_ALIGNMENT,
340 UNIFORM_BUFFER_MAX_SIZE,
341 MAX_ANISOTROPY
342 };
343
344 struct gr_buffer_handle_tag {
345 };
346 using gr_buffer_handle = ::util::ID<gr_buffer_handle_tag, int, -1>;
347
348 // stencil buffering stuff
349 extern int gr_stencil_mode;
350
351 /**
352 * This is a structure used by the shader to keep track
353 * of the values you want to use in the shade primitive.
354 */
355 typedef struct shader {
356 uint screen_sig; // current mode this is in
357 ubyte r, g, b, c; // factors and constant
358 ubyte lookup[256];
359 } shader;
360
361 #define AC_TYPE_NONE 0 // Not an alphacolor
362 #define AC_TYPE_HUD 1 // Doesn't change hue depending on background. Used for HUD stuff.
363 #define AC_TYPE_BLEND 2 // Changes hue depending on background. Used for stars, etc.
364
365 // NEVER REFERENCE THESE VALUES OUTSIDE OF THE GRAPHICS LIBRARY!!!
366 // If you need to get the rgb values of a "color" struct call
367 // gr_get_colors after calling gr_set_colors_fast.
368 typedef struct color {
369 uint screen_sig;
370 int is_alphacolor;
371 int alphacolor;
372 int magic;
373 ubyte red;
374 ubyte green;
375 ubyte blue;
376 ubyte alpha;
377 ubyte ac_type; // The type of alphacolor. See AC_TYPE_??? defines
378 ubyte raw8;
379 } color;
380
381 // Used by the team coloring code
382 typedef struct team_color {
383 struct {
384 float r, g, b;
385 } base;
386 struct {
387 float r, g, b;
388 } stripe;
389 } team_color;
390
391
392
393 typedef struct tsb_t {
394 vec3d tangent;
395 float scaler;
396 } tsb_t;
397
398 /**
399 * This should be basicly just like it is in the VB
400 * a list of triangles and their associated normals
401 */
402 class poly_list {
403 // helper function struct that let's us sort the indices.
404 // an instance is fed into std::sort and std::lower_bound.
405 // overloaded operator() is used for the comparison function.
406 struct finder {
407 poly_list* search_list;
408 bool compare_indices;
409 vertex* vert_to_find;
410 vec3d* norm_to_find;
411
412 finder(poly_list* _search_list): search_list(_search_list), compare_indices(true), vert_to_find(NULL), norm_to_find(NULL) {}
413 finder(poly_list* _search_list, vertex* _vert, vec3d* _norm): search_list(_search_list), compare_indices(false), vert_to_find(_vert), norm_to_find(_norm) {}
414
415 bool operator()(const uint a, const uint b);
416 };
417 public:
418 poly_list(): n_verts(0), vert(NULL), norm(NULL), tsb(NULL), submodels(NULL), sorted_indices(NULL), currently_allocated(0) {}
419 ~poly_list();
420 poly_list& operator=(const poly_list&);
421
422 void allocate(int size);
423 void make_index_buffer(SCP_vector<int> &vertex_list);
424 void calculate_tangent();
425 int n_verts;
426 vertex *vert;
427 vec3d *norm;
428 tsb_t *tsb;
429 int *submodels;
430
431 uint *sorted_indices;
432
433 int find_index(poly_list *plist, int idx);
434 int find_index_fast(poly_list *plist, int idx);
435 private:
436 int currently_allocated;
437 int find_first_vertex(int idx);
438 int find_first_vertex_fast(int idx);
439 void generate_sorted_index_list();
440 };
441
442 class buffer_data
443 {
444 public:
445 int flags;
446
447 int texture; // this is the texture the vertex buffer will use
448 size_t n_verts;
449
450 size_t index_offset;
451
452 const uint *get_index() const
453 {
454 return index;
455 }
456
457 uint i_first, i_last;
458
459 void release()
460 {
461 if (index) {
462 delete [] index;
463 index = NULL;
464 }
465 }
466
467 void assign(size_t i, uint j)
468 {
469 const_cast<uint *>(index)[i] = j;
470 if (i_first > i_last)
471 i_first = i_last = j;
472 else if (i_first > j)
473 i_first = j;
474 else if (i_last < j)
475 i_last = j;
476 }
477
478 // Constructor
479
480 buffer_data() :
481 flags(0), texture(-1), n_verts(0), index_offset(0),
482 i_first(1), i_last(0), index(NULL)
483 {
484 }
485
486 explicit buffer_data(size_t n_vrts) :
487 flags(0), texture(-1), n_verts(n_vrts), index_offset(0),
488 i_first(1), i_last(0), index(NULL)
489 {
490 if ( n_verts > 0 ) {
491 index = new(std::nothrow) uint[n_verts];
492 } else {
493 index = NULL;
494 }
495 }
496
497 // Copy-constructor
498 buffer_data(const buffer_data& other)
499 {
500 if ( other.index ) {
501 index = new(std::nothrow) uint[other.n_verts];
502 for (size_t i=0; i < other.n_verts; i++)
503 {
504 index[i] = other.index[i];
505 }
506 } else {
507 index = NULL;
508 }
509
510 flags = other.flags;
511 texture = other.texture;
512 n_verts = other.n_verts;
513
514 i_first = other.i_first;
515 i_last = other.i_last;
516
517 index_offset = other.index_offset;
518 }
519
520 // Copy-assignment operator
521 buffer_data& operator=(const buffer_data& rhs)
522 {
523 if (this != &rhs)
524 {
525 if ( index ) {
526 delete [] index;
527 }
528
529 if ( rhs.index && rhs.n_verts > 0 ) {
530 index = new(std::nothrow) uint[rhs.n_verts];
531 for (size_t i=0; i < rhs.n_verts; i++)
532 {
533 index[i] = rhs.index[i];
534 }
535 }
536
537 flags = rhs.flags;
538 texture = rhs.texture;
539 n_verts = rhs.n_verts;
540
541 i_first = rhs.i_first;
542 i_last = rhs.i_last;
543
544 index_offset = rhs.index_offset;
545 }
546 return *this;
547 }
548
549 // Destructor
550 ~buffer_data()
551 {
552 release();
553 }
554
555 private:
556 uint *index;
557 };
558
559 class vertex_buffer
560 {
561 public:
562 int flags;
563
564 size_t stride;
565 size_t vertex_offset;
566 size_t vertex_num_offset;
567
568 poly_list *model_list;
569
570 SCP_vector<buffer_data> tex_buf;
571
572 vertex_layout layout;
573
574 vertex_buffer() :
575 flags(0), stride(0), vertex_offset(0), vertex_num_offset(0), model_list(NULL)
576 {
577 }
578
579 ~vertex_buffer()
580 {
581 clear();
582 }
583
584 void release()
585 {
586 if (model_list) {
587 delete model_list;
588 model_list = NULL;
589 }
590
591 for (SCP_vector<buffer_data>::iterator tbi = tex_buf.begin(); tbi != tex_buf.end(); ++tbi) {
592 tbi->release();
593 }
594 }
595
596 void clear()
597 {
598 release();
599 tex_buf.clear();
600 }
601 };
602
603 struct indexed_vertex_source {
604 void* Vertex_list = nullptr;
605 void* Index_list = nullptr;
606
607 gr_buffer_handle Vbuffer_handle;
608 size_t Vertex_offset = 0;
609 size_t Base_vertex_offset = 0;
610
611 gr_buffer_handle Ibuffer_handle;
612 size_t Index_offset = 0;
613
614 uint Vertex_list_size = 0;
615 uint Index_list_size = 0;
616 };
617
618 struct light;
619
620 #define FIND_SCALED_NUM(x, x0, x1, y0, y1) ( ((((x) - (x0)) * ((y1) - (y0))) / ((x1) - (x0))) + (y0) )
621
622 #define GR_ALPHABLEND_NONE 0 // no blending
623 #define GR_ALPHABLEND_FILTER 1 // 50/50 mix of foreground, background, using intensity as alpha
624
625 #define GR_BITBLT_MODE_NORMAL 0 // Normal bitblting
626 #define GR_BITBLT_MODE_RLE 1 // RLE would be faster
627
628 // fog modes
629 #define GR_FOGMODE_NONE 0 // set this to turn off fog
630 #define GR_FOGMODE_FOG 1 // linear fog
631
632 enum class QueryType {
633 Timestamp
634 };
635
636 enum class BufferType {
637 Vertex,
638 Index,
639 Uniform
640 };
641
642 enum class BufferUsageHint { Static, Dynamic, Streaming, PersistentMapping };
643
644 /**
645 * @brief Type of a graphics sync object
646 */
647 typedef void* gr_sync;
648
649 typedef struct screen {
650 uint signature = 0; // changes when mode or palette or width or height changes
651 int max_w = 0, max_h = 0; // Width and height
652 int max_w_unscaled = 0, max_h_unscaled = 0;
653 int max_w_unscaled_zoomed = 0, max_h_unscaled_zoomed = 0;
654 int center_w = 0, center_h = 0; // Width and height of center monitor
655 int center_offset_x = 0, center_offset_y = 0;
656 int save_max_w = 0, save_max_h = 0; // Width and height
657 int save_max_w_unscaled = 0, save_max_h_unscaled = 0;
658 int save_max_w_unscaled_zoomed = 0, save_max_h_unscaled_zoomed = 0;
659 int save_center_w = 0, save_center_h = 0; // Width and height of center monitor
660 int save_center_offset_x = 0, save_center_offset_y = 0;
661 int res = 0; // GR_640 or GR_1024
662 int mode = 0; // What mode gr_init was called with.
663 float aspect = 0.0f, clip_aspect = 0.0f; // Aspect ratio = 0, aspect of clip_width/clip_height
664 int rowsize = 0; // What you need to add to go to next row (includes bytes_per_pixel)
665 int bits_per_pixel = 0; // How many bits per pixel it is. (7,8,15,16,24,32)
666 int bytes_per_pixel = 0; // How many bytes per pixel (1,2,3,4)
667 int offset_x = 0, offset_y = 0; // The offsets into the screen
668 int offset_x_unscaled = 0, offset_y_unscaled = 0; // Offsets into the screen, in unscaled dimensions
669 int clip_width = 0, clip_height = 0;
670 int clip_width_unscaled = 0, clip_height_unscaled = 0; // Height and width of clip aread, in unscaled dimensions
671 // center of clip area
672 float clip_center_x = 0.0f, clip_center_y = 0.0f;
673
674 float fog_near = 0.0f, fog_far = 0.0f;
675
676 // the clip_l,r,t,b are used internally. left and top are
677 // actually always 0, but it's nice to have the code work with
678 // arbitrary clipping regions.
679 int clip_left = 0, clip_right = 0, clip_top = 0, clip_bottom = 0;
680 // same as above except in unscaled dimensions
681 int clip_left_unscaled = 0, clip_right_unscaled = 0, clip_top_unscaled = 0, clip_bottom_unscaled = 0;
682
683 int current_alphablend_mode = 0; // See GR_ALPHABLEND defines above
684 int current_bitblt_mode = 0; // See GR_BITBLT_MODE defines above
685 int current_bitmap = 0;
686 color current_color{};
687 color current_fog_color{}; // current fog color
688 color current_clear_color{}; // current clear color
689 shader current_shader{};
690 float current_alpha = 0.0f;
691
692 bool custom_size = false;
693 int rendering_to_texture = 0; // wich texture we are rendering to, -1 if the back buffer
694 int rendering_to_face = 0; // wich face of the texture we are rendering to, -1 if the back buffer
695
696 int envmap_render_target = 0;
697
698 float line_width = 0.0f;
699
700 // switch onscreen, offscreen
701 std::function<void()> gf_flip;
702
703 // sets the clipping region
704 std::function<void(int x, int y, int w, int h, int resize_mode)> gf_set_clip;
705
706 // resets the clipping region to entire screen
707 std::function<void()> gf_reset_clip;
708
709 // clears entire clipping region to current color
710 std::function<void()> gf_clear;
711
712 // dumps the current screen to a file
713 std::function<void(const char* filename)> gf_print_screen;
714
715 // Retrieves the zbuffer mode.
716 std::function<int()> gf_zbuffer_get;
717
718 // Sets mode. Returns previous mode.
719 std::function<int(int mode)> gf_zbuffer_set;
720
721 // Clears the zbuffer. If use_zbuffer is FALSE, then zbuffering mode is ignored and zbuffer is always off.
722 std::function<void(int use_zbuffer)> gf_zbuffer_clear;
723
724 // Set the stencil buffer mode. Returns previous mode
725 std::function<int(int mode)> gf_stencil_set;
726
727 // Clears the stencil buffer.
728 std::function<void()> gf_stencil_clear;
729
730 std::function<int(int mode, float alpha)> gf_alpha_mask_set;
731
732 // Saves screen. Returns an id you pass to restore and free.
733 std::function<int()> gf_save_screen;
734
735 // Resets clip region and copies entire saved screen to the screen.
736 std::function<void(int id)> gf_restore_screen;
737
738 // Frees up a saved screen.
739 std::function<void(int id)> gf_free_screen;
740
741 // grab a region of the screen. assumes data is large enough
742 std::function<void(int front, int w, int h, ubyte* data)> gf_get_region;
743
744 // poly culling
745 std::function<int(int cull)> gf_set_cull;
746
747 // color buffer writes
748 std::function<int(int mode)> gf_set_color_buffer;
749
750 // preload a bitmap into texture memory
751 std::function<int(int bitmap_num, int is_aabitmap)> gf_preload;
752
753 // set the color to be used when clearing the background
754 std::function<void(int r, int g, int b)> gf_set_clear_color;
755
756 // Here be the bitmap functions
757 std::function<void(bitmap_slot* slot, bool release)> gf_bm_free_data;
758 std::function<void(bitmap_slot* slot)> gf_bm_create;
759 std::function<void(bitmap_slot* slot)> gf_bm_init;
760 std::function<void()> gf_bm_page_in_start;
761 std::function<bool(int handle, bitmap* bm)> gf_bm_data;
762
763 std::function<int(int handle, int* width, int* height, int* bpp, int* mm_lvl, int flags)> gf_bm_make_render_target;
764 std::function<int(int handle, int face)> gf_bm_set_render_target;
765
766 std::function<void(int)> gf_set_texture_addressing;
767
768 std::function<gr_buffer_handle(BufferType type, BufferUsageHint usage)> gf_create_buffer;
769 std::function<void(gr_buffer_handle handle)> gf_delete_buffer;
770
771 std::function<void(gr_buffer_handle handle, size_t size, const void* data)> gf_update_buffer_data;
772 std::function<void(gr_buffer_handle handle, size_t offset, size_t size, const void* data)>
773 gf_update_buffer_data_offset;
774 std::function<void*(gr_buffer_handle handle)> gf_map_buffer;
775 std::function<void(gr_buffer_handle handle, size_t offset, size_t size)> gf_flush_mapped_buffer;
776 std::function<void(void* data, size_t size)> gf_update_transform_buffer;
777
778 // postprocessing effects
779 std::function<void(const char*, int, const vec3d*)> gf_post_process_set_effect;
780 std::function<void()> gf_post_process_set_defaults;
781
782 std::function<void()> gf_post_process_begin;
783 std::function<void()> gf_post_process_end;
784 std::function<void()> gf_post_process_save_zbuffer;
785 std::function<void()> gf_post_process_restore_zbuffer;
786
787 std::function<void()> gf_deferred_lighting_begin;
788 std::function<void()> gf_deferred_lighting_end;
789 std::function<void()> gf_deferred_lighting_finish;
790
791 std::function<void()> gf_scene_texture_begin;
792 std::function<void()> gf_scene_texture_end;
793 std::function<void()> gf_copy_effect_texture;
794
795 std::function<void(int zbias)> gf_zbias;
796
797 std::function<void(int)> gf_set_fill_mode;
798
799 std::function<void(float width)> gf_set_line_width;
800
801 std::function<void(material* material_def, float rad)> gf_sphere;
802
803 std::function<int(shader_type type, unsigned int flags)> gf_maybe_create_shader;
804 std::function<void(const std::function<void(size_t, size_t)>& progress_callback)> gf_recompile_all_shaders;
805
806 std::function<void()> gf_clear_states;
807
808 std::function<void(int bitmap_handle, int bpp, const ubyte* data, int width, int height)> gf_update_texture;
809 std::function<void(void* data_out, int bitmap_num)> gf_get_bitmap_from_texture;
810
811 std::function<void(matrix4* shadow_view_matrix, const matrix* light_matrix, vec3d* eye_pos)> gf_shadow_map_start;
812 std::function<void()> gf_shadow_map_end;
813
814 std::function<void()> gf_start_decal_pass;
815 std::function<void()> gf_stop_decal_pass;
816
817 // new drawing functions
818 std::function<
819 void(model_material* material_info, indexed_vertex_source* vert_source, vertex_buffer* bufferp, size_t texi)>
820 gf_render_model;
821 std::function<void(shield_material* material_info,
822 primitive_type prim_type,
823 vertex_layout* layout,
824 gr_buffer_handle buffer_handle,
825 int n_verts)>
826 gf_render_shield_impact;
827 std::function<void(material* material_info,
828 primitive_type prim_type,
829 vertex_layout* layout,
830 int offset,
831 int n_verts,
832 gr_buffer_handle buffer_handle,
833 size_t buffer_offset)>
834 gf_render_primitives;
835 std::function<void(particle_material* material_info,
836 primitive_type prim_type,
837 vertex_layout* layout,
838 int offset,
839 int n_verts,
840 gr_buffer_handle buffer_handle)>
841 gf_render_primitives_particle;
842 std::function<void(distortion_material* material_info,
843 primitive_type prim_type,
844 vertex_layout* layout,
845 int offset,
846 int n_verts,
847 gr_buffer_handle buffer_handle)>
848 gf_render_primitives_distortion;
849 std::function<void(movie_material* material_info,
850 primitive_type prim_type,
851 vertex_layout* layout,
852 int n_verts,
853 gr_buffer_handle buffer,
854 size_t buffer_offset)>
855 gf_render_movie;
856 std::function<void(batched_bitmap_material* material_info,
857 primitive_type prim_type,
858 vertex_layout* layout,
859 int offset,
860 int n_verts,
861 gr_buffer_handle buffer_handle)>
862 gf_render_primitives_batched;
863 std::function<void(nanovg_material* material_info,
864 primitive_type prim_type,
865 vertex_layout* layout,
866 int offset,
867 int n_verts,
868 gr_buffer_handle buffer_handle)>
869 gf_render_nanovg;
870 std::function<void(decal_material* material_info,
871 primitive_type prim_type,
872 vertex_layout* layout,
873 int num_elements,
874 const indexed_vertex_source& buffers)>
875 gf_render_decals;
876 void (*gf_render_rocket_primitives)(interface_material* material_info,
877 primitive_type prim_type,
878 vertex_layout* layout,
879 int n_indices,
880 gr_buffer_handle vertex_buffer,
881 gr_buffer_handle index_buffer);
882
883 std::function<bool(gr_capability capability)> gf_is_capable;
884 std::function<bool(gr_property property, void* destination)> gf_get_property;
885
886 std::function<void(const char* name)> gf_push_debug_group;
887 std::function<void()> gf_pop_debug_group;
888
889 std::function<int()> gf_create_query_object;
890 std::function<void(int obj, QueryType type)> gf_query_value;
891 std::function<bool(int obj)> gf_query_value_available;
892 std::function<uint64_t(int obj)> gf_get_query_value;
893 std::function<void(int obj)> gf_delete_query_object;
894
895 std::unique_ptr<os::Viewport> (*gf_create_viewport)(const os::ViewPortProperties& props);
896 std::function<void(os::Viewport* view)> gf_use_viewport;
897
898 std::function<void(uniform_block_type bind_point, size_t offset, size_t size, gr_buffer_handle buffer)>
899 gf_bind_uniform_buffer;
900
901 std::function<gr_sync()> gf_sync_fence;
902 std::function<bool(gr_sync sync, uint64_t timeoutns)> gf_sync_wait;
903 std::function<void(gr_sync sync)> gf_sync_delete;
904
905 std::function<void(int x, int y, int width, int height)> gf_set_viewport;
906 } screen;
907
908 // handy macro
909 #define GR_MAYBE_CLEAR_RES(bmap) do { int bmw = -1; int bmh = -1; if(bmap != -1){ bm_get_info( bmap, &bmw, &bmh, NULL, NULL, NULL); if((bmw != gr_screen.max_w) || (bmh != gr_screen.max_h)){gr_clear();} } else {gr_clear();} } while(false);
910
911 //Window's interface to set up graphics:
912 //--------------------------------------
913 // Call this at application startup
914
915 // # Software Re-added by Kazan --- THIS HAS TO STAY -- It is used by standalone!
916 #define GR_DEFAULT (-1) // set to use default settings
917 #define GR_STUB (100)
918 #define GR_OPENGL (104) // Use OpenGl hardware renderer
919 #define GR_VULKAN (105) // Use Vulkan hardware renderer
920
921 // resolution constants - always keep resolutions in ascending order and starting from 0
922 #define GR_NUM_RESOLUTIONS 2
923 #define GR_640 0 // 640 x 480
924 #define GR_1024 1 // 1024 x 768
925
926 #define GR_1024_THRESHOLD_WIDTH 1024
927 #define GR_1024_THRESHOLD_HEIGHT 600
928
929 extern const char *Resolution_prefixes[GR_NUM_RESOLUTIONS];
930
931 extern bool gr_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int d_mode = GR_DEFAULT,
932 int d_width = GR_DEFAULT, int d_height = GR_DEFAULT, int d_depth = GR_DEFAULT);
933
934 extern void gr_screen_resize(int width, int height);
935 extern int gr_get_resolution_class(int width, int height);
936
937 // Call this when your app ends.
938 extern void gr_close();
939
940 extern screen gr_screen;
941
942 #define GR_FILL_MODE_WIRE 1
943 #define GR_FILL_MODE_SOLID 2
944
945 #define GR_ZBUFF_NONE 0
946 #define GR_ZBUFF_WRITE (1<<0)
947 #define GR_ZBUFF_READ (1<<1)
948 #define GR_ZBUFF_FULL (GR_ZBUFF_WRITE|GR_ZBUFF_READ)
949
950 #define GR_STENCIL_NONE 0
951 #define GR_STENCIL_READ 1
952 #define GR_STENCIL_WRITE 2
953
954 #define GR_RESIZE_NONE 0
955 #define GR_RESIZE_FULL 1
956 #define GR_RESIZE_FULL_CENTER 2
957 #define GR_RESIZE_MENU 3
958 #define GR_RESIZE_MENU_ZOOMED 4
959 #define GR_RESIZE_MENU_NO_OFFSET 5
960
961 void gr_set_screen_scale(int x, int y, int zoom_x = -1, int zoom_y = -1, int max_x = gr_screen.max_w, int max_y = gr_screen.max_h, int center_x = gr_screen.center_w, int center_y = gr_screen.center_h, bool force_stretch = false);
962 void gr_reset_screen_scale();
963 bool gr_unsize_screen_pos(int *x, int *y, int *w = NULL, int *h = NULL, int resize_mode = GR_RESIZE_FULL);
964 bool gr_resize_screen_pos(int *x, int *y, int *w = NULL, int *h = NULL, int resize_mode = GR_RESIZE_FULL);
965 bool gr_unsize_screen_posf(float *x, float *y, float *w = NULL, float *h = NULL, int resize_mode = GR_RESIZE_FULL);
966 bool gr_resize_screen_posf(float *x, float *y, float *w = NULL, float *h = NULL, int resize_mode = GR_RESIZE_FULL);
967
968 // Does formatted printing. This calls gr_string after formatting,
969 // so if you don't need to format the string, then call gr_string
970 // directly.
971 extern void gr_printf( int x, int y, const char * format, SCP_FORMAT_STRING ... ) SCP_FORMAT_STRING_ARGS(3, 4);
972 // same as gr_printf but positions text correctly in menus
973 extern void gr_printf_menu( int x, int y, const char * format, SCP_FORMAT_STRING ... ) SCP_FORMAT_STRING_ARGS(3, 4);
974 // same as gr_printf_menu but accounts for menu zooming
975 extern void gr_printf_menu_zoomed( int x, int y, const char * format, SCP_FORMAT_STRING ... ) SCP_FORMAT_STRING_ARGS(3, 4);
976 // same as gr_printf but doesn't resize for non-standard resolutions
977 extern void gr_printf_no_resize( int x, int y, const char * format, SCP_FORMAT_STRING ... ) SCP_FORMAT_STRING_ARGS(3, 4);
978
979 // Returns the size of the string in pixels in w and h
980 extern void gr_get_string_size( int *w, int *h, const char * text, int len = 9999 );
981
982 // Returns the height of the current font
983 extern int gr_get_font_height();
984
985 extern io::mouse::Cursor* Web_cursor;
986
987 // Called by OS when application gets/looses focus
988 extern void gr_activate(int active);
989
990 #define GR_CALL(x) (x)
991
992 // These macros make the function indirection look like the
993 // old Descent-style gr_xxx calls.
994
995 #define gr_print_screen GR_CALL(gr_screen.gf_print_screen)
996
997 //#define gr_flip GR_CALL(gr_screen.gf_flip)
998 void gr_flip(bool execute_scripting = true);
999
1000 //#define gr_set_clip GR_CALL(gr_screen.gf_set_clip)
1001 inline void gr_set_clip(int x, int y, int w, int h, int resize_mode=GR_RESIZE_FULL)
1002 {
1003 gr_screen.gf_set_clip(x, y, w, h, resize_mode);
1004 }
1005 #define gr_reset_clip GR_CALL(gr_screen.gf_reset_clip)
1006
1007 void gr_set_bitmap(int bitmap_num, int alphablend = GR_ALPHABLEND_NONE, int bitbltmode = GR_BITBLT_MODE_NORMAL, float alpha = 1.0f);
1008
1009 #define gr_clear GR_CALL(gr_screen.gf_clear)
1010
1011 #define gr_zbuffer_get GR_CALL(gr_screen.gf_zbuffer_get)
1012 #define gr_zbuffer_set GR_CALL(gr_screen.gf_zbuffer_set)
1013 #define gr_zbuffer_clear GR_CALL(gr_screen.gf_zbuffer_clear)
1014
1015 #define gr_stencil_set GR_CALL(gr_screen.gf_stencil_set)
1016 #define gr_stencil_clear GR_CALL(gr_screen.gf_stencil_clear)
1017
1018 #define gr_alpha_mask_set GR_CALL(gr_screen.gf_alpha_mask_set)
1019
1020 #define gr_save_screen GR_CALL(gr_screen.gf_save_screen)
1021 #define gr_restore_screen GR_CALL(gr_screen.gf_restore_screen)
1022 #define gr_free_screen GR_CALL(gr_screen.gf_free_screen)
1023
1024 #define gr_get_region GR_CALL(gr_screen.gf_get_region)
1025
1026 #define gr_set_cull GR_CALL(gr_screen.gf_set_cull)
1027 #define gr_set_color_buffer GR_CALL(gr_screen.gf_set_color_buffer)
1028
1029
1030 #define gr_preload GR_CALL(gr_screen.gf_preload)
1031
1032 #define gr_set_clear_color GR_CALL(gr_screen.gf_set_clear_color)
1033
1034 // Here be the bitmap functions
1035 #define gr_bm_free_data GR_CALL(gr_screen.gf_bm_free_data)
1036 #define gr_bm_create GR_CALL(gr_screen.gf_bm_create)
1037 #define gr_bm_init GR_CALL(gr_screen.gf_bm_init)
1038 #define gr_bm_page_in_start GR_CALL(gr_screen.gf_bm_page_in_start)
1039 #define gr_bm_data GR_CALL(gr_screen.gf_bm_data)
1040
1041 #define gr_bm_make_render_target GR_CALL(gr_screen.gf_bm_make_render_target)
1042
1043 inline int gr_bm_set_render_target(int n, int face = -1)
1044 {
1045 return gr_screen.gf_bm_set_render_target(n, face);
1046 }
1047
1048 #define gr_set_texture_addressing GR_CALL(gr_screen.gf_set_texture_addressing)
1049
1050 inline gr_buffer_handle gr_create_buffer(BufferType type, BufferUsageHint usage)
1051 {
1052 return gr_screen.gf_create_buffer(type, usage);
1053 }
1054
1055 #define gr_delete_buffer GR_CALL(gr_screen.gf_delete_buffer)
1056 #define gr_update_buffer_data GR_CALL(gr_screen.gf_update_buffer_data)
1057 #define gr_update_buffer_data_offset GR_CALL(gr_screen.gf_update_buffer_data_offset)
1058 inline void* gr_map_buffer(gr_buffer_handle handle)
1059 {
1060 return gr_screen.gf_map_buffer(handle);
1061 }
1062 inline void gr_flush_mapped_buffer(gr_buffer_handle handle, size_t offset, size_t size)
1063 {
1064 gr_screen.gf_flush_mapped_buffer(handle, offset, size);
1065 }
1066 #define gr_update_transform_buffer GR_CALL(gr_screen.gf_update_transform_buffer)
1067
1068 #define gr_scene_texture_begin GR_CALL(gr_screen.gf_scene_texture_begin)
1069 #define gr_scene_texture_end GR_CALL(gr_screen.gf_scene_texture_end)
1070 #define gr_copy_effect_texture GR_CALL(gr_screen.gf_copy_effect_texture)
1071
1072 #define gr_post_process_set_effect GR_CALL(gr_screen.gf_post_process_set_effect)
1073 #define gr_post_process_set_defaults GR_CALL(gr_screen.gf_post_process_set_defaults)
1074 #define gr_post_process_begin GR_CALL(gr_screen.gf_post_process_begin)
1075 #define gr_post_process_end GR_CALL(gr_screen.gf_post_process_end)
1076 #define gr_post_process_save_zbuffer GR_CALL(gr_screen.gf_post_process_save_zbuffer)
1077 inline void gr_post_process_restore_zbuffer()
1078 {
1079 gr_screen.gf_post_process_restore_zbuffer();
1080 }
1081
1082 #define gr_deferred_lighting_begin GR_CALL(gr_screen.gf_deferred_lighting_begin)
1083 #define gr_deferred_lighting_end GR_CALL(gr_screen.gf_deferred_lighting_end)
1084 #define gr_deferred_lighting_finish GR_CALL(gr_screen.gf_deferred_lighting_finish)
1085
1086 #define gr_zbias GR_CALL(gr_screen.gf_zbias)
1087 #define gr_set_fill_mode GR_CALL(gr_screen.gf_set_fill_mode)
1088
1089 #define gr_set_line_width GR_CALL(gr_screen.gf_set_line_width)
1090
1091 #define gr_sphere GR_CALL(gr_screen.gf_sphere)
1092
1093 #define gr_maybe_create_shader GR_CALL(gr_screen.gf_maybe_create_shader)
1094 #define gr_recompile_all_shaders GR_CALL(gr_screen.gf_recompile_all_shaders)
1095
1096 #define gr_clear_states GR_CALL(gr_screen.gf_clear_states)
1097
1098 #define gr_update_texture GR_CALL(gr_screen.gf_update_texture)
1099 #define gr_get_bitmap_from_texture GR_CALL(gr_screen.gf_get_bitmap_from_texture)
1100
1101 #define gr_shadow_map_start GR_CALL(gr_screen.gf_shadow_map_start)
1102 #define gr_shadow_map_end GR_CALL(gr_screen.gf_shadow_map_end)
1103 #define gr_render_shield_impact GR_CALL(gr_screen.gf_render_shield_impact)
1104
1105 inline void gr_render_primitives(material* material_info,
1106 primitive_type prim_type,
1107 vertex_layout* layout,
1108 int vert_offset,
1109 int n_verts,
1110 gr_buffer_handle buffer_handle = gr_buffer_handle(),
1111 size_t buffer_offset = 0)
1112 {
1113 gr_screen
1114 .gf_render_primitives(material_info, prim_type, layout, vert_offset, n_verts, buffer_handle, buffer_offset);
1115 }
1116
1117 inline void gr_render_primitives_particle(particle_material* material_info,
1118 primitive_type prim_type,
1119 vertex_layout* layout,
1120 int offset,
1121 int n_verts,
1122 gr_buffer_handle buffer_handle = gr_buffer_handle())
1123 {
1124 gr_screen.gf_render_primitives_particle(material_info, prim_type, layout, offset, n_verts, buffer_handle);
1125 }
1126
1127 inline void gr_render_primitives_batched(batched_bitmap_material* material_info,
1128 primitive_type prim_type,
1129 vertex_layout* layout,
1130 int offset,
1131 int n_verts,
1132 gr_buffer_handle buffer_handle = gr_buffer_handle())
1133 {
1134 gr_screen.gf_render_primitives_batched(material_info, prim_type, layout, offset, n_verts, buffer_handle);
1135 }
1136
1137 inline void gr_render_nanovg(nanovg_material* material_info,
1138 primitive_type prim_type,
1139 vertex_layout* layout,
1140 int offset,
1141 int n_verts,
1142 gr_buffer_handle buffer_handle)
1143 {
1144 gr_screen.gf_render_nanovg(material_info, prim_type, layout, offset, n_verts, buffer_handle);
1145 }
1146
1147 inline void gr_render_primitives_distortion(distortion_material* material_info,
1148 primitive_type prim_type,
1149 vertex_layout* layout,
1150 int offset,
1151 int n_verts,
1152 gr_buffer_handle buffer_handle = gr_buffer_handle())
1153 {
1154 gr_screen.gf_render_primitives_distortion(material_info, prim_type, layout, offset, n_verts, buffer_handle);
1155 }
1156
1157 inline void gr_render_movie(movie_material* material_info,
1158 primitive_type prim_type,
1159 vertex_layout* layout,
1160 int n_verts,
1161 gr_buffer_handle buffer,
1162 size_t buffer_offset = 0)
1163 {
1164 gr_screen.gf_render_movie(material_info, prim_type, layout, n_verts, buffer, buffer_offset);
1165 }
1166
1167 inline void gr_render_model(model_material* material_info, indexed_vertex_source *vert_source, vertex_buffer* bufferp, size_t texi)
1168 {
1169 gr_screen.gf_render_model(material_info, vert_source, bufferp, texi);
1170 }
1171
1172 inline void gr_render_rocket_primitives(interface_material* material_info,
1173 primitive_type prim_type,
1174 vertex_layout* layout,
1175 int n_indices,
1176 gr_buffer_handle vertex_buffer,
1177 gr_buffer_handle index_buffer)
1178 {
1179 gr_screen.gf_render_rocket_primitives(material_info, prim_type, layout, n_indices, vertex_buffer, index_buffer);
1180 }
1181
1182 inline bool gr_is_capable(gr_capability capability)
1183 {
1184 return gr_screen.gf_is_capable(capability);
1185 }
1186
1187 inline bool gr_get_property(gr_property property, void* destination)
1188 {
1189 return gr_screen.gf_get_property(property, destination);
1190 }
1191
1192 inline void gr_push_debug_group(const char* name)
1193 {
1194 gr_screen.gf_push_debug_group(name);
1195 }
1196
1197 inline void gr_pop_debug_group()
1198 {
1199 gr_screen.gf_pop_debug_group();
1200 }
1201
1202 inline int gr_create_query_object()
1203 {
1204 return gr_screen.gf_create_query_object();
1205 }
1206
1207 inline void gr_query_value(int obj, QueryType type)
1208 {
1209 gr_screen.gf_query_value(obj, type);
1210 }
1211
1212 inline bool gr_query_value_available(int obj)
1213 {
1214 return gr_screen.gf_query_value_available(obj);
1215 }
1216
1217 inline std::uint64_t gr_get_query_value(int obj)
1218 {
1219 return gr_screen.gf_get_query_value(obj);
1220 }
1221
1222 inline void gr_delete_query_object(int obj)
1223 {
1224 gr_screen.gf_delete_query_object(obj);
1225 }
1226
1227 inline std::unique_ptr<os::Viewport> gr_create_viewport(const os::ViewPortProperties& props)
1228 {
1229 return gr_screen.gf_create_viewport(props);
1230 }
1231 inline void gr_use_viewport(os::Viewport* view)
1232 {
1233 gr_screen.gf_use_viewport(view);
1234 }
1235 inline void gr_set_viewport(int x, int y, int width, int height)
1236 {
1237 gr_screen.gf_set_viewport(x, y, width, height);
1238 }
1239
1240 inline void gr_bind_uniform_buffer(uniform_block_type bind_point, size_t offset, size_t size, gr_buffer_handle buffer)
1241 {
1242 gr_screen.gf_bind_uniform_buffer(bind_point, offset, size, buffer);
1243 }
1244
1245 inline gr_sync gr_sync_fence()
1246 {
1247 return gr_screen.gf_sync_fence();
1248 }
1249 inline bool gr_sync_wait(gr_sync sync, uint64_t timeoutns)
1250 {
1251 return gr_screen.gf_sync_wait(sync, timeoutns);
1252 }
1253 inline void gr_sync_delete(gr_sync sync)
1254 {
1255 gr_screen.gf_sync_delete(sync);
1256 }
1257
1258 // color functions
1259 void gr_init_color(color *c, int r, int g, int b);
1260 void gr_init_alphacolor( color *clr, int r, int g, int b, int alpha, int type = AC_TYPE_HUD );
1261 void gr_set_color( int r, int g, int b );
1262 void gr_set_color_fast(color *dst);
1263
1264 // shader functions
1265 void gr_create_shader(shader *shade, ubyte r, ubyte g, ubyte b, ubyte c);
1266 void gr_set_shader(shader *shade);
1267
1268 // new bitmap functions
1269 void gr_bitmap(int x, int y, int resize_mode = GR_RESIZE_FULL);
1270 void gr_bitmap_uv(int _x, int _y, int _w, int _h, float _u0, float _v0, float _u1, float _v1, int resize_mode = GR_RESIZE_FULL);
1271
1272 // special function for drawing polylines. this function is specifically intended for
1273 // polylines where each section is no more than 90 degrees away from a previous section.
1274 // Moreover, it is _really_ intended for use with 45 degree angles.
1275 void gr_pline_special(SCP_vector<vec3d> *pts, int thickness,int resize_mode=GR_RESIZE_FULL);
1276
1277 #define VB_FLAG_POSITION (1<<0)
1278 #define VB_FLAG_RHW (1<<1) //incompatable with the next normal
1279 #define VB_FLAG_NORMAL (1<<2)
1280 #define VB_FLAG_DIFUSE (1<<3)
1281 #define VB_FLAG_SPECULAR (1<<4)
1282 #define VB_FLAG_UV1 (1<<5) //how many UV coords, only use one of these
1283 #define VB_FLAG_UV2 (1<<6)
1284 #define VB_FLAG_UV3 (1<<7)
1285 #define VB_FLAG_UV4 (1<<8)
1286 #define VB_FLAG_TANGENT (1<<9)
1287 #define VB_FLAG_LARGE_INDEX (1<<10)
1288 #define VB_FLAG_MODEL_ID (1<<11)
1289 #define VB_FLAG_TRANS (1<<12)
1290
1291 /**
1292 * @brief Prints the current time
1293 *
1294 * Draws the timestamp of the current #Missiontime in the format @c h:mm:ss at the specified coordinates
1295 *
1296 * @param x The x position where the timestamp should be draw
1297 * @param y The y position where the timestamp should be draw
1298 * @param timestamp The timestamp (in 65536ths of a second) to be printed
1299 * @param resize_mode The resize mode to use
1300 */
1301 void gr_print_timestamp(int x, int y, fix timestamp, int resize_mode);
1302
1303 namespace graphics {
1304 class DebugScope {
1305 public:
1306 explicit DebugScope(const char* name) {
1307 gr_push_debug_group(name);
1308 }
1309 ~DebugScope() {
1310 gr_pop_debug_group();
1311 }
1312 };
1313 }
1314
1315 #ifndef NDEBUG
1316 #define GR_DEBUG_SCOPE(name) ::graphics::DebugScope SCP_TOKEN_CONCAT(gr_scope, __LINE__)(name)
1317 #else
1318 #define GR_DEBUG_SCOPE(name) do {} while(false)
1319 #endif
1320
1321 enum AnimatedShader {
1322 ANIMATED_SHADER_LOADOUTSELECT_FS1= 0,
1323 ANIMATED_SHADER_LOADOUTSELECT_FS2= 1,
1324 ANIMATED_SHADER_CLOAK = 2,
1325 };
1326
1327 /**
1328 * @brief Retreives a uniform buffer for storing uniform block data
1329 * @param type The type of uniform data that will be stored in the buffer
1330 * @param num_elements The number of elements that will be used in the buffer
1331 * @param element_size_override Override what the size of the element should be instead of relying on the preconfigured
1332 * size for that block type
1333 * @return A structure which gives access to a memory buffer where the uniform data can be stored
1334 */
1335 graphics::util::UniformBuffer gr_get_uniform_buffer(uniform_block_type type, size_t num_elements,
1336 size_t element_size_override = 0);
1337
1338 struct VideoModeData {
1339 uint32_t width = 0;
1340 uint32_t height = 0;
1341 uint32_t bit_depth = 0;
1342 };
1343
1344 struct DisplayData {
1345 uint32_t index;
1346 SCP_string name;
1347
1348 int32_t x = 0;
1349 int32_t y = 0;
1350 int32_t width = 0;
1351 int32_t height = 0;
1352
1353 SCP_vector<VideoModeData> video_modes;
1354 };
1355
1356 SCP_vector<DisplayData> gr_enumerate_displays();
1357
1358 enum class GpuHeap {
1359 ModelVertex = 0,
1360 ModelIndex,
1361
1362 NUM_VALUES
1363 };
1364
1365 /**
1366 * @brief Allocates storage on the specified GPU heap and stores data in that storage
1367 * @param heap_type The heap type to store this memory on
1368 * @param size The size of the data
1369 * @param data A pointer to the data
1370 * @param[out] offset_out The offset at which the data is stored in the buffer
1371 * @param[out] handle_out The handle of the buffer object this data is stored in
1372 */
1373 void gr_heap_allocate(GpuHeap heap_type, size_t size, void* data, size_t& offset_out, gr_buffer_handle& handle_out);
1374
1375 /**
1376 * @brief Deallocates memory previously allocated with gr_heap_allocate.
1377 * @param heap_type The heap type to deallocate this memory from
1378 * @param data_offset The offset at which the data is stored.
1379 */
1380 void gr_heap_deallocate(GpuHeap heap_type, size_t data_offset);
1381
1382 void gr_set_gamma(float gamma);
1383
1384 void gr_get_post_process_effect_names(SCP_vector<SCP_string> &names);
1385
1386 // Include this last to make the 2D rendering function available everywhere
1387 #include "graphics/render.h"
1388
1389 #endif
1390