blob: 2407813fa5861232c675d964c1f6a88804258e10 [file] [log] [blame]
Camilla Berglund3249f812010-09-07 17:34:51 +02001//========================================================================
2// GLFW - An OpenGL framework
3// Platform: Any
Camilla Berglund38b0ccb2010-09-07 17:41:26 +02004// API version: 3.0
Camilla Berglund3249f812010-09-07 17:34:51 +02005// 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 Berglundcdfbbaf2010-09-08 17:01:39 +020033#include <string.h>
34
Camilla Berglund3249f812010-09-07 17:34:51 +020035
Camilla Berglund3249f812010-09-07 17:34:51 +020036#ifndef GL_VERSION_3_0
37#define GL_NUM_EXTENSIONS 0x821D
38#endif
39
Camilla Berglund1723c4a2010-09-09 20:59:50 +020040
41//////////////////////////////////////////////////////////////////////////
42////// GLFW internal API //////
43//////////////////////////////////////////////////////////////////////////
44
Camilla Berglund3249f812010-09-07 17:34:51 +020045//========================================================================
46// Parses the OpenGL version string and extracts the version number
47//========================================================================
48
Camilla Berglunda4d888c2010-09-08 15:58:43 +020049void _glfwParseGLVersion(int* major, int* minor, int* rev)
Camilla Berglund3249f812010-09-07 17:34:51 +020050{
51 GLuint _major, _minor = 0, _rev = 0;
Camilla Berglunda4d888c2010-09-08 15:58:43 +020052 const GLubyte* version;
53 const GLubyte* ptr;
Camilla Berglund3249f812010-09-07 17:34:51 +020054
55 // Get OpenGL version string
Camilla Berglund9e4137c2010-09-08 14:45:52 +020056 version = glGetString(GL_VERSION);
57 if (!version)
Camilla Berglund3249f812010-09-07 17:34:51 +020058 return;
Camilla Berglund3249f812010-09-07 17:34:51 +020059
60 // Parse string
61 ptr = version;
Camilla Berglund9e4137c2010-09-08 14:45:52 +020062 for (_major = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
63 _major = 10 * _major + (*ptr - '0');
Camilla Berglund105e9272010-09-08 01:57:24 +020064
Camilla Berglund9e4137c2010-09-08 14:45:52 +020065 if (*ptr == '.')
Camilla Berglund3249f812010-09-07 17:34:51 +020066 {
Camilla Berglund9e4137c2010-09-08 14:45:52 +020067 ptr++;
68 for (_minor = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
Camilla Berglund3249f812010-09-07 17:34:51 +020069 _minor = 10*_minor + (*ptr - '0');
Camilla Berglund105e9272010-09-08 01:57:24 +020070
Camilla Berglund9e4137c2010-09-08 14:45:52 +020071 if (*ptr == '.')
Camilla Berglund3249f812010-09-07 17:34:51 +020072 {
Camilla Berglund9e4137c2010-09-08 14:45:52 +020073 ptr++;
74 for (_rev = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
Camilla Berglund3249f812010-09-07 17:34:51 +020075 _rev = 10*_rev + (*ptr - '0');
Camilla Berglund3249f812010-09-07 17:34:51 +020076 }
77 }
78
79 // Return parsed values
80 *major = _major;
81 *minor = _minor;
82 *rev = _rev;
83}
84
85//========================================================================
Camilla Berglund1baf2332010-09-07 17:50:43 +020086// Check if a string can be found in an OpenGL extension string
Camilla Berglund3249f812010-09-07 17:34:51 +020087//========================================================================
88
Camilla Berglunda4d888c2010-09-08 15:58:43 +020089int _glfwStringInExtensionString(const char* string,
90 const GLubyte* extensions)
Camilla Berglund3249f812010-09-07 17:34:51 +020091{
Camilla Berglunda4d888c2010-09-08 15:58:43 +020092 const GLubyte* start;
93 GLubyte* where;
94 GLubyte* terminator;
Camilla Berglund3249f812010-09-07 17:34:51 +020095
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 Berglund9e4137c2010-09-08 14:45:52 +0200100 for (;;)
Camilla Berglund3249f812010-09-07 17:34:51 +0200101 {
Camilla Berglunda4d888c2010-09-08 15:58:43 +0200102 where = (GLubyte*) strstr((const char*) start, string);
Camilla Berglund9e4137c2010-09-08 14:45:52 +0200103 if (!where)
Camilla Berglund3249f812010-09-07 17:34:51 +0200104 return GL_FALSE;
Camilla Berglund105e9272010-09-08 01:57:24 +0200105
Camilla Berglund9e4137c2010-09-08 14:45:52 +0200106 terminator = where + strlen(string);
107 if (where == start || *(where - 1) == ' ')
Camilla Berglund3249f812010-09-07 17:34:51 +0200108 {
Camilla Berglund9e4137c2010-09-08 14:45:52 +0200109 if (*terminator == ' ' || *terminator == '\0')
Camilla Berglund3249f812010-09-07 17:34:51 +0200110 break;
Camilla Berglund3249f812010-09-07 17:34:51 +0200111 }
Camilla Berglund105e9272010-09-08 01:57:24 +0200112
Camilla Berglund3249f812010-09-07 17:34:51 +0200113 start = terminator;
114 }
115
116 return GL_TRUE;
117}
118
119
Camilla Berglund1723c4a2010-09-09 20:59:50 +0200120//////////////////////////////////////////////////////////////////////////
121////// GLFW public API //////
122//////////////////////////////////////////////////////////////////////////
Camilla Berglund3249f812010-09-07 17:34:51 +0200123
124//========================================================================
125// Check if an OpenGL extension is available at runtime
126//========================================================================
127
Camilla Berglunda4d888c2010-09-08 15:58:43 +0200128GLFWAPI int glfwExtensionSupported(const char* extension)
Camilla Berglund3249f812010-09-07 17:34:51 +0200129{
Camilla Berglunda4d888c2010-09-08 15:58:43 +0200130 const GLubyte* extensions;
Camilla Berglund973ff492010-09-14 00:17:00 +0200131 _GLFWwindow* window;
Camilla Berglunda4d888c2010-09-08 15:58:43 +0200132 GLubyte* where;
Camilla Berglund3249f812010-09-07 17:34:51 +0200133 GLint count;
134 int i;
135
Camilla Berglund922cd102010-09-09 21:34:42 +0200136 if (!_glfwInitialized)
137 {
138 _glfwSetError(GLFW_NOT_INITIALIZED);
Camilla Berglund3249f812010-09-07 17:34:51 +0200139 return GL_FALSE;
Camilla Berglund922cd102010-09-09 21:34:42 +0200140 }
Camilla Berglund3249f812010-09-07 17:34:51 +0200141
Camilla Berglund973ff492010-09-14 00:17:00 +0200142 window = _glfwLibrary.currentWindow;
143 if (!window)
Camilla Berglund922cd102010-09-09 21:34:42 +0200144 {
145 _glfwSetError(GLFW_NO_CURRENT_WINDOW);
146 return GL_FALSE;
147 }
148
Camilla Berglund3249f812010-09-07 17:34:51 +0200149 // Extension names should not have spaces
Camilla Berglunda4d888c2010-09-08 15:58:43 +0200150 where = (GLubyte*) strchr(extension, ' ');
Camilla Berglund9e4137c2010-09-08 14:45:52 +0200151 if (where || *extension == '\0')
Camilla Berglund3249f812010-09-07 17:34:51 +0200152 return GL_FALSE;
Camilla Berglund3249f812010-09-07 17:34:51 +0200153
Camilla Berglund135194a2010-09-09 18:15:32 +0200154 if (window->glMajor < 3)
Camilla Berglund3249f812010-09-07 17:34:51 +0200155 {
156 // Check if extension is in the old style OpenGL extensions string
157
Camilla Berglund9e4137c2010-09-08 14:45:52 +0200158 extensions = glGetString(GL_EXTENSIONS);
159 if (extensions != NULL)
Camilla Berglund3249f812010-09-07 17:34:51 +0200160 {
Camilla Berglund9e4137c2010-09-08 14:45:52 +0200161 if (_glfwStringInExtensionString(extension, extensions))
Camilla Berglund3249f812010-09-07 17:34:51 +0200162 return GL_TRUE;
Camilla Berglund3249f812010-09-07 17:34:51 +0200163 }
164 }
165 else
166 {
167 // Check if extension is in the modern OpenGL extensions string list
168
Camilla Berglund9e4137c2010-09-08 14:45:52 +0200169 glGetIntegerv(GL_NUM_EXTENSIONS, &count);
Camilla Berglund3249f812010-09-07 17:34:51 +0200170
Camilla Berglund9e4137c2010-09-08 14:45:52 +0200171 for (i = 0; i < count; i++)
Camilla Berglund3249f812010-09-07 17:34:51 +0200172 {
Camilla Berglund135194a2010-09-09 18:15:32 +0200173 if (strcmp((const char*) window->GetStringi(GL_EXTENSIONS, i),
Camilla Berglund9e4137c2010-09-08 14:45:52 +0200174 extension) == 0)
Camilla Berglund3249f812010-09-07 17:34:51 +0200175 {
176 return GL_TRUE;
177 }
178 }
179 }
180
181 // Additional platform specific extension checking (e.g. WGL)
Camilla Berglund9e4137c2010-09-08 14:45:52 +0200182 if (_glfwPlatformExtensionSupported(extension))
Camilla Berglund3249f812010-09-07 17:34:51 +0200183 return GL_TRUE;
Camilla Berglund3249f812010-09-07 17:34:51 +0200184
185 return GL_FALSE;
186}
187
188
189//========================================================================
Camilla Berglund1baf2332010-09-07 17:50:43 +0200190// Get the function pointer to an OpenGL function.
Camilla Berglund3249f812010-09-07 17:34:51 +0200191// This function can be used to get access to extended OpenGL functions.
192//========================================================================
193
Camilla Berglunda4d888c2010-09-08 15:58:43 +0200194GLFWAPI void* glfwGetProcAddress(const char* procname)
Camilla Berglund3249f812010-09-07 17:34:51 +0200195{
Camilla Berglund922cd102010-09-09 21:34:42 +0200196 if (!_glfwInitialized)
197 {
198 _glfwSetError(GLFW_NOT_INITIALIZED);
Camilla Berglund3249f812010-09-07 17:34:51 +0200199 return NULL;
Camilla Berglund922cd102010-09-09 21:34:42 +0200200 }
201
202 if (!_glfwLibrary.currentWindow)
203 {
204 _glfwSetError(GLFW_NO_CURRENT_WINDOW);
205 return NULL;
206 }
Camilla Berglund3249f812010-09-07 17:34:51 +0200207
Camilla Berglund9e4137c2010-09-08 14:45:52 +0200208 return _glfwPlatformGetProcAddress(procname);
Camilla Berglund3249f812010-09-07 17:34:51 +0200209}
210
211
212//========================================================================
213// Returns the OpenGL version
214//========================================================================
215
Camilla Berglunda4d888c2010-09-08 15:58:43 +0200216GLFWAPI void glfwGetGLVersion(int* major, int* minor, int* rev)
Camilla Berglund3249f812010-09-07 17:34:51 +0200217{
Camilla Berglund922cd102010-09-09 21:34:42 +0200218 if (!_glfwInitialized)
219 {
220 _glfwSetError(GLFW_NOT_INITIALIZED);
Camilla Berglund3249f812010-09-07 17:34:51 +0200221 return;
Camilla Berglund922cd102010-09-09 21:34:42 +0200222 }
Camilla Berglund3249f812010-09-07 17:34:51 +0200223
Camilla Berglund922cd102010-09-09 21:34:42 +0200224 if (!_glfwLibrary.currentWindow)
225 {
226 _glfwSetError(GLFW_NO_CURRENT_WINDOW);
227 return;
228 }
229
230 _GLFWwindow* window = _glfwLibrary.currentWindow;
Camilla Berglund135194a2010-09-09 18:15:32 +0200231
Camilla Berglund9e4137c2010-09-08 14:45:52 +0200232 if (major != NULL)
Camilla Berglund135194a2010-09-09 18:15:32 +0200233 *major = window->glMajor;
Camilla Berglund105e9272010-09-08 01:57:24 +0200234
Camilla Berglund9e4137c2010-09-08 14:45:52 +0200235 if (minor != NULL)
Camilla Berglund135194a2010-09-09 18:15:32 +0200236 *minor = window->glMinor;
Camilla Berglund105e9272010-09-08 01:57:24 +0200237
Camilla Berglund9e4137c2010-09-08 14:45:52 +0200238 if (rev != NULL)
Camilla Berglund135194a2010-09-09 18:15:32 +0200239 *rev = window->glRevision;
Camilla Berglund3249f812010-09-07 17:34:51 +0200240}
241