]> git.tdb.fi Git - libs/gl.git/blob - source/extension.cpp
Add function to check GLSL version
[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 inline Version _get_glsl_version()
107 {
108         string glsl_ver = reinterpret_cast<const char *>(glGetString(GL_SHADING_LANGUAGE_VERSION));
109         return Version(glsl_ver.substr(0, glsl_ver.find(' ')));
110 }
111
112 const Version &get_glsl_version()
113 {
114         static Version version = _get_glsl_version();
115         return version;
116 }
117
118 bool is_version_at_least(unsigned a, unsigned b)
119 {
120         return get_gl_version()>=Version(a, b);
121 }
122
123 ExtFunc *get_proc_address(const string &name)
124 {
125 #if defined(WIN32)
126         return reinterpret_cast<ExtFunc *>(wglGetProcAddress(name.c_str()));
127 #elif defined(__APPLE__)
128         (void)name;
129         return 0;  // Not supported
130 #else
131         return glXGetProcAddressARB(reinterpret_cast<const unsigned char *>(name.c_str()));
132 #endif
133 }
134
135 } // namespace GL
136 } // namespace Msp