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)
229 void gr_opengl_cleanup()
234 opengl_free_render_buffer();
238 SDL_DestroyWindow(GL_window);
244 void gr_opengl_init()
250 mprintf(( "Initializing OpenGL graphics device...\n" ));
254 if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
255 Error(LOCATION, "Couldn't init SDL: %s", SDL_GetError());
258 GL_window = SDL_CreateWindow(os_get_title(), SDL_WINDOWPOS_CENTERED,
259 SDL_WINDOWPOS_CENTERED,
260 gr_screen.max_w, gr_screen.max_h, SDL_WINDOW_OPENGL);
263 Error(LOCATION, "Couldn't create window: %s\n", SDL_GetError());
266 os_set_window(GL_window);
268 int a = 1, r = 5, g = 5, b = 5, bpp = 16;
269 int FSAA = os_config_read_uint("Video", "AntiAlias", 0);
271 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, r);
272 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, g);
273 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, b);
274 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, a);
275 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, bpp);
278 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
279 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, FSAA);
284 // try GL 2 first, then fall back to GL 1
285 if ( !opengl2_init() ) {
290 Error(LOCATION, "Unable to initialize OpenGL renderer!\n");
293 mprintf((" Attributes requested : ARGB %d%d%d%d, BPP %d, AA %d\n",
294 a, r, g, b, bpp, FSAA));
296 SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r);
297 SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g);
298 SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b);
299 SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &a);
300 SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &bpp);
301 SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &FSAA);
303 mprintf((" Attributes received : ARGB %d%d%d%d, BPP %d, AA %d\n",
304 a, r, g, b, bpp, FSAA));
307 SDL_DisableScreenSaver();
310 // maybe go fullscreen - should be done *after* main GL init
311 int fullscreen = os_config_read_uint("Video", "Fullscreen", 1);
312 if ( !Cmdline_window && (fullscreen || Cmdline_fullscreen) ) {
313 gr_force_fullscreen();
314 // poll for window events
321 gr_screen.bits_per_pixel = 16;
322 gr_screen.bytes_per_pixel = 2;
328 Gr_red.mask = 0x7C01;
333 Gr_green.mask = 0x3E1;
342 Gr_alpha.scale = 255;
349 gr_screen.bits_per_pixel = 32;
350 gr_screen.bytes_per_pixel = 4;
361 Gr_green.mask = 0xff00;
366 Gr_blue.mask = 0xff0000;
371 Gr_alpha.mask = 0xff000000;
376 Int3(); // Illegal bpp
380 // DDOI - set these so no one else does!
381 // texture values, always 5551 - 16-bit
382 Gr_t_red.mask = 0x7C01;
386 Gr_t_green.mask = 0x3E1;
387 Gr_t_green.shift = 6;
388 Gr_t_green.scale = 8;
390 Gr_t_blue.mask = 0x20;
394 Gr_t_alpha.mask = 0x1;
395 Gr_t_alpha.shift = 0;
396 Gr_t_alpha.scale = 255;
398 // alpha-texture values
399 Gr_ta_red.mask = 0x0f00;
401 Gr_ta_red.scale = 16;
403 Gr_ta_green.mask = 0x00f0;
404 Gr_ta_green.shift = 4;
405 Gr_ta_green.scale = 16;
407 Gr_ta_blue.mask = 0x000f;
408 Gr_ta_blue.shift = 0;
409 Gr_ta_blue.scale = 16;
411 Gr_ta_alpha.mask = 0xf000;
412 Gr_ta_alpha.shift = 12;
413 Gr_ta_alpha.scale = 16;
416 Gr_current_red = &Gr_red;
417 Gr_current_blue = &Gr_blue;
418 Gr_current_green = &Gr_green;
419 Gr_current_alpha = &Gr_alpha;