]> icculus.org git repositories - taylor/freespace2.git/blob - src/graphics/gropengl.cpp
switch from 1555 BGR to 5551 RGB
[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         os_set_window(NULL);
132
133         SDL_GL_DeleteContext(GL_context);
134         GL_context = NULL;
135
136         SDL_DestroyWindow(GL_window);
137         GL_window = NULL;
138
139         OGL_inited = false;
140 }
141
142 void gr_opengl_init()
143 {
144         if ( OGL_inited )       {
145                 gr_opengl_cleanup();
146         }
147
148         mprintf(( "Initializing OpenGL graphics device...\n" ));
149
150         OGL_inited = true;
151
152         if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
153                 Error(LOCATION, "Couldn't init SDL: %s", SDL_GetError());
154         }
155
156         int a = 1, r = 5, g = 5, b = 5, bpp = 16, db = 1;
157
158         SDL_GL_SetAttribute(SDL_GL_RED_SIZE, r);
159         SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, g);
160         SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, b);
161         SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, a);
162         SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, bpp);
163         SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, db);
164
165         FSAA = os_config_read_uint("Video", "AntiAlias", 0);
166
167         if (FSAA) {
168             SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
169             SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, FSAA);
170         }
171
172         GL_window = SDL_CreateWindow(os_get_title(), SDL_WINDOWPOS_CENTERED,
173                                                 SDL_WINDOWPOS_CENTERED,
174                                                 gr_screen.max_w, gr_screen.max_h, SDL_WINDOW_OPENGL);
175
176         if ( !GL_window ) {
177                 Error(LOCATION, "Couldn't create window: %s\n", SDL_GetError());
178         }
179
180         os_set_window(GL_window);
181
182         GL_context = SDL_GL_CreateContext(GL_window);
183
184         const char *gl_version = (const char*)glGetString(GL_VERSION);
185         int v_major = 0, v_minor = 0;
186
187         sscanf(gl_version, "%d.%d", &v_major, &v_minor);
188
189         GL_version = (v_major * 10) + v_minor;
190
191         // version check, require 1.2+ for sake of simplicity
192         if (GL_version < 12) {
193                 Error(LOCATION, "Minimum OpenGL version is 1.2!");
194         }
195
196         mprintf(("  Vendor   : %s\n", glGetString(GL_VENDOR)));
197         mprintf(("  Renderer : %s\n", glGetString(GL_RENDERER)));
198         mprintf(("  Version  : %s\n", gl_version));
199
200         // initial viewport setup
201         opengl_init_viewport();
202
203         // set up generic variables before further init() calls
204         opengl_set_variables();
205
206         // main GL init
207         opengl1_init();
208
209         mprintf(("  Attributes requested : ARGB %d%d%d%d, BPP %d, DB %d, AA %d\n", a, r, g, b, bpp, db, FSAA));
210
211         SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r);
212         SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g);
213         SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b);
214         SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &a);
215         SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &bpp);
216         SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &db);
217         SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &FSAA);
218
219         mprintf(("  Attributes received  : ARGB %d%d%d%d, BPP %d, DB %d, AA %d\n", a, r, g, b, bpp, db, FSAA));
220
221         SDL_DisableScreenSaver();
222         SDL_ShowCursor(0);
223
224         // maybe go fullscreen - should be done *after* main GL init
225         int fullscreen = os_config_read_uint("Video", "Fullscreen", 1);
226         if ( !Cmdline_window && (fullscreen || Cmdline_fullscreen) ) {
227                 SDL_SetWindowFullscreen(GL_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
228                 // poll for window events
229                 os_poll();
230         }
231
232         mprintf(("\n"));
233
234
235         switch (bpp) {
236                 case 15:
237                 case 16:
238                         gr_screen.bits_per_pixel = 16;
239                         gr_screen.bytes_per_pixel = 2;
240
241                         // screen values
242                         Gr_red.bits = 5;
243                         Gr_red.shift = 11;
244                         Gr_red.scale = 8;
245                         Gr_red.mask = 0x7C01;
246
247                         Gr_green.bits = 5;
248                         Gr_green.shift = 6;
249                         Gr_green.scale = 8;
250                         Gr_green.mask = 0x3E1;
251
252                         Gr_blue.bits = 5;
253                         Gr_blue.shift = 1;
254                         Gr_blue.scale = 8;
255                         Gr_blue.mask = 0x20;
256
257                         Gr_alpha.bits = 1;
258                         Gr_alpha.shift = 0;
259                         Gr_alpha.scale = 255;
260                         Gr_alpha.mask = 0x1;
261
262                         break;
263
264                 case 24:
265                 case 32:
266                         gr_screen.bits_per_pixel = 32;
267                         gr_screen.bytes_per_pixel = 4;
268
269                         // screen values
270                         Gr_red.bits = 8;
271                         Gr_red.shift = 16;
272                         Gr_red.scale = 1;
273                         Gr_red.mask = 0xff0000;
274
275                         Gr_green.bits = 8;
276                         Gr_green.shift = 8;
277                         Gr_green.scale = 1;
278                         Gr_green.mask = 0xff00;
279
280                         Gr_blue.bits = 8;
281                         Gr_blue.shift = 0;
282                         Gr_blue.scale = 1;
283                         Gr_blue.mask = 0xff;
284
285                         Gr_alpha.bits = 8;
286                         Gr_alpha.shift = 24;
287                         Gr_alpha.scale = 1;
288                         Gr_alpha.mask = 0xff000000;
289
290                         break;
291
292                 default:
293                         Int3(); // Illegal bpp
294                         break;
295         }
296
297         // DDOI - set these so no one else does!
298         // texture values, always 5551 - 16-bit
299         Gr_t_red.mask = 0x7C01;
300         Gr_t_red.shift = 11;
301         Gr_t_red.scale = 8;
302
303         Gr_t_green.mask = 0x3E1;
304         Gr_t_green.shift = 6;
305         Gr_t_green.scale = 8;
306
307         Gr_t_blue.mask = 0x20;
308         Gr_t_blue.shift = 1;
309         Gr_t_blue.scale = 8;
310
311         Gr_t_alpha.mask = 0x1;
312         Gr_t_alpha.shift = 0;
313         Gr_t_alpha.scale = 255;
314
315         // alpha-texture values
316         Gr_ta_red.mask = 0x0f00;
317         Gr_ta_red.shift = 8;
318         Gr_ta_red.scale = 16;
319
320         Gr_ta_green.mask = 0x00f0;
321         Gr_ta_green.shift = 4;
322         Gr_ta_green.scale = 16;
323
324         Gr_ta_blue.mask = 0x000f;
325         Gr_ta_blue.shift = 0;
326         Gr_ta_blue.scale = 16;
327
328         Gr_ta_alpha.mask = 0xf000;
329         Gr_ta_alpha.shift = 12;
330         Gr_ta_alpha.scale = 16;
331
332         // default to screen
333         Gr_current_red = &Gr_red;
334         Gr_current_blue = &Gr_blue;
335         Gr_current_green = &Gr_green;
336         Gr_current_alpha = &Gr_alpha;
337
338
339         Mouse_hidden++;
340         gr_reset_clip();
341         gr_clear();
342         gr_flip();
343         gr_clear();
344         Mouse_hidden--;
345 }