Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef GLH_EXTENSIONS
00018 #define GLH_EXTENSIONS
00019
00020 #include <string.h>
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023
00024
00025 #if defined(WIN32)
00026 # include <windows.h>
00027 #endif
00028
00029 #if _MSC_VER > 1500
00030 # include <system_error>
00031 #endif
00032
00033 #ifdef MACOS
00034 #include <OpenGL/gl.h>
00035 #else
00036 #include <GL/gl.h>
00037 #endif
00038
00039 #ifdef WIN32
00040 # include <GL/wglext.h>
00041 #endif
00042
00043 #define CHECK_MEMORY(ptr) \
00044 if (NULL == ptr) { \
00045 printf("Error allocating memory in file %s, line %d\n", __FILE__, __LINE__); \
00046 exit(-1); \
00047 }
00048
00049 #ifdef GLH_EXT_SINGLE_FILE
00050 # define GLH_EXTENSIONS_SINGLE_FILE // have to do this because glh_genext.h unsets GLH_EXT_SINGLE_FILE
00051 #endif
00052
00053 #if (defined(WIN32) || defined(UNIX))
00054 #include "glh_genext.h"
00055 #elif defined(MACOS)
00056 #include <OpenGL/glext.h>
00057 #else
00058 #include <GL/glext.h>
00059 #endif
00060
00061 #ifdef __cplusplus
00062 extern "C" {
00063 #endif
00064
00065 #ifdef GLH_EXTENSIONS_SINGLE_FILE
00066 static char *unsupportedExts = NULL;
00067 static char *sysExts = NULL;
00068 #ifndef GL_SHADER_CONSISTENT_NV
00069 #define GL_SHADER_CONSISTENT_NV 0x86DD
00070 #endif
00071 #ifndef GL_TEXTURE_SHADER_NV
00072 #define GL_TEXTURE_SHADER_NV 0x86DE
00073 #endif
00074 #ifndef GL_SHADER_OPERATION_NV
00075 #define GL_SHADER_OPERATION_NV 0x86DF
00076 #endif
00077
00078 static int ExtensionExists(const char* extName, const char* sysExts)
00079 {
00080 char *padExtName = (char*)malloc(strlen(extName) + 2);
00081 strcat(strcpy(padExtName, extName), " ");
00082
00083 if (0 == strcmp(extName, "GL_VERSION_1_2")) {
00084 const char *version = (const char*)glGetString(GL_VERSION);
00085 if (strstr(version, "1.0") == version || strstr(version, "1.1") == version) {
00086 return GL_FALSE;
00087 } else {
00088 return GL_TRUE;
00089 }
00090 }
00091 if (0 == strcmp(extName, "GL_VERSION_1_3")) {
00092 const char *version = (const char*)glGetString(GL_VERSION);
00093 if (strstr(version, "1.0") == version ||
00094 strstr(version, "1.1") == version ||
00095 strstr(version, "1.2") == version) {
00096 return GL_FALSE;
00097 } else {
00098 return GL_TRUE;
00099 }
00100 }
00101 if (0 == strcmp(extName, "GL_VERSION_1_4")) {
00102 const char *version = (const char*)glGetString(GL_VERSION);
00103 if (strstr(version, "1.0") == version ||
00104 strstr(version, "1.1") == version ||
00105 strstr(version, "1.2") == version ||
00106 strstr(version, "1.3") == version) {
00107 return GL_FALSE;
00108 } else {
00109 return GL_TRUE;
00110 }
00111 }
00112 if (0 == strcmp(extName, "GL_VERSION_1_5")) {
00113 const char *version = (const char*)glGetString(GL_VERSION);
00114 if (strstr(version, "1.0") == version ||
00115 strstr(version, "1.1") == version ||
00116 strstr(version, "1.2") == version ||
00117 strstr(version, "1.3") == version ||
00118 strstr(version, "1.4") == version) {
00119 return GL_FALSE;
00120 } else {
00121 return GL_TRUE;
00122 }
00123 }
00124 if (strstr(sysExts, padExtName)) {
00125 free(padExtName);
00126 return GL_TRUE;
00127 } else {
00128 free(padExtName);
00129 return GL_FALSE;
00130 }
00131 }
00132
00133 static const char* EatWhiteSpace(const char *str)
00134 {
00135 for (; *str && (' ' == *str || '\t' == *str || '\n' == *str); str++);
00136 return str;
00137 }
00138
00139 static const char* EatNonWhiteSpace(const char *str)
00140 {
00141 for (; *str && (' ' != *str && '\t' != *str && '\n' != *str); str++);
00142 return str;
00143 }
00144
00145 int glh_init_extensions(const char *origReqExts)
00146 {
00147
00148 size_t reqExtsLen;
00149 char *reqExts;
00150
00151 char *reqExt;
00152 int success = GL_TRUE;
00153
00154 if (NULL == sysExts) {
00155 const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
00156 size_t sysExtsLen = strlen(extensions);
00157 const char *winsys_extensions = "";
00158 size_t winsysExtsLen = 0;
00159 #if defined(WIN32)
00160 {
00161 PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 0;
00162 wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
00163 if(wglGetExtensionsStringARB)
00164 {
00165 winsys_extensions = wglGetExtensionsStringARB(wglGetCurrentDC());
00166 winsysExtsLen = strlen(winsys_extensions);
00167 }
00168 }
00169 #elif defined(UNIX)
00170 {
00171
00172 winsys_extensions = glXQueryExtensionsString (glXGetCurrentDisplay(),DefaultScreen(glXGetCurrentDisplay())) ;
00173 winsysExtsLen = strlen (winsys_extensions);
00174 }
00175 #endif
00176
00177 sysExts = (char*)malloc(sysExtsLen + winsysExtsLen + 3);
00178 CHECK_MEMORY(sysExts);
00179 strcpy(sysExts, extensions);
00180 sysExts[sysExtsLen] = ' ';
00181 sysExts[sysExtsLen + 1] = 0;
00182 strcat(sysExts, winsys_extensions);
00183 sysExts[sysExtsLen + 1 + winsysExtsLen] = ' ';
00184 sysExts[sysExtsLen + 1 + winsysExtsLen + 1] = 0;
00185 }
00186
00187 if (NULL == origReqExts)
00188 return GL_TRUE;
00189 reqExts = strdup(origReqExts);
00190 reqExtsLen = strlen(reqExts);
00191 if (NULL == unsupportedExts) {
00192 unsupportedExts = (char*)malloc(reqExtsLen + 2);
00193 } else if (reqExtsLen > strlen(unsupportedExts)) {
00194 unsupportedExts = (char*)realloc(unsupportedExts, reqExtsLen + 2);
00195 }
00196 CHECK_MEMORY(unsupportedExts);
00197 *unsupportedExts = 0;
00198
00199
00200 for (reqExt = reqExts;
00201 (reqExt = (char*)EatWhiteSpace(reqExt)) && *reqExt;
00202 reqExt = (char*)EatNonWhiteSpace(reqExt))
00203 {
00204 char *extEnd = (char*)EatNonWhiteSpace(reqExt);
00205 char saveChar = *extEnd;
00206 *extEnd = (char)0;
00207
00208 #if (defined(WIN32) || defined(UNIX))
00209 if (!ExtensionExists(reqExt, sysExts) || !glh_init_extension(reqExt)) {
00210 #elif defined(MACOS)
00211 if (!ExtensionExists(reqExt, sysExts)) {
00212 #endif
00213
00214 strcat(unsupportedExts, reqExt);
00215 strcat(unsupportedExts, " ");
00216 success = GL_FALSE;
00217 }
00218 *extEnd = saveChar;
00219 }
00220 free(reqExts);
00221 return success;
00222 }
00223
00224 const char* glh_get_unsupported_extensions()
00225 {
00226 return (const char*)unsupportedExts;
00227 }
00228
00229 void glh_shutdown_extensions()
00230 {
00231 if (unsupportedExts)
00232 {
00233 free(unsupportedExts);
00234 unsupportedExts = NULL;
00235 }
00236 if (sysExts)
00237 {
00238 free(sysExts);
00239 sysExts = NULL;
00240 }
00241 }
00242
00243 int glh_extension_supported(const char *extension)
00244 {
00245 static const GLubyte *extensions = NULL;
00246 const GLubyte *start;
00247 GLubyte *where, *terminator;
00248
00249
00250 where = (GLubyte *) strchr(extension, ' ');
00251 if (where || *extension == '\0')
00252 return 0;
00253
00254 if (!extensions)
00255 extensions = glGetString(GL_EXTENSIONS);
00256
00257
00258
00259
00260 start = extensions;
00261 for (;;)
00262 {
00263 where = (GLubyte *) strstr((const char *) start, extension);
00264 if (!where)
00265 break;
00266 terminator = where + strlen(extension);
00267 if (where == start || *(where - 1) == ' ')
00268 {
00269 if (*terminator == ' ' || *terminator == '\0')
00270 {
00271 return 1;
00272 }
00273 }
00274 start = terminator;
00275 }
00276 return 0;
00277 }
00278
00279 #else
00280 int glh_init_extensions(const char *origReqExts);
00281 const char* glh_get_unsupported_extensions();
00282 void glh_shutdown_extensions();
00283 int glh_extension_supported(const char *extension);
00284 #endif
00285
00286 #ifdef __cplusplus
00287 }
00288 #endif
00289
00290 #endif