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 #include <Standard_ProgramError.hxx>
33 #if (defined(_WIN32) || defined(__WIN32__))
35 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
38 #include <GL/glx.h> // glXGetProcAddress()
41 IMPLEMENT_STANDARD_HANDLE (OpenGl_Context, Standard_Transient)
42 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient)
44 //! Make record shorter to retrieve function pointer using variable with same name
45 #define FindProcShort(theStruct, theFunc) FindProc(#theFunc, theStruct->theFunc)
47 // =======================================================================
48 // function : OpenGl_Context
50 // =======================================================================
51 OpenGl_Context::OpenGl_Context()
63 myIsInitialized (Standard_False)
65 #if defined(MAC_OS_X_VERSION_10_3) && !defined(MACOSX_USE_GLX)
66 // Vendors can not extend functionality on this system
67 // and developers are limited to OpenGL support provided by Mac OS X SDK.
68 // We retrieve function pointers from system library
69 // to generalize extensions support on all platforms.
70 // In this way we also reach binary compatibility benefit between OS releases
71 // if some newest functionality is optionally used.
72 // Notice that GL version / extension availability checks are required
73 // because function pointers may be available but not functionality itself
74 // (depends on renderer).
75 myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
79 // =======================================================================
80 // function : ~OpenGl_Context
82 // =======================================================================
83 OpenGl_Context::~OpenGl_Context()
90 // =======================================================================
91 // function : MakeCurrent
93 // =======================================================================
94 Standard_Boolean OpenGl_Context::MakeCurrent()
96 #if (defined(_WIN32) || defined(__WIN32__))
97 if (myWindowDC == NULL || myGContext == NULL ||
98 !wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext))
100 //GLenum anErrCode = glGetError();
101 //const GLubyte* anErrorString = gluErrorString (anErrCode);
102 //std::cerr << "wglMakeCurrent() failed: " << anErrCode << " " << anErrorString << "\n";
103 return Standard_False;
106 if (myDisplay == NULL || myWindow == 0 || myGContext == 0 ||
107 !glXMakeCurrent ((Display* )myDisplay, (GLXDrawable )myWindow, (GLXContext )myGContext))
109 // if there is no current context it might be impossible to use glGetError() correctly
110 //std::cerr << "glXMakeCurrent() failed!\n";
111 return Standard_False;
114 return Standard_True;
117 // =======================================================================
118 // function : findProc
120 // =======================================================================
121 void* OpenGl_Context::findProc (const char* theFuncName)
123 #if (defined(_WIN32) || defined(__WIN32__))
124 return wglGetProcAddress (theFuncName);
125 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
126 return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
128 return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
132 // =======================================================================
133 // function : CheckExtension
135 // =======================================================================
136 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
138 if (theExtName == NULL)
140 std::cerr << "CheckExtension called with NULL string!\n";
141 return Standard_False;
143 int anExtNameLen = strlen (theExtName);
145 // available since OpenGL 3.0
146 // and the ONLY way to check extensions with OpenGL 3.1+ core profile
147 /**if (IsGlGreaterEqual (3, 0))
150 glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
151 for (GLint anIter = 0; anIter < anExtNb; ++anIter)
153 const char* anExtension = (const char* )core30->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
154 if (anExtension[anExtNameLen] == '\0' &&
155 strncmp (anExtension, theExtName, anExtNameLen) == 0)
157 return Standard_True;
160 return Standard_False;
163 // use old way with huge string for all extensions
164 const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
165 if (anExtString == NULL)
167 std::cerr << "glGetString (GL_EXTENSIONS) returns NULL! No GL context?\n";
168 return Standard_False;
171 // Search for theExtName in the extensions string.
172 // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
173 char* aPtrIter = (char* )anExtString;
174 const char* aPtrEnd = aPtrIter + strlen (anExtString);
175 while (aPtrIter < aPtrEnd)
177 int n = strcspn (aPtrIter, " ");
178 if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
180 return Standard_True;
184 return Standard_False;
187 // =======================================================================
190 // =======================================================================
191 void OpenGl_Context::Init()
198 #if (defined(_WIN32) || defined(__WIN32__))
199 myWindowDC = (Aspect_Handle )wglGetCurrentDC();
200 myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
202 myDisplay = (Aspect_Display )glXGetCurrentDisplay();
203 myGContext = (Aspect_RenderingContext )glXGetCurrentContext();
204 myWindow = (Aspect_Drawable )glXGetCurrentDrawable();
208 myIsInitialized = Standard_True;
211 // =======================================================================
214 // =======================================================================
215 #if (defined(_WIN32) || defined(__WIN32__))
216 void OpenGl_Context::Init (const Aspect_Handle theWindow,
217 const Aspect_Handle theWindowDC,
218 const Aspect_RenderingContext theGContext)
220 void OpenGl_Context::Init (const Aspect_Drawable theWindow,
221 const Aspect_Display theDisplay,
222 const Aspect_RenderingContext theGContext)
225 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
227 myWindow = theWindow;
228 myGContext = theGContext;
229 #if (defined(_WIN32) || defined(__WIN32__))
230 myWindowDC = theWindowDC;
232 myDisplay = theDisplay;
236 myIsInitialized = Standard_True;
239 // =======================================================================
240 // function : ResetErrors
242 // =======================================================================
243 void OpenGl_Context::ResetErrors()
245 while (glGetError() != GL_NO_ERROR)
251 // =======================================================================
252 // function : readGlVersion
254 // =======================================================================
255 void OpenGl_Context::readGlVersion()
261 // available since OpenGL 3.0
262 GLint aMajor, aMinor;
263 glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
264 glGetIntegerv (GL_MINOR_VERSION, &aMinor);
265 if (glGetError() == GL_NO_ERROR)
267 myGlVerMajor = aMajor;
268 myGlVerMinor = aMinor;
273 // Read version string.
274 // Notice that only first two numbers splitted by point '2.1 XXXXX' are significant.
275 // Following trash (after space) is vendor-specific.
276 // New drivers also returns micro version of GL like '3.3.0' which has no meaning
277 // and should be considered as vendor-specific too.
278 const char* aVerStr = (const char* )glGetString (GL_VERSION);
279 if (aVerStr == NULL || *aVerStr == '\0')
281 // invalid GL context
285 // parse string for major number
289 while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
293 if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
297 memcpy (aMajorStr, aVerStr, aMajIter);
298 aMajorStr[aMajIter] = '\0';
300 // parse string for minor number
301 size_t aMinIter = aMajIter + 1;
302 while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
306 size_t aMinLen = aMinIter - aMajIter - 1;
307 if (aMinLen == 0 || aMinLen >= sizeof(aMinorStr))
311 memcpy (aMinorStr, aVerStr, aMinLen);
312 aMinorStr[aMinLen] = '\0';
315 myGlVerMajor = atoi (aMajorStr);
316 myGlVerMinor = atoi (aMinorStr);
318 if (myGlVerMajor <= 0)
325 // =======================================================================
328 // =======================================================================
329 void OpenGl_Context::init()
334 // initialize VBO extension (ARB)
335 if (CheckExtension ("GL_ARB_vertex_buffer_object"))
337 arbVBO = new OpenGl_ArbVBO();
338 memset (arbVBO, 0, sizeof(OpenGl_ArbVBO)); // nullify whole structure
339 if (!FindProcShort (arbVBO, glGenBuffersARB)
340 || !FindProcShort (arbVBO, glBindBufferARB)
341 || !FindProcShort (arbVBO, glBufferDataARB)
342 || !FindProcShort (arbVBO, glDeleteBuffersARB))
349 // initialize FBO extension (EXT)
350 if (CheckExtension ("GL_EXT_framebuffer_object"))
352 extFBO = new OpenGl_ExtFBO();
353 memset (extFBO, 0, sizeof(OpenGl_ExtFBO)); // nullify whole structure
354 if (!FindProcShort (extFBO, glGenFramebuffersEXT)
355 || !FindProcShort (extFBO, glDeleteFramebuffersEXT)
356 || !FindProcShort (extFBO, glBindFramebufferEXT)
357 || !FindProcShort (extFBO, glFramebufferTexture2DEXT)
358 || !FindProcShort (extFBO, glCheckFramebufferStatusEXT)
359 || !FindProcShort (extFBO, glGenRenderbuffersEXT)
360 || !FindProcShort (extFBO, glDeleteRenderbuffersEXT)
361 || !FindProcShort (extFBO, glBindRenderbufferEXT)
362 || !FindProcShort (extFBO, glRenderbufferStorageEXT)
363 || !FindProcShort (extFBO, glFramebufferRenderbufferEXT))
370 myGlCore20 = new OpenGl_GlCore20();
371 memset (myGlCore20, 0, sizeof(OpenGl_GlCore20)); // nullify whole structure
373 // initialize OpenGL 1.2 core functionality
374 if (IsGlGreaterEqual (1, 2))
376 if (!FindProcShort (myGlCore20, glBlendColor)
377 || !FindProcShort (myGlCore20, glBlendEquation)
378 || !FindProcShort (myGlCore20, glDrawRangeElements)
379 || !FindProcShort (myGlCore20, glTexImage3D)
380 || !FindProcShort (myGlCore20, glTexSubImage3D)
381 || !FindProcShort (myGlCore20, glCopyTexSubImage3D))
388 // initialize OpenGL 1.3 core functionality
389 if (IsGlGreaterEqual (1, 3))
391 if (!FindProcShort (myGlCore20, glActiveTexture)
392 || !FindProcShort (myGlCore20, glSampleCoverage)
393 || !FindProcShort (myGlCore20, glCompressedTexImage3D)
394 || !FindProcShort (myGlCore20, glCompressedTexImage2D)
395 || !FindProcShort (myGlCore20, glCompressedTexImage1D)
396 || !FindProcShort (myGlCore20, glCompressedTexSubImage3D)
397 || !FindProcShort (myGlCore20, glCompressedTexSubImage2D)
398 || !FindProcShort (myGlCore20, glCompressedTexSubImage1D)
399 || !FindProcShort (myGlCore20, glGetCompressedTexImage)
401 || !FindProcShort (myGlCore20, glClientActiveTexture)
402 || !FindProcShort (myGlCore20, glMultiTexCoord1d)
403 || !FindProcShort (myGlCore20, glMultiTexCoord1dv)
404 || !FindProcShort (myGlCore20, glMultiTexCoord1f)
405 || !FindProcShort (myGlCore20, glMultiTexCoord1fv)
406 || !FindProcShort (myGlCore20, glMultiTexCoord1i)
407 || !FindProcShort (myGlCore20, glMultiTexCoord1iv)
408 || !FindProcShort (myGlCore20, glMultiTexCoord1s)
409 || !FindProcShort (myGlCore20, glMultiTexCoord1sv)
410 || !FindProcShort (myGlCore20, glMultiTexCoord2d)
411 || !FindProcShort (myGlCore20, glMultiTexCoord2dv)
412 || !FindProcShort (myGlCore20, glMultiTexCoord2f)
413 || !FindProcShort (myGlCore20, glMultiTexCoord2fv)
414 || !FindProcShort (myGlCore20, glMultiTexCoord2i)
415 || !FindProcShort (myGlCore20, glMultiTexCoord2iv)
416 || !FindProcShort (myGlCore20, glMultiTexCoord2s)
417 || !FindProcShort (myGlCore20, glMultiTexCoord2sv)
418 || !FindProcShort (myGlCore20, glMultiTexCoord3d)
419 || !FindProcShort (myGlCore20, glMultiTexCoord3dv)
420 || !FindProcShort (myGlCore20, glMultiTexCoord3f)
421 || !FindProcShort (myGlCore20, glMultiTexCoord3fv)
422 || !FindProcShort (myGlCore20, glMultiTexCoord3i)
423 || !FindProcShort (myGlCore20, glMultiTexCoord3iv)
424 || !FindProcShort (myGlCore20, glMultiTexCoord3s)
425 || !FindProcShort (myGlCore20, glMultiTexCoord3sv)
426 || !FindProcShort (myGlCore20, glMultiTexCoord4d)
427 || !FindProcShort (myGlCore20, glMultiTexCoord4dv)
428 || !FindProcShort (myGlCore20, glMultiTexCoord4f)
429 || !FindProcShort (myGlCore20, glMultiTexCoord4fv)
430 || !FindProcShort (myGlCore20, glMultiTexCoord4i)
431 || !FindProcShort (myGlCore20, glMultiTexCoord4iv)
432 || !FindProcShort (myGlCore20, glMultiTexCoord4s)
433 || !FindProcShort (myGlCore20, glMultiTexCoord4sv)
434 || !FindProcShort (myGlCore20, glLoadTransposeMatrixf)
435 || !FindProcShort (myGlCore20, glLoadTransposeMatrixd)
436 || !FindProcShort (myGlCore20, glMultTransposeMatrixf)
437 || !FindProcShort (myGlCore20, glMultTransposeMatrixd))
445 // initialize OpenGL 1.4 core functionality
446 if (IsGlGreaterEqual (1, 4))
448 if (!FindProcShort (myGlCore20, glBlendFuncSeparate)
449 || !FindProcShort (myGlCore20, glMultiDrawArrays)
450 || !FindProcShort (myGlCore20, glMultiDrawElements)
451 || !FindProcShort (myGlCore20, glPointParameterf)
452 || !FindProcShort (myGlCore20, glPointParameterfv)
453 || !FindProcShort (myGlCore20, glPointParameteri)
454 || !FindProcShort (myGlCore20, glPointParameteriv))
463 // initialize OpenGL 1.5 core functionality
464 if (IsGlGreaterEqual (1, 5))
466 if (!FindProcShort (myGlCore20, glGenQueries)
467 || !FindProcShort (myGlCore20, glDeleteQueries)
468 || !FindProcShort (myGlCore20, glIsQuery)
469 || !FindProcShort (myGlCore20, glBeginQuery)
470 || !FindProcShort (myGlCore20, glEndQuery)
471 || !FindProcShort (myGlCore20, glGetQueryiv)
472 || !FindProcShort (myGlCore20, glGetQueryObjectiv)
473 || !FindProcShort (myGlCore20, glGetQueryObjectuiv)
474 || !FindProcShort (myGlCore20, glBindBuffer)
475 || !FindProcShort (myGlCore20, glDeleteBuffers)
476 || !FindProcShort (myGlCore20, glGenBuffers)
477 || !FindProcShort (myGlCore20, glIsBuffer)
478 || !FindProcShort (myGlCore20, glBufferData)
479 || !FindProcShort (myGlCore20, glBufferSubData)
480 || !FindProcShort (myGlCore20, glGetBufferSubData)
481 || !FindProcShort (myGlCore20, glMapBuffer)
482 || !FindProcShort (myGlCore20, glUnmapBuffer)
483 || !FindProcShort (myGlCore20, glGetBufferParameteriv)
484 || !FindProcShort (myGlCore20, glGetBufferPointerv))
494 // initialize OpenGL 2.0 core functionality
495 if (IsGlGreaterEqual (2, 0))
497 if (!FindProcShort (myGlCore20, glBlendEquationSeparate)
498 || !FindProcShort (myGlCore20, glDrawBuffers)
499 || !FindProcShort (myGlCore20, glStencilOpSeparate)
500 || !FindProcShort (myGlCore20, glStencilFuncSeparate)
501 || !FindProcShort (myGlCore20, glStencilMaskSeparate)
502 || !FindProcShort (myGlCore20, glAttachShader)
503 || !FindProcShort (myGlCore20, glBindAttribLocation)
504 || !FindProcShort (myGlCore20, glCompileShader)
505 || !FindProcShort (myGlCore20, glCreateProgram)
506 || !FindProcShort (myGlCore20, glCreateShader)
507 || !FindProcShort (myGlCore20, glDeleteProgram)
508 || !FindProcShort (myGlCore20, glDeleteShader)
509 || !FindProcShort (myGlCore20, glDetachShader)
510 || !FindProcShort (myGlCore20, glDisableVertexAttribArray)
511 || !FindProcShort (myGlCore20, glEnableVertexAttribArray)
512 || !FindProcShort (myGlCore20, glGetActiveAttrib)
513 || !FindProcShort (myGlCore20, glGetActiveUniform)
514 || !FindProcShort (myGlCore20, glGetAttachedShaders)
515 || !FindProcShort (myGlCore20, glGetAttribLocation)
516 || !FindProcShort (myGlCore20, glGetProgramiv)
517 || !FindProcShort (myGlCore20, glGetProgramInfoLog)
518 || !FindProcShort (myGlCore20, glGetShaderiv)
519 || !FindProcShort (myGlCore20, glGetShaderInfoLog)
520 || !FindProcShort (myGlCore20, glGetShaderSource)
521 || !FindProcShort (myGlCore20, glGetUniformLocation)
522 || !FindProcShort (myGlCore20, glGetUniformfv)
523 || !FindProcShort (myGlCore20, glGetUniformiv)
524 || !FindProcShort (myGlCore20, glGetVertexAttribdv)
525 || !FindProcShort (myGlCore20, glGetVertexAttribfv)
526 || !FindProcShort (myGlCore20, glGetVertexAttribiv)
527 || !FindProcShort (myGlCore20, glGetVertexAttribPointerv)
528 || !FindProcShort (myGlCore20, glIsProgram)
529 || !FindProcShort (myGlCore20, glIsShader)
530 || !FindProcShort (myGlCore20, glLinkProgram)
531 || !FindProcShort (myGlCore20, glShaderSource)
532 || !FindProcShort (myGlCore20, glUseProgram)
533 || !FindProcShort (myGlCore20, glUniform1f)
534 || !FindProcShort (myGlCore20, glUniform2f)
535 || !FindProcShort (myGlCore20, glUniform3f)
536 || !FindProcShort (myGlCore20, glUniform4f)
537 || !FindProcShort (myGlCore20, glUniform1i)
538 || !FindProcShort (myGlCore20, glUniform2i)
539 || !FindProcShort (myGlCore20, glUniform3i)
540 || !FindProcShort (myGlCore20, glUniform4i)
541 || !FindProcShort (myGlCore20, glUniform1fv)
542 || !FindProcShort (myGlCore20, glUniform2fv)
543 || !FindProcShort (myGlCore20, glUniform3fv)
544 || !FindProcShort (myGlCore20, glUniform4fv)
545 || !FindProcShort (myGlCore20, glUniform1iv)
546 || !FindProcShort (myGlCore20, glUniform2iv)
547 || !FindProcShort (myGlCore20, glUniform3iv)
548 || !FindProcShort (myGlCore20, glUniform4iv)
549 || !FindProcShort (myGlCore20, glUniformMatrix2fv)
550 || !FindProcShort (myGlCore20, glUniformMatrix3fv)
551 || !FindProcShort (myGlCore20, glUniformMatrix4fv)
552 || !FindProcShort (myGlCore20, glValidateProgram)
553 || !FindProcShort (myGlCore20, glVertexAttrib1d)
554 || !FindProcShort (myGlCore20, glVertexAttrib1dv)
555 || !FindProcShort (myGlCore20, glVertexAttrib1f)
556 || !FindProcShort (myGlCore20, glVertexAttrib1fv)
557 || !FindProcShort (myGlCore20, glVertexAttrib1s)
558 || !FindProcShort (myGlCore20, glVertexAttrib1sv)
559 || !FindProcShort (myGlCore20, glVertexAttrib2d)
560 || !FindProcShort (myGlCore20, glVertexAttrib2dv)
561 || !FindProcShort (myGlCore20, glVertexAttrib2f)
562 || !FindProcShort (myGlCore20, glVertexAttrib2fv)
563 || !FindProcShort (myGlCore20, glVertexAttrib2s)
564 || !FindProcShort (myGlCore20, glVertexAttrib2sv)
565 || !FindProcShort (myGlCore20, glVertexAttrib3d)
566 || !FindProcShort (myGlCore20, glVertexAttrib3dv)
567 || !FindProcShort (myGlCore20, glVertexAttrib3f)
568 || !FindProcShort (myGlCore20, glVertexAttrib3fv)
569 || !FindProcShort (myGlCore20, glVertexAttrib3s)
570 || !FindProcShort (myGlCore20, glVertexAttrib3sv)
571 || !FindProcShort (myGlCore20, glVertexAttrib4Nbv)
572 || !FindProcShort (myGlCore20, glVertexAttrib4Niv)
573 || !FindProcShort (myGlCore20, glVertexAttrib4Nsv)
574 || !FindProcShort (myGlCore20, glVertexAttrib4Nub)
575 || !FindProcShort (myGlCore20, glVertexAttrib4Nubv)
576 || !FindProcShort (myGlCore20, glVertexAttrib4Nuiv)
577 || !FindProcShort (myGlCore20, glVertexAttrib4Nusv)
578 || !FindProcShort (myGlCore20, glVertexAttrib4bv)
579 || !FindProcShort (myGlCore20, glVertexAttrib4d)
580 || !FindProcShort (myGlCore20, glVertexAttrib4dv)
581 || !FindProcShort (myGlCore20, glVertexAttrib4f)
582 || !FindProcShort (myGlCore20, glVertexAttrib4fv)
583 || !FindProcShort (myGlCore20, glVertexAttrib4iv)
584 || !FindProcShort (myGlCore20, glVertexAttrib4s)
585 || !FindProcShort (myGlCore20, glVertexAttrib4sv)
586 || !FindProcShort (myGlCore20, glVertexAttrib4ubv)
587 || !FindProcShort (myGlCore20, glVertexAttrib4uiv)
588 || !FindProcShort (myGlCore20, glVertexAttrib4usv)
589 || !FindProcShort (myGlCore20, glVertexAttribPointer))
600 if (IsGlGreaterEqual (2, 0))