2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
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
9 #include "SDL_opengl.h"
12 #include "osregistry.h"
14 #include "gropenglinternal.h"
19 #include "grinternal.h"
26 bool OGL_inited = false;
29 SDL_Window *GL_window = NULL;
30 SDL_GLContext GL_context;
32 volatile int GL_activate = 0;
33 volatile int GL_deactivate = 0;
35 int GL_viewport_x = 0;
36 int GL_viewport_y = 0;
37 int GL_viewport_w = 640;
38 int GL_viewport_h = 480;
39 float GL_viewport_scale_w = 1.0f;
40 float GL_viewport_scale_h = 1.0f;
41 int GL_min_texture_width = 0;
42 int GL_max_texture_width = 0;
43 int GL_min_texture_height = 0;
44 int GL_max_texture_height = 0;
46 rb_t *render_buffer = NULL;
47 static size_t render_buffer_size = 0;
50 void opengl_alloc_render_buffer(unsigned int nelems)
56 if ( render_buffer && (nelems <= render_buffer_size) ) {
64 render_buffer = (rb_t*) malloc(sizeof(rb_t) * nelems);
65 render_buffer_size = nelems;
68 void opengl_free_render_buffer()
73 render_buffer_size = 0;
77 void opengl_set_variables()
79 GL_min_texture_height = 16;
80 GL_min_texture_width = 16;
82 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &GL_max_texture_width);
83 GL_max_texture_height = GL_max_texture_width;
85 // no texture is larger than 1024, so maybe don't use sections
86 if (GL_max_texture_width >= 1024) {
87 gr_screen.use_sections = 0;
91 void opengl_init_viewport()
95 GL_viewport_w = gr_screen.max_w;
96 GL_viewport_h = gr_screen.max_h;
97 GL_viewport_scale_w = 1.0f;
98 GL_viewport_scale_h = 1.0f;
100 glViewport(GL_viewport_x, GL_viewport_y, GL_viewport_w, GL_viewport_h);
103 void opengl_stuff_fog_value(float z, float *f_val)
111 f_float = 1.0f - ((gr_screen.fog_far - z) / (gr_screen.fog_far - gr_screen.fog_near));
113 if (f_float < 0.0f) {
115 } else if (f_float > 1.0f) {
122 void gr_opengl_force_windowed()
124 SDL_SetWindowFullscreen(GL_window, 0);
127 void gr_opengl_force_fullscreen()
129 SDL_SetWindowFullscreen(GL_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
132 void gr_opengl_toggle_fullscreen()
134 Uint32 flags = SDL_GetWindowFlags(GL_window);
136 if ( (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP ) {
137 gr_opengl_force_windowed();
139 gr_opengl_force_fullscreen();
143 void gr_opengl_clear()
145 glClearColor(gr_screen.current_clear_color.red / 255.0f,
146 gr_screen.current_clear_color.green / 255.0f,
147 gr_screen.current_clear_color.blue / 255.0f, 1.0f);
149 glClear( GL_COLOR_BUFFER_BIT );
152 void gr_opengl_reset_clip()
154 gr_screen.offset_x = 0;
155 gr_screen.offset_y = 0;
156 gr_screen.clip_left = 0;
157 gr_screen.clip_top = 0;
158 gr_screen.clip_right = gr_screen.max_w - 1;
159 gr_screen.clip_bottom = gr_screen.max_h - 1;
160 gr_screen.clip_width = gr_screen.max_w;
161 gr_screen.clip_height = gr_screen.max_h;
163 glDisable(GL_SCISSOR_TEST);
166 void gr_opengl_print_screen(const char *filename)
168 char tmp[MAX_FILENAME_LEN];
171 SDL_strlcpy( tmp, filename, SDL_arraysize(tmp) );
172 SDL_strlcat( tmp, NOX(".tga"), SDL_arraysize(tmp) );
174 buf = (ubyte*)malloc(GL_viewport_w * GL_viewport_h * 3);
180 CFILE *f = cfopen(tmp, "wb", CFILE_NORMAL, CF_TYPE_ROOT);
187 // Write the TGA header
188 cfwrite_ubyte( 0, f ); // IDLength;
189 cfwrite_ubyte( 0, f ); // ColorMapType;
190 cfwrite_ubyte( 2, f ); // ImageType; // 2 = 24bpp, uncompressed, 10=24bpp rle compressed
191 cfwrite_ushort( 0, f ); // CMapStart;
192 cfwrite_ushort( 0, f ); // CMapLength;
193 cfwrite_ubyte( 0, f ); // CMapDepth;
194 cfwrite_ushort( 0, f ); // XOffset;
195 cfwrite_ushort( 0, f ); // YOffset;
196 cfwrite_ushort( (ushort)GL_viewport_w, f ); // Width;
197 cfwrite_ushort( (ushort)GL_viewport_h, f ); // Height;
198 cfwrite_ubyte( 24, f ); //PixelDepth;
199 cfwrite_ubyte( 0, f ); //ImageDesc;
201 memset(buf, 0, GL_viewport_w * GL_viewport_h * 3);
203 glReadPixels(GL_viewport_x, GL_viewport_y, GL_viewport_w, GL_viewport_h, GL_RGB, GL_UNSIGNED_BYTE, buf);
205 cfwrite(buf, GL_viewport_w * GL_viewport_h * 3, 1, f);
212 uint gr_opengl_lock()
217 void gr_opengl_unlock()
221 void gr_opengl_zbias(int bias)
224 glEnable(GL_POLYGON_OFFSET_FILL);
225 glPolygonOffset(0.0f, GLfloat(-bias));
227 glDisable(GL_POLYGON_OFFSET_FILL);
231 void gr_opengl_set_cull(int cull)
234 glEnable (GL_CULL_FACE);
235 glFrontFace (GL_CCW);
237 glDisable (GL_CULL_FACE);
241 void gr_opengl_activate(int active)
246 // don't grab key/mouse if cmdline says so or if we're fullscreen
247 // if(!Cmdline_no_grab && !(SDL_GetVideoSurface()->flags & SDL_FULLSCREEN)) {
248 // SDL_WM_GrabInput(SDL_GRAB_ON);
253 // let go of mouse/keyboard
254 // SDL_WM_GrabInput(SDL_GRAB_OFF);
258 void gr_opengl_cleanup()
263 opengl_free_render_buffer();
267 SDL_GL_DeleteContext(GL_context);
270 SDL_DestroyWindow(GL_window);
276 void gr_opengl_init()
282 mprintf(( "Initializing OpenGL graphics device...\n" ));
286 if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
287 Error(LOCATION, "Couldn't init SDL: %s", SDL_GetError());
290 GL_window = SDL_CreateWindow(os_get_title(), SDL_WINDOWPOS_CENTERED,
291 SDL_WINDOWPOS_CENTERED,
292 gr_screen.max_w, gr_screen.max_h, SDL_WINDOW_OPENGL);
295 Error(LOCATION, "Couldn't create window: %s\n", SDL_GetError());
298 os_set_window(GL_window);
300 int a = 1, r = 5, g = 5, b = 5, bpp = 16;
301 int FSAA = os_config_read_uint("Video", "AntiAlias", 0);
303 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, r);
304 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, g);
305 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, b);
306 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, a);
307 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, bpp);
310 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
311 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, FSAA);
316 // try GL 2 first, then fall back to GL 1
317 if ( !opengl2_init() ) {
322 Error(LOCATION, "Unable to initialize OpenGL renderer!\n");
325 mprintf((" Attributes requested : ARGB %d%d%d%d, BPP %d, AA %d\n",
326 a, r, g, b, bpp, FSAA));
328 SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r);
329 SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g);
330 SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b);
331 SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &a);
332 SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &bpp);
333 SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &FSAA);
335 mprintf((" Attributes received : ARGB %d%d%d%d, BPP %d, AA %d\n",
336 a, r, g, b, bpp, FSAA));
339 SDL_DisableScreenSaver();
342 // maybe go fullscreen - should be done *after* main GL init
343 int fullscreen = os_config_read_uint("Video", "Fullscreen", 1);
344 if ( !Cmdline_window && (fullscreen || Cmdline_fullscreen) ) {
345 SDL_SetWindowFullscreen(GL_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
346 // poll for window events
353 gr_screen.bits_per_pixel = 16;
354 gr_screen.bytes_per_pixel = 2;
360 Gr_red.mask = 0x7C01;
365 Gr_green.mask = 0x3E1;
374 Gr_alpha.scale = 255;
381 gr_screen.bits_per_pixel = 32;
382 gr_screen.bytes_per_pixel = 4;
393 Gr_green.mask = 0xff00;
398 Gr_blue.mask = 0xff0000;
403 Gr_alpha.mask = 0xff000000;
408 Int3(); // Illegal bpp
412 // DDOI - set these so no one else does!
413 // texture values, always 5551 - 16-bit
414 Gr_t_red.mask = 0x7C01;
418 Gr_t_green.mask = 0x3E1;
419 Gr_t_green.shift = 6;
420 Gr_t_green.scale = 8;
422 Gr_t_blue.mask = 0x20;
426 Gr_t_alpha.mask = 0x1;
427 Gr_t_alpha.shift = 0;
428 Gr_t_alpha.scale = 255;
430 // alpha-texture values
431 Gr_ta_red.mask = 0x0f00;
433 Gr_ta_red.scale = 16;
435 Gr_ta_green.mask = 0x00f0;
436 Gr_ta_green.shift = 4;
437 Gr_ta_green.scale = 16;
439 Gr_ta_blue.mask = 0x000f;
440 Gr_ta_blue.shift = 0;
441 Gr_ta_blue.scale = 16;
443 Gr_ta_alpha.mask = 0xf000;
444 Gr_ta_alpha.shift = 12;
445 Gr_ta_alpha.scale = 16;
448 Gr_current_red = &Gr_red;
449 Gr_current_blue = &Gr_blue;
450 Gr_current_green = &Gr_green;
451 Gr_current_alpha = &Gr_alpha;