40 #pragma comment(lib, "opengl32.lib") 
   51 #define FUNC(ret, name, params) ret (GL_CALL_CONV *p##name) params; 
   52 #define FUNC2(ret, nameARB, nameCore, version, params) ret (GL_CALL_CONV *p##nameARB) params; 
   53 #define FUNC3(ret, nameARB, nameCore, version, params) ret (GL_CALL_CONV *p##nameCore) params; 
   61 static const char* 
exts = NULL;
 
   70     ENSURE(
exts && 
"call ogl_Init before using this function");
 
   83 #define MATCH(known_ext)\ 
   84     if(!strcmp(ext, #known_ext))\ 
   89         MATCH(GL_EXT_gpu_shader4);
 
   90         MATCH(GL_NV_conditional_render);
 
   91         MATCH(GL_ARB_color_buffer_float);
 
   92         MATCH(GL_ARB_depth_buffer_float);
 
   93         MATCH(GL_ARB_texture_float);
 
   94         MATCH(GL_EXT_packed_float);
 
   95         MATCH(GL_EXT_texture_shared_exponent);
 
   96         MATCH(GL_EXT_framebuffer_object);
 
   97         MATCH(GL_NV_half_float);
 
   98         MATCH(GL_ARB_half_float_pixel);
 
   99         MATCH(GL_EXT_framebuffer_multisample);
 
  100         MATCH(GL_EXT_framebuffer_blit);
 
  101         MATCH(GL_EXT_texture_integer);
 
  102         MATCH(GL_EXT_texture_array);
 
  103         MATCH(GL_EXT_packed_depth_stencil);
 
  104         MATCH(GL_EXT_draw_buffers2);
 
  105         MATCH(GL_EXT_texture_compression_rgtc);
 
  106         MATCH(GL_EXT_transform_feedback);
 
  107         MATCH(GL_APPLE_vertex_array_object);
 
  108         MATCH(GL_EXT_framebuffer_sRGB);
 
  112         MATCH(GL_ARB_pixel_buffer_object);
 
  113         MATCH(GL_EXT_texture_sRGB);
 
  117         MATCH(GL_ARB_shader_objects);
 
  118         MATCH(GL_ARB_vertex_shader);
 
  119         MATCH(GL_ARB_fragment_shader);
 
  120         MATCH(GL_ARB_shading_language_100);
 
  121         MATCH(GL_ARB_draw_buffers);
 
  122         MATCH(GL_ARB_texture_non_power_of_two);
 
  123         MATCH(GL_ARB_point_sprite);
 
  124         MATCH(GL_EXT_blend_equation_separate);
 
  128         MATCH(GL_ARB_vertex_buffer_object);
 
  129         MATCH(GL_ARB_occlusion_query);
 
  130         MATCH(GL_EXT_shadow_funcs);
 
  134         MATCH(GL_SGIS_generate_mipmap);
 
  135         MATCH(GL_NV_blend_square);
 
  136         MATCH(GL_ARB_depth_texture);
 
  137         MATCH(GL_ARB_shadow);
 
  138         MATCH(GL_EXT_fog_coord);
 
  139         MATCH(GL_EXT_multi_draw_arrays);
 
  140         MATCH(GL_ARB_point_parameters);
 
  141         MATCH(GL_EXT_secondary_color);
 
  142         MATCH(GL_EXT_blend_func_separate);
 
  143         MATCH(GL_EXT_stencil_wrap);
 
  144         MATCH(GL_ARB_texture_env_crossbar);
 
  145         MATCH(GL_EXT_texture_lod_bias);
 
  146         MATCH(GL_ARB_texture_mirrored_repeat);
 
  147         MATCH(GL_ARB_window_pos);
 
  151         MATCH(GL_EXT_blend_color);
 
  152         MATCH(GL_EXT_blend_minmax);
 
  153         MATCH(GL_EXT_blend_subtract);
 
  157         MATCH(GL_ARB_texture_compression);
 
  158         MATCH(GL_ARB_texture_cube_map);
 
  159         MATCH(GL_ARB_multisample);
 
  160         MATCH(GL_ARB_multitexture);
 
  161         MATCH(GL_ARB_transpose_matrix);
 
  162         MATCH(GL_ARB_texture_env_add);
 
  163         MATCH(GL_ARB_texture_env_combine);
 
  164         MATCH(GL_ARB_texture_env_dot3);
 
  165         MATCH(GL_ARB_texture_border_clamp);
 
  169         MATCH(GL_EXT_texture3D);
 
  171         MATCH(GL_EXT_packed_pixels);
 
  172         MATCH(GL_EXT_rescale_normal);
 
  173         MATCH(GL_EXT_separate_specular_color);
 
  174         MATCH(GL_SGIS_texture_edge_clamp);
 
  175         MATCH(GL_SGIS_texture_lod);
 
  176         MATCH(GL_EXT_draw_range_elements);
 
  189     ENSURE(
exts && 
"call ogl_Init before using this function");
 
  194     const char *p = 
exts, *end;
 
  197     if(!ext || ext[0] == 
'\0' || strchr(ext, 
' '))
 
  205         end = p + strlen(ext); 
 
  209         if((p == 
exts || p[-1] == 
' ') &&   
 
  210            (*end == 
' ' || *end == 
'\0'))   
 
  221     int desired_major, desired_minor;
 
  222     if(
sscanf_s(desired_version, 
"%d.%d", &desired_major, &desired_minor) != 2)
 
  232     const char* version = (
const char*)glGetString(GL_VERSION);
 
  235         (
sscanf_s(version, 
"%d.%d", &major, &minor) != 2 &&
 
  236          sscanf_s(version, 
"OpenGL ES %d.%d", &major, &minor) != 2))
 
  243     return (major > desired_major) ||
 
  244            (major == desired_major && minor >= desired_minor);
 
  271     va_start(args, dummy);
 
  274         ext = va_arg(args, 
const char*);
 
  304     glDrawElements(mode, count, type, indices);
 
  322     glTexCoord3f(s, t, r);
 
  343 #endif  // #if CONFIG2_GLES 
  355 #define FUNC(ret, name, params) p##name = (ret (GL_CALL_CONV*) params)SDL_GL_GetProcAddress(#name); 
  356 #define FUNC23(pname, ret, nameARB, nameCore, version, params) \ 
  358     if(ogl_HaveVersion(version)) \ 
  359         pname = (ret (GL_CALL_CONV*) params)SDL_GL_GetProcAddress(#nameCore); \ 
  361         pname = (ret (GL_CALL_CONV*) params)SDL_GL_GetProcAddress(#nameARB); 
  362 #define FUNC2(ret, nameARB, nameCore, version, params) FUNC23(p##nameARB, ret, nameARB, nameCore, version, params) 
  363 #define FUNC3(ret, nameARB, nameCore, version, params) FUNC23(p##nameCore, ret, nameARB, nameCore, version, params) 
  379 #define E(e) case e: debug_printf(L"%ls\n", WIDEN(#e)); break; 
  384     E(GL_INVALID_OPERATION)
 
  387     E(GL_STACK_UNDERFLOW)
 
  391     default: 
debug_printf(L
"Unknown GL error: %04x\n", err); 
break;
 
  396 #ifndef ogl_WarnIfError 
  402     bool error_enountered = 
false;
 
  403     GLenum first_error = 0;
 
  407         GLenum err = glGetError();
 
  408         if(err == GL_NO_ERROR)
 
  411         if(!error_enountered)
 
  414         error_enountered = 
true;
 
  419         debug_printf(L
"OpenGL error(s) occurred: %04x\n", (
unsigned int)first_error);
 
  434     bool error_enountered = 
false;
 
  435     bool error_ignored = 
false;
 
  436     GLenum first_error = 0;
 
  440         GLenum err = glGetError();
 
  441         if(err == GL_NO_ERROR)
 
  444         if(err == err_to_ignore)
 
  446             error_ignored = 
true;
 
  450         if(!error_enountered)
 
  453         error_enountered = 
true;
 
  458         debug_printf(L
"OpenGL error(s) occurred: %04x\n", (
unsigned int)first_error);
 
  460     return error_ignored;
 
  478     exts = (
const char*)glGetString(GL_EXTENSIONS);
 
static void GL_CALL_CONV dummy_glMultiTexCoord3fARB(int, float s, float t, float r)
static bool isImplementedInCore(const char *ext)
static void GL_CALL_CONV dummy_glClientActiveTextureARB(int)
static void importExtensionFunctions()
bool ogl_SquelchError(GLenum err_to_ignore)
ignore and reset the specified OpenGL error. 
bool ogl_HaveVersion(const char *desired_version)
make sure the OpenGL implementation version matches or is newer than the given version. 
static void enableDummyFunctions()
static void GL_CALL_CONV dummy_glActiveTextureARB(int)
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero. 
GLint ogl_max_tex_units
[pixels] 
const char * ogl_ExtensionString()
get a list of all supported extensions. 
static void dump_gl_error(GLenum err)
#define DEBUG_WARN_ERR(status)
display the error dialog with text corresponding to the given error code. 
bool ogl_HaveExtension(const char *ext)
check if an extension is supported by the OpenGL implementation. 
void ogl_Init()
initialization: import extension function pointers and do feature detect. 
#define GL_INVALID_FRAMEBUFFER_OPERATION
void ogl_WarnIfError()
raise a warning (break into the debugger) if an OpenGL error is pending. 
static void GL_CALL_CONV dummy_glMultiTexCoord2fARB(int, float s, float t)
void debug_printf(const wchar_t *fmt,...)
write a formatted string to the debug channel, subject to filtering (see below). 
static void GL_CALL_CONV dummy_glDrawRangeElementsEXT(GLenum mode, GLuint, GLuint, GLsizei count, GLenum type, GLvoid *indices)
const char * ogl_HaveExtensions(int dummy,...)
check if a list of extensions are all supported (as determined by ogl_HaveExtension).