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_opengles2.h"
12 #include "gropenglinternal.h"
19 #include "grinternal.h"
21 #include "osregistry.h"
24 int GL_two_inited = 0;
26 bool Use_mipmaps = false;
29 static gr_alpha_blend GL_current_alpha_blend = (gr_alpha_blend) -1;
30 static gr_zbuffer_type GL_current_zbuffer_type = (gr_zbuffer_type) -1;
32 void opengl2_set_state(gr_texture_source ts, gr_alpha_blend ab, gr_zbuffer_type zt)
34 opengl2_set_texture_state(ts);
36 if (ab != GL_current_alpha_blend) {
38 case ALPHA_BLEND_NONE: // 1*SrcPixel + 0*DestPixel
39 glBlendFunc(GL_ONE, GL_ZERO);
41 case ALPHA_BLEND_ADDITIVE: // 1*SrcPixel + 1*DestPixel
42 glBlendFunc(GL_ONE, GL_ONE);
44 case ALPHA_BLEND_ALPHA_ADDITIVE: // Alpha*SrcPixel + 1*DestPixel
45 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
47 case ALPHA_BLEND_ALPHA_BLEND_ALPHA: // Alpha*SrcPixel + (1-Alpha)*DestPixel
48 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
50 case ALPHA_BLEND_ALPHA_BLEND_SRC_COLOR: // Alpha*SrcPixel + (1-SrcPixel)*DestPixel
51 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR);
57 GL_current_alpha_blend = ab;
60 if (zt != GL_current_zbuffer_type) {
62 case ZBUFFER_TYPE_NONE:
63 glDepthFunc(GL_ALWAYS);
64 glDepthMask(GL_FALSE);
66 case ZBUFFER_TYPE_READ:
68 glDepthMask(GL_FALSE);
70 case ZBUFFER_TYPE_WRITE:
71 glDepthFunc(GL_ALWAYS);
74 case ZBUFFER_TYPE_FULL:
82 GL_current_zbuffer_type = zt;
86 void opengl2_cleanup()
88 if ( !GL_two_inited ) {
92 opengl2_tcache_cleanup();
93 opengl2_shader_cleanup();
98 static void opengl2_init_func_pointers()
100 gr_screen.gf_flip = gr_opengl2_flip;
101 gr_screen.gf_set_clip = gr_opengl2_set_clip;
102 gr_screen.gf_reset_clip = gr_opengl_reset_clip;
104 gr_screen.gf_clear = gr_opengl_clear;
106 gr_screen.gf_aabitmap = gr_opengl2_aabitmap;
107 gr_screen.gf_aabitmap_ex = gr_opengl2_aabitmap_ex;
109 gr_screen.gf_rect = gr_opengl2_rect;
110 gr_screen.gf_shade = gr_opengl2_shade;
111 gr_screen.gf_string = gr_opengl2_string;
112 gr_screen.gf_circle = gr_opengl2_circle;
114 gr_screen.gf_line = gr_opengl2_line;
115 gr_screen.gf_aaline = gr_opengl2_aaline;
116 gr_screen.gf_pixel = gr_opengl2_pixel;
117 gr_screen.gf_scaler = gr_opengl2_scaler;
118 gr_screen.gf_tmapper = gr_opengl2_tmapper;
120 gr_screen.gf_gradient = gr_opengl2_gradient;
122 gr_screen.gf_print_screen = gr_opengl_print_screen;
124 gr_screen.gf_fade_in = gr_opengl2_fade_in;
125 gr_screen.gf_fade_out = gr_opengl2_fade_out;
126 gr_screen.gf_flash = gr_opengl2_flash;
128 gr_screen.gf_zbuffer_clear = gr_opengl2_zbuffer_clear;
130 gr_screen.gf_save_screen = gr_opengl2_save_screen;
131 gr_screen.gf_restore_screen = gr_opengl2_restore_screen;
132 gr_screen.gf_free_screen = gr_opengl2_free_screen;
134 gr_screen.gf_dump_frame_start = gr_opengl2_dump_frame_start;
135 gr_screen.gf_dump_frame_stop = gr_opengl2_dump_frame_stop;
136 gr_screen.gf_dump_frame = gr_opengl2_dump_frame;
138 gr_screen.gf_set_gamma = gr_opengl2_set_gamma;
140 gr_screen.gf_lock = gr_opengl_lock;
141 gr_screen.gf_unlock = gr_opengl_unlock;
143 gr_screen.gf_fog_set = gr_opengl2_fog_set;
145 gr_screen.gf_get_region = gr_opengl2_get_region;
147 gr_screen.gf_set_cull = gr_opengl_set_cull;
149 gr_screen.gf_cross_fade = gr_opengl2_cross_fade;
151 gr_screen.gf_preload_init = gr_opengl2_preload_init;
152 gr_screen.gf_preload = gr_opengl2_preload;
154 gr_screen.gf_zbias = gr_opengl_zbias;
156 gr_screen.gf_force_windowed = gr_opengl_force_windowed;
157 gr_screen.gf_force_fullscreen = gr_opengl_force_fullscreen;
158 gr_screen.gf_toggle_fullscreen = gr_opengl_toggle_fullscreen;
160 gr_screen.gf_set_viewport = gr_opengl2_set_viewport;
162 gr_screen.gf_activate = gr_opengl_activate;
164 gr_screen.gf_release_texture = gr_opengl2_release_texture;
173 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
174 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
175 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
177 GL_context = SDL_GL_CreateContext(GL_window);
183 mprintf((" Vendor : %s\n", glGetString(GL_VENDOR)));
184 mprintf((" Renderer : %s\n", glGetString(GL_RENDERER)));
185 mprintf((" Version : %s\n", glGetString(GL_VERSION)));
187 // set up generic variables
188 opengl_set_variables();
190 opengl2_init_func_pointers();
191 opengl2_tcache_init();
192 opengl2_shader_init();
194 // initial viewport setup
195 gr_opengl2_set_viewport(gr_screen.max_w, gr_screen.max_h);
198 glEnable(GL_DEPTH_TEST);
201 glDepthRangef(0.0f, 1.0f);
203 glPixelStorei(GL_PACK_ALIGNMENT, 1);
204 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
206 if ( SDL_GL_ExtensionSupported("GL_OES_texture_npot") ) {
210 mprintf((" Mipmaps : %s\n", Use_mipmaps ? "Enabled" : "Disabled"));
215 gr_opengl_set_cull(1);
222 void gr_opengl2_flip()
224 if ( !GL_two_inited ) {
228 gr_opengl_reset_clip();
232 if ( mouse_is_visible() ) {
235 mouse_get_pos(&mx, &my);
237 if (Gr_cursor == -1) {
239 gr_set_color(255, 255, 255);
240 gr_opengl2_line(mx, my, mx+7, my+7);
241 gr_opengl2_line(mx, my, mx+5, my);
242 gr_opengl2_line(mx, my, mx, my+5);
245 gr_set_bitmap(Gr_cursor);
251 GLenum error = GL_NO_ERROR;
254 error = glGetError();
256 if (error != GL_NO_ERROR) {
257 nprintf(("Warning", "!!DEBUG!! OpenGL Error: %d\n", error));
259 } while (error != GL_NO_ERROR);
262 SDL_GL_SwapWindow(GL_window);
264 opengl2_tcache_frame();
267 void gr_opengl2_set_clip(int x, int y, int w, int h)
269 // check for sanity of parameters
270 CAP(x, 0, gr_screen.max_w - 1);
271 CAP(y, 0, gr_screen.max_h - 1);
272 CAP(w, 0, gr_screen.max_w - x);
273 CAP(h, 0, gr_screen.max_h - y);
275 gr_screen.offset_x = x;
276 gr_screen.offset_y = y;
277 gr_screen.clip_left = 0;
278 gr_screen.clip_right = w-1;
279 gr_screen.clip_top = 0;
280 gr_screen.clip_bottom = h-1;
281 gr_screen.clip_width = w;
282 gr_screen.clip_height = h;
284 glEnable(GL_SCISSOR_TEST);
285 glScissor(x, GL_viewport_h-y-h, w, h);
288 void gr_opengl2_fog_set(int fog_mode, int r, int g, int b, float fog_near, float fog_far)
290 gr_screen.current_fog_mode = fog_mode;
292 if (fog_mode == GR_FOGMODE_NONE) {
296 gr_screen.fog_near = fog_near;
297 gr_screen.fog_far = fog_far;
299 gr_init_color(&gr_screen.current_fog_color, r, g, b);
302 void gr_opengl2_zbuffer_clear(int mode)
306 Gr_zbuffering_mode = GR_ZBUFF_FULL;
307 Gr_global_zbuffering = 1;
309 opengl2_set_state(TEXTURE_SOURCE_NONE, ALPHA_BLEND_NONE, ZBUFFER_TYPE_FULL);
310 glClear(GL_DEPTH_BUFFER_BIT);
313 Gr_zbuffering_mode = GR_ZBUFF_NONE;
314 Gr_global_zbuffering = 0;
318 void gr_opengl2_fade_in(int instantaneous)
323 void gr_opengl2_fade_out(int instantaneous)
328 void gr_opengl2_get_region(int front, int w, int h, ubyte *data)
330 opengl2_set_state(TEXTURE_SOURCE_NO_FILTERING, ALPHA_BLEND_NONE, ZBUFFER_TYPE_NONE);
332 int x = GL_viewport_x;
333 int y = (GL_viewport_y+GL_viewport_h)-h-1;
335 GLenum pxtype = GL_UNSIGNED_SHORT_5_5_5_1;
337 if (gr_screen.bytes_per_pixel == 4) {
338 pxtype = GL_UNSIGNED_BYTE;
341 glReadPixels(x, y, w, h, GL_RGBA, pxtype, data);
344 int gr_opengl2_save_screen()
349 void gr_opengl2_restore_screen(int)
354 void gr_opengl2_free_screen(int)
359 void gr_opengl2_dump_frame_start(int first_frame, int frames_between_dumps)
364 void gr_opengl2_dump_frame_stop()
369 void gr_opengl2_dump_frame()
374 void gr_opengl2_set_viewport(int width, int height)
378 float ratio = gr_screen.max_w / i2fl(gr_screen.max_h);
381 h = fl2i((width / ratio) + 0.5f);
385 w = fl2i((height * ratio) + 0.5f);
389 y = (height - h) / 2;
395 GL_viewport_scale_w = w / i2fl(gr_screen.max_w);
396 GL_viewport_scale_h = h / i2fl(gr_screen.max_h);
398 glViewport(GL_viewport_x, GL_viewport_y, GL_viewport_w, GL_viewport_h);
400 // clear screen once to fix issues with edges on non-4:3