1 #include "TREGLExtensions.h"
2 #include <TCFoundation/mystring.h>
3 #include <TCFoundation/TCUserDefaults.h>
4 // !!!WARNING!!!
5 // The following is kind of bad form, but I'm going to do it anyway. I'm
6 // including a header file from a library that is dependent on this library.
7 // This works fine, because I'm not using any classes in the other library,
8 // just #defines, but it is still very strange behavior.
9 #include <LDLib/LDUserDefaultsKeys.h>
10 #include <stdio.h>
11
12 #ifdef WIN32
13 #if defined(_MSC_VER) && _MSC_VER >= 1400 && defined(_DEBUG)
14 #define new DEBUG_CLIENTBLOCK
15 #endif // _DEBUG
16 #endif // WIN32
17
18 namespace TREGLExtensionsNS
19 {
20 #ifndef GL_GLEXT_PROTOTYPES
21 // GL_NV_vertex_array_range
22 PFNGLVERTEXARRAYRANGENVPROC glVertexArrayRangeNV = NULL;
23 // GL_EXT_multi_draw_arrays
24 PFNGLMULTIDRAWELEMENTSEXTPROC glMultiDrawElementsEXT = NULL;
25 // GL_ARB_vertex_buffer_object
26 PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL;
27 PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL;
28 PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL;
29 PFNGLISBUFFERARBPROC glIsBufferARB = NULL;
30 PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL;
31 PFNGLBUFFERSUBDATAARBPROC glBufferSubDataARB = NULL;
32 PFNGLGETBUFFERSUBDATAARBPROC glGetBufferSubDataARB = NULL;
33 PFNGLMAPBUFFERARBPROC glMapBufferARB = NULL;
34 PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = NULL;
35 PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB = NULL;
36 PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB = NULL;
37 // GL_ARB_occlusion_query
38 PFNGLGENQUERIESARBPROC glGenQueriesARB = NULL;
39 PFNGLDELETEQUERIESARBPROC glDeleteQueriesARB = NULL;
40 PFNGLISQUERYARBPROC glIsQueryARB = NULL;
41 PFNGLBEGINQUERYARBPROC glBeginQueryARB = NULL;
42 PFNGLENDQUERYARBPROC glEndQueryARB = NULL;
43 PFNGLGETQUERYIVARBPROC glGetQueryivARB = NULL;
44 PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB = NULL;
45 PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB = NULL;
46 // GL_EXT_framebuffer_object
47 PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT = NULL;
48 PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT = NULL;
49 PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT = NULL;
50 PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT = NULL;
51 PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT = NULL;
52 PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC
53 glGetRenderbufferParameterivEXT = NULL;
54 PFNGLISFRAMEBUFFEREXTPROC glIsFramebufferEXT = NULL;
55 PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT = NULL;
56 PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT = NULL;
57 PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT = NULL;
58 PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT = NULL;
59 PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glFramebufferTexture1DEXT = NULL;
60 PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT = NULL;
61 PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT = NULL;
62 PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT = NULL;
63 PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC
64 glGetFramebufferAttachmentParameterivEXT = NULL;
65 PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT = NULL;
66 #endif // GL_GLEXT_PROTOTYPES
67
68 #ifdef WIN32
69 // WGL_EXT_pixel_format
70 PFNWGLGETPIXELFORMATATTRIBIVEXTPROC wglGetPixelFormatAttribivARB = NULL;
71 PFNWGLGETPIXELFORMATATTRIBFVEXTPROC wglGetPixelFormatAttribfvARB = NULL;
72 PFNWGLCHOOSEPIXELFORMATEXTPROC wglChoosePixelFormatARB = NULL;
73 // WGL_ARB_extensions_string
74 PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = NULL;
75 // WGL_ARB_pbuffer
76 PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = NULL;
77 PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = NULL;
78 PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = NULL;
79 PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = NULL;
80 PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = NULL;
81 #endif // WIN32
82 // WGL_NV_allocate_memory
83 PFNWGLALLOCATEMEMORYNVPROC wglAllocateMemoryNV = NULL;
84 PFNWGLFREEMEMORYNVPROC wglFreeMemoryNV = NULL;
85 }
86
87 // GL_NV_vertex_array_range
88 PFNGLVERTEXARRAYRANGENVPROC TREGLExtensions::sm_glVertexArrayRangeNV = NULL;
89 // GL_EXT_multi_draw_arrays
90 PFNGLMULTIDRAWELEMENTSEXTPROC TREGLExtensions::sm_glMultiDrawElementsEXT = NULL;
91 // GL_ARB_vertex_buffer_object
92 PFNGLBINDBUFFERARBPROC TREGLExtensions::sm_glBindBufferARB = NULL;
93 PFNGLDELETEBUFFERSARBPROC TREGLExtensions::sm_glDeleteBuffersARB = NULL;
94 PFNGLGENBUFFERSARBPROC TREGLExtensions::sm_glGenBuffersARB = NULL;
95 PFNGLISBUFFERARBPROC TREGLExtensions::sm_glIsBufferARB = NULL;
96 PFNGLBUFFERDATAARBPROC TREGLExtensions::sm_glBufferDataARB = NULL;
97 PFNGLBUFFERSUBDATAARBPROC TREGLExtensions::sm_glBufferSubDataARB = NULL;
98 PFNGLGETBUFFERSUBDATAARBPROC TREGLExtensions::sm_glGetBufferSubDataARB = NULL;
99 PFNGLMAPBUFFERARBPROC TREGLExtensions::sm_glMapBufferARB = NULL;
100 PFNGLUNMAPBUFFERARBPROC TREGLExtensions::sm_glUnmapBufferARB = NULL;
101 PFNGLGETBUFFERPARAMETERIVARBPROC TREGLExtensions::sm_glGetBufferParameterivARB =
102 NULL;
103 PFNGLGETBUFFERPOINTERVARBPROC TREGLExtensions::sm_glGetBufferPointervARB = NULL;
104 // GL_ARB_occlusion_query
105 PFNGLGENQUERIESARBPROC TREGLExtensions::sm_glGenQueriesARB = NULL;
106 PFNGLDELETEQUERIESARBPROC TREGLExtensions::sm_glDeleteQueriesARB = NULL;
107 PFNGLISQUERYARBPROC TREGLExtensions::sm_glIsQueryARB = NULL;
108 PFNGLBEGINQUERYARBPROC TREGLExtensions::sm_glBeginQueryARB = NULL;
109 PFNGLENDQUERYARBPROC TREGLExtensions::sm_glEndQueryARB = NULL;
110 PFNGLGETQUERYIVARBPROC TREGLExtensions::sm_glGetQueryivARB = NULL;
111 PFNGLGETQUERYOBJECTIVARBPROC TREGLExtensions::sm_glGetQueryObjectivARB = NULL;
112 PFNGLGETQUERYOBJECTUIVARBPROC TREGLExtensions::sm_glGetQueryObjectuivARB = NULL;
113 // GL_EXT_framebuffer_object
114 PFNGLISRENDERBUFFEREXTPROC TREGLExtensions::sm_glIsRenderbufferEXT = NULL;
115 PFNGLBINDRENDERBUFFEREXTPROC TREGLExtensions::sm_glBindRenderbufferEXT = NULL;
116 PFNGLDELETERENDERBUFFERSEXTPROC TREGLExtensions::sm_glDeleteRenderbuffersEXT =
117 NULL;
118 PFNGLGENRENDERBUFFERSEXTPROC TREGLExtensions::sm_glGenRenderbuffersEXT = NULL;
119 PFNGLRENDERBUFFERSTORAGEEXTPROC TREGLExtensions::sm_glRenderbufferStorageEXT =
120 NULL;
121 PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC
122 TREGLExtensions::sm_glGetRenderbufferParameterivEXT = NULL;
123 PFNGLISFRAMEBUFFEREXTPROC TREGLExtensions::sm_glIsFramebufferEXT = NULL;
124 PFNGLBINDFRAMEBUFFEREXTPROC TREGLExtensions::sm_glBindFramebufferEXT = NULL;
125 PFNGLDELETEFRAMEBUFFERSEXTPROC TREGLExtensions::sm_glDeleteFramebuffersEXT =
126 NULL;
127 PFNGLGENFRAMEBUFFERSEXTPROC TREGLExtensions::sm_glGenFramebuffersEXT = NULL;
128 PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC
129 TREGLExtensions::sm_glCheckFramebufferStatusEXT = NULL;
130 PFNGLFRAMEBUFFERTEXTURE1DEXTPROC TREGLExtensions::sm_glFramebufferTexture1DEXT =
131 NULL;
132 PFNGLFRAMEBUFFERTEXTURE2DEXTPROC TREGLExtensions::sm_glFramebufferTexture2DEXT =
133 NULL;
134 PFNGLFRAMEBUFFERTEXTURE3DEXTPROC TREGLExtensions::sm_glFramebufferTexture3DEXT =
135 NULL;
136 PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC
137 TREGLExtensions::sm_glFramebufferRenderbufferEXT = NULL;
138 PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC
139 TREGLExtensions::sm_glGetFramebufferAttachmentParameterivEXT = NULL;
140 PFNGLGENERATEMIPMAPEXTPROC TREGLExtensions::sm_glGenerateMipmapEXT = NULL;
141
142
143 StringSet TREGLExtensions::sm_glExtensions;
144 GLfloat TREGLExtensions::sm_maxAnisoLevel = 1.0f;
145 bool TREGLExtensions::sm_rendererIsMesa = false;
146 bool TREGLExtensions::sm_tempDisable = false;
147 std::string TREGLExtensions::sm_version;
148 int TREGLExtensions::sm_versionMaj = -1;
149 int TREGLExtensions::sm_versionMin = -1;
150
151 TREGLExtensions::TREGLExtensionsCleanup TREGLExtensions::sm_extensionsCleanup;
152
153 #ifdef WIN32
154 #define GET_EXTENSION(name) wglGetProcAddress(#name)
155 #else
156 #define GET_EXTENSION(name) (name)
157 #endif
158
~TREGLExtensionsCleanup(void)159 TREGLExtensions::TREGLExtensionsCleanup::~TREGLExtensionsCleanup(void)
160 {
161 TREGLExtensions::cleanup();
162 }
163
disableAll(bool disable)164 void TREGLExtensions::disableAll(bool disable)
165 {
166 sm_tempDisable = disable;
167 }
168
cleanup(void)169 void TREGLExtensions::cleanup(void)
170 {
171 sm_glExtensions.clear();
172 }
173
initExtensions(StringSet & extensions,const char * extensionsString)174 void TREGLExtensions::initExtensions(
175 StringSet &extensions,
176 const char *extensionsString)
177 {
178 int count;
179 char **components = componentsSeparatedByString(extensionsString, " ",
180 count);
181
182 for (int i = 0; i < count; i++)
183 {
184 extensions.insert(components[i]);
185 }
186 deleteStringArray(components, count);
187 }
188
setup(void)189 void TREGLExtensions::setup(void)
190 {
191 cleanup();
192 sm_version = (const char *)glGetString(GL_VERSION);
193 if (sscanf(sm_version.c_str(), "%d.%d", &sm_versionMaj, &sm_versionMin) !=
194 2)
195 {
196 sm_versionMaj = -1;
197 sm_versionMin = -1;
198 }
199 initExtensions(sm_glExtensions, (const char*)glGetString(GL_EXTENSIONS));
200 // Note that when we load the function pointers, don't want to pay
201 // attention to any ignore flags in the registry, so all the checks for
202 // extensions have the force flag set to true. Otherwise, if the
203 // program starts with the ignore flag set, and it later gets cleared,
204 // the function pointers won't be loaded.
205 if (haveVARExtension(true))
206 {
207 #ifdef WIN32
208 // NOTE: I should really change the __APPLE__ path to do their
209 // equivalent of wglGetProcAddress. However, since this extension won't
210 // work anyway without a bunch of glX stuff that I'm not going to do,
211 // I'm not going to make that change just for this.
212 sm_glVertexArrayRangeNV = (PFNGLVERTEXARRAYRANGENVPROC)
213 GET_EXTENSION(glVertexArrayRangeNV);
214 #endif // WIN32
215 }
216 const char *renderer = (const char *)glGetString(GL_RENDERER);
217 if (stringHasCaseInsensitivePrefix(renderer, "Mesa "))
218 {
219 sm_rendererIsMesa = true;
220 }
221 if (haveMultiDrawArraysExtension(true))
222 {
223 sm_glMultiDrawElementsEXT = (PFNGLMULTIDRAWELEMENTSEXTPROC)
224 GET_EXTENSION(glMultiDrawElementsEXT);
225 }
226 if (haveVBOExtension(true))
227 {
228 sm_glBindBufferARB = (PFNGLBINDBUFFERARBPROC)
229 GET_EXTENSION(glBindBufferARB);
230 sm_glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)
231 GET_EXTENSION(glDeleteBuffersARB);
232 sm_glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)
233 GET_EXTENSION(glGenBuffersARB);
234 sm_glIsBufferARB = (PFNGLISBUFFERARBPROC)
235 GET_EXTENSION(glIsBufferARB);
236 sm_glBufferDataARB = (PFNGLBUFFERDATAARBPROC)
237 GET_EXTENSION(glBufferDataARB);
238 sm_glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)
239 GET_EXTENSION(glBufferSubDataARB);
240 sm_glGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)
241 GET_EXTENSION(glGetBufferSubDataARB);
242 sm_glMapBufferARB = (PFNGLMAPBUFFERARBPROC)
243 GET_EXTENSION(glMapBufferARB);
244 sm_glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)
245 GET_EXTENSION(glUnmapBufferARB);
246 sm_glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)
247 GET_EXTENSION(glGetBufferParameterivARB);
248 sm_glGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)
249 GET_EXTENSION(glGetBufferPointervARB);
250 }
251 if (haveOcclusionQueryExtension(true))
252 {
253 sm_glGenQueriesARB = (PFNGLGENQUERIESARBPROC)
254 GET_EXTENSION(glGenQueriesARB);
255 sm_glDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC)
256 GET_EXTENSION(glDeleteQueriesARB);
257 sm_glIsQueryARB = (PFNGLISQUERYARBPROC)
258 GET_EXTENSION(glIsQueryARB);
259 sm_glBeginQueryARB = (PFNGLBEGINQUERYARBPROC)
260 GET_EXTENSION(glBeginQueryARB);
261 sm_glEndQueryARB = (PFNGLENDQUERYARBPROC)
262 GET_EXTENSION(glEndQueryARB);
263 sm_glGetQueryivARB = (PFNGLGETQUERYIVARBPROC)
264 GET_EXTENSION(glGetQueryivARB);
265 sm_glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)
266 GET_EXTENSION(glGetQueryObjectivARB);
267 sm_glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)
268 GET_EXTENSION(glGetQueryObjectuivARB);
269 }
270 if (haveAnisoExtension(true))
271 {
272 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &sm_maxAnisoLevel);
273 }
274 else
275 {
276 sm_maxAnisoLevel = 1.0f;
277 }
278 if (haveFramebufferObjectExtension(true))
279 {
280 sm_glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC)
281 GET_EXTENSION(glIsRenderbufferEXT);
282 sm_glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)
283 GET_EXTENSION(glBindRenderbufferEXT);
284 sm_glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)
285 GET_EXTENSION(glDeleteRenderbuffersEXT);
286 sm_glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)
287 GET_EXTENSION(glGenRenderbuffersEXT);
288 sm_glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)
289 GET_EXTENSION(glRenderbufferStorageEXT);
290 sm_glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)
291 GET_EXTENSION(glGetRenderbufferParameterivEXT);
292 sm_glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC)
293 GET_EXTENSION(glIsFramebufferEXT);
294 sm_glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)
295 GET_EXTENSION(glBindFramebufferEXT);
296 sm_glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)
297 GET_EXTENSION(glDeleteFramebuffersEXT);
298 sm_glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)
299 GET_EXTENSION(glGenFramebuffersEXT);
300 sm_glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
301 GET_EXTENSION(glCheckFramebufferStatusEXT);
302 sm_glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)
303 GET_EXTENSION(glFramebufferTexture1DEXT);
304 sm_glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
305 GET_EXTENSION(glFramebufferTexture2DEXT);
306 sm_glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)
307 GET_EXTENSION(glFramebufferTexture3DEXT);
308 sm_glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)
309 GET_EXTENSION(glFramebufferRenderbufferEXT);
310 sm_glGetFramebufferAttachmentParameterivEXT =
311 (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)
312 GET_EXTENSION(glGetFramebufferAttachmentParameterivEXT);
313 sm_glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC)
314 GET_EXTENSION(glGenerateMipmapEXT);
315 }
316 #ifndef GL_GLEXT_PROTOTYPES
317 using namespace TREGLExtensionsNS;
318 glVertexArrayRangeNV = sm_glVertexArrayRangeNV;
319 // GL_EXT_multi_draw_arrays
320 glMultiDrawElementsEXT = sm_glMultiDrawElementsEXT;
321 // GL_ARB_vertex_buffer_object
322 glBindBufferARB = sm_glBindBufferARB;
323 glDeleteBuffersARB = sm_glDeleteBuffersARB;
324 glGenBuffersARB = sm_glGenBuffersARB;
325 glIsBufferARB = sm_glIsBufferARB;
326 glBufferDataARB = sm_glBufferDataARB;
327 glBufferSubDataARB = sm_glBufferSubDataARB;
328 glGetBufferSubDataARB = sm_glGetBufferSubDataARB;
329 glMapBufferARB = sm_glMapBufferARB;
330 glUnmapBufferARB = sm_glUnmapBufferARB;
331 glGetBufferParameterivARB = sm_glGetBufferParameterivARB;
332 glGetBufferPointervARB = sm_glGetBufferPointervARB;
333 // GL_ARB_occlusion_query
334 glGenQueriesARB = sm_glGenQueriesARB;
335 glDeleteQueriesARB = sm_glDeleteQueriesARB;
336 glIsQueryARB = sm_glIsQueryARB;
337 glBeginQueryARB = sm_glBeginQueryARB;
338 glEndQueryARB = sm_glEndQueryARB;
339 glGetQueryivARB = sm_glGetQueryivARB;
340 glGetQueryObjectivARB = sm_glGetQueryObjectivARB;
341 glGetQueryObjectuivARB = sm_glGetQueryObjectuivARB;
342 // GL_EXT_framebuffer_object
343 glIsRenderbufferEXT = sm_glIsRenderbufferEXT;
344 glBindRenderbufferEXT = sm_glBindRenderbufferEXT;
345 glDeleteRenderbuffersEXT = sm_glDeleteRenderbuffersEXT;
346 glGenRenderbuffersEXT = sm_glGenRenderbuffersEXT;
347 glRenderbufferStorageEXT = sm_glRenderbufferStorageEXT;
348 glGetRenderbufferParameterivEXT = sm_glGetRenderbufferParameterivEXT;
349 glIsFramebufferEXT = sm_glIsFramebufferEXT;
350 glBindFramebufferEXT = sm_glBindFramebufferEXT;
351 glDeleteFramebuffersEXT = sm_glDeleteFramebuffersEXT;
352 glGenFramebuffersEXT = sm_glGenFramebuffersEXT;
353 glCheckFramebufferStatusEXT = sm_glCheckFramebufferStatusEXT;
354 glFramebufferTexture1DEXT = sm_glFramebufferTexture1DEXT;
355 glFramebufferTexture2DEXT = sm_glFramebufferTexture2DEXT;
356 glFramebufferTexture3DEXT = sm_glFramebufferTexture3DEXT;
357 glFramebufferRenderbufferEXT = sm_glFramebufferRenderbufferEXT;
358 glGetFramebufferAttachmentParameterivEXT =
359 sm_glGetFramebufferAttachmentParameterivEXT;
360 glGenerateMipmapEXT = sm_glGenerateMipmapEXT;
361 #endif // GL_GLEXT_PROTOTYPES
362 #ifdef WIN32
363 using namespace TREGLExtensionsNS;
364 if (haveVARExtension(true))
365 {
366 wglAllocateMemoryNV = (PFNWGLALLOCATEMEMORYNVPROC)
367 wglGetProcAddress("wglAllocateMemoryNV");
368 wglFreeMemoryNV = (PFNWGLFREEMEMORYNVPROC)
369 wglGetProcAddress("wglFreeMemoryNV");
370 }
371 #endif // WIN32
372 }
373
haveNvMultisampleFilterHintExtension(bool force)374 bool TREGLExtensions::haveNvMultisampleFilterHintExtension(bool force)
375 {
376 bool ignore = TCUserDefaults::boolForKey(IGNORE_MS_FILTER_HINT_KEY, false,
377 false);
378
379 return (!ignore || force) &&
380 checkForExtension("GL_NV_multisample_filter_hint", force);
381 }
382
haveVARExtension(bool force)383 bool TREGLExtensions::haveVARExtension(bool force)
384 {
385 bool ignore = TCUserDefaults::boolForKey(IGNORE_VAR_KEY, false, false);
386
387 using namespace TREGLExtensionsNS;
388 return (!ignore || force) && checkForExtension("GL_NV_vertex_array_range",
389 force);// && wglAllocateMemoryNV != NULL && wglFreeMemoryNV != NULL;
390 }
391
haveMultiDrawArraysExtension(bool force)392 bool TREGLExtensions::haveMultiDrawArraysExtension(bool force)
393 {
394 if (sm_rendererIsMesa)
395 {
396 // This extension apparently sucks on Mesa. As near as I can tell, it
397 // won't work inside a display list.
398 return false;
399 }
400 #ifdef __APPLE__
401 int one = 1;
402 TCByte binary[] = {1,0,0,0};
403
404 if (one != *(int*)binary)
405 {
406 // Doesn't work on PPC Mac (at least in Rosetta). The above checks to
407 // see if the current architecture is big endian or little endian. If
408 // it's big endian (PPC), we'll get here.
409 return false;
410 }
411 #endif
412 bool ignore = TCUserDefaults::boolForKey(IGNORE_MULTI_DRAW_ARRAYS_KEY,
413 false, false);
414
415 return (!ignore || force) && checkForExtension("GL_EXT_multi_draw_arrays",
416 force);
417 }
418
haveOcclusionQueryExtension(bool force)419 bool TREGLExtensions::haveOcclusionQueryExtension(bool force)
420 {
421 bool ignore = TCUserDefaults::boolForKey(IGNORE_OCCLUSION_QUERY_KEY, false,
422 false);
423
424 return (!ignore || force) && checkForExtension("GL_ARB_occlusion_query",
425 force);
426 }
427
haveFramebufferObjectExtension(bool force)428 bool TREGLExtensions::haveFramebufferObjectExtension(bool force)
429 {
430 bool ignore = TCUserDefaults::boolForKey(IGNORE_FRAMEBUFFER_OBJECT_KEY,
431 false, false);
432
433 return (!ignore || force) && checkForExtension("GL_EXT_framebuffer_object",
434 force);
435 }
436
haveClampToBorderExtension(bool force)437 bool TREGLExtensions::haveClampToBorderExtension(bool force)
438 {
439 bool ignore = TCUserDefaults::boolForKey(IGNORE_CLAMP_TO_BORDER, false,
440 false);
441
442 return (!ignore || force) && checkForOGLVersion(1, 3, force);
443 }
444
haveAnisoExtension(bool force)445 bool TREGLExtensions::haveAnisoExtension(bool force)
446 {
447 bool ignore = TCUserDefaults::boolForKey(IGNORE_ANISO_KEY, false, false);
448
449 return (!ignore || force) &&
450 checkForExtension("GL_EXT_texture_filter_anisotropic", force);
451 }
452
haveVBOExtension(bool force)453 bool TREGLExtensions::haveVBOExtension(bool force)
454 {
455 bool ignore = TCUserDefaults::boolForKey(IGNORE_VBO_KEY, false, false);
456
457 return (!ignore || force) &&
458 checkForExtension("GL_ARB_vertex_buffer_object", force);
459 }
460
checkForExtension(const StringSet & extensions,const char * extension,bool force)461 bool TREGLExtensions::checkForExtension(
462 const StringSet &extensions,
463 const char* extension,
464 bool force)
465 {
466 bool ignore = TCUserDefaults::boolForKey(IGNORE_ALL_OGL_EXTENSIONS, false,
467 false) || sm_tempDisable;
468
469 if (!ignore || force)
470 {
471 return extensions.find(extension) != extensions.end();
472 }
473 return false;
474 }
475
checkForExtension(const char * extension,bool force)476 bool TREGLExtensions::checkForExtension(const char* extension, bool force)
477 {
478 return checkForExtension(sm_glExtensions, extension, force);
479 }
480
checkForOGLVersion(int major,int minor,bool force)481 bool TREGLExtensions::checkForOGLVersion(
482 int major,
483 int minor,
484 bool force /*= false*/)
485 {
486 bool ignore = TCUserDefaults::boolForKey(IGNORE_ALL_OGL_EXTENSIONS, false,
487 false) || sm_tempDisable;
488
489 if (!ignore || force)
490 {
491 return sm_versionMaj > major ||
492 (sm_versionMaj == major && sm_versionMin >= minor);
493 }
494 return false;
495 }
496
getMaxAnisoLevel(void)497 GLfloat TREGLExtensions::getMaxAnisoLevel(void)
498 {
499 if (haveAnisoExtension())
500 {
501 return sm_maxAnisoLevel;
502 }
503 else
504 {
505 return 1.0f;
506 }
507 }
508