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
11 #include "SDL_opengl.h"
14 #include "gropenglinternal.h"
18 #include "grinternal.h"
19 #include "osregistry.h"
23 int GL_one_inited = 0;
26 static GLuint GL_stream_tex = 0;
27 static GLuint Gr_saved_screen_tex = 0;
29 static int Gr_opengl_mouse_saved = 0;
30 static int Gr_opengl_mouse_saved_x = 0;
31 static int Gr_opengl_mouse_saved_y = 0;
32 static int Gr_opengl_mouse_saved_w = 0;
33 static int Gr_opengl_mouse_saved_h = 0;
34 static ubyte *Gr_opengl_mouse_saved_data = NULL;
37 static gr_alpha_blend GL_current_alpha_blend = (gr_alpha_blend) -1;
38 static gr_zbuffer_type GL_current_zbuffer_type = (gr_zbuffer_type) -1;
40 void opengl1_set_state(gr_texture_source ts, gr_alpha_blend ab, gr_zbuffer_type zt)
42 opengl1_set_texture_state(ts);
44 if (ab != GL_current_alpha_blend) {
46 case ALPHA_BLEND_NONE: // 1*SrcPixel + 0*DestPixel
47 glBlendFunc(GL_ONE, GL_ZERO);
49 case ALPHA_BLEND_ADDITIVE: // 1*SrcPixel + 1*DestPixel
50 glBlendFunc(GL_ONE, GL_ONE);
52 case ALPHA_BLEND_ALPHA_ADDITIVE: // Alpha*SrcPixel + 1*DestPixel
53 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
55 case ALPHA_BLEND_ALPHA_BLEND_ALPHA: // Alpha*SrcPixel + (1-Alpha)*DestPixel
56 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
58 case ALPHA_BLEND_ALPHA_BLEND_SRC_COLOR: // Alpha*SrcPixel + (1-SrcPixel)*DestPixel
59 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR);
65 GL_current_alpha_blend = ab;
68 if (zt != GL_current_zbuffer_type) {
70 case ZBUFFER_TYPE_NONE:
71 glDepthFunc(GL_ALWAYS);
72 glDepthMask(GL_FALSE);
74 case ZBUFFER_TYPE_READ:
76 glDepthMask(GL_FALSE);
78 case ZBUFFER_TYPE_WRITE:
79 glDepthFunc(GL_ALWAYS);
82 case ZBUFFER_TYPE_FULL:
90 GL_current_zbuffer_type = zt;
94 void opengl1_cleanup()
96 if ( !GL_one_inited ) {
100 gr_opengl_reset_clip();
104 gr_opengl1_free_screen(0);
106 if (Gr_opengl_mouse_saved_data) {
107 free(Gr_opengl_mouse_saved_data);
108 Gr_opengl_mouse_saved_data = NULL;
111 opengl1_tcache_cleanup();
114 SDL_GL_DeleteContext(GL_context);
121 static void opengl1_init_func_pointers()
123 gr_screen.gf_flip = gr_opengl1_flip;
124 gr_screen.gf_set_clip = gr_opengl1_set_clip;
125 gr_screen.gf_reset_clip = gr_opengl_reset_clip;
127 gr_screen.gf_clear = gr_opengl_clear;
129 gr_screen.gf_aabitmap = gr_opengl1_aabitmap;
130 gr_screen.gf_aabitmap_ex = gr_opengl1_aabitmap_ex;
132 gr_screen.gf_rect = gr_opengl1_rect;
133 gr_screen.gf_shade = gr_opengl1_shade;
134 gr_screen.gf_string = gr_opengl1_string;
135 gr_screen.gf_circle = gr_opengl1_circle;
137 gr_screen.gf_line = gr_opengl1_line;
138 gr_screen.gf_aaline = gr_opengl1_aaline;
139 gr_screen.gf_pixel = gr_opengl1_pixel;
140 gr_screen.gf_scaler = gr_opengl1_scaler;
141 gr_screen.gf_tmapper = gr_opengl1_tmapper;
143 gr_screen.gf_gradient = gr_opengl1_gradient;
145 gr_screen.gf_print_screen = gr_opengl1_print_screen;
147 gr_screen.gf_fade_in = gr_opengl1_fade_in;
148 gr_screen.gf_fade_out = gr_opengl1_fade_out;
149 gr_screen.gf_flash = gr_opengl1_flash;
151 gr_screen.gf_zbuffer_clear = gr_opengl1_zbuffer_clear;
153 gr_screen.gf_save_screen = gr_opengl1_save_screen;
154 gr_screen.gf_restore_screen = gr_opengl1_restore_screen;
155 gr_screen.gf_free_screen = gr_opengl1_free_screen;
157 gr_screen.gf_dump_frame_start = gr_opengl1_dump_frame_start;
158 gr_screen.gf_dump_frame_stop = gr_opengl1_dump_frame_stop;
159 gr_screen.gf_dump_frame = gr_opengl1_dump_frame;
161 gr_screen.gf_stream_start = gr_opengl1_stream_start;
162 gr_screen.gf_stream_frame = gr_opengl1_stream_frame;
163 gr_screen.gf_stream_stop = gr_opengl1_stream_stop;
165 gr_screen.gf_set_gamma = gr_opengl1_set_gamma;
167 gr_screen.gf_lock = gr_opengl_lock;
168 gr_screen.gf_unlock = gr_opengl_unlock;
170 gr_screen.gf_fog_set = gr_opengl1_fog_set;
172 gr_screen.gf_get_region = gr_opengl1_get_region;
174 gr_screen.gf_set_cull = gr_opengl_set_cull;
176 gr_screen.gf_cross_fade = gr_opengl1_cross_fade;
178 gr_screen.gf_preload_init = gr_opengl1_preload_init;
179 gr_screen.gf_preload = gr_opengl1_preload;
181 gr_screen.gf_zbias = gr_opengl_zbias;
183 gr_screen.gf_set_viewport = gr_opengl1_set_viewport;
185 gr_screen.gf_activate = gr_opengl_activate;
187 gr_screen.gf_release_texture = gr_opengl1_release_texture;
198 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0);
199 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
200 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
202 GL_context = SDL_GL_CreateContext(GL_window);
209 mprintf((" Vendor : %s\n", glGetString(GL_VENDOR)));
210 mprintf((" Renderer : %s\n", glGetString(GL_RENDERER)));
211 mprintf((" Version : %s\n", glGetString(GL_VERSION)));
213 // set up generic variables
214 opengl_set_variables();
216 opengl1_init_func_pointers();
217 opengl1_tcache_init();
219 // initial viewport setup
220 gr_opengl1_set_viewport(gr_screen.max_w, gr_screen.max_h);
222 glShadeModel(GL_SMOOTH);
224 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
225 glHint(GL_FOG_HINT, GL_NICEST);
227 glEnable(GL_DEPTH_TEST);
230 glEnable(GL_TEXTURE_2D);
232 glDepthRange(0.0, 1.0);
234 glPixelStorei(GL_PACK_ALIGNMENT, 1);
235 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
240 gr_opengl_set_cull(1);
245 void gr_opengl1_flip()
247 if ( !GL_one_inited ) {
251 gr_opengl_reset_clip();
255 Gr_opengl_mouse_saved = 0;
257 if ( mouse_is_visible() ) {
260 mouse_get_pos( &mx, &my );
262 gr_opengl1_save_mouse_area(mx, my, 32, 32);
264 float u_scale, v_scale;
266 if ( opengl1_tcache_set(Gr_cursor, TCACHE_TYPE_BITMAP_INTERFACE, &u_scale, &v_scale) ) {
267 opengl1_set_state(TEXTURE_SOURCE_DECAL, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE);
270 bm_get_info(Gr_cursor, &bw, &bh);
277 const float tex_coord[] = { 0.0f, 0.0f, 0.0f, 1.0f * v_scale,
278 1.0f * u_scale, 0.0f, 1.0f * u_scale,
280 const int ver_coord[] = { x, y, x, h, w, y, w, h };
282 glColor4ub(255, 255, 255, 255);
284 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
285 glEnableClientState(GL_VERTEX_ARRAY);
287 glTexCoordPointer(2, GL_FLOAT, 0, &tex_coord);
288 glVertexPointer(2, GL_INT, 0, &ver_coord);
290 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
292 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
293 glDisableClientState(GL_VERTEX_ARRAY);
297 gr_set_color(255,255,255);
298 gr_opengl1_line(mx, my, mx+7, my + 7);
299 gr_opengl1_line(mx, my, mx+5, my );
300 gr_opengl1_line(mx, my, mx, my+5);
306 GLenum error = glGetError();
308 if (error != GL_NO_ERROR) {
309 mprintf(("!!DEBUG!! OpenGL Error: %d\n", error));
313 SDL_GL_SwapWindow(GL_window);
315 glClear(GL_COLOR_BUFFER_BIT);
317 opengl1_tcache_frame();
319 int cnt = GL_activate;
323 opengl1_tcache_flush();
329 GL_deactivate -= cnt;
333 void gr_opengl1_set_clip(int x, int y, int w, int h)
335 // check for sanity of parameters
336 CAP(x, 0, gr_screen.max_w - 1);
337 CAP(y, 0, gr_screen.max_h - 1);
338 CAP(w, 0, gr_screen.max_w - x);
339 CAP(h, 0, gr_screen.max_h - y);
341 gr_screen.offset_x = x;
342 gr_screen.offset_y = y;
343 gr_screen.clip_left = 0;
344 gr_screen.clip_right = w-1;
345 gr_screen.clip_top = 0;
346 gr_screen.clip_bottom = h-1;
347 gr_screen.clip_width = w;
348 gr_screen.clip_height = h;
350 x = fl2i((x * GL_viewport_scale_w) + 0.5f) + GL_viewport_x;
351 y = fl2i((y * GL_viewport_scale_h) + 0.5f) + GL_viewport_y;
352 w = fl2i((w * GL_viewport_scale_w) + 0.5f);
353 h = fl2i((h * GL_viewport_scale_h) + 0.5f);
355 glEnable(GL_SCISSOR_TEST);
356 glScissor(x, GL_viewport_h-y-h, w, h);
359 void gr_opengl1_fog_set(int fog_mode, int r, int g, int b, float fog_near, float fog_far)
361 SDL_assert((r >= 0) && (r < 256));
362 SDL_assert((g >= 0) && (g < 256));
363 SDL_assert((b >= 0) && (b < 256));
365 if (fog_mode == GR_FOGMODE_NONE) {
366 if (gr_screen.current_fog_mode != fog_mode) {
370 gr_screen.current_fog_mode = fog_mode;
375 if (gr_screen.current_fog_mode != fog_mode) {
377 glFogi(GL_FOG_MODE, GL_LINEAR);
379 gr_screen.current_fog_mode = fog_mode;
382 if ( (gr_screen.current_fog_color.red != r) ||
383 (gr_screen.current_fog_color.green != g) ||
384 (gr_screen.current_fog_color.blue != b) ) {
385 gr_init_color( &gr_screen.current_fog_color, r, g, b );
394 glFogfv(GL_FOG_COLOR, fc);
397 if( (fog_near >= 0.0f) && (fog_far >= 0.0f) &&
398 ((fog_near != gr_screen.fog_near) ||
399 (fog_far != gr_screen.fog_far)) ) {
400 gr_screen.fog_near = fog_near;
401 gr_screen.fog_far = fog_far;
403 glFogf(GL_FOG_START, fog_near);
404 glFogf(GL_FOG_END, fog_far);
408 void gr_opengl1_zbuffer_clear(int mode)
412 Gr_zbuffering_mode = GR_ZBUFF_FULL;
413 Gr_global_zbuffering = 1;
415 opengl1_set_state( TEXTURE_SOURCE_NONE, ALPHA_BLEND_NONE, ZBUFFER_TYPE_FULL );
416 glClear ( GL_DEPTH_BUFFER_BIT );
419 Gr_zbuffering_mode = GR_ZBUFF_NONE;
420 Gr_global_zbuffering = 0;
424 void gr_opengl1_print_screen(const char *filename)
426 char tmp[MAX_FILENAME_LEN];
429 SDL_strlcpy( tmp, filename, SDL_arraysize(tmp) );
430 SDL_strlcat( tmp, NOX(".tga"), SDL_arraysize(tmp) );
432 buf = (ubyte*)malloc(GL_viewport_w * GL_viewport_h * 3);
438 CFILE *f = cfopen(tmp, "wb", CFILE_NORMAL, CF_TYPE_ROOT);
445 // Write the TGA header
446 cfwrite_ubyte( 0, f ); // IDLength;
447 cfwrite_ubyte( 0, f ); // ColorMapType;
448 cfwrite_ubyte( 2, f ); // ImageType; // 2 = 24bpp, uncompressed, 10=24bpp rle compressed
449 cfwrite_ushort( 0, f ); // CMapStart;
450 cfwrite_ushort( 0, f ); // CMapLength;
451 cfwrite_ubyte( 0, f ); // CMapDepth;
452 cfwrite_ushort( 0, f ); // XOffset;
453 cfwrite_ushort( 0, f ); // YOffset;
454 cfwrite_ushort( (ushort)GL_viewport_w, f ); // Width;
455 cfwrite_ushort( (ushort)GL_viewport_h, f ); // Height;
456 cfwrite_ubyte( 24, f ); //PixelDepth;
457 cfwrite_ubyte( 0, f ); //ImageDesc;
459 memset(buf, 0, GL_viewport_w * GL_viewport_h * 3);
461 glReadBuffer(GL_FRONT);
463 glReadPixels(GL_viewport_x, GL_viewport_y, GL_viewport_w, GL_viewport_h, GL_BGR, GL_UNSIGNED_BYTE, buf);
465 cfwrite(buf, GL_viewport_w * GL_viewport_h * 3, 1, f);
472 void gr_opengl1_fade_in(int instantaneous)
477 void gr_opengl1_fade_out(int instantaneous)
482 void gr_opengl1_get_region(int front, int w, int h, ubyte *data)
484 opengl1_set_state(TEXTURE_SOURCE_NO_FILTERING, ALPHA_BLEND_NONE, ZBUFFER_TYPE_NONE);
486 GLenum pxtype = GL_UNSIGNED_SHORT_5_5_5_1;
488 if (gr_screen.bytes_per_pixel == 4) {
489 pxtype = GL_UNSIGNED_BYTE;
492 glReadBuffer( (front) ? GL_FRONT : GL_BACK );
494 glReadPixels(GL_viewport_x, (GL_viewport_y+GL_viewport_h)-h-1, w, h, GL_RGBA, pxtype, data);
497 void gr_opengl1_save_mouse_area(int x, int y, int w, int h)
501 if (Gr_saved_screen_tex) {
502 // already saved, don't need it again
506 w = fl2i((w * GL_viewport_scale_w) + 0.5f);
507 h = fl2i((h * GL_viewport_scale_h) + 0.5f);
514 CAP(x1, 0, GL_viewport_w);
515 CAP(x2, 0, GL_viewport_w);
516 CAP(y1, 0, GL_viewport_h);
517 CAP(y2, 0, GL_viewport_h);
519 Gr_opengl_mouse_saved_x = x1;
520 Gr_opengl_mouse_saved_y = y1;
521 Gr_opengl_mouse_saved_w = x2 - x1 + 1;
522 Gr_opengl_mouse_saved_h = y2 - y1 + 1;
524 if ( (Gr_opengl_mouse_saved_w < 1) || (Gr_opengl_mouse_saved_h < 1) ) {
528 if (Gr_opengl_mouse_saved_data == NULL) {
529 Gr_opengl_mouse_saved_data = (ubyte*)malloc(w * h * 3);
531 if ( !Gr_opengl_mouse_saved_data ) {
536 x1 = GL_viewport_x+Gr_opengl_mouse_saved_x;
537 y1 = (GL_viewport_y+GL_viewport_h)-Gr_opengl_mouse_saved_y-Gr_opengl_mouse_saved_h;
539 glReadBuffer(GL_BACK);
541 glReadPixels(x1, y1, Gr_opengl_mouse_saved_w, Gr_opengl_mouse_saved_h,
542 GL_RGB, GL_UNSIGNED_BYTE, Gr_opengl_mouse_saved_data);
544 Gr_opengl_mouse_saved = 1;
547 int gr_opengl1_save_screen()
549 gr_opengl_reset_clip();
551 if (Gr_saved_screen_tex) {
552 mprintf(( "Screen already saved!\n" ));
556 glGenTextures(1, &Gr_saved_screen_tex);
558 if ( !Gr_saved_screen_tex ) {
559 mprintf(( "Couldn't create texture for saved screen!\n" ));
563 glBindTexture(GL_TEXTURE_2D, Gr_saved_screen_tex);
565 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
566 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
567 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
568 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
569 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
571 glReadBuffer(GL_FRONT);
573 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GL_viewport_x, GL_viewport_y,
574 GL_viewport_w, GL_viewport_h, 0);
576 if (Gr_opengl_mouse_saved) {
577 int x = Gr_opengl_mouse_saved_x;
578 int y = GL_viewport_h-Gr_opengl_mouse_saved_y-Gr_opengl_mouse_saved_h;
580 glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, Gr_opengl_mouse_saved_w,
581 Gr_opengl_mouse_saved_h, GL_RGB, GL_UNSIGNED_BYTE,
582 Gr_opengl_mouse_saved_data);
585 glBindTexture(GL_TEXTURE_2D, 0);
590 void gr_opengl1_restore_screen(int)
592 gr_opengl_reset_clip();
594 if ( !Gr_saved_screen_tex ) {
601 int w = fl2i(GL_viewport_w / GL_viewport_scale_w + 0.5f);
602 int h = fl2i(GL_viewport_h / GL_viewport_scale_h + 0.5f);
604 const int tex_coord[] = { 0, 1, 0, 0, 1, 1, 1, 0 }; // y-flipped
605 const int ver_coord[] = { x, y, x, h, w, y, w, h };
607 glColor4ub(255, 255, 255, 255);
609 glBindTexture(GL_TEXTURE_2D, Gr_saved_screen_tex);
611 opengl1_set_state(TEXTURE_SOURCE_NO_FILTERING, ALPHA_BLEND_NONE, ZBUFFER_TYPE_NONE);
613 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
614 glEnableClientState(GL_VERTEX_ARRAY);
616 glTexCoordPointer(2, GL_INT, 0, &tex_coord);
617 glVertexPointer(2, GL_INT, 0, &ver_coord);
619 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
621 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
622 glDisableClientState(GL_VERTEX_ARRAY);
624 glBindTexture(GL_TEXTURE_2D, 0);
627 void gr_opengl1_free_screen(int)
629 if (Gr_saved_screen_tex) {
630 glDeleteTextures(1, &Gr_saved_screen_tex);
631 Gr_saved_screen_tex = 0;
635 void gr_opengl1_dump_frame_start(int first_frame, int frames_between_dumps)
640 void gr_opengl1_dump_frame_stop()
645 void gr_opengl1_dump_frame()
650 static int GL_stream_w = 0;
651 static int GL_stream_h = 0;
652 static bool GL_stream_scale = false;
653 static float GL_stream_scale_by = 1.0f;
655 static rb_t GL_stream[4];
657 void gr_opengl1_stream_start(int x, int y, int w, int h)
663 if (gr_screen.use_sections) {
664 mprintf(("GR_STREAM: Bitmap sections not supported\n"));
668 int tex_w = next_pow2(w);
669 int tex_h = next_pow2(h);
671 glGenTextures(1, &GL_stream_tex);
673 glBindTexture(GL_TEXTURE_2D, GL_stream_tex);
675 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
676 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
677 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
678 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
680 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, NULL);
682 glBindTexture(GL_TEXTURE_2D, 0);
684 uint scale = os_config_read_uint("Video", "ScaleMovies", 1);
687 GL_stream_scale = true;
688 GL_stream_scale_by = GL_viewport_w / i2fl(w);
690 GL_stream_scale = false;
696 sx = scale ? 0 : ((gr_screen.max_w - w) / 2);
702 sy = scale ? ((480 - h) / 2) : ((gr_screen.max_h - h) / 2);
710 GL_stream[0].x = i2fl(sx);
711 GL_stream[0].y = i2fl(sy);
712 GL_stream[0].u = 0.0f;
713 GL_stream[0].v = 0.0f;
715 GL_stream[1].x = i2fl(sx);
716 GL_stream[1].y = i2fl(sy + h);
717 GL_stream[1].u = 0.0f;
718 GL_stream[1].v = i2fl(h) / i2fl(tex_h);
720 GL_stream[2].x = i2fl(sx + w);
721 GL_stream[2].y = i2fl(sy);
722 GL_stream[2].u = i2fl(w) / i2fl(tex_w);
723 GL_stream[2].v = 0.0f;
725 GL_stream[3].x = i2fl(sx + w);
726 GL_stream[3].y = i2fl(sy + h);
727 GL_stream[3].u = i2fl(w) / i2fl(tex_w);
728 GL_stream[3].v = i2fl(h) / i2fl(tex_h);
730 glDisable(GL_DEPTH_TEST);
733 void gr_opengl1_stream_frame(ubyte *frame)
735 if ( !GL_stream_tex ) {
739 glEnableClientState(GL_VERTEX_ARRAY);
740 glVertexPointer(2, GL_FLOAT, sizeof(rb_t), &GL_stream[0].x);
742 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
743 glTexCoordPointer(2, GL_FLOAT, sizeof(rb_t), &GL_stream[0].u);
745 glBindTexture(GL_TEXTURE_2D, GL_stream_tex);
747 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GL_stream_w, GL_stream_h, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, frame);
749 if (GL_stream_scale) {
752 glScalef(GL_stream_scale_by, GL_stream_scale_by, 1.0f);
755 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
757 if (GL_stream_scale) {
761 glBindTexture(GL_TEXTURE_2D, 0);
763 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
764 glDisableClientState(GL_VERTEX_ARRAY);
767 void gr_opengl1_stream_stop()
770 glBindTexture(GL_TEXTURE_2D, 0);
771 glDeleteTextures(1, &GL_stream_tex);
774 glEnable(GL_DEPTH_TEST);
778 void gr_opengl1_set_viewport(int width, int height)
782 float ratio = gr_screen.max_w / i2fl(gr_screen.max_h);
785 h = fl2i((width / ratio) + 0.5f);
789 w = fl2i((height * ratio) + 0.5f);
793 y = (height - h) / 2;
799 GL_viewport_scale_w = w / i2fl(gr_screen.max_w);
800 GL_viewport_scale_h = h / i2fl(gr_screen.max_h);
802 gr_screen.viewport_offset_x = x;
803 gr_screen.viewport_offset_y = y;
805 gr_screen.viewport_scale_factor_x = 1.0f / GL_viewport_scale_w;
806 gr_screen.viewport_scale_factor_y = 1.0f / GL_viewport_scale_h;
808 glViewport(GL_viewport_x, GL_viewport_y, GL_viewport_w, GL_viewport_h);
810 glMatrixMode(GL_PROJECTION);
812 glOrtho(0, GL_viewport_w, GL_viewport_h, 0, 0.0, 1.0);
813 glMatrixMode(GL_MODELVIEW);
815 glScalef(GL_viewport_scale_w, GL_viewport_scale_h, 1.0f);
817 // free mouse cursor storage, since the size might have changed
818 if (Gr_opengl_mouse_saved_data) {
819 free(Gr_opengl_mouse_saved_data);
820 Gr_opengl_mouse_saved_data = NULL;
823 // adjust scale factor for gr_stream (movies)
824 if (GL_stream_tex && GL_stream_scale) {
825 GL_stream_scale_by = GL_viewport_w / i2fl(GL_stream_w);