]> icculus.org git repositories - taylor/freespace2.git/blob - src/graphics/gropengl.cpp
set/get window title
[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 < 0) {
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 static 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 static 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(NULL, "FSAA", 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         mprintf(("  Attributes requested: ARGB %d%d%d%d, BPP %d, DB %d, AA %d\n", a, r, g, b, bpp, db, FSAA));
190
191         SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r);
192         SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g);
193         SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b);
194         SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &a);
195         SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &bpp);
196         SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &db);
197         SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &FSAA);
198
199         mprintf(("  Attributes received : ARGB %d%d%d%d, BPP %d, DB %d, AA %d\n", a, r, g, b, bpp, db, FSAA));
200
201
202         SDL_DisableScreenSaver();
203         SDL_ShowCursor(0);
204
205         // initial viewport setup
206         opengl_init_viewport();
207
208         // set up generic variables before further init() calls
209         opengl_set_variables();
210
211         // main GL init
212         opengl1_init();
213
214         // maybe go fullscreen - should be done *after* main GL init
215         int fullscreen = os_config_read_uint(NULL, "Fullscreen", 1);
216         if ( !Cmdline_window && (fullscreen || Cmdline_fullscreen) ) {
217                 SDL_SetWindowFullscreen(GL_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
218                 // poll for window events
219                 os_poll();
220         }
221
222         mprintf(("\n"));
223
224
225         switch (bpp) {
226                 case 15:
227                 case 16:
228                         gr_screen.bits_per_pixel = 16;
229                         gr_screen.bytes_per_pixel = 2;
230
231                         // screen values
232                         Gr_red.bits = 5;
233                         Gr_red.shift = 10;
234                         Gr_red.scale = 8;
235                         Gr_red.mask = 0x7C00;
236
237                         Gr_green.bits = 5;
238                         Gr_green.shift = 5;
239                         Gr_green.scale = 8;
240                         Gr_green.mask = 0x3E0;
241
242                         Gr_blue.bits = 5;
243                         Gr_blue.shift = 0;
244                         Gr_blue.scale = 8;
245                         Gr_blue.mask = 0x1F;
246
247                         Gr_alpha.bits = 1;
248                         Gr_alpha.shift = 15;
249                         Gr_alpha.scale = 255;
250                         Gr_alpha.mask = 0x8000;
251
252                         break;
253
254                 case 24:
255                 case 32:
256                         gr_screen.bits_per_pixel = 32;
257                         gr_screen.bytes_per_pixel = 4;
258
259                         // screen values
260                         Gr_red.bits = 8;
261                         Gr_red.shift = 16;
262                         Gr_red.scale = 1;
263                         Gr_red.mask = 0xff0000;
264
265                         Gr_green.bits = 8;
266                         Gr_green.shift = 8;
267                         Gr_green.scale = 1;
268                         Gr_green.mask = 0xff00;
269
270                         Gr_blue.bits = 8;
271                         Gr_blue.shift = 0;
272                         Gr_blue.scale = 1;
273                         Gr_blue.mask = 0xff;
274
275                         Gr_alpha.bits = 8;
276                         Gr_alpha.shift = 24;
277                         Gr_alpha.scale = 1;
278                         Gr_alpha.mask = 0xff000000;
279
280                         break;
281
282                 default:
283                         Int3(); // Illegal bpp
284                         break;
285         }
286
287         // DDOI - set these so no one else does!
288         // texture values, always 1555 - 16-bit
289         Gr_t_red.mask = 0x7C00;
290         Gr_t_red.shift = 10;
291         Gr_t_red.scale = 8;
292
293         Gr_t_green.mask = 0x3E0;
294         Gr_t_green.shift = 5;
295         Gr_t_green.scale = 8;
296
297         Gr_t_blue.mask = 0x1F;
298         Gr_t_blue.shift = 0;
299         Gr_t_blue.scale = 8;
300
301         Gr_t_alpha.mask = 0x8000;
302         Gr_t_alpha.scale = 255;
303         Gr_t_alpha.shift = 15;
304
305         // alpha-texture values
306         Gr_ta_red.mask = 0x0f00;
307         Gr_ta_red.shift = 8;
308         Gr_ta_red.scale = 16;
309
310         Gr_ta_green.mask = 0x00f0;
311         Gr_ta_green.shift = 4;
312         Gr_ta_green.scale = 16;
313
314         Gr_ta_blue.mask = 0x000f;
315         Gr_ta_blue.shift = 0;
316         Gr_ta_blue.scale = 16;
317
318         Gr_ta_alpha.mask = 0xf000;
319         Gr_ta_alpha.shift = 12;
320         Gr_ta_alpha.scale = 16;
321
322         // default to screen
323         Gr_current_red = &Gr_red;
324         Gr_current_blue = &Gr_blue;
325         Gr_current_green = &Gr_green;
326         Gr_current_alpha = &Gr_alpha;
327
328
329         Mouse_hidden++;
330         gr_reset_clip();
331         gr_clear();
332         gr_flip();
333         gr_clear();
334         Mouse_hidden--;
335 }