]> icculus.org git repositories - taylor/freespace2.git/blob - src/graphics/gropengl.cpp
fix popup condition testing
[taylor/freespace2.git] / src / graphics / gropengl.cpp
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
6  * the source.
7  */
8
9 #include "SDL_opengl.h"
10
11 #include "pstypes.h"
12 #include "osregistry.h"
13 #include "gropengl.h"
14 #include "gropenglinternal.h"
15 #include "grgl1.h"
16 #include "grgl2.h"
17 #include "grinternal.h"
18 #include "cmdline.h"
19 #include "mouse.h"
20 #include "osapi.h"
21
22
23 bool OGL_inited = false;
24
25 SDL_Window *GL_window = NULL;
26 SDL_GLContext GL_context;
27
28 volatile int GL_activate = 0;
29 volatile int GL_deactivate = 0;
30
31 int GL_viewport_x = 0;
32 int GL_viewport_y = 0;
33 int GL_viewport_w = 640;
34 int GL_viewport_h = 480;
35 float GL_viewport_scale_w = 1.0f;
36 float GL_viewport_scale_h = 1.0f;
37 int GL_min_texture_width = 0;
38 int GL_max_texture_width = 0;
39 int GL_min_texture_height = 0;
40 int GL_max_texture_height = 0;
41
42 rb_t *render_buffer = NULL;
43 static size_t render_buffer_size = 0;
44
45
46 void opengl_alloc_render_buffer(unsigned int nelems)
47 {
48         if (nelems < 1) {
49                 nelems = 1;
50         }
51
52         if ( render_buffer && (nelems <= render_buffer_size) ) {
53                 return;
54         }
55
56         if (render_buffer) {
57                 free(render_buffer);
58         }
59
60         render_buffer = (rb_t*) malloc(sizeof(rb_t) * nelems);
61         render_buffer_size = nelems;
62 }
63
64 void opengl_free_render_buffer()
65 {
66         if (render_buffer) {
67                 free(render_buffer);
68                 render_buffer = NULL;
69                 render_buffer_size = 0;
70         }
71 }
72
73 void opengl_set_variables()
74 {
75         GL_min_texture_height = 16;
76         GL_min_texture_width = 16;
77
78         glGetIntegerv(GL_MAX_TEXTURE_SIZE, &GL_max_texture_width);
79         GL_max_texture_height = GL_max_texture_width;
80
81         // no texture is larger than 1024, so maybe don't use sections
82         if (GL_max_texture_width >= 1024) {
83                 gr_screen.use_sections = 0;
84         }
85 }
86
87 void opengl_init_viewport()
88 {
89         GL_viewport_x = 0;
90         GL_viewport_y = 0;
91         GL_viewport_w = gr_screen.max_w;
92         GL_viewport_h = gr_screen.max_h;
93         GL_viewport_scale_w = 1.0f;
94         GL_viewport_scale_h = 1.0f;
95
96         glViewport(GL_viewport_x, GL_viewport_y, GL_viewport_w, GL_viewport_h);
97 }
98
99 void opengl_stuff_fog_value(float z, float *f_val)
100 {
101         float f_float;
102
103         if ( !f_val ) {
104                 return;
105         }
106
107         f_float = 1.0f - ((gr_screen.fog_far - z) / (gr_screen.fog_far - gr_screen.fog_near));
108
109         if (f_float < 0.0f) {
110                 f_float = 0.0f;
111         } else if (f_float > 1.0f) {
112                 f_float = 1.0f;
113         }
114
115         *f_val = f_float;
116 }
117
118 void gr_opengl_clear()
119 {
120         glClearColor(gr_screen.current_clear_color.red / 255.0f,
121                 gr_screen.current_clear_color.green / 255.0f,
122                 gr_screen.current_clear_color.blue / 255.0f, 1.0f);
123
124         glClear( GL_COLOR_BUFFER_BIT );
125 }
126
127 void gr_opengl_reset_clip()
128 {
129         gr_screen.offset_x = 0;
130         gr_screen.offset_y = 0;
131         gr_screen.clip_left = 0;
132         gr_screen.clip_top = 0;
133         gr_screen.clip_right = gr_screen.max_w - 1;
134         gr_screen.clip_bottom = gr_screen.max_h - 1;
135         gr_screen.clip_width = gr_screen.max_w;
136         gr_screen.clip_height = gr_screen.max_h;
137
138         glDisable(GL_SCISSOR_TEST);
139 }
140
141 uint gr_opengl_lock()
142 {
143         return 1;
144 }
145
146 void gr_opengl_unlock()
147 {
148 }
149
150 void gr_opengl_zbias(int bias)
151 {
152         if (bias) {
153                 glEnable(GL_POLYGON_OFFSET_FILL);
154                 glPolygonOffset(0.0f, GLfloat(-bias));
155         } else {
156                 glDisable(GL_POLYGON_OFFSET_FILL);
157         }
158 }
159
160 void gr_opengl_set_cull(int cull)
161 {
162         if (cull) {
163                 glEnable (GL_CULL_FACE);
164                 glFrontFace (GL_CCW);
165         } else {
166                 glDisable (GL_CULL_FACE);
167         }
168 }
169
170 void gr_opengl_activate(int active)
171 {
172         if (active) {
173                 GL_activate++;
174         } else {
175                 GL_deactivate++;
176         }
177 }
178
179 void gr_opengl_cleanup()
180 {
181 #ifdef LEGACY_GL
182         opengl1_cleanup();
183 #endif
184         opengl2_cleanup();
185
186         opengl_free_render_buffer();
187
188         os_set_window(NULL);
189
190         SDL_DestroyWindow(GL_window);
191         GL_window = NULL;
192
193         OGL_inited = false;
194 }
195
196 void gr_opengl_init()
197 {
198         if ( OGL_inited )       {
199                 gr_opengl_cleanup();
200         }
201
202         mprintf(( "Initializing OpenGL graphics device...\n" ));
203
204         OGL_inited = true;
205
206         if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
207                 Error(LOCATION, "Couldn't init SDL: %s", SDL_GetError());
208         }
209
210         Uint32 window_flags = SDL_WINDOW_OPENGL;
211
212 #ifdef __EMSCRIPTEN__
213         window_flags |= SDL_WINDOW_RESIZABLE;
214 #endif
215
216         GL_window = SDL_CreateWindow(os_get_title(), SDL_WINDOWPOS_CENTERED,
217                                                 SDL_WINDOWPOS_CENTERED,
218                                                 gr_screen.max_w, gr_screen.max_h, window_flags);
219
220         if ( !GL_window ) {
221                 Error(LOCATION, "Couldn't create window: %s\n", SDL_GetError());
222         }
223
224         os_set_window(GL_window);
225
226         int a = 1, r = 5, g = 5, b = 5, bpp = 16;
227         int FSAA = os_config_read_uint("Video", "AntiAlias", 0);
228
229         SDL_GL_SetAttribute(SDL_GL_RED_SIZE, r);
230         SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, g);
231         SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, b);
232         SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, a);
233         SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, bpp);
234
235         if (FSAA) {
236                 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
237                 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, FSAA);
238         }
239
240         // try GL 2 first, then fall back to legacy GL (if enabled)
241         int rc = opengl2_init();
242
243 #ifdef LEGACY_GL
244         if ( !rc ) {
245                 rc = opengl1_init();
246         }
247 #endif
248
249         if ( !rc ) {
250                 Error(LOCATION, "Unable to initialize OpenGL renderer!\n");
251         }
252
253         mprintf(("  Attributes requested : ARGB %d%d%d%d, BPP %d, AA %d\n",
254                          a, r, g, b, bpp, FSAA));
255
256         SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r);
257         SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g);
258         SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b);
259         SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &a);
260         SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &bpp);
261         SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &FSAA);
262
263         mprintf(("  Attributes received  : ARGB %d%d%d%d, BPP %d, AA %d\n",
264                          a, r, g, b, bpp, FSAA));
265         mprintf(("\n"));
266
267         SDL_StopTextInput();
268         SDL_DisableScreenSaver();
269         SDL_ShowCursor(0);
270
271         // maybe go fullscreen - should be done *after* main GL init
272         int fullscreen = os_config_read_uint("Video", "Fullscreen", 1);
273         if ( !Cmdline_window && (fullscreen || Cmdline_fullscreen) ) {
274                 gr_force_fullscreen();
275         }
276
277         // if fullscreen or using resizable window then poll for window events
278         if ( gr_screen.fullscreen || (window_flags & SDL_WINDOW_RESIZABLE) ) {
279                 os_poll();
280         }
281
282         switch (bpp) {
283                 case 15:
284                 case 16:
285                         gr_screen.bits_per_pixel = 16;
286                         gr_screen.bytes_per_pixel = 2;
287
288                         // screen values
289                         Gr_red.bits = 5;
290                         Gr_red.shift = 11;
291                         Gr_red.scale = 8;
292                         Gr_red.mask = 0x7C01;
293
294                         Gr_green.bits = 5;
295                         Gr_green.shift = 6;
296                         Gr_green.scale = 8;
297                         Gr_green.mask = 0x3E1;
298
299                         Gr_blue.bits = 5;
300                         Gr_blue.shift = 1;
301                         Gr_blue.scale = 8;
302                         Gr_blue.mask = 0x20;
303
304                         Gr_alpha.bits = 1;
305                         Gr_alpha.shift = 0;
306                         Gr_alpha.scale = 255;
307                         Gr_alpha.mask = 0x1;
308
309                         break;
310
311                 case 24:
312                 case 32:
313                         gr_screen.bits_per_pixel = 32;
314                         gr_screen.bytes_per_pixel = 4;
315
316                         // screen values
317                         Gr_red.bits = 8;
318                         Gr_red.shift = 0;
319                         Gr_red.scale = 1;
320                         Gr_red.mask = 0xff;
321
322                         Gr_green.bits = 8;
323                         Gr_green.shift = 8;
324                         Gr_green.scale = 1;
325                         Gr_green.mask = 0xff00;
326
327                         Gr_blue.bits = 8;
328                         Gr_blue.shift = 16;
329                         Gr_blue.scale = 1;
330                         Gr_blue.mask = 0xff0000;
331
332                         Gr_alpha.bits = 8;
333                         Gr_alpha.shift = 24;
334                         Gr_alpha.scale = 1;
335                         Gr_alpha.mask = 0xff000000;
336
337                         break;
338
339                 default:
340                         Int3(); // Illegal bpp
341                         break;
342         }
343
344         // DDOI - set these so no one else does!
345         // texture values, always 5551 - 16-bit
346         Gr_t_red.mask = 0x7C01;
347         Gr_t_red.shift = 11;
348         Gr_t_red.scale = 8;
349
350         Gr_t_green.mask = 0x3E1;
351         Gr_t_green.shift = 6;
352         Gr_t_green.scale = 8;
353
354         Gr_t_blue.mask = 0x20;
355         Gr_t_blue.shift = 1;
356         Gr_t_blue.scale = 8;
357
358         Gr_t_alpha.mask = 0x1;
359         Gr_t_alpha.shift = 0;
360         Gr_t_alpha.scale = 255;
361
362         // alpha-texture values
363         Gr_ta_red.mask = 0x0f00;
364         Gr_ta_red.shift = 8;
365         Gr_ta_red.scale = 16;
366
367         Gr_ta_green.mask = 0x00f0;
368         Gr_ta_green.shift = 4;
369         Gr_ta_green.scale = 16;
370
371         Gr_ta_blue.mask = 0x000f;
372         Gr_ta_blue.shift = 0;
373         Gr_ta_blue.scale = 16;
374
375         Gr_ta_alpha.mask = 0xf000;
376         Gr_ta_alpha.shift = 12;
377         Gr_ta_alpha.scale = 16;
378
379         // default to screen
380         Gr_current_red = &Gr_red;
381         Gr_current_blue = &Gr_blue;
382         Gr_current_green = &Gr_green;
383         Gr_current_alpha = &Gr_alpha;
384
385
386         Mouse_hidden++;
387         gr_reset_clip();
388         gr_clear();
389         gr_flip();
390         gr_clear();
391         Mouse_hidden--;
392 }