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_clear()
124 glClearColor(gr_screen.current_clear_color.red / 255.0f,
125 gr_screen.current_clear_color.green / 255.0f,
126 gr_screen.current_clear_color.blue / 255.0f, 1.0f);
128 glClear( GL_COLOR_BUFFER_BIT );
131 void gr_opengl_reset_clip()
133 gr_screen.offset_x = 0;
134 gr_screen.offset_y = 0;
135 gr_screen.clip_left = 0;
136 gr_screen.clip_top = 0;
137 gr_screen.clip_right = gr_screen.max_w - 1;
138 gr_screen.clip_bottom = gr_screen.max_h - 1;
139 gr_screen.clip_width = gr_screen.max_w;
140 gr_screen.clip_height = gr_screen.max_h;
142 glDisable(GL_SCISSOR_TEST);
145 void gr_opengl_print_screen(const char *filename)
147 char tmp[MAX_FILENAME_LEN];
150 SDL_strlcpy( tmp, filename, SDL_arraysize(tmp) );
151 SDL_strlcat( tmp, NOX(".tga"), SDL_arraysize(tmp) );
153 buf = (ubyte*)malloc(GL_viewport_w * GL_viewport_h * 3);
159 CFILE *f = cfopen(tmp, "wb", CFILE_NORMAL, CF_TYPE_ROOT);
166 // Write the TGA header
167 cfwrite_ubyte( 0, f ); // IDLength;
168 cfwrite_ubyte( 0, f ); // ColorMapType;
169 cfwrite_ubyte( 2, f ); // ImageType; // 2 = 24bpp, uncompressed, 10=24bpp rle compressed
170 cfwrite_ushort( 0, f ); // CMapStart;
171 cfwrite_ushort( 0, f ); // CMapLength;
172 cfwrite_ubyte( 0, f ); // CMapDepth;
173 cfwrite_ushort( 0, f ); // XOffset;
174 cfwrite_ushort( 0, f ); // YOffset;
175 cfwrite_ushort( (ushort)GL_viewport_w, f ); // Width;
176 cfwrite_ushort( (ushort)GL_viewport_h, f ); // Height;
177 cfwrite_ubyte( 24, f ); //PixelDepth;
178 cfwrite_ubyte( 0, f ); //ImageDesc;
180 memset(buf, 0, GL_viewport_w * GL_viewport_h * 3);
182 glReadPixels(GL_viewport_x, GL_viewport_y, GL_viewport_w, GL_viewport_h, GL_RGB, GL_UNSIGNED_BYTE, buf);
184 cfwrite(buf, GL_viewport_w * GL_viewport_h * 3, 1, f);
191 uint gr_opengl_lock()
196 void gr_opengl_unlock()
200 void gr_opengl_zbias(int bias)
203 glEnable(GL_POLYGON_OFFSET_FILL);
204 glPolygonOffset(0.0f, GLfloat(-bias));
206 glDisable(GL_POLYGON_OFFSET_FILL);
210 void gr_opengl_set_cull(int cull)
213 glEnable (GL_CULL_FACE);
214 glFrontFace (GL_CCW);
216 glDisable (GL_CULL_FACE);
220 void gr_opengl_activate(int active)
225 // don't grab key/mouse if cmdline says so or if we're fullscreen
226 // if(!Cmdline_no_grab && !(SDL_GetVideoSurface()->flags & SDL_FULLSCREEN)) {
227 // SDL_WM_GrabInput(SDL_GRAB_ON);
232 // let go of mouse/keyboard
233 // SDL_WM_GrabInput(SDL_GRAB_OFF);
237 void gr_opengl_cleanup()
242 opengl_free_render_buffer();
246 SDL_DestroyWindow(GL_window);
252 void gr_opengl_init()
258 mprintf(( "Initializing OpenGL graphics device...\n" ));
262 if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
263 Error(LOCATION, "Couldn't init SDL: %s", SDL_GetError());
266 GL_window = SDL_CreateWindow(os_get_title(), SDL_WINDOWPOS_CENTERED,
267 SDL_WINDOWPOS_CENTERED,
268 gr_screen.max_w, gr_screen.max_h, SDL_WINDOW_OPENGL);
271 Error(LOCATION, "Couldn't create window: %s\n", SDL_GetError());
274 os_set_window(GL_window);
276 int a = 1, r = 5, g = 5, b = 5, bpp = 16;
277 int FSAA = os_config_read_uint("Video", "AntiAlias", 0);
279 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, r);
280 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, g);
281 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, b);
282 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, a);
283 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, bpp);
286 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
287 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, FSAA);
292 // try GL 2 first, then fall back to GL 1
293 if ( !opengl2_init() ) {
298 Error(LOCATION, "Unable to initialize OpenGL renderer!\n");
301 mprintf((" Attributes requested : ARGB %d%d%d%d, BPP %d, AA %d\n",
302 a, r, g, b, bpp, FSAA));
304 SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r);
305 SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g);
306 SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b);
307 SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &a);
308 SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &bpp);
309 SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &FSAA);
311 mprintf((" Attributes received : ARGB %d%d%d%d, BPP %d, AA %d\n",
312 a, r, g, b, bpp, FSAA));
315 SDL_DisableScreenSaver();
318 // maybe go fullscreen - should be done *after* main GL init
319 int fullscreen = os_config_read_uint("Video", "Fullscreen", 1);
320 if ( !Cmdline_window && (fullscreen || Cmdline_fullscreen) ) {
321 gr_force_fullscreen();
322 // poll for window events
329 gr_screen.bits_per_pixel = 16;
330 gr_screen.bytes_per_pixel = 2;
336 Gr_red.mask = 0x7C01;
341 Gr_green.mask = 0x3E1;
350 Gr_alpha.scale = 255;
357 gr_screen.bits_per_pixel = 32;
358 gr_screen.bytes_per_pixel = 4;
369 Gr_green.mask = 0xff00;
374 Gr_blue.mask = 0xff0000;
379 Gr_alpha.mask = 0xff000000;
384 Int3(); // Illegal bpp
388 // DDOI - set these so no one else does!
389 // texture values, always 5551 - 16-bit
390 Gr_t_red.mask = 0x7C01;
394 Gr_t_green.mask = 0x3E1;
395 Gr_t_green.shift = 6;
396 Gr_t_green.scale = 8;
398 Gr_t_blue.mask = 0x20;
402 Gr_t_alpha.mask = 0x1;
403 Gr_t_alpha.shift = 0;
404 Gr_t_alpha.scale = 255;
406 // alpha-texture values
407 Gr_ta_red.mask = 0x0f00;
409 Gr_ta_red.scale = 16;
411 Gr_ta_green.mask = 0x00f0;
412 Gr_ta_green.shift = 4;
413 Gr_ta_green.scale = 16;
415 Gr_ta_blue.mask = 0x000f;
416 Gr_ta_blue.shift = 0;
417 Gr_ta_blue.scale = 16;
419 Gr_ta_alpha.mask = 0xf000;
420 Gr_ta_alpha.shift = 12;
421 Gr_ta_alpha.scale = 16;
424 Gr_current_red = &Gr_red;
425 Gr_current_blue = &Gr_blue;
426 Gr_current_green = &Gr_green;
427 Gr_current_alpha = &Gr_alpha;