1 // Created on: 2012-01-26
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 2012-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
21 #if (defined(_WIN32) || defined(__WIN32__))
25 #include <OpenGl_Context.hxx>
27 #include <OpenGl_ArbVBO.hxx>
28 #include <OpenGl_ExtFBO.hxx>
29 #include <OpenGl_GlCore20.hxx>
31 #if (defined(_WIN32) || defined(__WIN32__))
33 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
36 #include <GL/glx.h> // glXGetProcAddress()
39 IMPLEMENT_STANDARD_HANDLE (OpenGl_Context, Standard_Transient)
40 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient)
42 //! Make record shorter to retrieve function pointer using variable with same name
43 #define FindProcShort(theStruct, theFunc) FindProc(#theFunc, theStruct->theFunc)
45 // =======================================================================
46 // function : OpenGl_Context
48 // =======================================================================
49 OpenGl_Context::OpenGl_Context()
61 myIsInitialized (Standard_False)
63 #if defined(MAC_OS_X_VERSION_10_3) && !defined(MACOSX_USE_GLX)
64 // Vendors can not extend functionality on this system
65 // and developers are limited to OpenGL support provided by Mac OS X SDK.
66 // We retrieve function pointers from system library
67 // to generalize extensions support on all platforms.
68 // In this way we also reach binary compatibility benefit between OS releases
69 // if some newest functionality is optionally used.
70 // Notice that GL version / extension availability checks are required
71 // because function pointers may be available but not functionality itself
72 // (depends on renderer).
73 myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
77 // =======================================================================
78 // function : ~OpenGl_Context
80 // =======================================================================
81 OpenGl_Context::~OpenGl_Context()
88 // =======================================================================
89 // function : findProc
91 // =======================================================================
92 void* OpenGl_Context::findProc (const char* theFuncName)
94 #if (defined(_WIN32) || defined(__WIN32__))
95 return wglGetProcAddress (theFuncName);
96 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
97 return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
99 return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
103 // =======================================================================
104 // function : CheckExtension
106 // =======================================================================
107 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName)
109 if (theExtName == NULL)
111 std::cerr << "CheckExtension called with NULL string!\n";
112 return Standard_False;
114 int anExtNameLen = strlen (theExtName);
116 // available since OpenGL 3.0
117 // and the ONLY way to check extensions with OpenGL 3.1+ core profile
118 /**if (IsGlUpperEqual (3, 0))
121 glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
122 for (GLint anIter = 0; anIter < anExtNb; ++anIter)
124 const char* anExtension = (const char* )core30->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
125 if (anExtension[anExtNameLen] == '\0' &&
126 strncmp (anExtension, theExtName, anExtNameLen) == 0)
128 return Standard_True;
131 return Standard_False;
134 // use old way with huge string for all extensions
135 const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
136 if (anExtString == NULL)
138 std::cerr << "glGetString (GL_EXTENSIONS) returns NULL! No GL context?\n";
139 return Standard_False;
142 // Search for theExtName in the extensions string.
143 // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
144 char* aPtrIter = (char* )anExtString;
145 const char* aPtrEnd = aPtrIter + strlen (anExtString);
146 while (aPtrIter < aPtrEnd)
148 int n = strcspn (aPtrIter, " ");
149 if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
151 return Standard_True;
155 return Standard_False;
158 // =======================================================================
161 // =======================================================================
162 void OpenGl_Context::Init()
164 if (!myIsInitialized)
167 myIsInitialized = Standard_True;
171 // =======================================================================
172 // function : ResetErrors
174 // =======================================================================
175 void OpenGl_Context::ResetErrors()
177 while (glGetError() != GL_NO_ERROR)
183 // =======================================================================
184 // function : readGlVersion
186 // =======================================================================
187 void OpenGl_Context::readGlVersion()
193 // available since OpenGL 3.0
194 GLint aMajor, aMinor;
195 glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
196 glGetIntegerv (GL_MINOR_VERSION, &aMinor);
197 if (glGetError() == GL_NO_ERROR)
199 myGlVerMajor = aMajor;
200 myGlVerMinor = aMinor;
205 // Read version string.
206 // Notice that only first two numbers splitted by point '2.1 XXXXX' are significant.
207 // Following trash (after space) is vendor-specific.
208 // New drivers also returns micro version of GL like '3.3.0' which has no meaning
209 // and should be considered as vendor-specific too.
210 const char* aVerStr = (const char* )glGetString (GL_VERSION);
211 if (aVerStr == NULL || *aVerStr == '\0')
213 // invalid GL context
217 // parse string for major number
221 while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
225 if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
229 memcpy (aMajorStr, aVerStr, aMajIter);
230 aMajorStr[aMajIter] = '\0';
232 // parse string for minor number
233 size_t aMinIter = aMajIter + 1;
234 while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
238 size_t aMinLen = aMinIter - aMajIter - 1;
239 if (aMinLen == 0 || aMinLen >= sizeof(aMinorStr))
243 memcpy (aMinorStr, aVerStr, aMinLen);
244 aMinorStr[aMinLen] = '\0';
247 myGlVerMajor = atoi (aMajorStr);
248 myGlVerMinor = atoi (aMinorStr);
250 if (myGlVerMajor <= 0)
257 // =======================================================================
260 // =======================================================================
261 void OpenGl_Context::init()
266 // initialize VBO extension (ARB)
267 if (CheckExtension ("GL_ARB_vertex_buffer_object"))
269 arbVBO = new OpenGl_ArbVBO();
270 memset (arbVBO, 0, sizeof(OpenGl_ArbVBO)); // nullify whole structure
271 if (!FindProcShort (arbVBO, glGenBuffersARB)
272 || !FindProcShort (arbVBO, glBindBufferARB)
273 || !FindProcShort (arbVBO, glBufferDataARB)
274 || !FindProcShort (arbVBO, glDeleteBuffersARB))
281 // initialize FBO extension (EXT)
282 if (CheckExtension ("GL_EXT_framebuffer_object"))
284 extFBO = new OpenGl_ExtFBO();
285 memset (extFBO, 0, sizeof(OpenGl_ExtFBO)); // nullify whole structure
286 if (!FindProcShort (extFBO, glGenFramebuffersEXT)
287 || !FindProcShort (extFBO, glDeleteFramebuffersEXT)
288 || !FindProcShort (extFBO, glBindFramebufferEXT)
289 || !FindProcShort (extFBO, glFramebufferTexture2DEXT)
290 || !FindProcShort (extFBO, glCheckFramebufferStatusEXT)
291 || !FindProcShort (extFBO, glGenRenderbuffersEXT)
292 || !FindProcShort (extFBO, glDeleteRenderbuffersEXT)
293 || !FindProcShort (extFBO, glBindRenderbufferEXT)
294 || !FindProcShort (extFBO, glRenderbufferStorageEXT)
295 || !FindProcShort (extFBO, glFramebufferRenderbufferEXT))
302 myGlCore20 = new OpenGl_GlCore20();
303 memset (myGlCore20, 0, sizeof(OpenGl_GlCore20)); // nullify whole structure
305 // initialize OpenGL 1.2 core functionality
306 if (IsGlUpperEqual (1, 2))
308 if (!FindProcShort (myGlCore20, glBlendColor)
309 || !FindProcShort (myGlCore20, glBlendEquation)
310 || !FindProcShort (myGlCore20, glDrawRangeElements)
311 || !FindProcShort (myGlCore20, glTexImage3D)
312 || !FindProcShort (myGlCore20, glTexSubImage3D)
313 || !FindProcShort (myGlCore20, glCopyTexSubImage3D))
320 // initialize OpenGL 1.3 core functionality
321 if (IsGlUpperEqual (1, 3))
323 if (!FindProcShort (myGlCore20, glActiveTexture)
324 || !FindProcShort (myGlCore20, glSampleCoverage)
325 || !FindProcShort (myGlCore20, glCompressedTexImage3D)
326 || !FindProcShort (myGlCore20, glCompressedTexImage2D)
327 || !FindProcShort (myGlCore20, glCompressedTexImage1D)
328 || !FindProcShort (myGlCore20, glCompressedTexSubImage3D)
329 || !FindProcShort (myGlCore20, glCompressedTexSubImage2D)
330 || !FindProcShort (myGlCore20, glCompressedTexSubImage1D)
331 || !FindProcShort (myGlCore20, glGetCompressedTexImage)
333 || !FindProcShort (myGlCore20, glClientActiveTexture)
334 || !FindProcShort (myGlCore20, glMultiTexCoord1d)
335 || !FindProcShort (myGlCore20, glMultiTexCoord1dv)
336 || !FindProcShort (myGlCore20, glMultiTexCoord1f)
337 || !FindProcShort (myGlCore20, glMultiTexCoord1fv)
338 || !FindProcShort (myGlCore20, glMultiTexCoord1i)
339 || !FindProcShort (myGlCore20, glMultiTexCoord1iv)
340 || !FindProcShort (myGlCore20, glMultiTexCoord1s)
341 || !FindProcShort (myGlCore20, glMultiTexCoord1sv)
342 || !FindProcShort (myGlCore20, glMultiTexCoord2d)
343 || !FindProcShort (myGlCore20, glMultiTexCoord2dv)
344 || !FindProcShort (myGlCore20, glMultiTexCoord2f)
345 || !FindProcShort (myGlCore20, glMultiTexCoord2fv)
346 || !FindProcShort (myGlCore20, glMultiTexCoord2i)
347 || !FindProcShort (myGlCore20, glMultiTexCoord2iv)
348 || !FindProcShort (myGlCore20, glMultiTexCoord2s)
349 || !FindProcShort (myGlCore20, glMultiTexCoord2sv)
350 || !FindProcShort (myGlCore20, glMultiTexCoord3d)
351 || !FindProcShort (myGlCore20, glMultiTexCoord3dv)
352 || !FindProcShort (myGlCore20, glMultiTexCoord3f)
353 || !FindProcShort (myGlCore20, glMultiTexCoord3fv)
354 || !FindProcShort (myGlCore20, glMultiTexCoord3i)
355 || !FindProcShort (myGlCore20, glMultiTexCoord3iv)
356 || !FindProcShort (myGlCore20, glMultiTexCoord3s)
357 || !FindProcShort (myGlCore20, glMultiTexCoord3sv)
358 || !FindProcShort (myGlCore20, glMultiTexCoord4d)
359 || !FindProcShort (myGlCore20, glMultiTexCoord4dv)
360 || !FindProcShort (myGlCore20, glMultiTexCoord4f)
361 || !FindProcShort (myGlCore20, glMultiTexCoord4fv)
362 || !FindProcShort (myGlCore20, glMultiTexCoord4i)
363 || !FindProcShort (myGlCore20, glMultiTexCoord4iv)
364 || !FindProcShort (myGlCore20, glMultiTexCoord4s)
365 || !FindProcShort (myGlCore20, glMultiTexCoord4sv)
366 || !FindProcShort (myGlCore20, glLoadTransposeMatrixf)
367 || !FindProcShort (myGlCore20, glLoadTransposeMatrixd)
368 || !FindProcShort (myGlCore20, glMultTransposeMatrixf)
369 || !FindProcShort (myGlCore20, glMultTransposeMatrixd))
377 // initialize OpenGL 1.4 core functionality
378 if (IsGlUpperEqual (1, 4))
380 if (!FindProcShort (myGlCore20, glBlendFuncSeparate)
381 || !FindProcShort (myGlCore20, glMultiDrawArrays)
382 || !FindProcShort (myGlCore20, glMultiDrawElements)
383 || !FindProcShort (myGlCore20, glPointParameterf)
384 || !FindProcShort (myGlCore20, glPointParameterfv)
385 || !FindProcShort (myGlCore20, glPointParameteri)
386 || !FindProcShort (myGlCore20, glPointParameteriv))
395 // initialize OpenGL 1.5 core functionality
396 if (IsGlUpperEqual (1, 5))
398 if (!FindProcShort (myGlCore20, glGenQueries)
399 || !FindProcShort (myGlCore20, glDeleteQueries)
400 || !FindProcShort (myGlCore20, glIsQuery)
401 || !FindProcShort (myGlCore20, glBeginQuery)
402 || !FindProcShort (myGlCore20, glEndQuery)
403 || !FindProcShort (myGlCore20, glGetQueryiv)
404 || !FindProcShort (myGlCore20, glGetQueryObjectiv)
405 || !FindProcShort (myGlCore20, glGetQueryObjectuiv)
406 || !FindProcShort (myGlCore20, glBindBuffer)
407 || !FindProcShort (myGlCore20, glDeleteBuffers)
408 || !FindProcShort (myGlCore20, glGenBuffers)
409 || !FindProcShort (myGlCore20, glIsBuffer)
410 || !FindProcShort (myGlCore20, glBufferData)
411 || !FindProcShort (myGlCore20, glBufferSubData)
412 || !FindProcShort (myGlCore20, glGetBufferSubData)
413 || !FindProcShort (myGlCore20, glMapBuffer)
414 || !FindProcShort (myGlCore20, glUnmapBuffer)
415 || !FindProcShort (myGlCore20, glGetBufferParameteriv)
416 || !FindProcShort (myGlCore20, glGetBufferPointerv))
426 // initialize OpenGL 2.0 core functionality
427 if (IsGlUpperEqual (2, 0))
429 if (!FindProcShort (myGlCore20, glBlendEquationSeparate)
430 || !FindProcShort (myGlCore20, glDrawBuffers)
431 || !FindProcShort (myGlCore20, glStencilOpSeparate)
432 || !FindProcShort (myGlCore20, glStencilFuncSeparate)
433 || !FindProcShort (myGlCore20, glStencilMaskSeparate)
434 || !FindProcShort (myGlCore20, glAttachShader)
435 || !FindProcShort (myGlCore20, glBindAttribLocation)
436 || !FindProcShort (myGlCore20, glCompileShader)
437 || !FindProcShort (myGlCore20, glCreateProgram)
438 || !FindProcShort (myGlCore20, glCreateShader)
439 || !FindProcShort (myGlCore20, glDeleteProgram)
440 || !FindProcShort (myGlCore20, glDeleteShader)
441 || !FindProcShort (myGlCore20, glDetachShader)
442 || !FindProcShort (myGlCore20, glDisableVertexAttribArray)
443 || !FindProcShort (myGlCore20, glEnableVertexAttribArray)
444 || !FindProcShort (myGlCore20, glGetActiveAttrib)
445 || !FindProcShort (myGlCore20, glGetActiveUniform)
446 || !FindProcShort (myGlCore20, glGetAttachedShaders)
447 || !FindProcShort (myGlCore20, glGetAttribLocation)
448 || !FindProcShort (myGlCore20, glGetProgramiv)
449 || !FindProcShort (myGlCore20, glGetProgramInfoLog)
450 || !FindProcShort (myGlCore20, glGetShaderiv)
451 || !FindProcShort (myGlCore20, glGetShaderInfoLog)
452 || !FindProcShort (myGlCore20, glGetShaderSource)
453 || !FindProcShort (myGlCore20, glGetUniformLocation)
454 || !FindProcShort (myGlCore20, glGetUniformfv)
455 || !FindProcShort (myGlCore20, glGetUniformiv)
456 || !FindProcShort (myGlCore20, glGetVertexAttribdv)
457 || !FindProcShort (myGlCore20, glGetVertexAttribfv)
458 || !FindProcShort (myGlCore20, glGetVertexAttribiv)
459 || !FindProcShort (myGlCore20, glGetVertexAttribPointerv)
460 || !FindProcShort (myGlCore20, glIsProgram)
461 || !FindProcShort (myGlCore20, glIsShader)
462 || !FindProcShort (myGlCore20, glLinkProgram)
463 || !FindProcShort (myGlCore20, glShaderSource)
464 || !FindProcShort (myGlCore20, glUseProgram)
465 || !FindProcShort (myGlCore20, glUniform1f)
466 || !FindProcShort (myGlCore20, glUniform2f)
467 || !FindProcShort (myGlCore20, glUniform3f)
468 || !FindProcShort (myGlCore20, glUniform4f)
469 || !FindProcShort (myGlCore20, glUniform1i)
470 || !FindProcShort (myGlCore20, glUniform2i)
471 || !FindProcShort (myGlCore20, glUniform3i)
472 || !FindProcShort (myGlCore20, glUniform4i)
473 || !FindProcShort (myGlCore20, glUniform1fv)
474 || !FindProcShort (myGlCore20, glUniform2fv)
475 || !FindProcShort (myGlCore20, glUniform3fv)
476 || !FindProcShort (myGlCore20, glUniform4fv)
477 || !FindProcShort (myGlCore20, glUniform1iv)
478 || !FindProcShort (myGlCore20, glUniform2iv)
479 || !FindProcShort (myGlCore20, glUniform3iv)
480 || !FindProcShort (myGlCore20, glUniform4iv)
481 || !FindProcShort (myGlCore20, glUniformMatrix2fv)
482 || !FindProcShort (myGlCore20, glUniformMatrix3fv)
483 || !FindProcShort (myGlCore20, glUniformMatrix4fv)
484 || !FindProcShort (myGlCore20, glValidateProgram)
485 || !FindProcShort (myGlCore20, glVertexAttrib1d)
486 || !FindProcShort (myGlCore20, glVertexAttrib1dv)
487 || !FindProcShort (myGlCore20, glVertexAttrib1f)
488 || !FindProcShort (myGlCore20, glVertexAttrib1fv)
489 || !FindProcShort (myGlCore20, glVertexAttrib1s)
490 || !FindProcShort (myGlCore20, glVertexAttrib1sv)
491 || !FindProcShort (myGlCore20, glVertexAttrib2d)
492 || !FindProcShort (myGlCore20, glVertexAttrib2dv)
493 || !FindProcShort (myGlCore20, glVertexAttrib2f)
494 || !FindProcShort (myGlCore20, glVertexAttrib2fv)
495 || !FindProcShort (myGlCore20, glVertexAttrib2s)
496 || !FindProcShort (myGlCore20, glVertexAttrib2sv)
497 || !FindProcShort (myGlCore20, glVertexAttrib3d)
498 || !FindProcShort (myGlCore20, glVertexAttrib3dv)
499 || !FindProcShort (myGlCore20, glVertexAttrib3f)
500 || !FindProcShort (myGlCore20, glVertexAttrib3fv)
501 || !FindProcShort (myGlCore20, glVertexAttrib3s)
502 || !FindProcShort (myGlCore20, glVertexAttrib3sv)
503 || !FindProcShort (myGlCore20, glVertexAttrib4Nbv)
504 || !FindProcShort (myGlCore20, glVertexAttrib4Niv)
505 || !FindProcShort (myGlCore20, glVertexAttrib4Nsv)
506 || !FindProcShort (myGlCore20, glVertexAttrib4Nub)
507 || !FindProcShort (myGlCore20, glVertexAttrib4Nubv)
508 || !FindProcShort (myGlCore20, glVertexAttrib4Nuiv)
509 || !FindProcShort (myGlCore20, glVertexAttrib4Nusv)
510 || !FindProcShort (myGlCore20, glVertexAttrib4bv)
511 || !FindProcShort (myGlCore20, glVertexAttrib4d)
512 || !FindProcShort (myGlCore20, glVertexAttrib4dv)
513 || !FindProcShort (myGlCore20, glVertexAttrib4f)
514 || !FindProcShort (myGlCore20, glVertexAttrib4fv)
515 || !FindProcShort (myGlCore20, glVertexAttrib4iv)
516 || !FindProcShort (myGlCore20, glVertexAttrib4s)
517 || !FindProcShort (myGlCore20, glVertexAttrib4sv)
518 || !FindProcShort (myGlCore20, glVertexAttrib4ubv)
519 || !FindProcShort (myGlCore20, glVertexAttrib4uiv)
520 || !FindProcShort (myGlCore20, glVertexAttrib4usv)
521 || !FindProcShort (myGlCore20, glVertexAttribPointer))
532 if (IsGlUpperEqual (2, 0))