Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 1 | //======================================================================== |
| 2 | // GLFW - An OpenGL framework |
| 3 | // Platform: Any |
Camilla Berglund | 38b0ccb | 2010-09-07 17:41:26 +0200 | [diff] [blame] | 4 | // API version: 3.0 |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 5 | // WWW: http://www.glfw.org/ |
| 6 | //------------------------------------------------------------------------ |
| 7 | // Copyright (c) 2002-2006 Marcus Geelnard |
| 8 | // Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> |
| 9 | // |
| 10 | // This software is provided 'as-is', without any express or implied |
| 11 | // warranty. In no event will the authors be held liable for any damages |
| 12 | // arising from the use of this software. |
| 13 | // |
| 14 | // Permission is granted to anyone to use this software for any purpose, |
| 15 | // including commercial applications, and to alter it and redistribute it |
| 16 | // freely, subject to the following restrictions: |
| 17 | // |
| 18 | // 1. The origin of this software must not be misrepresented; you must not |
| 19 | // claim that you wrote the original software. If you use this software |
| 20 | // in a product, an acknowledgment in the product documentation would |
| 21 | // be appreciated but is not required. |
| 22 | // |
| 23 | // 2. Altered source versions must be plainly marked as such, and must not |
| 24 | // be misrepresented as being the original software. |
| 25 | // |
| 26 | // 3. This notice may not be removed or altered from any source |
| 27 | // distribution. |
| 28 | // |
| 29 | //======================================================================== |
| 30 | |
| 31 | #include "internal.h" |
| 32 | |
Camilla Berglund | cdfbbaf | 2010-09-08 17:01:39 +0200 | [diff] [blame] | 33 | #include <string.h> |
| 34 | |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 35 | |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 36 | #ifndef GL_VERSION_3_0 |
| 37 | #define GL_NUM_EXTENSIONS 0x821D |
| 38 | #endif |
| 39 | |
Camilla Berglund | 1723c4a | 2010-09-09 20:59:50 +0200 | [diff] [blame] | 40 | |
| 41 | ////////////////////////////////////////////////////////////////////////// |
| 42 | ////// GLFW internal API ////// |
| 43 | ////////////////////////////////////////////////////////////////////////// |
| 44 | |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 45 | //======================================================================== |
| 46 | // Parses the OpenGL version string and extracts the version number |
| 47 | //======================================================================== |
| 48 | |
Camilla Berglund | a4d888c | 2010-09-08 15:58:43 +0200 | [diff] [blame] | 49 | void _glfwParseGLVersion(int* major, int* minor, int* rev) |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 50 | { |
| 51 | GLuint _major, _minor = 0, _rev = 0; |
Camilla Berglund | a4d888c | 2010-09-08 15:58:43 +0200 | [diff] [blame] | 52 | const GLubyte* version; |
| 53 | const GLubyte* ptr; |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 54 | |
| 55 | // Get OpenGL version string |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 56 | version = glGetString(GL_VERSION); |
| 57 | if (!version) |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 58 | return; |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 59 | |
| 60 | // Parse string |
| 61 | ptr = version; |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 62 | for (_major = 0; *ptr >= '0' && *ptr <= '9'; ptr++) |
| 63 | _major = 10 * _major + (*ptr - '0'); |
Camilla Berglund | 105e927 | 2010-09-08 01:57:24 +0200 | [diff] [blame] | 64 | |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 65 | if (*ptr == '.') |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 66 | { |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 67 | ptr++; |
| 68 | for (_minor = 0; *ptr >= '0' && *ptr <= '9'; ptr++) |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 69 | _minor = 10*_minor + (*ptr - '0'); |
Camilla Berglund | 105e927 | 2010-09-08 01:57:24 +0200 | [diff] [blame] | 70 | |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 71 | if (*ptr == '.') |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 72 | { |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 73 | ptr++; |
| 74 | for (_rev = 0; *ptr >= '0' && *ptr <= '9'; ptr++) |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 75 | _rev = 10*_rev + (*ptr - '0'); |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 76 | } |
| 77 | } |
| 78 | |
| 79 | // Return parsed values |
| 80 | *major = _major; |
| 81 | *minor = _minor; |
| 82 | *rev = _rev; |
| 83 | } |
| 84 | |
| 85 | //======================================================================== |
Camilla Berglund | 1baf233 | 2010-09-07 17:50:43 +0200 | [diff] [blame] | 86 | // Check if a string can be found in an OpenGL extension string |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 87 | //======================================================================== |
| 88 | |
Camilla Berglund | a4d888c | 2010-09-08 15:58:43 +0200 | [diff] [blame] | 89 | int _glfwStringInExtensionString(const char* string, |
| 90 | const GLubyte* extensions) |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 91 | { |
Camilla Berglund | a4d888c | 2010-09-08 15:58:43 +0200 | [diff] [blame] | 92 | const GLubyte* start; |
| 93 | GLubyte* where; |
| 94 | GLubyte* terminator; |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 95 | |
| 96 | // It takes a bit of care to be fool-proof about parsing the |
| 97 | // OpenGL extensions string. Don't be fooled by sub-strings, |
| 98 | // etc. |
| 99 | start = extensions; |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 100 | for (;;) |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 101 | { |
Camilla Berglund | a4d888c | 2010-09-08 15:58:43 +0200 | [diff] [blame] | 102 | where = (GLubyte*) strstr((const char*) start, string); |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 103 | if (!where) |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 104 | return GL_FALSE; |
Camilla Berglund | 105e927 | 2010-09-08 01:57:24 +0200 | [diff] [blame] | 105 | |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 106 | terminator = where + strlen(string); |
| 107 | if (where == start || *(where - 1) == ' ') |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 108 | { |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 109 | if (*terminator == ' ' || *terminator == '\0') |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 110 | break; |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 111 | } |
Camilla Berglund | 105e927 | 2010-09-08 01:57:24 +0200 | [diff] [blame] | 112 | |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 113 | start = terminator; |
| 114 | } |
| 115 | |
| 116 | return GL_TRUE; |
| 117 | } |
| 118 | |
| 119 | |
Camilla Berglund | 1723c4a | 2010-09-09 20:59:50 +0200 | [diff] [blame] | 120 | ////////////////////////////////////////////////////////////////////////// |
| 121 | ////// GLFW public API ////// |
| 122 | ////////////////////////////////////////////////////////////////////////// |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 123 | |
| 124 | //======================================================================== |
| 125 | // Check if an OpenGL extension is available at runtime |
| 126 | //======================================================================== |
| 127 | |
Camilla Berglund | a4d888c | 2010-09-08 15:58:43 +0200 | [diff] [blame] | 128 | GLFWAPI int glfwExtensionSupported(const char* extension) |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 129 | { |
Camilla Berglund | a4d888c | 2010-09-08 15:58:43 +0200 | [diff] [blame] | 130 | const GLubyte* extensions; |
Camilla Berglund | 973ff49 | 2010-09-14 00:17:00 +0200 | [diff] [blame^] | 131 | _GLFWwindow* window; |
Camilla Berglund | a4d888c | 2010-09-08 15:58:43 +0200 | [diff] [blame] | 132 | GLubyte* where; |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 133 | GLint count; |
| 134 | int i; |
| 135 | |
Camilla Berglund | 922cd10 | 2010-09-09 21:34:42 +0200 | [diff] [blame] | 136 | if (!_glfwInitialized) |
| 137 | { |
| 138 | _glfwSetError(GLFW_NOT_INITIALIZED); |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 139 | return GL_FALSE; |
Camilla Berglund | 922cd10 | 2010-09-09 21:34:42 +0200 | [diff] [blame] | 140 | } |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 141 | |
Camilla Berglund | 973ff49 | 2010-09-14 00:17:00 +0200 | [diff] [blame^] | 142 | window = _glfwLibrary.currentWindow; |
| 143 | if (!window) |
Camilla Berglund | 922cd10 | 2010-09-09 21:34:42 +0200 | [diff] [blame] | 144 | { |
| 145 | _glfwSetError(GLFW_NO_CURRENT_WINDOW); |
| 146 | return GL_FALSE; |
| 147 | } |
| 148 | |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 149 | // Extension names should not have spaces |
Camilla Berglund | a4d888c | 2010-09-08 15:58:43 +0200 | [diff] [blame] | 150 | where = (GLubyte*) strchr(extension, ' '); |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 151 | if (where || *extension == '\0') |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 152 | return GL_FALSE; |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 153 | |
Camilla Berglund | 135194a | 2010-09-09 18:15:32 +0200 | [diff] [blame] | 154 | if (window->glMajor < 3) |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 155 | { |
| 156 | // Check if extension is in the old style OpenGL extensions string |
| 157 | |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 158 | extensions = glGetString(GL_EXTENSIONS); |
| 159 | if (extensions != NULL) |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 160 | { |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 161 | if (_glfwStringInExtensionString(extension, extensions)) |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 162 | return GL_TRUE; |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 163 | } |
| 164 | } |
| 165 | else |
| 166 | { |
| 167 | // Check if extension is in the modern OpenGL extensions string list |
| 168 | |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 169 | glGetIntegerv(GL_NUM_EXTENSIONS, &count); |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 170 | |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 171 | for (i = 0; i < count; i++) |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 172 | { |
Camilla Berglund | 135194a | 2010-09-09 18:15:32 +0200 | [diff] [blame] | 173 | if (strcmp((const char*) window->GetStringi(GL_EXTENSIONS, i), |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 174 | extension) == 0) |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 175 | { |
| 176 | return GL_TRUE; |
| 177 | } |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | // Additional platform specific extension checking (e.g. WGL) |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 182 | if (_glfwPlatformExtensionSupported(extension)) |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 183 | return GL_TRUE; |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 184 | |
| 185 | return GL_FALSE; |
| 186 | } |
| 187 | |
| 188 | |
| 189 | //======================================================================== |
Camilla Berglund | 1baf233 | 2010-09-07 17:50:43 +0200 | [diff] [blame] | 190 | // Get the function pointer to an OpenGL function. |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 191 | // This function can be used to get access to extended OpenGL functions. |
| 192 | //======================================================================== |
| 193 | |
Camilla Berglund | a4d888c | 2010-09-08 15:58:43 +0200 | [diff] [blame] | 194 | GLFWAPI void* glfwGetProcAddress(const char* procname) |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 195 | { |
Camilla Berglund | 922cd10 | 2010-09-09 21:34:42 +0200 | [diff] [blame] | 196 | if (!_glfwInitialized) |
| 197 | { |
| 198 | _glfwSetError(GLFW_NOT_INITIALIZED); |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 199 | return NULL; |
Camilla Berglund | 922cd10 | 2010-09-09 21:34:42 +0200 | [diff] [blame] | 200 | } |
| 201 | |
| 202 | if (!_glfwLibrary.currentWindow) |
| 203 | { |
| 204 | _glfwSetError(GLFW_NO_CURRENT_WINDOW); |
| 205 | return NULL; |
| 206 | } |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 207 | |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 208 | return _glfwPlatformGetProcAddress(procname); |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 209 | } |
| 210 | |
| 211 | |
| 212 | //======================================================================== |
| 213 | // Returns the OpenGL version |
| 214 | //======================================================================== |
| 215 | |
Camilla Berglund | a4d888c | 2010-09-08 15:58:43 +0200 | [diff] [blame] | 216 | GLFWAPI void glfwGetGLVersion(int* major, int* minor, int* rev) |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 217 | { |
Camilla Berglund | 922cd10 | 2010-09-09 21:34:42 +0200 | [diff] [blame] | 218 | if (!_glfwInitialized) |
| 219 | { |
| 220 | _glfwSetError(GLFW_NOT_INITIALIZED); |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 221 | return; |
Camilla Berglund | 922cd10 | 2010-09-09 21:34:42 +0200 | [diff] [blame] | 222 | } |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 223 | |
Camilla Berglund | 922cd10 | 2010-09-09 21:34:42 +0200 | [diff] [blame] | 224 | if (!_glfwLibrary.currentWindow) |
| 225 | { |
| 226 | _glfwSetError(GLFW_NO_CURRENT_WINDOW); |
| 227 | return; |
| 228 | } |
| 229 | |
| 230 | _GLFWwindow* window = _glfwLibrary.currentWindow; |
Camilla Berglund | 135194a | 2010-09-09 18:15:32 +0200 | [diff] [blame] | 231 | |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 232 | if (major != NULL) |
Camilla Berglund | 135194a | 2010-09-09 18:15:32 +0200 | [diff] [blame] | 233 | *major = window->glMajor; |
Camilla Berglund | 105e927 | 2010-09-08 01:57:24 +0200 | [diff] [blame] | 234 | |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 235 | if (minor != NULL) |
Camilla Berglund | 135194a | 2010-09-09 18:15:32 +0200 | [diff] [blame] | 236 | *minor = window->glMinor; |
Camilla Berglund | 105e927 | 2010-09-08 01:57:24 +0200 | [diff] [blame] | 237 | |
Camilla Berglund | 9e4137c | 2010-09-08 14:45:52 +0200 | [diff] [blame] | 238 | if (rev != NULL) |
Camilla Berglund | 135194a | 2010-09-09 18:15:32 +0200 | [diff] [blame] | 239 | *rev = window->glRevision; |
Camilla Berglund | 3249f81 | 2010-09-07 17:34:51 +0200 | [diff] [blame] | 240 | } |
| 241 | |