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_DestroyWindow(GL_window);
273 void gr_opengl_init()
279 mprintf(( "Initializing OpenGL graphics device...\n" ));
283 if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
284 Error(LOCATION, "Couldn't init SDL: %s", SDL_GetError());
287 GL_window = SDL_CreateWindow(os_get_title(), SDL_WINDOWPOS_CENTERED,
288 SDL_WINDOWPOS_CENTERED,
289 gr_screen.max_w, gr_screen.max_h, SDL_WINDOW_OPENGL);
292 Error(LOCATION, "Couldn't create window: %s\n", SDL_GetError());
295 os_set_window(GL_window);
297 int a = 1, r = 5, g = 5, b = 5, bpp = 16;
298 int FSAA = os_config_read_uint("Video", "AntiAlias", 0);
300 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, r);
301 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, g);
302 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, b);
303 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, a);
304 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, bpp);
307 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
308 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, FSAA);
313 // try GL 2 first, then fall back to GL 1
314 if ( !opengl2_init() ) {
319 Error(LOCATION, "Unable to initialize OpenGL renderer!\n");
322 mprintf((" Attributes requested : ARGB %d%d%d%d, BPP %d, AA %d\n",
323 a, r, g, b, bpp, FSAA));
325 SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r);
326 SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g);
327 SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b);
328 SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &a);
329 SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &bpp);
330 SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &FSAA);
332 mprintf((" Attributes received : ARGB %d%d%d%d, BPP %d, AA %d\n",
333 a, r, g, b, bpp, FSAA));
336 SDL_DisableScreenSaver();
339 // maybe go fullscreen - should be done *after* main GL init
340 int fullscreen = os_config_read_uint("Video", "Fullscreen", 1);
341 if ( !Cmdline_window && (fullscreen || Cmdline_fullscreen) ) {
342 SDL_SetWindowFullscreen(GL_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
343 // poll for window events
350 gr_screen.bits_per_pixel = 16;
351 gr_screen.bytes_per_pixel = 2;
357 Gr_red.mask = 0x7C01;
362 Gr_green.mask = 0x3E1;
371 Gr_alpha.scale = 255;
378 gr_screen.bits_per_pixel = 32;
379 gr_screen.bytes_per_pixel = 4;
390 Gr_green.mask = 0xff00;
395 Gr_blue.mask = 0xff0000;
400 Gr_alpha.mask = 0xff000000;
405 Int3(); // Illegal bpp
409 // DDOI - set these so no one else does!
410 // texture values, always 5551 - 16-bit
411 Gr_t_red.mask = 0x7C01;
415 Gr_t_green.mask = 0x3E1;
416 Gr_t_green.shift = 6;
417 Gr_t_green.scale = 8;
419 Gr_t_blue.mask = 0x20;
423 Gr_t_alpha.mask = 0x1;
424 Gr_t_alpha.shift = 0;
425 Gr_t_alpha.scale = 255;
427 // alpha-texture values
428 Gr_ta_red.mask = 0x0f00;
430 Gr_ta_red.scale = 16;
432 Gr_ta_green.mask = 0x00f0;
433 Gr_ta_green.shift = 4;
434 Gr_ta_green.scale = 16;
436 Gr_ta_blue.mask = 0x000f;
437 Gr_ta_blue.shift = 0;
438 Gr_ta_blue.scale = 16;
440 Gr_ta_alpha.mask = 0xf000;
441 Gr_ta_alpha.shift = 12;
442 Gr_ta_alpha.scale = 16;
445 Gr_current_red = &Gr_red;
446 Gr_current_blue = &Gr_blue;
447 Gr_current_green = &Gr_green;
448 Gr_current_alpha = &Gr_alpha;