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 gr_opengl_force_windowed()
105 SDL_SetWindowFullscreen(GL_window, 0);
108 void gr_opengl_force_fullscreen()
110 SDL_SetWindowFullscreen(GL_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
113 void gr_opengl_toggle_fullscreen()
115 Uint32 flags = SDL_GetWindowFlags(GL_window);
117 if ( (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP ) {
118 gr_opengl_force_windowed();
120 gr_opengl_force_fullscreen();
124 void gr_opengl_clear()
126 glClearColor(gr_screen.current_clear_color.red / 255.0f,
127 gr_screen.current_clear_color.green / 255.0f,
128 gr_screen.current_clear_color.blue / 255.0f, 1.0f);
130 glClear( GL_COLOR_BUFFER_BIT );
133 void gr_opengl_reset_clip()
135 gr_screen.offset_x = 0;
136 gr_screen.offset_y = 0;
137 gr_screen.clip_left = 0;
138 gr_screen.clip_top = 0;
139 gr_screen.clip_right = gr_screen.max_w - 1;
140 gr_screen.clip_bottom = gr_screen.max_h - 1;
141 gr_screen.clip_width = gr_screen.max_w;
142 gr_screen.clip_height = gr_screen.max_h;
144 glDisable(GL_SCISSOR_TEST);
147 void gr_opengl_print_screen(const char *filename)
149 char tmp[MAX_FILENAME_LEN];
152 SDL_strlcpy( tmp, filename, SDL_arraysize(tmp) );
153 SDL_strlcat( tmp, NOX(".tga"), SDL_arraysize(tmp) );
155 buf = (ubyte*)malloc(GL_viewport_w * GL_viewport_h * 3);
161 CFILE *f = cfopen(tmp, "wb", CFILE_NORMAL, CF_TYPE_ROOT);
168 // Write the TGA header
169 cfwrite_ubyte( 0, f ); // IDLength;
170 cfwrite_ubyte( 0, f ); // ColorMapType;
171 cfwrite_ubyte( 2, f ); // ImageType; // 2 = 24bpp, uncompressed, 10=24bpp rle compressed
172 cfwrite_ushort( 0, f ); // CMapStart;
173 cfwrite_ushort( 0, f ); // CMapLength;
174 cfwrite_ubyte( 0, f ); // CMapDepth;
175 cfwrite_ushort( 0, f ); // XOffset;
176 cfwrite_ushort( 0, f ); // YOffset;
177 cfwrite_ushort( (ushort)GL_viewport_w, f ); // Width;
178 cfwrite_ushort( (ushort)GL_viewport_h, f ); // Height;
179 cfwrite_ubyte( 24, f ); //PixelDepth;
180 cfwrite_ubyte( 0, f ); //ImageDesc;
182 memset(buf, 0, GL_viewport_w * GL_viewport_h * 3);
184 glReadPixels(GL_viewport_x, GL_viewport_y, GL_viewport_w, GL_viewport_h, GL_RGB, GL_UNSIGNED_BYTE, buf);
186 cfwrite(buf, GL_viewport_w * GL_viewport_h * 3, 1, f);
193 uint gr_opengl_lock()
198 void gr_opengl_unlock()
202 void gr_opengl_zbias(int bias)
205 glEnable(GL_POLYGON_OFFSET_FILL);
206 glPolygonOffset(0.0f, GLfloat(-bias));
208 glDisable(GL_POLYGON_OFFSET_FILL);
212 void gr_opengl_set_cull(int cull)
215 glEnable (GL_CULL_FACE);
216 glFrontFace (GL_CCW);
218 glDisable (GL_CULL_FACE);
222 void gr_opengl_activate(int active)
227 // don't grab key/mouse if cmdline says so or if we're fullscreen
228 // if(!Cmdline_no_grab && !(SDL_GetVideoSurface()->flags & SDL_FULLSCREEN)) {
229 // SDL_WM_GrabInput(SDL_GRAB_ON);
234 // let go of mouse/keyboard
235 // SDL_WM_GrabInput(SDL_GRAB_OFF);
239 void gr_opengl_cleanup()
244 opengl_free_render_buffer();
248 SDL_GL_DeleteContext(GL_context);
251 SDL_DestroyWindow(GL_window);
257 void gr_opengl_init()
263 mprintf(( "Initializing OpenGL graphics device...\n" ));
267 if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
268 Error(LOCATION, "Couldn't init SDL: %s", SDL_GetError());
271 GL_window = SDL_CreateWindow(os_get_title(), SDL_WINDOWPOS_CENTERED,
272 SDL_WINDOWPOS_CENTERED,
273 gr_screen.max_w, gr_screen.max_h, SDL_WINDOW_OPENGL);
276 Error(LOCATION, "Couldn't create window: %s\n", SDL_GetError());
279 os_set_window(GL_window);
281 int a = 1, r = 5, g = 5, b = 5, bpp = 16;
282 int FSAA = os_config_read_uint("Video", "AntiAlias", 0);
284 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, r);
285 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, g);
286 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, b);
287 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, a);
288 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, bpp);
291 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
292 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, FSAA);
297 // try GL 2 first, then fall back to GL 1
298 if ( !opengl2_init() ) {
303 Error(LOCATION, "Unable to initialize OpenGL renderer!\n");
306 mprintf((" Attributes requested : ARGB %d%d%d%d, BPP %d, AA %d\n",
307 a, r, g, b, bpp, FSAA));
309 SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r);
310 SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g);
311 SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b);
312 SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &a);
313 SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &bpp);
314 SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &FSAA);
316 mprintf((" Attributes received : ARGB %d%d%d%d, BPP %d, AA %d\n",
317 a, r, g, b, bpp, FSAA));
320 SDL_DisableScreenSaver();
323 // maybe go fullscreen - should be done *after* main GL init
324 int fullscreen = os_config_read_uint("Video", "Fullscreen", 1);
325 if ( !Cmdline_window && (fullscreen || Cmdline_fullscreen) ) {
326 SDL_SetWindowFullscreen(GL_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
327 // poll for window events
334 gr_screen.bits_per_pixel = 16;
335 gr_screen.bytes_per_pixel = 2;
341 Gr_red.mask = 0x7C01;
346 Gr_green.mask = 0x3E1;
355 Gr_alpha.scale = 255;
362 gr_screen.bits_per_pixel = 32;
363 gr_screen.bytes_per_pixel = 4;
369 Gr_red.mask = 0xff0000;
374 Gr_green.mask = 0xff00;
384 Gr_alpha.mask = 0xff000000;
389 Int3(); // Illegal bpp
393 // DDOI - set these so no one else does!
394 // texture values, always 5551 - 16-bit
395 Gr_t_red.mask = 0x7C01;
399 Gr_t_green.mask = 0x3E1;
400 Gr_t_green.shift = 6;
401 Gr_t_green.scale = 8;
403 Gr_t_blue.mask = 0x20;
407 Gr_t_alpha.mask = 0x1;
408 Gr_t_alpha.shift = 0;
409 Gr_t_alpha.scale = 255;
411 // alpha-texture values
412 Gr_ta_red.mask = 0x0f00;
414 Gr_ta_red.scale = 16;
416 Gr_ta_green.mask = 0x00f0;
417 Gr_ta_green.shift = 4;
418 Gr_ta_green.scale = 16;
420 Gr_ta_blue.mask = 0x000f;
421 Gr_ta_blue.shift = 0;
422 Gr_ta_blue.scale = 16;
424 Gr_ta_alpha.mask = 0xf000;
425 Gr_ta_alpha.shift = 12;
426 Gr_ta_alpha.scale = 16;
429 Gr_current_red = &Gr_red;
430 Gr_current_blue = &Gr_blue;
431 Gr_current_green = &Gr_green;
432 Gr_current_alpha = &Gr_alpha;