1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef WIN32
#include <windows.h>
#endif
#include "extensions.h"
#include "demolib_prefs.h"
#include "exception.h"
#include <GL/gl.h>
#if __linux__
#include <GL/glx.h>
extern "C" {
void (*glXGetProcAddressARB(const GLubyte *procName))();
}
#endif
bool GLExtensions::has_ext(const char *ext)
{
/*
* ATI drivers on Windows have known to be very buggy on this
* extension (unless my code is really fucked up, it could of
* course be), so disable it if we're using an ATI card :-)
*/
if (strcmp(ext, "GL_EXT_draw_range_elements") == 0) {
const char *vendor = (const char *)glGetString(GL_VENDOR);
if (vendor == NULL || strstr(vendor, "ATI ") != NULL) {
return false;
}
}
const char *extensions = (const char *)glGetString(GL_EXTENSIONS);
if (extensions == NULL) return false;
int extlen = strlen(ext);
const char *ptr = extensions;
while (ptr && *ptr) {
if (strncmp(ptr, ext, extlen) == 0 &&
(ptr[extlen] == ' ' || ptr[extlen] == '\0')) {
return true;
}
ptr = strchr(ptr, ' ');
if (ptr != NULL) ptr++;
}
return false;
}
void *GLExtensions::func_ptr(const char *function)
{
#if __linux__
void *ptr = (void *)glXGetProcAddressARB((GLubyte *)function);
#else
void *ptr = (void *)wglGetProcAddressARB(function);
#endif
/*
* Some OpenGL drivers (like the Kyro2 drivers on Linux) expose stuff
* like glDrawRangeElements but _not_ glDrawRangeElementsEXT, even
* though they advertise the extension. Thus, if getting an -EXT or
* -ARB function pointer fails (which it should _never_ do, since we
* always check for extension availability first), we simply try
* without the suffix before finally giving up.
*/
const char *suffix = function + strlen(function) - 3; /* ugly? ;-) */
if (ptr == NULL &&
(strcmp(suffix, "EXT") == 0 || strcmp(suffix, "ARB") == 0)) {
char *tmp = strdup(function);
tmp[strlen(tmp) - 3] = '\0';
#if __linux__
ptr = (void *)glXGetProcAddressARB((GLubyte *)tmp);
#else
ptr = (void *)wglGetProcAddressARB(tmp);
#endif
free(tmp);
}
if (ptr == NULL) {
throw new FatalException(function, "Not found in OpenGL libraries!");
}
return ptr;
}
|