source: GTP/branches/IllumWPdeliver2008dec/IlluminationWP/demos/Standalone/Hierarchical Systems Demo [OpenGL]/RESOURCES/include/glh/glh_extensions.h @ 3255

Revision 3255, 8.4 KB checked in by szirmay, 15 years ago (diff)
Line 
1// Comments:
2//
3//   The trick with GLH_EXT_SINGLE_FILE is that you need to have it defined in
4// exactly one cpp file because it piggy-backs the function implementations in
5// the header.  You don't want multiple implementations defined or the linker
6// gets mad, but one file must have the implementations in it or the linker
7// gets mad for different reasons.
8//
9//   The goal was to avoid having this helper require a separate cpp file.  One
10// thing you could do is just have a glh_extensions.cpp that did
11//
12// #define GLH_EXT_SINGLE_FILE
13// #include <glh_extensions.h>
14//
15// and make it the only file that ever defines GLH_EXT_SINGLE_FILE.
16
17#ifndef GLH_EXTENSIONS
18#define GLH_EXTENSIONS
19
20#include <string.h>
21#include <stdio.h>
22#include <stdlib.h>
23
24#if defined(WIN32)
25# include <windows.h>
26#endif
27
28#ifdef MACOS
29#include <OpenGL/gl.h>
30#else
31#include <GL/gl.h>
32#endif
33
34#ifdef WIN32
35# include <GL/wglext.h>
36#endif
37
38#define CHECK_MEMORY(ptr) \
39    if (NULL == ptr) { \
40        printf("Error allocating memory in file %s, line %d\n", __FILE__, __LINE__); \
41        exit(-1); \
42    }
43
44#ifdef GLH_EXT_SINGLE_FILE
45#  define GLH_EXTENSIONS_SINGLE_FILE  // have to do this because glh_genext.h unsets GLH_EXT_SINGLE_FILE
46#endif
47
48#if (defined(WIN32) || defined(UNIX))
49#include "glh_genext.h"
50#elif defined(MACOS)
51#include <OpenGL/glext.h>
52#else
53#include <GL/glext.h>
54#endif
55
56#ifdef __cplusplus
57extern "C" {
58#endif
59
60#ifdef GLH_EXTENSIONS_SINGLE_FILE
61static char *unsupportedExts = NULL;
62static char *sysExts = NULL;
63#ifndef GL_SHADER_CONSISTENT_NV
64#define GL_SHADER_CONSISTENT_NV           0x86DD
65#endif
66#ifndef GL_TEXTURE_SHADER_NV
67#define GL_TEXTURE_SHADER_NV              0x86DE
68#endif
69#ifndef GL_SHADER_OPERATION_NV
70#define GL_SHADER_OPERATION_NV            0x86DF
71#endif
72
73static int ExtensionExists(const char* extName, const char* sysExts)
74{
75    char *padExtName = (char*)malloc(strlen(extName) + 2);
76    strcat(strcpy(padExtName, extName), " ");
77
78    if (0 == strcmp(extName, "GL_VERSION_1_2")) {
79        const char *version = (const char*)glGetString(GL_VERSION);
80        if (strstr(version, "1.0") == version || strstr(version, "1.1") == version) {
81            return GL_FALSE;
82        } else {
83            return GL_TRUE;
84        }
85    }
86    if (0 == strcmp(extName, "GL_VERSION_1_3")) {
87        const char *version = (const char*)glGetString(GL_VERSION);
88        if (strstr(version, "1.0") == version ||
89            strstr(version, "1.1") == version ||
90            strstr(version, "1.2") == version) {
91            return GL_FALSE;
92        } else {
93            return GL_TRUE;
94        }
95    }
96    if (0 == strcmp(extName, "GL_VERSION_1_4")) {
97        const char *version = (const char*)glGetString(GL_VERSION);
98        if (strstr(version, "1.0") == version ||
99            strstr(version, "1.1") == version ||
100            strstr(version, "1.2") == version ||
101            strstr(version, "1.3") == version) {
102            return GL_FALSE;
103        } else {
104            return GL_TRUE;
105        }
106    }
107    if (0 == strcmp(extName, "GL_VERSION_1_5")) {
108        const char *version = (const char*)glGetString(GL_VERSION);
109        if (strstr(version, "1.0") == version ||
110            strstr(version, "1.1") == version ||
111            strstr(version, "1.2") == version ||
112            strstr(version, "1.3") == version ||
113            strstr(version, "1.4") == version) {
114            return GL_FALSE;
115        } else {
116            return GL_TRUE;
117        }
118    }
119    if (strstr(sysExts, padExtName)) {
120        free(padExtName);
121        return GL_TRUE;
122    } else {
123        free(padExtName);
124        return GL_FALSE;
125    }
126}
127
128static const char* EatWhiteSpace(const char *str)
129{
130    for (; *str && (' ' == *str || '\t' == *str || '\n' == *str); str++);
131    return str;
132}
133
134static const char* EatNonWhiteSpace(const char *str)
135{
136    for (; *str && (' ' != *str && '\t' != *str && '\n' != *str); str++);
137    return str;
138}
139
140int glh_init_extensions(const char *origReqExts)
141{
142    // Length of requested extensions string
143    size_t reqExtsLen;
144    char *reqExts;
145    // Ptr for individual extensions within reqExts
146    char *reqExt;
147    int success = GL_TRUE;
148    // build space-padded extension string
149    if (NULL == sysExts) {
150        const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
151        size_t sysExtsLen = strlen(extensions);
152        const char *winsys_extensions = "";     
153        size_t winsysExtsLen = 0;
154#if defined(WIN32)
155        {
156            PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 0;
157            wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
158            if(wglGetExtensionsStringARB)
159            {
160                winsys_extensions = wglGetExtensionsStringARB(wglGetCurrentDC());
161                winsysExtsLen = strlen(winsys_extensions);
162            }
163        }
164#elif defined(UNIX)
165        {
166
167          winsys_extensions = glXQueryExtensionsString (glXGetCurrentDisplay(),DefaultScreen(glXGetCurrentDisplay())) ;
168          winsysExtsLen = strlen (winsys_extensions);
169        }
170#endif
171        // Add 2 bytes, one for padding space, one for terminating NULL
172        sysExts = (char*)malloc(sysExtsLen + winsysExtsLen + 3);
173        CHECK_MEMORY(sysExts);
174        strcpy(sysExts, extensions);
175        sysExts[sysExtsLen] = ' ';
176        sysExts[sysExtsLen + 1] = 0;
177        strcat(sysExts, winsys_extensions);
178        sysExts[sysExtsLen + 1 + winsysExtsLen] = ' ';
179        sysExts[sysExtsLen + 1 + winsysExtsLen + 1] = 0;
180    }
181
182    if (NULL == origReqExts)
183        return GL_TRUE;
184    reqExts = strdup(origReqExts);
185    reqExtsLen = strlen(reqExts);
186    if (NULL == unsupportedExts) {
187        unsupportedExts = (char*)malloc(reqExtsLen + 2);
188    } else if (reqExtsLen > strlen(unsupportedExts)) {
189        unsupportedExts = (char*)realloc(unsupportedExts, reqExtsLen + 2);
190    }
191    CHECK_MEMORY(unsupportedExts);
192    *unsupportedExts = 0;
193
194    // Parse requested extension list
195    for (reqExt = reqExts;
196        (reqExt = (char*)EatWhiteSpace(reqExt)) && *reqExt;
197        reqExt = (char*)EatNonWhiteSpace(reqExt))
198    {
199        char *extEnd = (char*)EatNonWhiteSpace(reqExt);
200        char saveChar = *extEnd;
201        *extEnd = (char)0;
202
203#if (defined(WIN32) || defined(UNIX))
204        if (!ExtensionExists(reqExt, sysExts) || !glh_init_extension(reqExt)) {
205#elif defined(MACOS)
206        if (!ExtensionExists(reqExt, sysExts)) {    // don't try to get function pointers if on MacOS
207#endif
208            // add reqExt to end of unsupportedExts
209            strcat(unsupportedExts, reqExt);
210            strcat(unsupportedExts, " ");
211            success = GL_FALSE;
212        }
213        *extEnd = saveChar;
214    }
215    free(reqExts);
216    return success;
217}
218
219const char* glh_get_unsupported_extensions()
220{
221    return (const char*)unsupportedExts;
222}
223
224void glh_shutdown_extensions()
225{
226    if (unsupportedExts)
227    {
228        free(unsupportedExts);
229        unsupportedExts = NULL;
230    }
231    if (sysExts)
232    {
233        free(sysExts);
234        sysExts = NULL;
235    }
236}
237
238int glh_extension_supported(const char *extension)
239{
240    static const GLubyte *extensions = NULL;
241    const GLubyte *start;
242    GLubyte *where, *terminator;
243   
244    // Extension names should not have spaces.
245    where = (GLubyte *) strchr(extension, ' ');
246    if (where || *extension == '\0')
247      return 0;
248   
249    if (!extensions)
250      extensions = glGetString(GL_EXTENSIONS);
251
252    // It takes a bit of care to be fool-proof about parsing the
253    // OpenGL extensions string.  Don't be fooled by sub-strings,
254    // etc.
255    start = extensions;
256    for (;;)
257    {
258        where = (GLubyte *) strstr((const char *) start, extension);
259        if (!where)
260            break;
261        terminator = where + strlen(extension);
262        if (where == start || *(where - 1) == ' ')
263        {
264            if (*terminator == ' ' || *terminator == '\0')
265            {
266                return 1;
267            }
268        }
269        start = terminator;
270    }
271    return 0;
272}
273
274#else
275int glh_init_extensions(const char *origReqExts);
276const char* glh_get_unsupported_extensions();
277void glh_shutdown_extensions();
278int glh_extension_supported(const char *extension);
279#endif /* GLH_EXT_SINGLE_FILE */
280
281#ifdef __cplusplus
282}
283#endif
284
285#endif /* GLH_EXTENSIONS */
Note: See TracBrowser for help on using the repository browser.