FS2_Open
Open source remastering of the Freespace 2 engine
2d.cpp
Go to the documentation of this file.
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 
11 
12 #ifdef _WIN32
13 #include <windows.h>
14 #include <windowsx.h>
15 #endif
16 
17 #include <limits.h>
18 #include <algorithm>
19 
20 #include "cmdline/cmdline.h"
21 #include "debugconsole/console.h"
22 #include "gamesequence/gamesequence.h" //WMC - for scripting hooks in gr_flip()
23 #include "globalincs/systemvars.h"
24 #include "graphics/2d.h"
25 #include "graphics/font.h"
26 #include "graphics/grbatch.h"
27 #include "graphics/grinternal.h"
28 #include "graphics/gropengl.h" // Includes for different rendering systems
29 #include "graphics/gropengldraw.h"
30 #include "graphics/grstub.h"
31 #include "io/keycontrol.h" // m!m
32 #include "io/timer.h"
33 #include "osapi/osapi.h"
34 #include "palman/palman.h"
35 #include "parse/scripting.h"
36 #include "render/3d.h"
37 
38 #if defined(SCP_UNIX) && !defined(__APPLE__)
39 #if ( SDL_VERSION_ATLEAST(1, 2, 7) )
40 #include "SDL_cpuinfo.h"
41 #endif
42 #endif // SCP_UNIX && !__APPLE__
43 
44 const char *Resolution_prefixes[GR_NUM_RESOLUTIONS] = { "", "2_" };
45 
47 
52 
53 
54 ubyte Gr_original_palette[768]; // The palette
56 char Gr_current_palette_name[128] = NOX("none");
57 
58 // cursor stuff
59 int Gr_cursor = -1;
61 int Gr_cursor_size = 32; // default w/h
62 
63 int Gr_inited = 0;
64 
66 
67 float Gr_gamma = 1.8f;
68 int Gr_gamma_int = 180;
69 
70 // z-buffer stuff
71 int gr_zbuffering = 0;
74 
75 // stencil buffer stuff
77 
78 // alpha mask stuff
79 int gr_alpha_test = 0;
80 
81 // Default clipping distances
82 const float Default_min_draw_distance = 1.0f;
83 const float Default_max_draw_distance = 1e10;
86 
87 static int GL_cursor_nframes = 0;
88 
89 // Pre-computed screen resize vars
90 static float Gr_full_resize_X = 1.0f, Gr_full_resize_Y = 1.0f;
91 static float Gr_full_center_resize_X = 1.0f, Gr_full_center_resize_Y = 1.0f;
92 static float Gr_resize_X = 1.0f, Gr_resize_Y = 1.0f;
93 static float Gr_menu_offset_X = 0.0f, Gr_menu_offset_Y = 0.0f;
94 static float Gr_menu_zoomed_offset_X = 0.0f, Gr_menu_zoomed_offset_Y = 0.0f;
95 
98 float Gr_save_resize_X = 1.0f, Gr_save_resize_Y = 1.0f;
101 
103 
104 void gr_set_screen_scale(int w, int h, int zoom_w, int zoom_h, int max_w, int max_h, int center_w, int center_h, bool force_stretch)
105 {
106  bool do_zoom = zoom_w > 0 && zoom_h > 0 && (zoom_w != w || zoom_h != h);
107 
108  Gr_full_resize_X = (float)max_w / (float)w;
109  Gr_full_resize_Y = (float)max_h / (float)h;
110 
111  Gr_full_center_resize_X = (float)center_w / (float)w;
112  Gr_full_center_resize_Y = (float)center_h / (float)h;
113 
114  if (do_zoom) {
115  float aspect_quotient = ((float)center_w / (float)center_h) / ((float)zoom_w / (float)zoom_h);
116 
117  Gr_resize_X = (float)center_w / (float)zoom_w / ((aspect_quotient > 1.0f) ? aspect_quotient : 1.0f);
118  Gr_resize_Y = (float)center_h / (float)zoom_h * ((aspect_quotient < 1.0f) ? aspect_quotient : 1.0f);
119 
120  Gr_menu_offset_X = ((center_w - w * Gr_resize_X) / 2.0f) + gr_screen.center_offset_x;
121  Gr_menu_offset_Y = ((center_h - h * Gr_resize_Y) / 2.0f) + gr_screen.center_offset_y;
122 
123  Gr_menu_zoomed_offset_X = (Gr_menu_offset_X >= 0.0f) ? Gr_menu_offset_X : gr_screen.center_offset_x;
124  Gr_menu_zoomed_offset_Y = (Gr_menu_offset_Y >= 0.0f) ? Gr_menu_offset_Y : gr_screen.center_offset_y;
125 
126  if (force_stretch || Cmdline_stretch_menu) {
127  if (Gr_menu_offset_X > (float)gr_screen.center_offset_x) {
128  Gr_resize_X = Gr_full_center_resize_X;
129  Gr_menu_offset_X = Gr_menu_zoomed_offset_X = (float)gr_screen.center_offset_x;
130  }
131  if (Gr_menu_offset_Y > (float)gr_screen.center_offset_y) {
132  Gr_resize_Y = Gr_full_center_resize_Y;
133  Gr_menu_offset_Y = Gr_menu_zoomed_offset_Y = (float)gr_screen.center_offset_y;
134  }
135  }
136  } else {
137  if (force_stretch || Cmdline_stretch_menu) {
138  Gr_resize_X = Gr_full_center_resize_X;
139  Gr_resize_Y = Gr_full_center_resize_Y;
140 
141  Gr_menu_offset_X = Gr_menu_zoomed_offset_X = (float)gr_screen.center_offset_x;
142  Gr_menu_offset_Y = Gr_menu_zoomed_offset_Y = (float)gr_screen.center_offset_y;
143  } else {
144  float aspect_quotient = ((float)center_w / (float)center_h) / ((float)w / (float)h);
145 
146  Gr_resize_X = Gr_full_center_resize_X / ((aspect_quotient > 1.0f) ? aspect_quotient : 1.0f);
147  Gr_resize_Y = Gr_full_center_resize_Y * ((aspect_quotient < 1.0f) ? aspect_quotient : 1.0f);
148 
149  Gr_menu_offset_X = Gr_menu_zoomed_offset_X = ((aspect_quotient > 1.0f) ? ((center_w - w * Gr_resize_X) / 2.0f) : 0.0f) + gr_screen.center_offset_x;
150  Gr_menu_offset_Y = Gr_menu_zoomed_offset_Y = ((aspect_quotient < 1.0f) ? ((center_h - h * Gr_resize_Y) / 2.0f) : 0.0f) + gr_screen.center_offset_y;
151  }
152  }
153 
154  gr_screen.custom_size = (w != max_w || w != center_w || h != max_h || h != center_h);
155 
156  if (gr_screen.rendering_to_texture == -1) {
157  gr_screen.max_w_unscaled = w;
158  gr_screen.max_h_unscaled = h;
159 
160  if (do_zoom) {
161  gr_screen.max_w_unscaled_zoomed = gr_screen.max_w_unscaled + fl2i(Gr_menu_offset_X * 2.0f / Gr_resize_X);
162  gr_screen.max_h_unscaled_zoomed = gr_screen.max_h_unscaled + fl2i(Gr_menu_offset_Y * 2.0f / Gr_resize_Y);
163  if (gr_screen.max_w_unscaled_zoomed > gr_screen.max_w_unscaled) {
164  gr_screen.max_w_unscaled_zoomed = gr_screen.max_w_unscaled;
165  }
166  if (gr_screen.max_h_unscaled_zoomed > gr_screen.max_h_unscaled) {
167  gr_screen.max_h_unscaled_zoomed = gr_screen.max_h_unscaled;
168  }
169  } else {
170  gr_screen.max_w_unscaled_zoomed = gr_screen.max_w_unscaled;
171  gr_screen.max_h_unscaled_zoomed = gr_screen.max_h_unscaled;
172  }
173  }
174 }
175 
177 {
178  Gr_full_resize_X = Gr_save_full_resize_X;
179  Gr_full_resize_Y = Gr_save_full_resize_Y;
180 
181  Gr_full_center_resize_X = Gr_save_full_center_resize_X;
182  Gr_full_center_resize_Y = Gr_save_full_center_resize_Y;
183 
184  Gr_resize_X = Gr_save_resize_X;
185  Gr_resize_Y = Gr_save_resize_Y;
186 
187  Gr_menu_offset_X = Gr_save_menu_offset_X;
188  Gr_menu_offset_Y = Gr_save_menu_offset_Y;
189 
190  Gr_menu_zoomed_offset_X = Gr_save_menu_zoomed_offset_X;
191  Gr_menu_zoomed_offset_Y = Gr_save_menu_zoomed_offset_Y;
192 
194 
195  if (gr_screen.rendering_to_texture == -1) {
196  gr_screen.max_w_unscaled = gr_screen.max_w_unscaled_zoomed = (gr_screen.res == GR_1024) ? 1024 : 640;
197  gr_screen.max_h_unscaled = gr_screen.max_h_unscaled_zoomed = (gr_screen.res == GR_1024) ? 768 : 480;
198  }
199 }
200 
212 bool gr_resize_screen_pos(int *x, int *y, int *w, int *h, int resize_mode)
213 {
214  if ( resize_mode == GR_RESIZE_NONE || (!gr_screen.custom_size && (gr_screen.rendering_to_texture == -1)) ) {
215  return false;
216  }
217 
218  float xy_tmp = 0.0f;
219 
220  if ( x ) {
221  switch (resize_mode) {
222  case GR_RESIZE_FULL:
223  xy_tmp = (*x) * Gr_full_resize_X;
224  break;
225 
227  xy_tmp = (*x) * Gr_full_center_resize_X + (float)gr_screen.center_offset_x;
228  break;
229 
230  case GR_RESIZE_MENU:
231  xy_tmp = (*x) * Gr_resize_X + Gr_menu_offset_X;
232  break;
233 
235  xy_tmp = (*x) * Gr_resize_X + Gr_menu_zoomed_offset_X;
236  break;
237 
239  xy_tmp = (*x) * Gr_resize_X;
240  break;
241  }
242  (*x) = fl2ir(xy_tmp);
243  }
244 
245  if ( y ) {
246  switch (resize_mode) {
247  case GR_RESIZE_FULL:
248  xy_tmp = (*y) * Gr_full_resize_Y;
249  break;
250 
252  xy_tmp = (*y) * Gr_full_center_resize_Y + (float)gr_screen.center_offset_y;
253  break;
254 
255  case GR_RESIZE_MENU:
256  xy_tmp = (*y) * Gr_resize_Y + Gr_menu_offset_Y;
257  break;
258 
260  xy_tmp = (*y) * Gr_resize_Y + Gr_menu_zoomed_offset_Y;
261  break;
262 
264  xy_tmp = (*y) * Gr_resize_Y;
265  break;
266  }
267  (*y) = fl2ir(xy_tmp);
268  }
269 
270  if ( w ) {
271  switch (resize_mode) {
272  case GR_RESIZE_FULL:
273  xy_tmp = (*w) * Gr_full_resize_X;
274  break;
275 
277  xy_tmp = (*w) * Gr_full_center_resize_X;
278  break;
279 
280  case GR_RESIZE_MENU:
283  xy_tmp = (*w) * Gr_resize_X;
284  break;
285  }
286  (*w) = fl2ir(xy_tmp);
287  }
288 
289  if ( h ) {
290  switch (resize_mode) {
291  case GR_RESIZE_FULL:
292  xy_tmp = (*h) * Gr_full_resize_Y;
293  break;
294 
296  xy_tmp = (*h) * Gr_full_center_resize_Y;
297  break;
298 
299  case GR_RESIZE_MENU:
302  xy_tmp = (*h) * Gr_resize_Y;
303  break;
304  }
305  (*h) = fl2ir(xy_tmp);
306  }
307 
308  return true;
309 }
310 
320 bool gr_unsize_screen_pos(int *x, int *y, int *w, int *h, int resize_mode)
321 {
322  if ( resize_mode == GR_RESIZE_NONE || (!gr_screen.custom_size && (gr_screen.rendering_to_texture == -1)) ) {
323  return false;
324  }
325 
326  float xy_tmp = 0.0f;
327 
328  if ( x ) {
329  switch (resize_mode) {
330  case GR_RESIZE_FULL:
331  xy_tmp = (*x) / Gr_full_resize_X;
332  break;
333 
335  xy_tmp = ((*x) - (float)gr_screen.center_offset_x) / Gr_full_center_resize_X;
336  break;
337 
338  case GR_RESIZE_MENU:
339  xy_tmp = ((*x) - Gr_menu_offset_X) / Gr_resize_X;
340  break;
341 
343  xy_tmp = ((*x) - Gr_menu_zoomed_offset_X) / Gr_resize_X;
344  break;
345 
347  xy_tmp = (*x) / Gr_resize_X;
348  break;
349  }
350  (*x) = fl2ir(xy_tmp);
351  }
352 
353  if ( y ) {
354  switch (resize_mode) {
355  case GR_RESIZE_FULL:
356  xy_tmp = (*y) / Gr_full_resize_Y;
357  break;
358 
360  xy_tmp = ((*y) - (float)gr_screen.center_offset_y) / Gr_full_center_resize_Y;
361  break;
362 
363  case GR_RESIZE_MENU:
364  xy_tmp = ((*y) - Gr_menu_offset_Y) / Gr_resize_Y;
365  break;
366 
368  xy_tmp = ((*y) - Gr_menu_zoomed_offset_Y) / Gr_resize_Y;
369  break;
370 
372  xy_tmp = (*y) / Gr_resize_Y;
373  break;
374  }
375  (*y) = fl2ir(xy_tmp);
376  }
377 
378  if ( w ) {
379  switch (resize_mode) {
380  case GR_RESIZE_FULL:
381  xy_tmp = (*w) / Gr_full_resize_X;
382  break;
383 
385  xy_tmp = (*w) / Gr_full_center_resize_X;
386  break;
387 
388  case GR_RESIZE_MENU:
391  xy_tmp = (*w) / Gr_resize_X;
392  break;
393  }
394  (*w) = fl2ir(xy_tmp);
395  }
396 
397  if ( h ) {
398  switch (resize_mode) {
399  case GR_RESIZE_FULL:
400  xy_tmp = (*h) / Gr_full_resize_Y;
401  break;
402 
404  xy_tmp = (*h) / Gr_full_center_resize_Y;
405  break;
406 
407  case GR_RESIZE_MENU:
410  xy_tmp = (*h) / Gr_resize_Y;
411  break;
412  }
413  (*h) = fl2ir(xy_tmp);
414  }
415 
416  return true;
417 }
418 
430 bool gr_resize_screen_posf(float *x, float *y, float *w, float *h, int resize_mode)
431 {
432  if ( resize_mode == GR_RESIZE_NONE || (!gr_screen.custom_size && (gr_screen.rendering_to_texture == -1)) ) {
433  return false;
434  }
435 
436  float xy_tmp = 0.0f;
437 
438  if ( x ) {
439  switch (resize_mode) {
440  case GR_RESIZE_FULL:
441  xy_tmp = (*x) * Gr_full_resize_X;
442  break;
443 
445  xy_tmp = (*x) * Gr_full_center_resize_X + (float)gr_screen.center_offset_x;
446  break;
447 
448  case GR_RESIZE_MENU:
449  xy_tmp = (*x) * Gr_resize_X + Gr_menu_offset_X;
450  break;
451 
453  xy_tmp = (*x) * Gr_resize_X + Gr_menu_zoomed_offset_X;
454  break;
455 
457  xy_tmp = (*x) * Gr_resize_X;
458  break;
459  }
460  (*x) = xy_tmp;
461  }
462 
463  if ( y ) {
464  switch (resize_mode) {
465  case GR_RESIZE_FULL:
466  xy_tmp = (*y) * Gr_full_resize_Y;
467  break;
468 
470  xy_tmp = (*y) * Gr_full_center_resize_Y + (float)gr_screen.center_offset_y;
471  break;
472 
473  case GR_RESIZE_MENU:
474  xy_tmp = (*y) * Gr_resize_Y + Gr_menu_offset_Y;
475  break;
476 
478  xy_tmp = (*y) * Gr_resize_Y + Gr_menu_zoomed_offset_Y;
479  break;
480 
482  xy_tmp = (*y) * Gr_resize_Y;
483  break;
484  }
485  (*y) = xy_tmp;
486  }
487 
488  if ( w ) {
489  switch (resize_mode) {
490  case GR_RESIZE_FULL:
491  xy_tmp = (*w) * Gr_full_resize_X;
492  break;
493 
495  xy_tmp = (*w) * Gr_full_center_resize_X;
496  break;
497 
498  case GR_RESIZE_MENU:
501  xy_tmp = (*w) * Gr_resize_X;
502  break;
503  }
504  (*w) = xy_tmp;
505  }
506 
507  if ( h ) {
508  switch (resize_mode) {
509  case GR_RESIZE_FULL:
510  xy_tmp = (*h) * Gr_full_resize_Y;
511  break;
512 
514  xy_tmp = (*h) * Gr_full_center_resize_Y;
515  break;
516 
517  case GR_RESIZE_MENU:
520  xy_tmp = (*h) * Gr_resize_Y;
521  break;
522  }
523  (*h) = xy_tmp;
524  }
525 
526  return true;
527 }
528 
538 bool gr_unsize_screen_posf(float *x, float *y, float *w, float *h, int resize_mode)
539 {
540  if ( resize_mode == GR_RESIZE_NONE || (!gr_screen.custom_size && (gr_screen.rendering_to_texture == -1)) ) {
541  return false;
542  }
543 
544  float xy_tmp = 0.0f;
545 
546  if ( x ) {
547  switch (resize_mode) {
548  case GR_RESIZE_FULL:
549  xy_tmp = (*x) / Gr_full_resize_X;
550  break;
551 
553  xy_tmp = ((*x) - (float)gr_screen.center_offset_x) / Gr_full_center_resize_X;
554  break;
555 
556  case GR_RESIZE_MENU:
557  xy_tmp = ((*x) - Gr_menu_offset_X) / Gr_resize_X;
558  break;
559 
561  xy_tmp = ((*x) - Gr_menu_zoomed_offset_X) / Gr_resize_X;
562  break;
563 
565  xy_tmp = (*x) / Gr_resize_X;
566  break;
567  }
568  (*x) = xy_tmp;
569  }
570 
571  if ( y ) {
572  switch (resize_mode) {
573  case GR_RESIZE_FULL:
574  xy_tmp = (*y) / Gr_full_resize_Y;
575  break;
576 
578  xy_tmp = ((*y) - (float)gr_screen.center_offset_y) / Gr_full_center_resize_Y;
579  break;
580 
581  case GR_RESIZE_MENU:
582  xy_tmp = ((*y) - Gr_menu_offset_Y) / Gr_resize_Y;
583  break;
584 
586  xy_tmp = ((*y) - Gr_menu_zoomed_offset_Y) / Gr_resize_Y;
587  break;
588 
590  xy_tmp = (*y) / Gr_resize_Y;
591  break;
592  }
593  (*y) = xy_tmp;
594  }
595 
596  if ( w ) {
597  switch (resize_mode) {
598  case GR_RESIZE_FULL:
599  xy_tmp = (*w) / Gr_full_resize_X;
600  break;
601 
603  xy_tmp = (*w) / Gr_full_center_resize_X;
604  break;
605 
606  case GR_RESIZE_MENU:
609  xy_tmp = (*w) / Gr_resize_X;
610  break;
611  }
612  (*w) = xy_tmp;
613  }
614 
615  if ( h ) {
616  switch (resize_mode) {
617  case GR_RESIZE_FULL:
618  xy_tmp = (*h) / Gr_full_resize_Y;
619  break;
620 
622  xy_tmp = (*h) / Gr_full_center_resize_Y;
623  break;
624 
625  case GR_RESIZE_MENU:
628  xy_tmp = (*h) / Gr_resize_Y;
629  break;
630  }
631  (*h) = xy_tmp;
632  }
633 
634  return true;
635 }
636 
637 void gr_close()
638 {
639  if ( !Gr_inited ) {
640  return;
641  }
642 
643  palette_flush();
644 
645  switch (gr_screen.mode) {
646  case GR_OPENGL:
648  break;
649 
650  case GR_STUB:
651  break;
652 
653  default:
654  Int3(); // Invalid graphics mode
655  }
656 
657  gr_font_close();
658 
659  Gr_inited = 0;
660 }
661 
662 
666 DCF(clear_color, "set clear color r, g, b")
667 {
668  ubyte r, g, b;
669 
670  dc_stuff_ubyte(&r);
671  dc_stuff_ubyte(&g);
672  dc_stuff_ubyte(&b);
673 
674  // set the color
675  gr_set_clear_color(r, g, b);
676 }
677 
678 void gr_set_palette_internal( const char *name, ubyte * palette, int restrict_font_to_128 )
679 {
680  if ( palette == NULL ) {
681  // Create a default palette
682  int r,g,b,i;
683  i = 0;
684 
685  for (r=0; r<6; r++ )
686  for (g=0; g<6; g++ )
687  for (b=0; b<6; b++ ) {
688  Gr_current_palette[i*3+0] = (unsigned char)(r*51);
689  Gr_current_palette[i*3+1] = (unsigned char)(g*51);
690  Gr_current_palette[i*3+2] = (unsigned char)(b*51);
691  i++;
692  }
693  for ( i=216;i<256; i++ ) {
694  Gr_current_palette[i*3+0] = (unsigned char)((i-216)*6);
695  Gr_current_palette[i*3+1] = (unsigned char)((i-216)*6);
696  Gr_current_palette[i*3+2] = (unsigned char)((i-216)*6);
697  }
698  memmove( Gr_original_palette, Gr_current_palette, 768 );
699  } else {
700  memmove( Gr_original_palette, palette, 768 );
701  memmove( Gr_current_palette, palette, 768 );
702  }
703 
704  if ( Gr_inited ) {
705  if (gr_screen.gf_set_palette) {
706  (*gr_screen.gf_set_palette)(Gr_current_palette, restrict_font_to_128 );
707 
708  // Since the palette set code might shuffle the palette,
709  // reload it into the source palette
710  if ( palette ) {
711  memmove( palette, Gr_current_palette, 768 );
712  }
713  }
714 
715  // Update Palette Manager tables
716  memmove( gr_palette, Gr_current_palette, 768 );
717  palette_update(name, restrict_font_to_128);
718  }
719 }
720 
721 
722 void gr_set_palette( const char *name, ubyte * palette, int restrict_font_to_128 )
723 {
724  char *p;
725  palette_flush();
727  p = strchr( Gr_current_palette_name, '.' );
728  if ( p ) *p = 0;
729  gr_screen.signature = Gr_signature++;
730  gr_set_palette_internal( name, palette, restrict_font_to_128 );
731 }
732 
734 {
735  // this should only be called from FRED!!
736  if ( !Fred_running ) {
737  Int3();
738  return;
739  }
740 
741  gr_screen.save_center_w = gr_screen.center_w = gr_screen.save_max_w = gr_screen.max_w = gr_screen.max_w_unscaled = gr_screen.max_w_unscaled_zoomed = width;
742  gr_screen.save_center_h = gr_screen.center_h = gr_screen.save_max_h = gr_screen.max_h = gr_screen.max_h_unscaled = gr_screen.max_h_unscaled_zoomed = height;
743 
744  gr_screen.offset_x = gr_screen.offset_x_unscaled = 0;
745  gr_screen.offset_y = gr_screen.offset_y_unscaled = 0;
746 
747  gr_screen.clip_left = gr_screen.clip_left_unscaled = 0;
748  gr_screen.clip_top = gr_screen.clip_top_unscaled = 0;
749  gr_screen.clip_right = gr_screen.clip_right_unscaled = gr_screen.max_w - 1;
750  gr_screen.clip_bottom = gr_screen.clip_bottom_unscaled = gr_screen.max_h - 1;
751  gr_screen.clip_width = gr_screen.clip_width_unscaled = gr_screen.max_w;
752  gr_screen.clip_height = gr_screen.clip_height_unscaled = gr_screen.max_h;
753  gr_screen.clip_aspect = i2fl(gr_screen.clip_width) / i2fl(gr_screen.clip_height);
754 
755  if (gr_screen.custom_size) {
756  gr_unsize_screen_pos( &gr_screen.max_w_unscaled, &gr_screen.max_h_unscaled );
760  }
761 
762  gr_screen.save_max_w_unscaled = gr_screen.max_w_unscaled;
763  gr_screen.save_max_h_unscaled = gr_screen.max_h_unscaled;
766 
767  if (gr_screen.mode == GR_OPENGL) {
768  extern void opengl_setup_viewport();
770  }
771 }
772 
774 {
775  if ((width >= GR_1024_THRESHOLD_WIDTH) && (height >= GR_1024_THRESHOLD_HEIGHT)) {
776  return GR_1024;
777  } else {
778  return GR_640;
779  }
780 }
781 
782 static bool gr_init_sub(int mode, int width, int height, int depth, float center_aspect_ratio)
783 {
784  int res = GR_1024;
785  bool rc = false;
786 
787  memset( &gr_screen, 0, sizeof(screen) );
788 
789  float aspect_ratio = (float)width / (float)height;
790 
791  if ( (((width == 640) && (height == 480)) || ((width == 1024) && (height == 768))) && (aspect_ratio == center_aspect_ratio) ) {
792  gr_screen.custom_size = false;
793  } else {
794  gr_screen.custom_size = true;
795  }
796 
797  gr_screen.save_max_w = gr_screen.max_w = gr_screen.max_w_unscaled = gr_screen.max_w_unscaled_zoomed = width;
798  gr_screen.save_max_h = gr_screen.max_h = gr_screen.max_h_unscaled = gr_screen.max_h_unscaled_zoomed = height;
799  if (aspect_ratio > center_aspect_ratio) {
800  gr_screen.save_center_w = gr_screen.center_w = fl2ir(height * center_aspect_ratio);
801  gr_screen.save_center_h = gr_screen.center_h = height;
802  } else if (aspect_ratio < center_aspect_ratio) {
803  gr_screen.save_center_w = gr_screen.center_w = width;
804  gr_screen.save_center_h = gr_screen.center_h = fl2ir(width / center_aspect_ratio);
805  } else {
806  gr_screen.save_center_w = gr_screen.center_w = width;
807  gr_screen.save_center_h = gr_screen.center_h = height;
808  }
809  gr_screen.save_center_offset_x = gr_screen.center_offset_x = (width - gr_screen.center_w) / 2;
810  gr_screen.save_center_offset_y = gr_screen.center_offset_y = (height - gr_screen.center_h) / 2;
811 
812  res = gr_get_resolution_class(gr_screen.center_w, gr_screen.center_h);
813 
814  if (Fred_running) {
815  gr_screen.custom_size = false;
816  res = GR_640;
817  mode = GR_OPENGL;
818  }
819 
821 
822  Gr_save_full_resize_X = Gr_full_resize_X = (float)width / ((res == GR_1024) ? 1024.0f : 640.0f);
823  Gr_save_full_resize_Y = Gr_full_resize_Y = (float)height / ((res == GR_1024) ? 768.0f : 480.0f);
824 
825  Gr_save_full_center_resize_X = Gr_full_center_resize_X = (float)gr_screen.center_w / ((res == GR_1024) ? 1024.0f : 640.0f);
826  Gr_save_full_center_resize_Y = Gr_full_center_resize_Y = (float)gr_screen.center_h / ((res == GR_1024) ? 768.0f : 480.0f);
827 
828  if (gr_screen.custom_size && !Cmdline_stretch_menu) {
829  float aspect_quotient = center_aspect_ratio / (4.0f / 3.0f);
830 
831  Gr_save_resize_X = Gr_resize_X = Gr_full_center_resize_X / ((aspect_quotient > 1.0f) ? aspect_quotient : 1.0f);
832  Gr_save_resize_Y = Gr_resize_Y = Gr_full_center_resize_Y * ((aspect_quotient < 1.0f) ? aspect_quotient : 1.0f);
833 
834  Gr_save_menu_offset_X = Gr_menu_offset_X = ((aspect_quotient > 1.0f) ? ((gr_screen.center_w - gr_screen.center_w / aspect_quotient) / 2.0f) : 0.0f) + gr_screen.center_offset_x;
835  Gr_save_menu_offset_Y = Gr_menu_offset_Y = ((aspect_quotient < 1.0f) ? ((gr_screen.center_h - gr_screen.center_h * aspect_quotient) / 2.0f) : 0.0f) + gr_screen.center_offset_y;
836  } else {
837  Gr_save_resize_X = Gr_resize_X = Gr_full_center_resize_X;
838  Gr_save_resize_Y = Gr_resize_Y = Gr_full_center_resize_Y;
839 
840  Gr_save_menu_offset_X = Gr_menu_offset_X = (float)gr_screen.center_offset_x;
841  Gr_save_menu_offset_Y = Gr_menu_offset_Y = (float)gr_screen.center_offset_y;
842  }
843 
844  Gr_save_menu_zoomed_offset_X = Gr_menu_zoomed_offset_X = Gr_menu_offset_X;
845  Gr_save_menu_zoomed_offset_Y = Gr_menu_zoomed_offset_Y = Gr_menu_offset_Y;
846 
847 
848  gr_screen.signature = Gr_signature++;
849  gr_screen.bits_per_pixel = depth;
850  gr_screen.bytes_per_pixel= depth / 8;
851  gr_screen.rendering_to_texture = -1;
852  gr_screen.envmap_render_target = -1;
853  gr_screen.mode = mode;
854  gr_screen.res = res;
855  gr_screen.aspect = 1.0f; // Normal PC screen
856 
857  gr_screen.offset_x = gr_screen.offset_x_unscaled = 0;
858  gr_screen.offset_y = gr_screen.offset_y_unscaled = 0;
859 
860  gr_screen.clip_left = gr_screen.clip_left_unscaled = 0;
861  gr_screen.clip_top = gr_screen.clip_top_unscaled = 0;
862  gr_screen.clip_right = gr_screen.clip_right_unscaled = gr_screen.max_w - 1;
863  gr_screen.clip_bottom = gr_screen.clip_bottom_unscaled = gr_screen.max_h - 1;
864  gr_screen.clip_width = gr_screen.clip_width_unscaled = gr_screen.max_w;
865  gr_screen.clip_height = gr_screen.clip_height_unscaled = gr_screen.max_h;
866  gr_screen.clip_aspect = i2fl(gr_screen.clip_width) / i2fl(gr_screen.clip_height);
867  gr_screen.clip_center_x = (gr_screen.clip_left + gr_screen.clip_right) * 0.5f;
868  gr_screen.clip_center_y = (gr_screen.clip_top + gr_screen.clip_bottom) * 0.5f;
869 
870  if (gr_screen.custom_size) {
871  gr_unsize_screen_pos( &gr_screen.max_w_unscaled, &gr_screen.max_h_unscaled );
875  }
876 
877  gr_screen.save_max_w_unscaled = gr_screen.max_w_unscaled;
878  gr_screen.save_max_h_unscaled = gr_screen.max_h_unscaled;
881 
882 #ifdef WIN32
883  // FRED doesn't need this
884  if ( !Fred_running && !Is_standalone ) {
885  // for Windows, we need to do this just before the *_init() calls
886  extern void win32_create_window(int width, int height);
887  win32_create_window( width, height );
888  }
889 #endif
890 
891  switch (mode) {
892  case GR_OPENGL:
893  rc = gr_opengl_init();
894  break;
895  case GR_STUB:
896  rc = gr_stub_init();
897  break;
898  default:
899  Int3(); // Invalid graphics mode
900  }
901 
902  if ( !rc ) {
903  return false;
904  }
905 
906  return true;
907 }
908 
909 bool gr_init(int d_mode, int d_width, int d_height, int d_depth)
910 {
911  int width = 1024, height = 768, depth = 32, mode = GR_OPENGL;
912  float center_aspect_ratio = -1.0f;
913  const char *ptr = NULL;
914  const char *Default_video_settings = "OGL -(1024x768)x32 bit";
915 
916  if ( !Gr_inited ) {
917  atexit(gr_close);
918  }
919 
920  // If already inited, shutdown the previous graphics
921  if (Gr_inited) {
922  switch (gr_screen.mode) {
923  case GR_OPENGL:
925  break;
926 
927  case GR_STUB:
928  break;
929 
930  default:
931  Int3(); // Invalid graphics mode
932  }
933  }
934 
935  // We cannot continue without this, quit, but try to help the user out first
936  ptr = os_config_read_string(NULL, NOX("VideocardFs2open"), NULL);
937 
938  // if we don't have a config string then construct one, using OpenGL 1024x768 32-bit as the default
939  if (ptr == NULL) {
940  ptr = Default_video_settings;
941  }
942 
943  Assert( ptr != NULL );
944 
945  // NOTE: The "ptr+5" is to skip over the initial "????-" in the video string.
946  // If the format of that string changes you'll have to change this too!!!
947  if ( sscanf(ptr+5, "(%dx%d)x%d ", &width, &height, &depth) != 3 ) {
948  Error(LOCATION, "Can't understand 'VideocardFs2open' config entry!");
949  }
950 
951  if (Cmdline_res != NULL) {
952  int tmp_width = 0;
953  int tmp_height = 0;
954 
955  if ( sscanf(Cmdline_res, "%dx%d", &tmp_width, &tmp_height) == 2 ) {
956  width = tmp_width;
957  height = tmp_height;
958  }
959  }
960  if (Cmdline_center_res != NULL) {
961  int tmp_center_width = 0;
962  int tmp_center_height = 0;
963 
964  if ( (sscanf(Cmdline_center_res, "%dx%d", &tmp_center_width, &tmp_center_height) == 2) && (tmp_center_width > 0) && (tmp_center_height > 0) ) {
965  center_aspect_ratio = (float)tmp_center_width / (float)tmp_center_height;
966  }
967  }
968 
969  if (d_mode == GR_DEFAULT) {
970  // OpenGL should be default
971  mode = GR_OPENGL;
972  } else {
973  mode = d_mode;
974  }
975 
976  // see if we passed good values, and use those instead of the config settings
977  if ( (d_width != GR_DEFAULT) && (d_height != GR_DEFAULT) ) {
978  width = d_width;
979  height = d_height;
980  }
981 
982  if (d_depth != GR_DEFAULT) {
983  depth = d_depth;
984  }
985 
986  if (gr_get_resolution_class(width, height) != GR_640) {
987  // check for hi-res interface files so that we can verify our width/height is correct
988  bool has_sparky_hi = (cf_exists_full("2_ChoosePilot-m.pcx", CF_TYPE_ANY) && cf_exists_full("2_TechShipData-m.pcx", CF_TYPE_ANY));
989 
990  // if we don't have it then fall back to 640x480 mode instead
991  if ( !has_sparky_hi ) {
992  if ( (width == 1024) && (height == 768) ) {
993  width = 640;
994  height = 480;
995  center_aspect_ratio = -1.0f;
996  } else {
997  width = 800;
998  height = 600;
999  center_aspect_ratio = -1.0f;
1000  }
1001  }
1002  }
1003 
1004  // if we are in standalone mode then just use special defaults
1005  if (Is_standalone) {
1006  mode = GR_STUB;
1007  width = 640;
1008  height = 480;
1009  depth = 16;
1010  center_aspect_ratio = -1.0f;
1011  }
1012 
1013 // These compiler macros will force windowed mode at the specified resolution if
1014 // built in debug mode. This helps if you run with the debugger active as the
1015 // game won't be switching from fullscreen to minimized every time you hit a breakpoint or
1016 // warning message.
1017 #ifdef _DEBUG
1018 #ifdef _FORCE_DEBUG_WIDESCREEN
1019  width = 1280;
1020  height = 800;
1021  depth = 32;
1022  center_aspect_ratio = -1.0f;
1023  Cmdline_window = 1;
1024 #elif defined(_FORCE_DEBUG_1024)
1025  width = 1024;
1026  height = 768;
1027  depth = 32;
1028  center_aspect_ratio = -1.0f;
1029  Cmdline_window = 1;
1030 #elif defined(_FORCE_DEBUG_640)
1031  width = 640;
1032  height = 480;
1033  depth = 32;
1034  center_aspect_ratio = -1.0f;
1035  Cmdline_window = 1;
1036 #endif
1037 #endif
1038 
1039  if (center_aspect_ratio <= 0.0f) {
1040  float aspect_ratio = (float)width / (float)height;
1041  if (aspect_ratio > 3.5f) {
1042  center_aspect_ratio = aspect_ratio * 0.3f;
1043  } else {
1044  center_aspect_ratio = aspect_ratio;
1045  }
1046  }
1047 
1048  // now try to actually init everything...
1049  if ( gr_init_sub(mode, width, height, depth, center_aspect_ratio) == false ) {
1050  return false;
1051  }
1052 
1054 
1055  bm_init();
1056 
1057  if (Gr_cursor < 0) {
1058  int w, h;
1059 
1060  Gr_cursor = bm_load( "cursor" );
1061 
1062  if (Gr_cursor >= 0) {
1063  // get cursor size, so that we can be sure to account for the full thing
1064  // in later cursor hiding code
1065  bm_get_info(Gr_cursor, &w, &h);
1066  Gr_cursor_size = MAX(w, h);
1067 
1068  if (Gr_cursor_size <= 0) {
1069  Int3();
1070  Gr_cursor_size = 32;
1071  }
1072  }
1073  }
1074 
1075  // load the web pointer cursor bitmap
1076  if (Web_cursor_bitmap < 0) {
1077  //if it still hasn't loaded then this usually means that the executable isn't in the same directory as the main fs2 install
1078  if ( (Web_cursor_bitmap = bm_load_animation("cursorweb")) < 0 ) {
1079  Error(LOCATION, "\nWeb cursor bitmap not found. This is most likely due to one of three reasons:\n"
1080  "\t1) You're running FreeSpace Open from somewhere other than your FreeSpace 2 folder;\n"
1081  "\t2) You've somehow corrupted your FreeSpace 2 installation, e.g. by modifying or removing the retail VP files;\n"
1082  "\t3) You haven't installed FreeSpace 2 at all. (Note that installing FreeSpace Open does NOT remove the need for a FreeSpace 2 installation.)\n"
1083  "Number 1 can be fixed by simply moving the FreeSpace Open executable file to the FreeSpace 2 folder. Numbers 2 and 3 can be fixed by installing or reinstalling FreeSpace 2.\n");
1084  }
1085  }
1086 
1087  mprintf(("GRAPHICS: Initializing default colors...\n"));
1088 
1089  gr_set_color(0,0,0);
1090  gr_set_clear_color(0, 0, 0);
1091 
1092  gr_set_shader(NULL);
1093 
1095 
1096  Gr_inited = 1;
1097 
1098  return true;
1099 }
1100 
1102 {
1103  if ( !Gr_inited ) {
1104  return;
1105  }
1106 
1107  switch( gr_screen.mode ) {
1108  case GR_OPENGL:
1109  break;
1110  case GR_STUB:
1111  break;
1112  default:
1113  Int3(); // Invalid graphics mode
1114  }
1115 
1116  if ( Os_debugger_running ) {
1117  Sleep(1000);
1118  }
1119 }
1120 
1122 void gr_activate(int active)
1123 {
1124 
1125  if (gr_activated == active) {
1126  return;
1127  }
1128  gr_activated = active;
1129 
1130  if ( !Gr_inited ) {
1131  return;
1132  }
1133 
1134  switch( gr_screen.mode ) {
1135  case GR_OPENGL:
1136  extern void gr_opengl_activate(int active);
1137  gr_opengl_activate(active);
1138  break;
1139  case GR_STUB:
1140  break;
1141  default:
1142  Int3(); // Invalid graphics mode
1143  }
1144 
1145 }
1146 
1147 // color stuff
1148 void gr_get_color( int *r, int *g, int *b )
1149 {
1150  if (r) *r = gr_screen.current_color.red;
1151  if (g) *g = gr_screen.current_color.green;
1152  if (b) *b = gr_screen.current_color.blue;
1153 }
1154 
1155 void gr_init_color(color *c, int r, int g, int b)
1156 {
1157  CAP(r, 0, 255);
1158  CAP(g, 0, 255);
1159  CAP(b, 0, 255);
1160 
1161  c->screen_sig = gr_screen.signature;
1162  c->red = (ubyte)r;
1163  c->green = (ubyte)g;
1164  c->blue = (ubyte)b;
1165  c->alpha = 255;
1166  c->ac_type = AC_TYPE_NONE;
1167  c->alphacolor = -1;
1168  c->is_alphacolor = 0;
1169  c->magic = 0xAC01;
1170  c->raw8 = 0;
1171 }
1172 
1173 void gr_init_alphacolor( color *clr, int r, int g, int b, int alpha, int type )
1174 {
1175  CAP(r, 0, 255);
1176  CAP(g, 0, 255);
1177  CAP(b, 0, 255);
1178  CAP(alpha, 0, 255);
1179 
1180  gr_init_color( clr, r, g, b );
1181 
1182  clr->alpha = (ubyte)alpha;
1183  clr->ac_type = (ubyte)type;
1184  clr->alphacolor = -1;
1185  clr->is_alphacolor = 1;
1186 }
1187 
1188 void gr_set_color( int r, int g, int b )
1189 {
1190  Assert((r >= 0) && (r < 256));
1191  Assert((g >= 0) && (g < 256));
1192  Assert((b >= 0) && (b < 256));
1193 
1194  gr_init_color( &gr_screen.current_color, r, g, b );
1195 }
1196 
1198 {
1199  if ( dst->screen_sig != gr_screen.signature ) {
1200  if (dst->is_alphacolor) {
1201  gr_init_alphacolor( dst, dst->red, dst->green, dst->blue, dst->alpha, dst->ac_type );
1202  } else {
1203  gr_init_color( dst, dst->red, dst->green, dst->blue );
1204  }
1205  }
1206 
1207  gr_screen.current_color = *dst;
1208 }
1209 
1210 // shader functions
1212 {
1213  shade->screen_sig = gr_screen.signature;
1214  shade->r = r;
1215  shade->g = g;
1216  shade->b = b;
1217  shade->c = c;
1218 }
1219 
1220 void gr_set_shader(shader *shade)
1221 {
1222  if (shade) {
1223  if (shade->screen_sig != gr_screen.signature) {
1224  gr_create_shader( shade, shade->r, shade->g, shade->b, shade->c );
1225  }
1226  gr_screen.current_shader = *shade;
1227  } else {
1228  gr_create_shader( &gr_screen.current_shader, 0, 0, 0, 0 );
1229  }
1230 }
1231 
1242 void gr_set_cursor_bitmap(int n, int lock)
1243 {
1244  int w, h;
1245  static int locked = 0;
1246 
1247  if ( !locked || (lock == GR_CURSOR_UNLOCK) ) {
1248  // if we are changing the cursor to something different
1249  // then unload the previous cursor's data - taylor
1250  if ( (Gr_cursor >= 0) && (Gr_cursor != n) ) {
1251  // be sure to avoid changing a cursor which is simply another frame
1252  if ( (GL_cursor_nframes < 2) || ((n - Gr_cursor) >= GL_cursor_nframes) ) {
1254  }
1255  }
1256 
1257  if (n != Gr_cursor) {
1258  // get cursor size, so that we can be sure to account for the full thing
1259  // in later cursor hiding code
1260  bm_get_info(n, &w, &h, NULL, &GL_cursor_nframes);
1261  Assert( GL_cursor_nframes > 0 );
1262 
1263  Gr_cursor_size = MAX(w, h);
1264 
1265  if (Gr_cursor_size <= 0) {
1266  Int3();
1267  Gr_cursor_size = 32;
1268  }
1269  }
1270 
1271  Gr_cursor = n;
1272  } else {
1273  locked = 0;
1274  }
1275 
1276  if (lock == GR_CURSOR_LOCK) {
1277  locked = 1;
1278  }
1279 }
1280 
1282 {
1283  if (n < 0) {
1284  return;
1285  }
1286 
1287  if (Gr_cursor == n) {
1289  Gr_cursor = -1;
1290  }
1291 }
1292 
1298 {
1299  return Gr_cursor;
1300 }
1301 
1302 // new bitmap functions
1303 void gr_bitmap(int _x, int _y, int resize_mode)
1304 {
1305  int _w, _h;
1306  float x, y, w, h;
1307  vertex verts[4];
1308 
1309  if (gr_screen.mode == GR_STUB) {
1310  return;
1311  }
1312 
1313  bm_get_info(gr_screen.current_bitmap, &_w, &_h, NULL, NULL, NULL);
1314 
1315  x = i2fl(_x);
1316  y = i2fl(_y);
1317  w = i2fl(_w);
1318  h = i2fl(_h);
1319 
1320  // I will tidy this up later - RT
1321  if ( resize_mode != GR_RESIZE_NONE && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)) ) {
1322  gr_resize_screen_posf(&x, &y, &w, &h, resize_mode);
1323  }
1324 
1325  memset(verts, 0, sizeof(verts));
1326 
1327  verts[0].screen.xyw.x = x;
1328  verts[0].screen.xyw.y = y;
1329  verts[0].texture_position.u = 0.0f;
1330  verts[0].texture_position.v = 0.0f;
1331 
1332  verts[1].screen.xyw.x = x + w;
1333  verts[1].screen.xyw.y = y;
1334  verts[1].texture_position.u = 1.0f;
1335  verts[1].texture_position.v = 0.0f;
1336 
1337  verts[2].screen.xyw.x = x + w;
1338  verts[2].screen.xyw.y = y + h;
1339  verts[2].texture_position.u = 1.0f;
1340  verts[2].texture_position.v = 1.0f;
1341 
1342  verts[3].screen.xyw.x = x;
1343  verts[3].screen.xyw.y = y + h;
1344  verts[3].texture_position.u = 0.0f;
1345  verts[3].texture_position.v = 1.0f;
1346 
1347  // turn off zbuffering
1348  int saved_zbuffer_mode = gr_zbuffer_get();
1350 
1352 
1353  gr_zbuffer_set(saved_zbuffer_mode);
1354 }
1355 
1356 void gr_bitmap_uv(int _x, int _y, int _w, int _h, float _u0, float _v0, float _u1, float _v1, int resize_mode)
1357 {
1358  float x, y, w, h;
1359  vertex verts[4];
1360 
1361  if (gr_screen.mode == GR_STUB) {
1362  return;
1363  }
1364 
1365  x = i2fl(_x);
1366  y = i2fl(_y);
1367  w = i2fl(_w);
1368  h = i2fl(_h);
1369 
1370  // I will tidy this up later - RT
1371  if ( resize_mode != GR_RESIZE_NONE && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)) ) {
1372  gr_resize_screen_posf(&x, &y, &w, &h, resize_mode);
1373  }
1374 
1375  memset(verts, 0, sizeof(verts));
1376 
1377  verts[0].screen.xyw.x = x;
1378  verts[0].screen.xyw.y = y;
1379  verts[0].texture_position.u = _u0;
1380  verts[0].texture_position.v = _v0;
1381 
1382  verts[1].screen.xyw.x = x + w;
1383  verts[1].screen.xyw.y = y;
1384  verts[1].texture_position.u = _u1;
1385  verts[1].texture_position.v = _v0;
1386 
1387  verts[2].screen.xyw.x = x + w;
1388  verts[2].screen.xyw.y = y + h;
1389  verts[2].texture_position.u = _u1;
1390  verts[2].texture_position.v = _v1;
1391 
1392  verts[3].screen.xyw.x = x;
1393  verts[3].screen.xyw.y = y + h;
1394  verts[3].texture_position.u = _u0;
1395  verts[3].texture_position.v = _v1;
1396 
1397  // turn off zbuffering
1398  int saved_zbuffer_mode = gr_zbuffer_get();
1400 
1402 
1403  gr_zbuffer_set(saved_zbuffer_mode);
1404 }
1405 
1406 // NEW new bitmap functions -Bobboau
1407 void gr_bitmap_list(bitmap_2d_list* list, int n_bm, int resize_mode)
1408 {
1409  for (int i = 0; i < n_bm; i++) {
1410  bitmap_2d_list *l = &list[i];
1411 
1412  bm_get_info(gr_screen.current_bitmap, &l->w, &l->h, NULL, NULL, NULL);
1413 
1414  if ( resize_mode != GR_RESIZE_NONE && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)) ) {
1415  gr_resize_screen_pos(&l->x, &l->y, &l->w, &l->h, resize_mode);
1416  }
1417  }
1418 
1420 }
1421 
1422 // _->NEW<-_ NEW new bitmap functions -Bobboau
1423 //takes a list of rectangles that have assosiated rectangles in a texture
1424 void gr_bitmap_list(bitmap_rect_list* list, int n_bm, int resize_mode)
1425 {
1426  for(int i = 0; i < n_bm; i++) {
1427  bitmap_2d_list *l = &list[i].screen_rect;
1428 
1429  // if no valid hight or width values were given get some from the bitmap
1430  if ( (l->w <= 0) || (l->h <= 0) ) {
1431  bm_get_info(gr_screen.current_bitmap, &l->w, &l->h, NULL, NULL, NULL);
1432  }
1433 
1434  if ( resize_mode != GR_RESIZE_NONE && (gr_screen.custom_size || (gr_screen.rendering_to_texture != -1)) ) {
1435  gr_resize_screen_pos(&l->x, &l->y, &l->w, &l->h, resize_mode);
1436  }
1437  }
1438 
1440 }
1441 
1442 
1446 void gr_pline_helper(vec3d *out, vec3d *in1, vec3d *in2, int thickness)
1447 {
1448  vec3d slope;
1449 
1450  // slope of the line
1451  if(vm_vec_same(in1, in2)) {
1452  slope = vmd_zero_vector;
1453  } else {
1454  vm_vec_sub(&slope, in2, in1);
1455  float temp = -slope.xyz.x;
1456  slope.xyz.x = slope.xyz.y;
1457  slope.xyz.y = temp;
1458  vm_vec_normalize(&slope);
1459  }
1460  // get the points
1461  vm_vec_scale_add(out, in1, &slope, (float)thickness);
1462 }
1463 
1471 void gr_pline_special(SCP_vector<vec3d> *pts, int thickness,int resize_mode)
1472 {
1473  vec3d s1, s2, e1, e2, dir;
1474  vec3d last_e1, last_e2;
1475  vertex v[4];
1476  vertex *verts[4] = {&v[0], &v[1], &v[2], &v[3]};
1477  int saved_zbuffer_mode, idx;
1478  int started_frame = 0;
1479 
1480  int num_pts = pts->size();
1481 
1482  // if we have less than 2 pts, bail
1483  if(num_pts < 2) {
1484  return;
1485  }
1486 
1487  extern int G3_count;
1488  if(G3_count == 0) {
1489  g3_start_frame(1);
1490  started_frame = 1;
1491  }
1492 
1493  // turn off zbuffering
1494  saved_zbuffer_mode = gr_zbuffer_get();
1496 
1497  // turn off culling
1498  int cull = gr_set_cull(0);
1499 
1500  // draw each section
1501  last_e1 = vmd_zero_vector;
1502  last_e2 = vmd_zero_vector;
1503  int j;
1504  for(idx=0; idx<num_pts-1; idx++) {
1505  // get the start and endpoints
1506  s1 = pts->at(idx); // start 1 (on the line)
1507  e1 = pts->at(idx+1); // end 1 (on the line)
1508  gr_pline_helper(&s2, &s1, &e1, thickness); // start 2
1509  vm_vec_sub(&dir, &e1, &s1);
1510  vm_vec_add(&e2, &s2, &dir); // end 2
1511 
1512  // stuff coords
1513  v[0].screen.xyw.x = (float)ceil(s1.xyz.x);
1514  v[0].screen.xyw.y = (float)ceil(s1.xyz.y);
1515  v[0].screen.xyw.w = 0.0f;
1516  v[0].texture_position.u = 0.5f;
1517  v[0].texture_position.v = 0.5f;
1518  v[0].flags = PF_PROJECTED;
1519  v[0].codes = 0;
1520  v[0].r = gr_screen.current_color.red;
1521  v[0].g = gr_screen.current_color.green;
1522  v[0].b = gr_screen.current_color.blue;
1523 
1524  v[1].screen.xyw.x = (float)ceil(s2.xyz.x);
1525  v[1].screen.xyw.y = (float)ceil(s2.xyz.y);
1526  v[1].screen.xyw.w = 0.0f;
1527  v[1].texture_position.u = 0.5f;
1528  v[1].texture_position.v = 0.5f;
1529  v[1].flags = PF_PROJECTED;
1530  v[1].codes = 0;
1531  v[1].r = gr_screen.current_color.red;
1532  v[1].g = gr_screen.current_color.green;
1533  v[1].b = gr_screen.current_color.blue;
1534 
1535  v[2].screen.xyw.x = (float)ceil(e2.xyz.x);
1536  v[2].screen.xyw.y = (float)ceil(e2.xyz.y);
1537  v[2].screen.xyw.w = 0.0f;
1538  v[2].texture_position.u = 0.5f;
1539  v[2].texture_position.v = 0.5f;
1540  v[2].flags = PF_PROJECTED;
1541  v[2].codes = 0;
1542  v[2].r = gr_screen.current_color.red;
1543  v[2].g = gr_screen.current_color.green;
1544  v[2].b = gr_screen.current_color.blue;
1545 
1546  v[3].screen.xyw.x = (float)ceil(e1.xyz.x);
1547  v[3].screen.xyw.y = (float)ceil(e1.xyz.y);
1548  v[3].screen.xyw.w = 0.0f;
1549  v[3].texture_position.u = 0.5f;
1550  v[3].texture_position.v = 0.5f;
1551  v[3].flags = PF_PROJECTED;
1552  v[3].codes = 0;
1553  v[3].r = gr_screen.current_color.red;
1554  v[3].g = gr_screen.current_color.green;
1555  v[3].b = gr_screen.current_color.blue;
1556 
1557  //We could really do this better...but oh well. _WMC
1558  if(resize_mode != GR_RESIZE_NONE) {
1559  for(j=0;j<4;j++) {
1560  gr_resize_screen_posf(&v[j].screen.xyw.x,&v[j].screen.xyw.y,NULL,NULL,resize_mode);
1561  }
1562  }
1563 
1564  // draw the polys
1566 
1567  // if we're past the first section, draw a "patch" triangle to fill any gaps
1568  if(idx > 0) {
1569  // stuff coords
1570  v[0].screen.xyw.x = (float)ceil(s1.xyz.x);
1571  v[0].screen.xyw.y = (float)ceil(s1.xyz.y);
1572  v[0].screen.xyw.w = 0.0f;
1573  v[0].texture_position.u = 0.5f;
1574  v[0].texture_position.v = 0.5f;
1575  v[0].flags = PF_PROJECTED;
1576  v[0].codes = 0;
1577  v[0].r = gr_screen.current_color.red;
1578  v[0].g = gr_screen.current_color.green;
1579  v[0].b = gr_screen.current_color.blue;
1580 
1581  v[1].screen.xyw.x = (float)ceil(s2.xyz.x);
1582  v[1].screen.xyw.y = (float)ceil(s2.xyz.y);
1583  v[1].screen.xyw.w = 0.0f;
1584  v[1].texture_position.u = 0.5f;
1585  v[1].texture_position.v = 0.5f;
1586  v[1].flags = PF_PROJECTED;
1587  v[1].codes = 0;
1588  v[1].r = gr_screen.current_color.red;
1589  v[1].g = gr_screen.current_color.green;
1590  v[1].b = gr_screen.current_color.blue;
1591 
1592 
1593  v[2].screen.xyw.x = (float)ceil(last_e2.xyz.x);
1594  v[2].screen.xyw.y = (float)ceil(last_e2.xyz.y);
1595  v[2].screen.xyw.w = 0.0f;
1596  v[2].texture_position.u = 0.5f;
1597  v[2].texture_position.v = 0.5f;
1598  v[2].flags = PF_PROJECTED;
1599  v[2].codes = 0;
1600  v[2].r = gr_screen.current_color.red;
1601  v[2].g = gr_screen.current_color.green;
1602  v[2].b = gr_screen.current_color.blue;
1603 
1604  //Inefficiency or flexibility? you be the judge -WMC
1605  if(resize_mode != GR_RESIZE_NONE) {
1606  for(j=0;j<3;j++) {
1607  gr_resize_screen_posf(&v[j].screen.xyw.x,&v[j].screen.xyw.y,NULL,NULL,resize_mode);
1608  }
1609  }
1610 
1612  }
1613 
1614  // store our endpoints
1615  last_e1 = e1;
1616  last_e2 = e2;
1617  }
1618 
1619  if(started_frame) {
1620  g3_end_frame();
1621  }
1622 
1623  // restore zbuffer mode
1624  gr_zbuffer_set(saved_zbuffer_mode);
1625 
1626  // restore culling
1627  gr_set_cull(cull);
1628 }
1629 
1630 int poly_list::find_first_vertex(int idx)
1631 {
1632  vec3d *o_norm = &norm[idx];
1633  vertex *o_vert = &vert[idx];
1634  vec3d *p_norm = &norm[0];
1635  vertex *p_vert = &vert[0];
1636 
1637  // we should always equal ourselves, so just use that as the stopping point
1638  for (int i = 0; i < idx; i++) {
1639  if ( (*p_norm == *o_norm)
1640  && (p_vert->world == o_vert->world)
1641  && (p_vert->texture_position == o_vert->texture_position) )
1642  {
1643  return i;
1644  }
1645 
1646  ++p_norm;
1647  ++p_vert;
1648  }
1649 
1650  return idx;
1651 }
1652 
1653 int poly_list::find_first_vertex_fast(int idx)
1654 {
1655  uint* first_idx = std::lower_bound(sorted_indices, sorted_indices + n_verts, idx, finder(this, NULL, NULL));
1656 
1657  if ( first_idx == sorted_indices + n_verts ) {
1658  // if this happens then idx was never in the index list to begin with which is not good
1659  mprintf(("Sorted index list missing index %d!", idx));
1660  Int3();
1661  return idx;
1662  }
1663 
1664  return *first_idx;
1665 }
1666 
1670 int poly_list::find_index(poly_list *plist, int idx)
1671 {
1672  vec3d *o_norm = &plist->norm[idx];
1673  vertex *o_vert = &plist->vert[idx];
1674  vec3d *p_norm = &norm[0];
1675  vertex *p_vert = &vert[0];
1676 
1677  for (int i = 0; i < n_verts; i++) {
1678  if ( (*p_norm == *o_norm)
1679  && (p_vert->world == o_vert->world)
1680  && (p_vert->texture_position == o_vert->texture_position))
1681  {
1682  return i;
1683  }
1684 
1685  ++p_vert;
1686  ++p_norm;
1687  }
1688 
1689  return -1;
1690 }
1691 
1693 {
1694  // searching for an out of bounds index using the finder means we're trying to find the vert and norm we're passing into the finder instance
1695  uint* first_idx = std::lower_bound(sorted_indices, sorted_indices + n_verts, n_verts, finder(this, &plist->vert[idx], &plist->norm[idx]));
1696 
1697  if (first_idx == sorted_indices + n_verts) {
1698  return -1;
1699  }
1700 
1701  return *first_idx;
1702 }
1703 
1704 void poly_list::allocate(int _verts)
1705 {
1706  if (_verts <= currently_allocated)
1707  return;
1708 
1709  if (vert != NULL) {
1710  vm_free(vert);
1711  vert = NULL;
1712  }
1713 
1714  if (norm != NULL) {
1715  vm_free(norm);
1716  norm = NULL;
1717  }
1718 
1719  if (tsb != NULL) {
1720  vm_free(tsb);
1721  tsb = NULL;
1722  }
1723 
1724  if ( submodels != NULL ) {
1725  vm_free(submodels);
1726  submodels = NULL;
1727  }
1728 
1729  if ( sorted_indices != NULL ) {
1731  sorted_indices = NULL;
1732  }
1733 
1734  if (_verts) {
1735  vert = (vertex*)vm_malloc(sizeof(vertex) * _verts);
1736  norm = (vec3d*)vm_malloc(sizeof(vec3d) * _verts);
1737 
1738  if (Cmdline_normal) {
1739  tsb = (tsb_t*)vm_malloc(sizeof(tsb_t) * _verts);
1740  }
1741 
1742  if ( GLSL_version >= 130 ) {
1743  submodels = (int*)vm_malloc(sizeof(int) * _verts);
1744  }
1745 
1746  sorted_indices = (uint*)vm_malloc(sizeof(uint) * _verts);
1747  }
1748 
1749  n_verts = 0;
1750  currently_allocated = _verts;
1751 }
1752 
1754 {
1755  if (vert != NULL) {
1756  vm_free(vert);
1757  vert = NULL;
1758  }
1759 
1760  if (norm != NULL) {
1761  vm_free(norm);
1762  norm = NULL;
1763  }
1764 
1765  if (tsb != NULL) {
1766  vm_free(tsb);
1767  tsb = NULL;
1768  }
1769 
1770  if ( submodels != NULL ) {
1771  vm_free(submodels);
1772  submodels = NULL;
1773  }
1774 
1775  if (sorted_indices != NULL) {
1777  sorted_indices = NULL;
1778  }
1779 }
1780 
1782 {
1783  vertex *v0, *v1, *v2;
1784  vec3d *t0, *t1, *t2;
1785  vec3d side0, side1;
1786  vec3d vt0, vt1;
1787  float deltaU0, deltaV0, deltaU1, deltaV1;
1788  vec3d tangent, binormal, cross;
1789  float magg, scale;
1790 
1791  if ( !Cmdline_normal ) {
1792  return;
1793  }
1794 
1795  Assert( !(n_verts % 3) );
1796 
1797  for (int i = 0; i < n_verts; i += 3) {
1798  // vertex (reading)
1799  v0 = &vert[i];
1800  v1 = &vert[i+1];
1801  v2 = &vert[i+2];
1802  // tangents (writing)
1803  t0 = &tsb[i].tangent;
1804  t1 = &tsb[i+1].tangent;
1805  t2 = &tsb[i+2].tangent;
1806 
1807 
1808  deltaU0 = v1->texture_position.u - v0->texture_position.u;
1809  deltaV0 = v1->texture_position.v - v0->texture_position.v;
1810 
1811  deltaU1 = v2->texture_position.u - v0->texture_position.u;
1812  deltaV1 = v2->texture_position.v - v0->texture_position.v;
1813 
1814  // quick short circuit for NULL case
1815  float n = (deltaU0 * deltaV1) - (deltaU1 * deltaV0);
1816 
1817  if (n == 0.0f) {
1818  // hit NULL, so just set identity
1819  tangent = vmd_x_vector;
1820  binormal = vmd_y_vector;
1821  } else {
1822  float blah = 1.0f / n;
1823 
1824  vm_vec_sub(&side0, &v1->world, &v0->world);
1825  vm_vec_sub(&side1, &v2->world, &v0->world);
1826 
1827  // tangent
1828  vm_vec_copy_scale(&vt0, &side0, deltaV1);
1829  vm_vec_copy_scale(&vt1, &side1, deltaV0);
1830  vm_vec_sub(&tangent, &vt0, &vt1);
1831  vm_vec_scale(&tangent, blah);
1832 
1833  // binormal
1834  vm_vec_copy_scale(&vt0, &side0, deltaU1);
1835  vm_vec_copy_scale(&vt1, &side1, deltaU0);
1836  vm_vec_sub(&binormal, &vt0, &vt1);
1837  vm_vec_scale(&binormal, blah);
1838  }
1839 
1840  // orthogonalize tangent (for all 3 verts)
1841  magg = vm_vec_dot(&norm[i], &tangent);
1842  vm_vec_scale_sub(t0, &tangent, &norm[i], magg);
1844 
1845  magg = vm_vec_dot(&norm[i+1], &tangent);
1846  vm_vec_scale_sub(t1, &tangent, &norm[i+1], magg);
1848 
1849  magg = vm_vec_dot(&norm[i+2], &tangent);
1850  vm_vec_scale_sub(t2, &tangent, &norm[i+2], magg);
1852 
1853  // compute handedness (for all 3 verts)
1854  vm_vec_cross(&cross, &norm[i], &tangent);
1855  scale = vm_vec_dot(&cross, &binormal);
1856  tsb[i].scaler = (scale < 0.0f) ? -1.0f : 1.0f;
1857 
1858  vm_vec_cross(&cross, &norm[i+1], &tangent);
1859  scale = vm_vec_dot(&cross, &binormal);
1860  tsb[i+1].scaler = (scale < 0.0f) ? -1.0f : 1.0f;
1861 
1862  vm_vec_cross(&cross, &norm[i+2], &tangent);
1863  scale = vm_vec_dot(&cross, &binormal);
1864  tsb[i+2].scaler = (scale < 0.0f) ? -1.0f : 1.0f;
1865  }
1866 }
1867 
1868 static poly_list buffer_list_internal;
1869 
1871 {
1872  int nverts = 0;
1873  int j, z = 0;
1874  ubyte *nverts_good = NULL;
1875 
1876  // calculate tangent space data (must be done early)
1878 
1879  // using vm_malloc() here rather than 'new' so we get the extra out-of-memory check
1880  nverts_good = (ubyte *) vm_malloc(n_verts);
1881 
1882  Assert( nverts_good != NULL );
1883  if ( nverts_good == NULL )
1884  return;
1885 
1886  memset( nverts_good, 0, n_verts );
1887 
1888  vertex_list.reserve(n_verts);
1889 
1890  generate_sorted_index_list();
1891 
1892  for (j = 0; j < n_verts; j++) {
1893  if (find_first_vertex_fast(j) == j) {
1894  nverts++;
1895  nverts_good[j] = 1;
1896  vertex_list.push_back(j);
1897  }
1898  }
1899 
1900  // if there is nothig to change then bail
1901  if (n_verts == nverts) {
1902  if (nverts_good != NULL) {
1903  vm_free(nverts_good);
1904  }
1905 
1906  return;
1907  }
1908 
1909  buffer_list_internal.n_verts = 0;
1910  buffer_list_internal.allocate(nverts);
1911 
1912  for (j = 0; j < n_verts; j++) {
1913  if ( !nverts_good[j] ) {
1914  continue;
1915  }
1916 
1917  buffer_list_internal.vert[z] = vert[j];
1918  buffer_list_internal.norm[z] = norm[j];
1919 
1920  if (Cmdline_normal) {
1921  buffer_list_internal.tsb[z] = tsb[j];
1922  }
1923 
1924  if ( GLSL_version >= 130 ) {
1925  buffer_list_internal.submodels[z] = submodels[j];
1926  }
1927 
1928  buffer_list_internal.n_verts++;
1929  z++;
1930  }
1931 
1932  Assert(nverts == buffer_list_internal.n_verts);
1933 
1934  if (nverts_good != NULL) {
1935  vm_free(nverts_good);
1936  }
1937 
1938  buffer_list_internal.generate_sorted_index_list();
1939 
1940  (*this) = buffer_list_internal;
1941 }
1942 
1944 {
1945  allocate(other_list.n_verts);
1946 
1947  memcpy(norm, other_list.norm, sizeof(vec3d) * other_list.n_verts);
1948  memcpy(vert, other_list.vert, sizeof(vertex) * other_list.n_verts);
1949 
1950  if (Cmdline_normal) {
1951  memcpy(tsb, other_list.tsb, sizeof(tsb_t) * other_list.n_verts);
1952  }
1953 
1954  if ( GLSL_version >= 130 ) {
1955  memcpy(submodels, other_list.submodels, sizeof(int) * other_list.n_verts);
1956  }
1957 
1958  memcpy(sorted_indices, other_list.sorted_indices, sizeof(uint) * other_list.n_verts);
1959 
1960  n_verts = other_list.n_verts;
1961 
1962  return *this;
1963 }
1964 
1965 void poly_list::generate_sorted_index_list()
1966 {
1967  for ( int j = 0; j < n_verts; ++j) {
1968  sorted_indices[j] = j;
1969  }
1970 
1971  std::sort(sorted_indices, sorted_indices + n_verts, finder(this));
1972 }
1973 
1974 bool poly_list::finder::operator()(const uint a, const uint b)
1975 {
1976  vertex *vert_a;
1977  vertex *vert_b;
1978  vec3d *norm_a;
1979  vec3d *norm_b;
1980 
1981  Assert(search_list != NULL);
1982 
1983  if ( a == (uint)search_list->n_verts ) {
1984  Assert(vert_to_find != NULL);
1985  Assert(norm_to_find != NULL);
1986  Assert(a != b);
1987 
1988  vert_a = vert_to_find;
1989  norm_a = norm_to_find;
1990  } else {
1991  vert_a = &search_list->vert[a];
1992  norm_a = &search_list->norm[a];
1993  }
1994 
1995  if ( b == (uint)search_list->n_verts ) {
1996  Assert(vert_to_find != NULL);
1997  Assert(norm_to_find != NULL);
1998  Assert(a != b);
1999 
2000  vert_b = vert_to_find;
2001  norm_b = norm_to_find;
2002  } else {
2003  vert_b = &search_list->vert[b];
2004  norm_b = &search_list->norm[b];
2005  }
2006 
2007  if (norm_a->xyz.x != norm_b->xyz.x) {
2008  return norm_a->xyz.x < norm_b->xyz.x;
2009  }
2010 
2011  if (norm_a->xyz.y != norm_b->xyz.y) {
2012  return norm_a->xyz.y < norm_b->xyz.y;
2013  }
2014 
2015  if (norm_a->xyz.z != norm_b->xyz.z) {
2016  return norm_a->xyz.z < norm_b->xyz.z;
2017  }
2018 
2019  if (vert_a->world.xyz.x != vert_b->world.xyz.x) {
2020  return vert_a->world.xyz.x < vert_b->world.xyz.x;
2021  }
2022 
2023  if (vert_a->world.xyz.y != vert_b->world.xyz.y) {
2024  return vert_a->world.xyz.y < vert_b->world.xyz.y;
2025  }
2026 
2027  if (vert_a->world.xyz.z != vert_b->world.xyz.z) {
2028  return vert_a->world.xyz.z < vert_b->world.xyz.z;
2029  }
2030 
2031  if (vert_a->texture_position.u != vert_b->texture_position.u) {
2032  return vert_a->texture_position.u < vert_b->texture_position.u;
2033  }
2034 
2035  if ( vert_a->texture_position.v != vert_b->texture_position.v ) {
2036  return vert_a->texture_position.v < vert_b->texture_position.v;
2037  }
2038 
2039  if ( !compare_indices ) {
2040  return vert_a->texture_position.v < vert_b->texture_position.v;
2041  } else {
2042  return a < b;
2043  }
2044 }
2045 
2046 void gr_shield_icon(coord2d coords[6], int resize_mode)
2047 {
2048  if (gr_screen.mode == GR_STUB) {
2049  return;
2050  }
2051 
2052  if (resize_mode != GR_RESIZE_NONE) {
2053  gr_resize_screen_pos(&coords[0].x, &coords[0].y, NULL, NULL, resize_mode);
2054  gr_resize_screen_pos(&coords[1].x, &coords[1].y, NULL, NULL, resize_mode);
2055  gr_resize_screen_pos(&coords[2].x, &coords[2].y, NULL, NULL, resize_mode);
2056  gr_resize_screen_pos(&coords[3].x, &coords[3].y, NULL, NULL, resize_mode);
2057  gr_resize_screen_pos(&coords[4].x, &coords[4].y, NULL, NULL, resize_mode);
2058  gr_resize_screen_pos(&coords[5].x, &coords[5].y, NULL, NULL, resize_mode);
2059  }
2060 
2061  g3_draw_2d_shield_icon(coords,
2062  gr_screen.current_color.red,
2063  gr_screen.current_color.green,
2064  gr_screen.current_color.blue,
2065  gr_screen.current_color.alpha);
2066 }
2067 
2068 void gr_rect(int x, int y, int w, int h, int resize_mode)
2069 {
2070  if (gr_screen.mode == GR_STUB) {
2071  return;
2072  }
2073 
2074  if (resize_mode != GR_RESIZE_NONE) {
2075  gr_resize_screen_pos(&x, &y, &w, &h, resize_mode);
2076  }
2077 
2078  g3_draw_2d_rect(x, y, w, h,
2079  gr_screen.current_color.red,
2080  gr_screen.current_color.green,
2081  gr_screen.current_color.blue,
2082  gr_screen.current_color.alpha);
2083 }
2084 
2085 void gr_shade(int x, int y, int w, int h, int resize_mode)
2086 {
2087  int r, g, b, a;
2088 
2089  if (gr_screen.mode == GR_STUB) {
2090  return;
2091  }
2092 
2093  if (resize_mode != GR_RESIZE_NONE) {
2094  gr_resize_screen_pos(&x, &y, &w, &h, resize_mode);
2095  }
2096 
2097  r = (int)gr_screen.current_shader.r;
2098  g = (int)gr_screen.current_shader.g;
2099  b = (int)gr_screen.current_shader.b;
2100  a = (int)gr_screen.current_shader.c;
2101 
2102  g3_draw_2d_rect(x, y, w, h, r, g, b, a);
2103 }
2104 
2105 void gr_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha)
2106 {
2107  gr_screen.current_alpha = alpha;
2108  gr_screen.current_alphablend_mode = alphablend_mode;
2109  gr_screen.current_bitblt_mode = bitblt_mode;
2110  gr_screen.current_bitmap = bitmap_num;
2111 }
2112 
2113 void gr_flip()
2114 {
2115  // m!m avoid running CHA_ONFRAME when the "Quit mission" popup is shown. See mantis 2446 for reference
2117  {
2118  profile_begin("LUA On Frame");
2119  //WMC - Evaluate global hook if not override.
2121  //WMC - Do conditional hooks. Yippee!
2123  //WMC - Do scripting reset stuff
2125  profile_end("LUA On Frame");
2126  }
2127 
2128  gr_screen.gf_flip();
2129 }
2130 
2132  bool lighting,
2133  bool fog,
2134  bool textured,
2135  bool in_shadow_map,
2136  bool thruster_scale,
2137  bool transform,
2138  bool team_color_set,
2139  int tmap_flags,
2140  int spec_map,
2141  int glow_map,
2142  int normal_map,
2143  int height_map,
2144  int env_map,
2145  int misc_map
2146 ) {
2147  uint shader_flags = 0;
2148 
2149  if ( GLSL_version >= 120 ) {
2150  shader_flags |= SDR_FLAG_MODEL_CLIP;
2151  }
2152 
2153  if ( transform ) {
2154  shader_flags |= SDR_FLAG_MODEL_TRANSFORM;
2155  }
2156 
2157  if ( in_shadow_map ) {
2158  // if we're building the shadow map, we likely only need the flags here and above so bail
2159  shader_flags |= SDR_FLAG_MODEL_SHADOW_MAP;
2160 
2161  return shader_flags;
2162  }
2163 
2164  // setup shader flags for the things that we want/need
2165  if ( lighting ) {
2166  shader_flags |= SDR_FLAG_MODEL_LIGHT;
2167  }
2168 
2169  if ( fog ) {
2170  shader_flags |= SDR_FLAG_MODEL_FOG;
2171  }
2172 
2173  if ( tmap_flags & TMAP_ANIMATED_SHADER ) {
2174  shader_flags |= SDR_FLAG_MODEL_ANIMATED;
2175  }
2176 
2177  if ( textured ) {
2178  if ( !Basemap_override ) {
2179  shader_flags |= SDR_FLAG_MODEL_DIFFUSE_MAP;
2180  }
2181 
2182  if ( glow_map > 0 ) {
2183  shader_flags |= SDR_FLAG_MODEL_GLOW_MAP;
2184  }
2185 
2186  if ( lighting ) {
2187  if ( ( spec_map > 0 ) && !Specmap_override ) {
2188  shader_flags |= SDR_FLAG_MODEL_SPEC_MAP;
2189 
2190  if ( ( env_map > 0 ) && !Envmap_override ) {
2191  shader_flags |= SDR_FLAG_MODEL_ENV_MAP;
2192  }
2193  }
2194 
2195  if ( ( normal_map > 0) && !Normalmap_override ) {
2196  shader_flags |= SDR_FLAG_MODEL_NORMAL_MAP;
2197  }
2198 
2199  if ( ( height_map > 0) && !Heightmap_override ) {
2200  shader_flags |= SDR_FLAG_MODEL_HEIGHT_MAP;
2201  }
2202 
2203  if ( Cmdline_shadow_quality && !in_shadow_map && !Shadow_override) {
2204  shader_flags |= SDR_FLAG_MODEL_SHADOWS;
2205  }
2206  }
2207 
2208  if ( misc_map > 0 ) {
2209  shader_flags |= SDR_FLAG_MODEL_MISC_MAP;
2210  }
2211 
2212  if ( team_color_set ) {
2213  shader_flags |= SDR_FLAG_MODEL_TEAMCOLOR;
2214  }
2215  }
2216 
2217  if ( Deferred_lighting ) {
2218  shader_flags |= SDR_FLAG_MODEL_DEFERRED;
2219  }
2220 
2221  if ( thruster_scale ) {
2222  shader_flags |= SDR_FLAG_MODEL_THRUSTER;
2223  }
2224 
2225  return shader_flags;
2226 }
bool Save_custom_screen_size
Definition: 2d.cpp:102
void gr_rect(int x, int y, int w, int h, int resize_mode)
Definition: 2d.cpp:2068
int gr_alpha_test
Definition: 2d.cpp:79
bool gr_opengl_init()
Definition: gropengl.cpp:1832
int * submodels
Definition: 2d.h:156
float Gr_save_full_resize_X
Definition: 2d.cpp:96
int save_center_offset_x
Definition: 2d.h:369
#define gr_zbuffer_set
Definition: 2d.h:817
bool gr_resize_screen_posf(float *x, float *y, float *w, float *h, int resize_mode)
Definition: 2d.cpp:430
void gr_close()
Definition: 2d.cpp:637
struct screen3d::@234::@236 xyw
int i
Definition: multi_pxo.cpp:466
#define vm_free(ptr)
Definition: pstypes.h:548
float current_alpha
Definition: 2d.h:400
shader current_shader
Definition: 2d.h:399
color_gun Gr_ta_alpha
Definition: 2d.cpp:50
bool gr_init(int d_mode, int d_width, int d_height, int d_depth)
Definition: 2d.cpp:909
#define GR_RESIZE_MENU_NO_OFFSET
Definition: 2d.h:686
float Gr_save_full_center_resize_X
Definition: 2d.cpp:97
GLfloat GLfloat GLfloat GLfloat h
Definition: Glext.h:7280
void vm_vec_scale_add(vec3d *dest, const vec3d *src1, const vec3d *src2, float k)
Definition: vecmat.cpp:266
void gr_flip()
Definition: 2d.cpp:2113
bool Basemap_override
Definition: systemvars.cpp:70
void(* gf_set_palette)(const ubyte *new_pal, int restrict_alphacolor)
Definition: 2d.h:412
int offset_y_unscaled
Definition: 2d.h:377
color_gun Gr_t_red
Definition: 2d.cpp:49
vec3d tangent
Definition: 2d.h:121
#define GR_RESIZE_MENU
Definition: 2d.h:684
float v
Definition: pstypes.h:135
color_gun Gr_ta_blue
Definition: 2d.cpp:50
vec3d * norm
Definition: 2d.h:154
ubyte g
Definition: pstypes.h:175
#define AC_TYPE_NONE
Definition: 2d.h:88
int mode
Definition: 2d.h:371
color_gun Gr_ta_red
Definition: 2d.cpp:50
#define SDR_FLAG_MODEL_CLIP
Definition: 2d.h:65
int Fred_running
Definition: fred.cpp:44
float Gr_save_menu_offset_Y
Definition: 2d.cpp:99
int save_max_h_unscaled
Definition: 2d.h:366
void gr_unset_cursor_bitmap(int n)
Definition: 2d.cpp:1281
int Web_cursor_bitmap
Definition: 2d.cpp:60
int gr_get_resolution_class(int width, int height)
Definition: 2d.cpp:773
Assert(pm!=NULL)
bitmap_2d_list screen_rect
Definition: tmapper.h:127
int clip_width_unscaled
Definition: 2d.h:379
void gr_force_windowed()
Definition: 2d.cpp:1101
Definition: pstypes.h:88
#define fl2ir(fl)
Definition: floating.h:34
#define gr_set_clear_color
Definition: 2d.h:850
#define GR_NUM_RESOLUTIONS
Definition: 2d.h:651
#define mprintf(args)
Definition: pstypes.h:238
#define SDR_FLAG_MODEL_DIFFUSE_MAP
Definition: 2d.h:50
void gr_init_alphacolor(color *clr, int r, int g, int b, int alpha, int type)
Definition: 2d.cpp:1173
GLint GLint GLsizei GLsizei GLsizei depth
Definition: Glext.h:5180
Definition: 2d.h:95
#define gr_render
Definition: 2d.h:805
int res
Definition: 2d.h:370
int max_h_unscaled
Definition: 2d.h:361
int g3_draw_2d_poly_bitmap_rect_list(bitmap_rect_list *b_list, int n_bm, uint additional_tmap_flags)
Definition: 3ddraw.cpp:1885
int bm_get_info(int handle, int *w, int *h, ubyte *flags, int *nframes, int *fps)
Gets info on the bitmap indexed by handle.
Definition: bmpman.cpp:769
ubyte r
Definition: 2d.h:84
struct vec3d::@225::@227 xyz
int center_h
Definition: 2d.h:363
bool Deferred_lighting
void gr_font_close()
Definition: font.cpp:356
GLclampf f
Definition: Glext.h:7097
#define GR_ZBUFF_NONE
Definition: 2d.h:672
#define GR_DEFAULT
Definition: 2d.h:646
int bits_per_pixel
Definition: 2d.h:374
float clip_center_y
Definition: 2d.h:381
DCF(clear_color,"set clear color r, g, b")
Definition: 2d.cpp:666
int center_offset_y
Definition: 2d.h:364
Definition: 2d.h:82
void gr_set_palette_internal(const char *name, ubyte *palette, int restrict_font_to_128)
Definition: 2d.cpp:678
void gr_pline_special(SCP_vector< vec3d > *pts, int thickness, int resize_mode)
Definition: 2d.cpp:1471
fix t2
Definition: animplay.cpp:37
void gr_pline_helper(vec3d *out, vec3d *in1, vec3d *in2, int thickness)
Definition: 2d.cpp:1446
GLenum mode
Definition: Glext.h:5794
int save_max_w
Definition: 2d.h:365
int center_w
Definition: 2d.h:363
int gr_stencil_mode
Definition: 2d.cpp:76
void gr_set_screen_scale(int w, int h, int zoom_w, int zoom_h, int max_w, int max_h, int center_w, int center_h, bool force_stretch)
Definition: 2d.cpp:104
#define SDR_FLAG_MODEL_DEFERRED
Definition: 2d.h:60
bool Shadow_override
Definition: systemvars.cpp:80
ubyte b
Definition: 2d.h:84
int n_verts
Definition: 2d.h:152
const char * os_config_read_string(const char *section, const char *name, const char *default_value)
Definition: osregistry.cpp:322
void gr_set_color_fast(color *dst)
Definition: 2d.cpp:1197
ubyte blue
Definition: 2d.h:102
void gr_opengl_activate(int active)
Definition: gropengl.cpp:287
void profile_begin(const char *name)
Definition: profiling.cpp:80
GLenum GLenum GLenum GLenum GLenum scale
Definition: Glext.h:8503
void gr_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha)
Definition: 2d.cpp:2105
GLfloat GLfloat GLfloat v2
Definition: Glext.h:5640
int max_w_unscaled
Definition: 2d.h:361
#define GR_RESIZE_FULL_CENTER
Definition: 2d.h:683
#define Int3()
Definition: pstypes.h:292
poly_list & operator=(poly_list &)
Definition: 2d.cpp:1943
int is_alphacolor
Definition: 2d.h:97
float clip_center_x
Definition: 2d.h:381
#define SDR_FLAG_MODEL_LIGHT
Definition: 2d.h:48
void EndFrame()
Definition: scripting.cpp:952
color_gun * Gr_current_green
Definition: 2d.cpp:51
void g3_draw_2d_rect(int x, int y, int w, int h, int r, int g, int b, int a)
Definition: 3ddraw.cpp:1651
#define GR_RESIZE_NONE
Definition: 2d.h:681
void(* gf_flip)()
Definition: 2d.h:409
void bm_init()
Initilizes the bitmap manager.
Definition: bmpman.cpp:916
#define GR_OPENGL
Definition: 2d.h:648
float Gr_save_resize_Y
Definition: 2d.cpp:98
#define SDR_FLAG_MODEL_FOG
Definition: 2d.h:49
script_state Script_system("FS2_Open Scripting")
#define TMAP_ANIMATED_SHADER
Definition: tmapper.h:76
ubyte g
Definition: 2d.h:84
int clip_height
Definition: 2d.h:378
GLenum type
Definition: Gl.h:1492
void os_set_title(const char *title)
Definition: osapi.cpp:172
int bm_load_animation(const char *real_filename, int *nframes, int *fps, int *keyframe, int can_drop_frames, int dir_type)
Loads a bitmap sequance so we can draw with it.
Definition: bmpman.cpp:1420
GLint GLsizei width
Definition: Gl.h:1505
ubyte green
Definition: 2d.h:101
#define SDR_FLAG_MODEL_MISC_MAP
Definition: 2d.h:57
uint signature
Definition: 2d.h:359
void gr_set_color(int r, int g, int b)
Definition: 2d.cpp:1188
uv_pair texture_position
Definition: pstypes.h:174
void opengl_setup_viewport()
Definition: gropengl.cpp:1297
int Gr_cursor_size
Definition: 2d.cpp:61
int bytes_per_pixel
Definition: 2d.h:375
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
const char * Osreg_title
Definition: osregistry.cpp:36
const float Default_min_draw_distance
Definition: 2d.cpp:82
int Os_debugger_running
Definition: osapi.cpp:68
#define SDR_FLAG_MODEL_SPEC_MAP
Definition: 2d.h:52
int clip_left_unscaled
Definition: 2d.h:390
GLdouble GLdouble GLdouble r
Definition: Glext.h:5337
uint * sorted_indices
Definition: 2d.h:158
#define CHA_ONFRAME
Definition: scripting.h:46
unsigned int uint
Definition: pstypes.h:64
screen3d screen
Definition: pstypes.h:173
int offset_x
Definition: 2d.h:376
GLboolean GLboolean g
Definition: Glext.h:5781
void vm_vec_scale(vec3d *dest, float s)
Definition: vecmat.cpp:248
GLuint coords
Definition: Glext.h:6925
#define TMAP_FLAG_GOURAUD
Definition: tmapper.h:40
GLenum GLenum dst
Definition: Glext.h:5917
int clip_top_unscaled
Definition: 2d.h:390
void gr_get_color(int *r, int *g, int *b)
Definition: 2d.cpp:1148
int clip_right_unscaled
Definition: 2d.h:390
float clip_aspect
Definition: 2d.h:372
GLboolean GLboolean GLboolean GLboolean a
Definition: Glext.h:5781
#define SDR_FLAG_MODEL_SHADOW_MAP
Definition: 2d.h:61
int alphacolor
Definition: 2d.h:98
float Gr_save_menu_zoomed_offset_X
Definition: 2d.cpp:100
int offset_x_unscaled
Definition: 2d.h:377
int cf_exists_full(const char *filename, int dir_type)
Definition: cfile.cpp:527
int Cmdline_normal
Definition: cmdline.cpp:331
int magic
Definition: 2d.h:99
uint screen_sig
Definition: 2d.h:96
bool Specmap_override
Definition: systemvars.cpp:72
float Max_draw_distance
Definition: 2d.cpp:85
GLfloat v0
Definition: Glext.h:5638
#define w(p)
Definition: modelsinc.h:68
bool Heightmap_override
Definition: systemvars.cpp:74
color_gun Gr_ta_green
Definition: 2d.cpp:50
void gr_shade(int x, int y, int w, int h, int resize_mode)
Definition: 2d.cpp:2085
int Gr_inited
Definition: 2d.cpp:63
color_gun * Gr_current_red
Definition: 2d.cpp:51
GLdouble GLdouble z
Definition: Glext.h:5451
tsb_t * tsb
Definition: 2d.h:155
ubyte red
Definition: 2d.h:100
#define GR_640
Definition: 2d.h:652
void gr_shield_icon(coord2d coords[6], int resize_mode)
Definition: 2d.cpp:2046
void gr_opengl_cleanup(int minimize)
Definition: gropengl.cpp:587
float u
Definition: pstypes.h:135
void win32_create_window(int width, int height)
Definition: osapi.cpp:635
ubyte ac_type
Definition: 2d.h:104
#define SDR_FLAG_MODEL_NORMAL_MAP
Definition: 2d.h:53
int find_index(poly_list *plist, int idx)
Definition: 2d.cpp:1670
#define GR_1024_THRESHOLD_WIDTH
Definition: 2d.h:655
color_gun * Gr_current_blue
Definition: 2d.cpp:51
void make_index_buffer(SCP_vector< int > &vertex_list)
Definition: 2d.cpp:1870
int find_index_fast(poly_list *plist, int idx)
Definition: 2d.cpp:1692
int clip_bottom
Definition: 2d.h:388
float vm_vec_normalize_safe(vec3d *v)
Definition: vecmat.cpp:471
int idx
Definition: multiui.cpp:761
vec3d vmd_y_vector
Definition: vecmat.cpp:26
int Cmdline_window
Definition: cmdline.cpp:502
#define TMAP_FLAG_INTERFACE
Definition: tmapper.h:57
ubyte c
Definition: 2d.h:84
void vm_vec_scale_sub(vec3d *dest, const vec3d *src1, const vec3d *src2, float k)
Definition: vecmat.cpp:275
char * Cmdline_center_res
Definition: cmdline.cpp:505
int clip_top
Definition: 2d.h:388
vec3d vmd_x_vector
Definition: vecmat.cpp:25
void gr_set_palette(const char *name, ubyte *palette, int restrict_font_to_128)
Definition: 2d.cpp:722
int save_max_w_unscaled_zoomed
Definition: 2d.h:367
#define GR_STUB
Definition: 2d.h:647
void dc_stuff_ubyte(ubyte *i)
Stuffs an unsigned byte to the given variable. Supports binary (0b), hexadecimal (0x), and octal (0o) formats.
int Cmdline_shadow_quality
Definition: cmdline.cpp:344
GLint GLint GLint GLint GLint x
Definition: Glext.h:5182
ubyte alpha
Definition: 2d.h:103
GLclampd n
Definition: Glext.h:7286
uint Gr_signature
Definition: 2d.cpp:65
unsigned char ubyte
Definition: pstypes.h:62
void palette_flush()
Definition: palman.cpp:483
int GLSL_version
Definition: gropengl.cpp:58
int save_center_h
Definition: 2d.h:368
color_gun Gr_t_blue
Definition: 2d.cpp:49
#define gr_set_cull
Definition: 2d.h:838
void palette_update(const char *name_with_extension, int restrict_font_to_128)
Definition: palman.cpp:497
int max_w
Definition: 2d.h:360
#define NOX(s)
Definition: pstypes.h:473
#define TMAP_FLAG_RGB
Definition: tmapper.h:39
ubyte b
Definition: pstypes.h:175
void vm_vec_copy_scale(vec3d *dest, const vec3d *src, float s)
Definition: vecmat.cpp:257
GLfloat GLfloat v1
Definition: Glext.h:5639
#define GR_RESIZE_FULL
Definition: 2d.h:682
int gr_get_cursor_bitmap()
Definition: 2d.cpp:1297
void _cdecl void void _cdecl Error(const char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
#define SDR_FLAG_MODEL_TEAMCOLOR
Definition: 2d.h:58
ubyte flags
Definition: pstypes.h:178
float Gr_save_full_center_resize_Y
Definition: 2d.cpp:97
vertex * vert
Definition: 2d.h:153
float Gr_save_menu_offset_X
Definition: 2d.cpp:99
#define vm_malloc(size)
Definition: pstypes.h:547
ubyte gr_palette[256 *3]
Definition: palman.cpp:27
int envmap_render_target
Definition: 2d.h:406
GLuint const GLchar * name
Definition: Glext.h:5608
#define SDR_FLAG_MODEL_GLOW_MAP
Definition: 2d.h:51
int RunCondition(int condition, char format='\0', void *data=NULL, class object *objp=NULL, int more_data=0)
Definition: scripting.cpp:924
int offset_y
Definition: 2d.h:376
color_gun Gr_t_alpha
Definition: 2d.cpp:49
int max_w_unscaled_zoomed
Definition: 2d.h:362
int RunBytecode(script_hook &hd, char format='\0', void *data=NULL)
Definition: scripting.cpp:918
float Gr_gamma
Definition: 2d.cpp:67
void vm_vec_sub(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:168
fix t1
Definition: animplay.cpp:37
void gr_activate(int active)
Definition: 2d.cpp:1122
int bm_load(const char *real_filename)
Loads a bitmap so we can draw with it later.
Definition: bmpman.cpp:1119
GLboolean GLboolean GLboolean b
Definition: Glext.h:5781
int gr_global_zbuffering
Definition: 2d.cpp:73
#define SDR_FLAG_MODEL_ENV_MAP
Definition: 2d.h:55
bool gr_resize_screen_pos(int *x, int *y, int *w, int *h, int resize_mode)
Definition: 2d.cpp:212
color_gun Gr_red
Definition: 2d.cpp:48
void profile_end(const char *name)
Definition: profiling.cpp:130
int clip_right
Definition: 2d.h:388
void gr_set_cursor_bitmap(int n, int lock)
Definition: 2d.cpp:1242
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
int save_center_offset_y
Definition: 2d.h:369
Definition: 2d.h:120
char Gr_current_palette_name[128]
Definition: 2d.cpp:56
int vm_vec_same(const vec3d *v1, const vec3d *v2)
Definition: vecmat.cpp:1526
void CAP(T &v, T mn, T mx)
Definition: pstypes.h:478
uint screen_sig
Definition: 2d.h:83
#define GR_1024_THRESHOLD_HEIGHT
Definition: 2d.h:656
GLint GLsizei GLsizei height
Definition: Gl.h:1505
GLubyte GLubyte GLubyte GLubyte w
Definition: Glext.h:5679
#define SDR_FLAG_MODEL_HEIGHT_MAP
Definition: 2d.h:54
const char * Resolution_prefixes[GR_NUM_RESOLUTIONS]
Definition: 2d.cpp:44
int clip_bottom_unscaled
Definition: 2d.h:390
#define fl2i(fl)
Definition: floating.h:33
void gr_bitmap_list(bitmap_2d_list *list, int n_bm, int resize_mode)
Definition: 2d.cpp:1407
bool quit_mission_popup_shown
Definition: keycontrol.cpp:214
int gr_zbuffering
Definition: 2d.cpp:71
bool Envmap_override
Definition: systemvars.cpp:71
#define g3_end_frame()
Definition: 3d.h:49
float Gr_save_resize_X
Definition: 2d.cpp:98
int clip_width
Definition: 2d.h:378
ubyte Gr_original_palette[768]
Definition: 2d.cpp:54
int Gr_gamma_int
Definition: 2d.cpp:68
screen gr_screen
Definition: 2d.cpp:46
float Min_draw_distance
Definition: 2d.cpp:84
bool custom_size
Definition: 2d.h:402
color_gun Gr_alpha
Definition: 2d.cpp:48
color_gun * Gr_current_alpha
Definition: 2d.cpp:51
color_gun Gr_t_green
Definition: 2d.cpp:49
int center_offset_x
Definition: 2d.h:364
bool Normalmap_override
Definition: systemvars.cpp:73
ubyte raw8
Definition: 2d.h:105
GLfloat GLfloat p
Definition: Glext.h:8373
int clip_height_unscaled
Definition: 2d.h:379
void Sleep(int mili)
#define SDR_FLAG_MODEL_SHADOWS
Definition: 2d.h:63
An overhauled/updated debug console to allow monitoring, testing, and general debugging of new featur...
#define LOCATION
Definition: pstypes.h:245
int max_h
Definition: 2d.h:360
void gr_reset_screen_scale()
Definition: 2d.cpp:176
#define TMAP_FLAG_TEXTURED
Definition: tmapper.h:36
float Gr_save_full_resize_Y
Definition: 2d.cpp:96
uint gr_determine_model_shader_flags(bool lighting, bool fog, bool textured, bool in_shadow_map, bool thruster_scale, bool transform, bool team_color_set, int tmap_flags, int spec_map, int glow_map, int normal_map, int height_map, int env_map, int misc_map)
Definition: 2d.cpp:2131
int current_bitblt_mode
Definition: 2d.h:393
color_gun Gr_green
Definition: 2d.cpp:48
int save_max_w_unscaled
Definition: 2d.h:366
void g3_draw_2d_shield_icon(const coord2d coords[6], const int r, const int g, const int b, const int a)
Definition: 3ddraw.cpp:1551
script_hook Script_globalhook
Definition: scripting.cpp:27
color current_color
Definition: 2d.h:396
Definition: 2d.h:129
bool gr_unsize_screen_pos(int *x, int *y, int *w, int *h, int resize_mode)
Definition: 2d.cpp:320
const float Default_max_draw_distance
Definition: 2d.cpp:83
void gr_bitmap_uv(int _x, int _y, int _w, int _h, float _u0, float _v0, float _u1, float _v1, int resize_mode)
Definition: 2d.cpp:1356
int current_alphablend_mode
Definition: 2d.h:392
float vm_vec_dot(const vec3d *v0, const vec3d *v1)
Definition: vecmat.cpp:312
char * Cmdline_res
Definition: cmdline.cpp:504
#define i2fl(i)
Definition: floating.h:32
#define PF_PROJECTED
Definition: 3d.h:21
void gr_screen_resize(int width, int height)
Definition: 2d.cpp:733
bool gr_stub_init()
Definition: grstub.cpp:537
void gr_bitmap(int _x, int _y, int resize_mode)
Definition: 2d.cpp:1303
#define SDR_FLAG_MODEL_ANIMATED
Definition: 2d.h:56
int gr_zbuffering_mode
Definition: 2d.cpp:72
vec3d world
Definition: pstypes.h:172
int temp
Definition: lua.cpp:4996
void gr_create_shader(shader *shade, ubyte r, ubyte g, ubyte b, ubyte c)
Definition: 2d.cpp:1211
bool gr_unsize_screen_posf(float *x, float *y, float *w, float *h, int resize_mode)
Definition: 2d.cpp:538
#define MAX(a, b)
Definition: pstypes.h:299
int G3_count
Definition: 3dsetup.cpp:59
int bm_unload(int handle, int clear_render_targets, bool nodebug)
Unloads a bitmap's data, but not the bitmap info.
Definition: bmpman.cpp:2890
int clip_left
Definition: 2d.h:388
int g3_draw_2d_poly_bitmap_list(bitmap_2d_list *b_list, int n_bm, uint additional_tmap_flags)
Definition: 3ddraw.cpp:1794
ubyte codes
Definition: pstypes.h:177
vec3d * vm_vec_cross(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:645
#define gr_zbuffer_get
Definition: 2d.h:816
false
Definition: lua.cpp:6789
int save_max_h_unscaled_zoomed
Definition: 2d.h:367
#define GR_CURSOR_LOCK
Definition: 2d.h:720
float scaler
Definition: 2d.h:122
#define SDR_FLAG_MODEL_TRANSFORM
Definition: 2d.h:59
GLclampf GLclampf GLclampf alpha
Definition: Glext.h:5177
int rendering_to_texture
Definition: 2d.h:403
int save_center_w
Definition: 2d.h:368
vec3d vmd_zero_vector
Definition: vecmat.cpp:24
#define CF_TYPE_ANY
Definition: cfile.h:42
void gr_set_shader(shader *shade)
Definition: 2d.cpp:1220
int save_max_h
Definition: 2d.h:365
int gr_activated
Definition: 2d.cpp:1121
int Cmdline_stretch_menu
Definition: cmdline.cpp:382
#define SDR_FLAG_MODEL_THRUSTER
Definition: 2d.h:64
void allocate(int size)
Definition: 2d.cpp:1704
void vm_vec_add(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:159
const GLdouble * v
Definition: Glext.h:5322
void gr_init_color(color *c, int r, int g, int b)
Definition: 2d.cpp:1155
#define GR_CURSOR_UNLOCK
Definition: 2d.h:721
#define GR_1024
Definition: 2d.h:653
ubyte Gr_current_palette[768]
Definition: 2d.cpp:55
int max_h_unscaled_zoomed
Definition: 2d.h:362
int g3_draw_poly_constant_sw(int nv, vertex **pointlist, uint tmap_flags, float constant_sw)
Definition: 3ddraw.cpp:381
float aspect
Definition: 2d.h:372
const GLubyte * c
Definition: Glext.h:8376
ubyte r
Definition: pstypes.h:175
int Gr_cursor
Definition: 2d.cpp:59
GLint y
Definition: Gl.h:1505
void calculate_tangent()
Definition: 2d.cpp:1781
GLuint res
Definition: Glext.h:9084
Definition: 2d.h:358
#define g3_start_frame(zbuffer_flag)
Definition: 3d.h:39
float vm_vec_normalize(vec3d *v)
Definition: vecmat.cpp:460
#define strcpy_s(...)
Definition: safe_strings.h:67
int current_bitmap
Definition: 2d.h:395
int Is_standalone
Definition: systemvars.cpp:59
float Gr_save_menu_zoomed_offset_Y
Definition: 2d.cpp:100
color_gun Gr_blue
Definition: 2d.cpp:48
~poly_list()
Definition: 2d.cpp:1753
#define GR_RESIZE_MENU_ZOOMED
Definition: 2d.h:685