]> git.tdb.fi Git - libs/gl.git/blob - source/extension.cpp
Refactor version number extraction and checks
[libs/gl.git] / source / extension.cpp
1 #include <set>
2 #if !defined(WIN32) && !defined(__APPLE__)
3 #define GLX_GLXEXT_PROTOTYPES
4 #include <GL/glx.h>
5 #endif
6 #include <msp/strings/format.h>
7 #include <msp/strings/utils.h>
8 #include "error.h"
9 #include "extension.h"
10 #include "gl.h"
11
12 using namespace std;
13
14 namespace Msp {
15 namespace GL {
16
17 Version::Version()
18 {
19         major = 0;
20         minor = 0;
21 }
22
23 Version::Version(unsigned short a, unsigned short i)
24 {
25         major = a;
26         minor = i;
27 }
28
29 Version::Version(const string &s)
30 {
31         vector<string> parts = split(s, '.');
32         major = lexical_cast<unsigned>(parts[0]);
33         minor = lexical_cast<unsigned>(parts[1]);
34 }
35
36 bool Version::operator>=(const Version &other) const
37 {
38         return major>other.major || (major==other.major && minor>=other.minor);
39 }
40
41
42 Extension::Extension(const char *n, InitFunc f):
43         name(n),
44         init_func(f),
45         init_done(false),
46         support(UNSUPPORTED)
47 { }
48
49 Extension::operator bool() const
50 {
51         if(!init_done)
52         {
53                 support = init_func();
54                 init_done = true;
55         }
56
57         return support>UNSUPPORTED;
58 }
59
60
61 Require::Require(const Extension &ext)
62 {
63         if(!ext)
64                 throw unsupported_extension(ext.get_name());
65 }
66
67
68 bool is_supported(const string &ext)
69 {
70         static set<string> extensions;
71         static bool init_done = false;
72
73         if(!init_done)
74         {
75                 if(const char *gl_ext = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)))
76                 {
77                         vector<string> exts = split(gl_ext);
78                         extensions.insert(exts.begin(), exts.end());
79                 }
80
81                 string renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
82                 if(renderer.find("Radeon")!=string::npos)
83                         /* Radeon doesn't process NV_primitive_restart correctly and treats
84                         the restart index as a normal element if the indices are stored in a
85                         buffer. */
86                         extensions.erase("GL_NV_primitive_restart");
87
88                 init_done = true;
89         }
90
91         return extensions.count(ext);
92 }
93
94 inline Version _get_gl_version()
95 {
96         string gl_ver = reinterpret_cast<const char *>(glGetString(GL_VERSION));
97         return Version(gl_ver.substr(0, gl_ver.find(' ')));
98 }
99
100 const Version &get_gl_version()
101 {
102         static Version version = _get_gl_version();
103         return version;
104 }
105
106 bool is_version_at_least(unsigned a, unsigned b)
107 {
108         return get_gl_version()>=Version(a, b);
109 }
110
111 ExtFunc *get_proc_address(const string &name)
112 {
113 #if defined(WIN32)
114         return reinterpret_cast<ExtFunc *>(wglGetProcAddress(name.c_str()));
115 #elif defined(__APPLE__)
116         (void)name;
117         return 0;  // Not supported
118 #else
119         return glXGetProcAddressARB(reinterpret_cast<const unsigned char *>(name.c_str()));
120 #endif
121 }
122
123 } // namespace GL
124 } // namespace Msp