from glad.lang.common.loader import BaseLoader from glad.lang.c.loader import LOAD_OPENGL_DLL, LOAD_OPENGL_DLL_H, LOAD_OPENGL_GLAPI_H _OPENGL_LOADER = \ LOAD_OPENGL_DLL % {'pre':'static', 'init':'open_gl', 'proc':'get_proc', 'terminate':'close_gl'} + ''' int gladLoadGL(void) { int status = 0; if(open_gl()) { status = gladLoadGLLoader(&get_proc); close_gl(); } return status; } ''' _OPENGL_HAS_EXT = ''' struct gladGLversionStruct GLVersion; #if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) #define _GLAD_IS_SOME_NEW_VERSION 1 #endif static int max_loaded_major; static int max_loaded_minor; static const char *exts = NULL; static int num_exts_i = 0; static const char **exts_i = NULL; static int get_exts(void) { #ifdef _GLAD_IS_SOME_NEW_VERSION if(max_loaded_major < 3) { #endif exts = (const char *)glGetString(GL_EXTENSIONS); #ifdef _GLAD_IS_SOME_NEW_VERSION } else { unsigned int index; num_exts_i = 0; glGetIntegerv(GL_NUM_EXTENSIONS, &num_exts_i); if (num_exts_i > 0) { exts_i = (const char **)realloc((void *)exts_i, (size_t)num_exts_i * (sizeof *exts_i)); } if (exts_i == NULL) { return 0; } for(index = 0; index < (unsigned)num_exts_i; index++) { exts_i[index] = (const char*)glGetStringi(GL_EXTENSIONS, index); } } #endif return 1; } static void free_exts(void) { if (exts_i != NULL) { free(exts_i); exts_i = NULL; } } static int has_ext(const char *ext) { #ifdef _GLAD_IS_SOME_NEW_VERSION if(max_loaded_major < 3) { #endif const char *extensions; const char *loc; const char *terminator; extensions = exts; if(extensions == NULL || ext == NULL) { return 0; } while(1) { loc = strstr(extensions, ext); if(loc == NULL) { return 0; } terminator = loc + strlen(ext); if((loc == extensions || *(loc - 1) == ' ') && (*terminator == ' ' || *terminator == '\\0')) { return 1; } extensions = terminator; } #ifdef _GLAD_IS_SOME_NEW_VERSION } else { int index; for(index = 0; index < num_exts_i; index++) { const char *e = exts_i[index]; if(strcmp(e, ext) == 0) { return 1; } } } #endif return 0; } ''' _OPENGL_HEADER_START = ''' #ifndef __glad_h_ #define __glad_h_ ''' _OPENGL_HEADER_INCLUDE_ERROR = ''' #ifdef __{0}_h_ #error {1} header already included, remove this include, glad already provides it #endif #define __{0}_h_ ''' _OPENGL_HEADER = ''' #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif #include #endif #ifndef APIENTRY #define APIENTRY #endif #ifndef APIENTRYP #define APIENTRYP APIENTRY * #endif #ifdef __cplusplus extern "C" { #endif struct gladGLversionStruct { int major; int minor; }; typedef void* (* GLADloadproc)(const char *name); ''' + LOAD_OPENGL_GLAPI_H + ''' GLAPI struct gladGLversionStruct GLVersion; ''' _OPENGL_HEADER_LOADER = ''' GLAPI int gladLoadGL(void); ''' + LOAD_OPENGL_DLL_H _OPENGL_HEADER_END = ''' #ifdef __cplusplus } #endif #endif ''' _FIND_VERSION = ''' /* Thank you @elmindreda * https://github.com/elmindreda/greg/blob/master/templates/greg.c.in#L176 * https://github.com/glfw/glfw/blob/master/src/context.c#L36 */ int i, major, minor; const char* version; const char* prefixes[] = { "OpenGL ES-CM ", "OpenGL ES-CL ", "OpenGL ES ", NULL }; version = (const char*) glGetString(GL_VERSION); if (!version) return; for (i = 0; prefixes[i]; i++) { const size_t length = strlen(prefixes[i]); if (strncmp(version, prefixes[i], length) == 0) { version += length; break; } } /* PR #18 */ #ifdef _MSC_VER sscanf_s(version, "%d.%d", &major, &minor); #else sscanf(version, "%d.%d", &major, &minor); #endif GLVersion.major = major; GLVersion.minor = minor; max_loaded_major = major; max_loaded_minor = minor; ''' class OpenGLCLoader(BaseLoader): def write(self, fobj): if not self.disabled and 'gl' in self.apis: fobj.write(_OPENGL_LOADER) def write_begin_load(self, fobj): fobj.write('\tGLVersion.major = 0; GLVersion.minor = 0;\n') fobj.write('\tglGetString = (PFNGLGETSTRINGPROC)load("glGetString");\n') fobj.write('\tif(glGetString == NULL) return 0;\n') fobj.write('\tif(glGetString(GL_VERSION) == NULL) return 0;\n') def write_end_load(self, fobj): fobj.write('\treturn GLVersion.major != 0 || GLVersion.minor != 0;\n') def write_find_core(self, fobj): fobj.write(_FIND_VERSION) def write_find_core_end(self, fobj): fobj.write(_FIND_VERSION) def write_has_ext(self, fobj): fobj.write(_OPENGL_HAS_EXT) def write_header(self, fobj): fobj.write(_OPENGL_HEADER_START) written = set() for api, hname, name in [ ('gl', 'gl', 'OpenGL'), ('gles1', 'gl', 'OpenGL ES 1'), ('gles2', 'gl2', 'OpenGL ES 2'), ('gles2', 'gl3', 'OpenGL ES 3') ]: if api in self.apis and hname not in written: fobj.write(_OPENGL_HEADER_INCLUDE_ERROR.format(hname, name)) written.add(hname) fobj.write(_OPENGL_HEADER) if not self.disabled and 'gl' in self.apis: fobj.write(_OPENGL_HEADER_LOADER) def write_header_end(self, fobj): fobj.write(_OPENGL_HEADER_END)