]> icculus.org git repositories - taylor/freespace2.git/blob - src/graphics/gropengl.cpp
quiet some OCD
[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 "pstypes.h"
10 #include "osregistry.h"
11 #include "gropengl.h"
12 #include "grgl1.h"
13 #include "gropenglinternal.h"
14 #include "2d.h"
15 #include "bmpman.h"
16 #include "grinternal.h"
17 #include "cmdline.h"
18 #include "mouse.h"
19 #include "osapi.h"
20
21
22 bool OGL_inited = false;
23 int GL_version = 0;
24
25 SDL_Window *GL_window = NULL;
26 SDL_GLContext GL_context;
27
28 static int FSAA = 0;
29
30 int GL_viewport_x = 0;
31 int GL_viewport_y = 0;
32 int GL_viewport_w = 640;
33 int GL_viewport_h = 480;
34 float GL_viewport_scale_w = 1.0f;
35 float GL_viewport_scale_h = 1.0f;
36 int GL_min_texture_width = 0;
37 int GL_max_texture_width = 0;
38 int GL_min_texture_height = 0;
39 int GL_max_texture_height = 0;
40
41 rb_t *render_buffer = NULL;
42 static size_t render_buffer_size = 0;
43
44
45 void opengl_alloc_render_buffer(unsigned int nelems)
46 {
47         if (nelems < 1) {
48                 nelems = 1;
49         }
50
51         if ( render_buffer && (nelems <= render_buffer_size) ) {
52                 return;
53         }
54
55         if (render_buffer) {
56                 free(render_buffer);
57         }
58
59         render_buffer = (rb_t*) malloc(sizeof(rb_t) * nelems);
60         render_buffer_size = nelems;
61 }
62
63 void opengl_free_render_buffer()
64 {
65         if (render_buffer) {
66                 free(render_buffer);
67                 render_buffer = NULL;
68                 render_buffer_size = 0;
69         }
70 }
71
72 void opengl_set_variables()
73 {
74         GL_min_texture_height = 16;
75         GL_min_texture_width = 16;
76
77         glGetIntegerv(GL_MAX_TEXTURE_SIZE, &GL_max_texture_width);
78         GL_max_texture_height = GL_max_texture_width;
79
80         // no texture is larger than 1024, so maybe don't use sections
81         if (GL_max_texture_width >= 1024) {
82                 gr_screen.use_sections = 0;
83         }
84 }
85
86 void opengl_init_viewport()
87 {
88         GL_viewport_x = 0;
89         GL_viewport_y = 0;
90         GL_viewport_w = gr_screen.max_w;
91         GL_viewport_h = gr_screen.max_h;
92         GL_viewport_scale_w = 1.0f;
93         GL_viewport_scale_h = 1.0f;
94
95         glViewport(GL_viewport_x, GL_viewport_y, GL_viewport_w, GL_viewport_h);
96
97         glMatrixMode(GL_PROJECTION);
98         glLoadIdentity();
99         glOrtho(0, GL_viewport_w, GL_viewport_h, 0, 0.0, 1.0);
100         glMatrixMode(GL_MODELVIEW);
101         glLoadIdentity();
102 }
103
104 void gr_opengl_force_windowed()
105 {
106         SDL_SetWindowFullscreen(GL_window, 0);
107 }
108
109 void gr_opengl_force_fullscreen()
110 {
111         SDL_SetWindowFullscreen(GL_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
112 }
113
114 void gr_opengl_toggle_fullscreen()
115 {
116         Uint32 flags = SDL_GetWindowFlags(GL_window);
117
118         if ( (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP ) {
119                 gr_opengl_force_windowed();
120         } else {
121                 gr_opengl_force_fullscreen();
122         }
123 }
124
125 void gr_opengl_cleanup()
126 {
127         opengl1_cleanup();
128
129         opengl_free_render_buffer();
130 }
131
132 void gr_opengl_init()
133 {
134         if ( OGL_inited )       {
135                 gr_opengl_cleanup();
136                 OGL_inited = false;
137         }
138
139         mprintf(( "Initializing OpenGL graphics device...\n" ));
140
141         OGL_inited = true;
142
143         if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
144                 Error(LOCATION, "Couldn't init SDL: %s", SDL_GetError());
145         }
146
147         int a = 1, r = 5, g = 5, b = 5, bpp = 16, db = 1;
148
149         SDL_GL_SetAttribute(SDL_GL_RED_SIZE, r);
150         SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, g);
151         SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, b);
152         SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, a);
153         SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, bpp);
154         SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, db);
155
156         FSAA = os_config_read_uint("Video", "AntiAlias", 0);
157
158         if (FSAA) {
159             SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
160             SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, FSAA);
161         }
162
163         GL_window = SDL_CreateWindow(os_get_title(), SDL_WINDOWPOS_CENTERED,
164                                                 SDL_WINDOWPOS_CENTERED,
165                                                 gr_screen.max_w, gr_screen.max_h, SDL_WINDOW_OPENGL);
166
167         if ( !GL_window ) {
168                 Error(LOCATION, "Couldn't create window: %s\n", SDL_GetError());
169         }
170
171         GL_context = SDL_GL_CreateContext(GL_window);
172
173         const char *gl_version = (const char*)glGetString(GL_VERSION);
174         int v_major = 0, v_minor = 0;
175
176         sscanf(gl_version, "%d.%d", &v_major, &v_minor);
177
178         GL_version = (v_major * 10) + v_minor;
179
180         // version check, require 1.2+ for sake of simplicity
181         if (GL_version < 12) {
182                 Error(LOCATION, "Minimum OpenGL version is 1.2!");
183         }
184
185         mprintf(("  Vendor   : %s\n", glGetString(GL_VENDOR)));
186         mprintf(("  Renderer : %s\n", glGetString(GL_RENDERER)));
187         mprintf(("  Version  : %s\n", gl_version));
188
189         // initial viewport setup
190         opengl_init_viewport();
191
192         // set up generic variables before further init() calls
193         opengl_set_variables();
194
195         // main GL init
196         opengl1_init();
197
198         mprintf(("  Attributes requested : ARGB %d%d%d%d, BPP %d, DB %d, AA %d\n", a, r, g, b, bpp, db, FSAA));
199
200         SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r);
201         SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g);
202         SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b);
203         SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &a);
204         SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &bpp);
205         SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &db);
206         SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &FSAA);
207
208         mprintf(("  Attributes received  : ARGB %d%d%d%d, BPP %d, DB %d, AA %d\n", a, r, g, b, bpp, db, FSAA));
209
210         SDL_DisableScreenSaver();
211         SDL_ShowCursor(0);
212
213         // maybe go fullscreen - should be done *after* main GL init
214         int fullscreen = os_config_read_uint("Video", "Fullscreen", 1);
215         if ( !Cmdline_window && (fullscreen || Cmdline_fullscreen) ) {
216                 SDL_SetWindowFullscreen(GL_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
217                 // poll for window events
218                 os_poll();
219         }
220
221         mprintf(("\n"));
222
223
224         switch (bpp) {
225                 case 15:
226                 case 16:
227                         gr_screen.bits_per_pixel = 16;
228                         gr_screen.bytes_per_pixel = 2;
229
230                         // screen values
231                         Gr_red.bits = 5;
232                         Gr_red.shift = 10;
233                         Gr_red.scale = 8;
234                         Gr_red.mask = 0x7C00;
235
236                         Gr_green.bits = 5;
237                         Gr_green.shift = 5;
238                         Gr_green.scale = 8;
239                         Gr_green.mask = 0x3E0;
240
241                         Gr_blue.bits = 5;
242                         Gr_blue.shift = 0;
243                         Gr_blue.scale = 8;
244                         Gr_blue.mask = 0x1F;
245
246                         Gr_alpha.bits = 1;
247                         Gr_alpha.shift = 15;
248                         Gr_alpha.scale = 255;
249                         Gr_alpha.mask = 0x8000;
250
251                         break;
252
253                 case 24:
254                 case 32:
255                         gr_screen.bits_per_pixel = 32;
256                         gr_screen.bytes_per_pixel = 4;
257
258                         // screen values
259                         Gr_red.bits = 8;
260                         Gr_red.shift = 16;
261                         Gr_red.scale = 1;
262                         Gr_red.mask = 0xff0000;
263
264                         Gr_green.bits = 8;
265                         Gr_green.shift = 8;
266                         Gr_green.scale = 1;
267                         Gr_green.mask = 0xff00;
268
269                         Gr_blue.bits = 8;
270                         Gr_blue.shift = 0;
271                         Gr_blue.scale = 1;
272                         Gr_blue.mask = 0xff;
273
274                         Gr_alpha.bits = 8;
275                         Gr_alpha.shift = 24;
276                         Gr_alpha.scale = 1;
277                         Gr_alpha.mask = 0xff000000;
278
279                         break;
280
281                 default:
282                         Int3(); // Illegal bpp
283                         break;
284         }
285
286         // DDOI - set these so no one else does!
287         // texture values, always 1555 - 16-bit
288         Gr_t_red.mask = 0x7C00;
289         Gr_t_red.shift = 10;
290         Gr_t_red.scale = 8;
291
292         Gr_t_green.mask = 0x3E0;
293         Gr_t_green.shift = 5;
294         Gr_t_green.scale = 8;
295
296         Gr_t_blue.mask = 0x1F;
297         Gr_t_blue.shift = 0;
298         Gr_t_blue.scale = 8;
299
300         Gr_t_alpha.mask = 0x8000;
301         Gr_t_alpha.scale = 255;
302         Gr_t_alpha.shift = 15;
303
304         // alpha-texture values
305         Gr_ta_red.mask = 0x0f00;
306         Gr_ta_red.shift = 8;
307         Gr_ta_red.scale = 16;
308
309         Gr_ta_green.mask = 0x00f0;
310         Gr_ta_green.shift = 4;
311         Gr_ta_green.scale = 16;
312
313         Gr_ta_blue.mask = 0x000f;
314         Gr_ta_blue.shift = 0;
315         Gr_ta_blue.scale = 16;
316
317         Gr_ta_alpha.mask = 0xf000;
318         Gr_ta_alpha.shift = 12;
319         Gr_ta_alpha.scale = 16;
320
321         // default to screen
322         Gr_current_red = &Gr_red;
323         Gr_current_blue = &Gr_blue;
324         Gr_current_green = &Gr_green;
325         Gr_current_alpha = &Gr_alpha;
326
327
328         Mouse_hidden++;
329         gr_reset_clip();
330         gr_clear();
331         gr_flip();
332         gr_clear();
333         Mouse_hidden--;
334 }