1 // File: OpenGl_Context.cxx
2 // Created: 26 January 2012
3 // Author: Kirill GAVRILOV
4 // Copyright: OPEN CASCADE 2012
6 #if (defined(_WIN32) || defined(__WIN32__))
10 #include <OpenGl_Context.hxx>
12 #include <OpenGl_ArbVBO.hxx>
13 #include <OpenGl_ExtFBO.hxx>
14 #include <OpenGl_GlCore20.hxx>
16 #if (defined(_WIN32) || defined(__WIN32__))
18 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
21 #include <GL/glx.h> // glXGetProcAddress()
24 IMPLEMENT_STANDARD_HANDLE (OpenGl_Context, Standard_Transient)
25 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient)
27 //! Make record shorter to retrieve function pointer using variable with same name
28 #define FindProcShort(theStruct, theFunc) FindProc(#theFunc, theStruct->theFunc)
30 // =======================================================================
31 // function : OpenGl_Context
33 // =======================================================================
34 OpenGl_Context::OpenGl_Context()
46 myIsInitialized (Standard_False)
48 #if defined(MAC_OS_X_VERSION_10_3) && !defined(MACOSX_USE_GLX)
49 // Vendors can not extend functionality on this system
50 // and developers are limited to OpenGL support provided by Mac OS X SDK.
51 // We retrieve function pointers from system library
52 // to generalize extensions support on all platforms.
53 // In this way we also reach binary compatibility benefit between OS releases
54 // if some newest functionality is optionally used.
55 // Notice that GL version / extension availability checks are required
56 // because function pointers may be available but not functionality itself
57 // (depends on renderer).
58 myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
62 // =======================================================================
63 // function : ~OpenGl_Context
65 // =======================================================================
66 OpenGl_Context::~OpenGl_Context()
73 // =======================================================================
74 // function : findProc
76 // =======================================================================
77 void* OpenGl_Context::findProc (const char* theFuncName)
79 #if (defined(_WIN32) || defined(__WIN32__))
80 return wglGetProcAddress (theFuncName);
81 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
82 return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
84 return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
88 // =======================================================================
89 // function : CheckExtension
91 // =======================================================================
92 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName)
94 if (theExtName == NULL)
96 std::cerr << "CheckExtension called with NULL string!\n";
97 return Standard_False;
99 int anExtNameLen = strlen (theExtName);
101 // available since OpenGL 3.0
102 // and the ONLY way to check extensions with OpenGL 3.1+ core profile
103 /**if (IsGlUpperEqual (3, 0))
106 glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
107 for (GLint anIter = 0; anIter < anExtNb; ++anIter)
109 const char* anExtension = (const char* )core30->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
110 if (anExtension[anExtNameLen] == '\0' &&
111 strncmp (anExtension, theExtName, anExtNameLen) == 0)
113 return Standard_True;
116 return Standard_False;
119 // use old way with huge string for all extensions
120 const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
121 if (anExtString == NULL)
123 std::cerr << "glGetString (GL_EXTENSIONS) returns NULL! No GL context?\n";
124 return Standard_False;
127 // Search for theExtName in the extensions string.
128 // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
129 char* aPtrIter = (char* )anExtString;
130 const char* aPtrEnd = aPtrIter + strlen (anExtString);
131 while (aPtrIter < aPtrEnd)
133 int n = strcspn (aPtrIter, " ");
134 if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
136 return Standard_True;
140 return Standard_False;
143 // =======================================================================
146 // =======================================================================
147 void OpenGl_Context::Init()
149 if (!myIsInitialized)
152 myIsInitialized = Standard_True;
156 // =======================================================================
157 // function : ResetErrors
159 // =======================================================================
160 void OpenGl_Context::ResetErrors()
162 while (glGetError() != GL_NO_ERROR)
168 // =======================================================================
169 // function : readGlVersion
171 // =======================================================================
172 void OpenGl_Context::readGlVersion()
178 // available since OpenGL 3.0
179 GLint aMajor, aMinor;
180 glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
181 glGetIntegerv (GL_MINOR_VERSION, &aMinor);
182 if (glGetError() == GL_NO_ERROR)
184 myGlVerMajor = aMajor;
185 myGlVerMinor = aMinor;
190 // Read version string.
191 // Notice that only first two numbers splitted by point '2.1 XXXXX' are significant.
192 // Following trash (after space) is vendor-specific.
193 // New drivers also returns micro version of GL like '3.3.0' which has no meaning
194 // and should be considered as vendor-specific too.
195 const char* aVerStr = (const char* )glGetString (GL_VERSION);
196 if (aVerStr == NULL || *aVerStr == '\0')
198 // invalid GL context
202 // parse string for major number
206 while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
210 if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
214 memcpy (aMajorStr, aVerStr, aMajIter);
215 aMajorStr[aMajIter] = '\0';
217 // parse string for minor number
218 size_t aMinIter = aMajIter + 1;
219 while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
223 size_t aMinLen = aMinIter - aMajIter - 1;
224 if (aMinLen == 0 || aMinLen >= sizeof(aMinorStr))
228 memcpy (aMinorStr, aVerStr, aMinLen);
229 aMinorStr[aMinLen] = '\0';
232 myGlVerMajor = atoi (aMajorStr);
233 myGlVerMinor = atoi (aMinorStr);
235 if (myGlVerMajor <= 0)
242 // =======================================================================
245 // =======================================================================
246 void OpenGl_Context::init()
251 // initialize VBO extension (ARB)
252 if (CheckExtension ("GL_ARB_vertex_buffer_object"))
254 arbVBO = new OpenGl_ArbVBO();
255 memset (arbVBO, 0, sizeof(OpenGl_ArbVBO)); // nullify whole structure
256 if (!FindProcShort (arbVBO, glGenBuffersARB)
257 || !FindProcShort (arbVBO, glBindBufferARB)
258 || !FindProcShort (arbVBO, glBufferDataARB)
259 || !FindProcShort (arbVBO, glDeleteBuffersARB))
266 // initialize FBO extension (EXT)
267 if (CheckExtension ("GL_EXT_framebuffer_object"))
269 extFBO = new OpenGl_ExtFBO();
270 memset (extFBO, 0, sizeof(OpenGl_ExtFBO)); // nullify whole structure
271 if (!FindProcShort (extFBO, glGenFramebuffersEXT)
272 || !FindProcShort (extFBO, glDeleteFramebuffersEXT)
273 || !FindProcShort (extFBO, glBindFramebufferEXT)
274 || !FindProcShort (extFBO, glFramebufferTexture2DEXT)
275 || !FindProcShort (extFBO, glCheckFramebufferStatusEXT)
276 || !FindProcShort (extFBO, glGenRenderbuffersEXT)
277 || !FindProcShort (extFBO, glDeleteRenderbuffersEXT)
278 || !FindProcShort (extFBO, glBindRenderbufferEXT)
279 || !FindProcShort (extFBO, glRenderbufferStorageEXT)
280 || !FindProcShort (extFBO, glFramebufferRenderbufferEXT))
287 myGlCore20 = new OpenGl_GlCore20();
288 memset (myGlCore20, 0, sizeof(OpenGl_GlCore20)); // nullify whole structure
290 // initialize OpenGL 1.2 core functionality
291 if (IsGlUpperEqual (1, 2))
293 if (!FindProcShort (myGlCore20, glBlendColor)
294 || !FindProcShort (myGlCore20, glBlendEquation)
295 || !FindProcShort (myGlCore20, glDrawRangeElements)
296 || !FindProcShort (myGlCore20, glTexImage3D)
297 || !FindProcShort (myGlCore20, glTexSubImage3D)
298 || !FindProcShort (myGlCore20, glCopyTexSubImage3D))
305 // initialize OpenGL 1.3 core functionality
306 if (IsGlUpperEqual (1, 3))
308 if (!FindProcShort (myGlCore20, glActiveTexture)
309 || !FindProcShort (myGlCore20, glSampleCoverage)
310 || !FindProcShort (myGlCore20, glCompressedTexImage3D)
311 || !FindProcShort (myGlCore20, glCompressedTexImage2D)
312 || !FindProcShort (myGlCore20, glCompressedTexImage1D)
313 || !FindProcShort (myGlCore20, glCompressedTexSubImage3D)
314 || !FindProcShort (myGlCore20, glCompressedTexSubImage2D)
315 || !FindProcShort (myGlCore20, glCompressedTexSubImage1D)
316 || !FindProcShort (myGlCore20, glGetCompressedTexImage)
318 || !FindProcShort (myGlCore20, glClientActiveTexture)
319 || !FindProcShort (myGlCore20, glMultiTexCoord1d)
320 || !FindProcShort (myGlCore20, glMultiTexCoord1dv)
321 || !FindProcShort (myGlCore20, glMultiTexCoord1f)
322 || !FindProcShort (myGlCore20, glMultiTexCoord1fv)
323 || !FindProcShort (myGlCore20, glMultiTexCoord1i)
324 || !FindProcShort (myGlCore20, glMultiTexCoord1iv)
325 || !FindProcShort (myGlCore20, glMultiTexCoord1s)
326 || !FindProcShort (myGlCore20, glMultiTexCoord1sv)
327 || !FindProcShort (myGlCore20, glMultiTexCoord2d)
328 || !FindProcShort (myGlCore20, glMultiTexCoord2dv)
329 || !FindProcShort (myGlCore20, glMultiTexCoord2f)
330 || !FindProcShort (myGlCore20, glMultiTexCoord2fv)
331 || !FindProcShort (myGlCore20, glMultiTexCoord2i)
332 || !FindProcShort (myGlCore20, glMultiTexCoord2iv)
333 || !FindProcShort (myGlCore20, glMultiTexCoord2s)
334 || !FindProcShort (myGlCore20, glMultiTexCoord2sv)
335 || !FindProcShort (myGlCore20, glMultiTexCoord3d)
336 || !FindProcShort (myGlCore20, glMultiTexCoord3dv)
337 || !FindProcShort (myGlCore20, glMultiTexCoord3f)
338 || !FindProcShort (myGlCore20, glMultiTexCoord3fv)
339 || !FindProcShort (myGlCore20, glMultiTexCoord3i)
340 || !FindProcShort (myGlCore20, glMultiTexCoord3iv)
341 || !FindProcShort (myGlCore20, glMultiTexCoord3s)
342 || !FindProcShort (myGlCore20, glMultiTexCoord3sv)
343 || !FindProcShort (myGlCore20, glMultiTexCoord4d)
344 || !FindProcShort (myGlCore20, glMultiTexCoord4dv)
345 || !FindProcShort (myGlCore20, glMultiTexCoord4f)
346 || !FindProcShort (myGlCore20, glMultiTexCoord4fv)
347 || !FindProcShort (myGlCore20, glMultiTexCoord4i)
348 || !FindProcShort (myGlCore20, glMultiTexCoord4iv)
349 || !FindProcShort (myGlCore20, glMultiTexCoord4s)
350 || !FindProcShort (myGlCore20, glMultiTexCoord4sv)
351 || !FindProcShort (myGlCore20, glLoadTransposeMatrixf)
352 || !FindProcShort (myGlCore20, glLoadTransposeMatrixd)
353 || !FindProcShort (myGlCore20, glMultTransposeMatrixf)
354 || !FindProcShort (myGlCore20, glMultTransposeMatrixd))
362 // initialize OpenGL 1.4 core functionality
363 if (IsGlUpperEqual (1, 4))
365 if (!FindProcShort (myGlCore20, glBlendFuncSeparate)
366 || !FindProcShort (myGlCore20, glMultiDrawArrays)
367 || !FindProcShort (myGlCore20, glMultiDrawElements)
368 || !FindProcShort (myGlCore20, glPointParameterf)
369 || !FindProcShort (myGlCore20, glPointParameterfv)
370 || !FindProcShort (myGlCore20, glPointParameteri)
371 || !FindProcShort (myGlCore20, glPointParameteriv))
380 // initialize OpenGL 1.5 core functionality
381 if (IsGlUpperEqual (1, 5))
383 if (!FindProcShort (myGlCore20, glGenQueries)
384 || !FindProcShort (myGlCore20, glDeleteQueries)
385 || !FindProcShort (myGlCore20, glIsQuery)
386 || !FindProcShort (myGlCore20, glBeginQuery)
387 || !FindProcShort (myGlCore20, glEndQuery)
388 || !FindProcShort (myGlCore20, glGetQueryiv)
389 || !FindProcShort (myGlCore20, glGetQueryObjectiv)
390 || !FindProcShort (myGlCore20, glGetQueryObjectuiv)
391 || !FindProcShort (myGlCore20, glBindBuffer)
392 || !FindProcShort (myGlCore20, glDeleteBuffers)
393 || !FindProcShort (myGlCore20, glGenBuffers)
394 || !FindProcShort (myGlCore20, glIsBuffer)
395 || !FindProcShort (myGlCore20, glBufferData)
396 || !FindProcShort (myGlCore20, glBufferSubData)
397 || !FindProcShort (myGlCore20, glGetBufferSubData)
398 || !FindProcShort (myGlCore20, glMapBuffer)
399 || !FindProcShort (myGlCore20, glUnmapBuffer)
400 || !FindProcShort (myGlCore20, glGetBufferParameteriv)
401 || !FindProcShort (myGlCore20, glGetBufferPointerv))
411 // initialize OpenGL 2.0 core functionality
412 if (IsGlUpperEqual (2, 0))
414 if (!FindProcShort (myGlCore20, glBlendEquationSeparate)
415 || !FindProcShort (myGlCore20, glDrawBuffers)
416 || !FindProcShort (myGlCore20, glStencilOpSeparate)
417 || !FindProcShort (myGlCore20, glStencilFuncSeparate)
418 || !FindProcShort (myGlCore20, glStencilMaskSeparate)
419 || !FindProcShort (myGlCore20, glAttachShader)
420 || !FindProcShort (myGlCore20, glBindAttribLocation)
421 || !FindProcShort (myGlCore20, glCompileShader)
422 || !FindProcShort (myGlCore20, glCreateProgram)
423 || !FindProcShort (myGlCore20, glCreateShader)
424 || !FindProcShort (myGlCore20, glDeleteProgram)
425 || !FindProcShort (myGlCore20, glDeleteShader)
426 || !FindProcShort (myGlCore20, glDetachShader)
427 || !FindProcShort (myGlCore20, glDisableVertexAttribArray)
428 || !FindProcShort (myGlCore20, glEnableVertexAttribArray)
429 || !FindProcShort (myGlCore20, glGetActiveAttrib)
430 || !FindProcShort (myGlCore20, glGetActiveUniform)
431 || !FindProcShort (myGlCore20, glGetAttachedShaders)
432 || !FindProcShort (myGlCore20, glGetAttribLocation)
433 || !FindProcShort (myGlCore20, glGetProgramiv)
434 || !FindProcShort (myGlCore20, glGetProgramInfoLog)
435 || !FindProcShort (myGlCore20, glGetShaderiv)
436 || !FindProcShort (myGlCore20, glGetShaderInfoLog)
437 || !FindProcShort (myGlCore20, glGetShaderSource)
438 || !FindProcShort (myGlCore20, glGetUniformLocation)
439 || !FindProcShort (myGlCore20, glGetUniformfv)
440 || !FindProcShort (myGlCore20, glGetUniformiv)
441 || !FindProcShort (myGlCore20, glGetVertexAttribdv)
442 || !FindProcShort (myGlCore20, glGetVertexAttribfv)
443 || !FindProcShort (myGlCore20, glGetVertexAttribiv)
444 || !FindProcShort (myGlCore20, glGetVertexAttribPointerv)
445 || !FindProcShort (myGlCore20, glIsProgram)
446 || !FindProcShort (myGlCore20, glIsShader)
447 || !FindProcShort (myGlCore20, glLinkProgram)
448 || !FindProcShort (myGlCore20, glShaderSource)
449 || !FindProcShort (myGlCore20, glUseProgram)
450 || !FindProcShort (myGlCore20, glUniform1f)
451 || !FindProcShort (myGlCore20, glUniform2f)
452 || !FindProcShort (myGlCore20, glUniform3f)
453 || !FindProcShort (myGlCore20, glUniform4f)
454 || !FindProcShort (myGlCore20, glUniform1i)
455 || !FindProcShort (myGlCore20, glUniform2i)
456 || !FindProcShort (myGlCore20, glUniform3i)
457 || !FindProcShort (myGlCore20, glUniform4i)
458 || !FindProcShort (myGlCore20, glUniform1fv)
459 || !FindProcShort (myGlCore20, glUniform2fv)
460 || !FindProcShort (myGlCore20, glUniform3fv)
461 || !FindProcShort (myGlCore20, glUniform4fv)
462 || !FindProcShort (myGlCore20, glUniform1iv)
463 || !FindProcShort (myGlCore20, glUniform2iv)
464 || !FindProcShort (myGlCore20, glUniform3iv)
465 || !FindProcShort (myGlCore20, glUniform4iv)
466 || !FindProcShort (myGlCore20, glUniformMatrix2fv)
467 || !FindProcShort (myGlCore20, glUniformMatrix3fv)
468 || !FindProcShort (myGlCore20, glUniformMatrix4fv)
469 || !FindProcShort (myGlCore20, glValidateProgram)
470 || !FindProcShort (myGlCore20, glVertexAttrib1d)
471 || !FindProcShort (myGlCore20, glVertexAttrib1dv)
472 || !FindProcShort (myGlCore20, glVertexAttrib1f)
473 || !FindProcShort (myGlCore20, glVertexAttrib1fv)
474 || !FindProcShort (myGlCore20, glVertexAttrib1s)
475 || !FindProcShort (myGlCore20, glVertexAttrib1sv)
476 || !FindProcShort (myGlCore20, glVertexAttrib2d)
477 || !FindProcShort (myGlCore20, glVertexAttrib2dv)
478 || !FindProcShort (myGlCore20, glVertexAttrib2f)
479 || !FindProcShort (myGlCore20, glVertexAttrib2fv)
480 || !FindProcShort (myGlCore20, glVertexAttrib2s)
481 || !FindProcShort (myGlCore20, glVertexAttrib2sv)
482 || !FindProcShort (myGlCore20, glVertexAttrib3d)
483 || !FindProcShort (myGlCore20, glVertexAttrib3dv)
484 || !FindProcShort (myGlCore20, glVertexAttrib3f)
485 || !FindProcShort (myGlCore20, glVertexAttrib3fv)
486 || !FindProcShort (myGlCore20, glVertexAttrib3s)
487 || !FindProcShort (myGlCore20, glVertexAttrib3sv)
488 || !FindProcShort (myGlCore20, glVertexAttrib4Nbv)
489 || !FindProcShort (myGlCore20, glVertexAttrib4Niv)
490 || !FindProcShort (myGlCore20, glVertexAttrib4Nsv)
491 || !FindProcShort (myGlCore20, glVertexAttrib4Nub)
492 || !FindProcShort (myGlCore20, glVertexAttrib4Nubv)
493 || !FindProcShort (myGlCore20, glVertexAttrib4Nuiv)
494 || !FindProcShort (myGlCore20, glVertexAttrib4Nusv)
495 || !FindProcShort (myGlCore20, glVertexAttrib4bv)
496 || !FindProcShort (myGlCore20, glVertexAttrib4d)
497 || !FindProcShort (myGlCore20, glVertexAttrib4dv)
498 || !FindProcShort (myGlCore20, glVertexAttrib4f)
499 || !FindProcShort (myGlCore20, glVertexAttrib4fv)
500 || !FindProcShort (myGlCore20, glVertexAttrib4iv)
501 || !FindProcShort (myGlCore20, glVertexAttrib4s)
502 || !FindProcShort (myGlCore20, glVertexAttrib4sv)
503 || !FindProcShort (myGlCore20, glVertexAttrib4ubv)
504 || !FindProcShort (myGlCore20, glVertexAttrib4uiv)
505 || !FindProcShort (myGlCore20, glVertexAttrib4usv)
506 || !FindProcShort (myGlCore20, glVertexAttribPointer))
517 if (IsGlUpperEqual (2, 0))