291b73c08d9557a335a180a1b9bd7f33ae90a89e
[occt.git] / src / OpenGl / OpenGl_Context.cxx
1 // Created on: 2012-01-26
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 2012-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #if defined(_WIN32)
17   #include <windows.h>
18 #endif
19
20 #include <OpenGl_Context.hxx>
21
22 #include <OpenGl_ArbTBO.hxx>
23 #include <OpenGl_ArbIns.hxx>
24 #include <OpenGl_ArbDbg.hxx>
25 #include <OpenGl_ArbFBO.hxx>
26 #include <OpenGl_ExtGS.hxx>
27 #include <OpenGl_ArbTexBindless.hxx>
28 #include <OpenGl_GlCore44.hxx>
29 #include <OpenGl_FrameBuffer.hxx>
30 #include <OpenGl_Sampler.hxx>
31 #include <OpenGl_ShaderManager.hxx>
32 #include <Graphic3d_TransformUtils.hxx>
33
34 #include <Message_Messenger.hxx>
35
36 #include <NCollection_Vector.hxx>
37
38 #include <Standard_ProgramError.hxx>
39
40 #if defined(HAVE_EGL)
41   #include <EGL/egl.h>
42   #ifdef _MSC_VER
43     #pragma comment(lib, "libEGL.lib")
44   #endif
45 #elif defined(_WIN32)
46   //
47 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
48   #include <dlfcn.h>
49   #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
50     //
51   #else
52     #include <OpenGL/OpenGL.h>
53   #endif
54 #else
55   #include <GL/glx.h> // glXGetProcAddress()
56 #endif
57
58 #ifdef HAVE_GL2PS
59   #include <gl2ps.h>
60   #ifdef _MSC_VER
61     #pragma comment (lib, "gl2ps.lib")
62   #endif
63 #endif
64
65
66 namespace
67 {
68   static const Handle(OpenGl_Resource) NULL_GL_RESOURCE;
69 }
70
71 // =======================================================================
72 // function : OpenGl_Context
73 // purpose  :
74 // =======================================================================
75 OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
76 : core11     (NULL),
77   core11fwd  (NULL),
78   core15     (NULL),
79   core15fwd  (NULL),
80   core20     (NULL),
81   core20fwd  (NULL),
82   core32     (NULL),
83   core32back (NULL),
84   core33     (NULL),
85   core33back (NULL),
86   core41     (NULL),
87   core41back (NULL),
88   core42     (NULL),
89   core42back (NULL),
90   core43     (NULL),
91   core43back (NULL),
92   core44     (NULL),
93   core44back (NULL),
94   caps   (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()),
95 #if defined(GL_ES_VERSION_2_0)
96   hasHighp   (Standard_False),
97   hasUintIndex(Standard_False),
98   hasTexRGBA8(Standard_False),
99 #else
100   hasHighp   (Standard_True),
101   hasUintIndex(Standard_True),
102   hasTexRGBA8(Standard_True),
103 #endif
104   arbNPTW  (Standard_False),
105   arbTexRG (Standard_False),
106   arbTexBindless (NULL),
107   arbTBO (NULL),
108   arbTboRGB32 (Standard_False),
109   arbIns (NULL),
110   arbDbg (NULL),
111   arbFBO (NULL),
112   arbFBOBlit (NULL),
113   extGS  (NULL),
114   extBgra(Standard_False),
115   extAnis(Standard_False),
116   extPDS (Standard_False),
117   atiMem (Standard_False),
118   nvxMem (Standard_False),
119   mySharedResources (new OpenGl_ResourcesMap()),
120   myDelayed         (new OpenGl_DelayReleaseMap()),
121   myUnusedResources (new OpenGl_ResourcesStack()),
122   myClippingState (),
123   myGlLibHandle (NULL),
124   myFuncs (new OpenGl_GlFunctions()),
125   myAnisoMax   (1),
126   myTexClamp   (GL_CLAMP_TO_EDGE),
127   myMaxTexDim  (1024),
128   myMaxClipPlanes (6),
129   myMaxMsaaSamples(0),
130   myGlVerMajor (0),
131   myGlVerMinor (0),
132   myIsInitialized (Standard_False),
133   myIsStereoBuffers (Standard_False),
134   myIsGlNormalizeEnabled (Standard_False),
135 #if !defined(GL_ES_VERSION_2_0)
136   myRenderMode (GL_RENDER),
137 #else
138   myRenderMode (0),
139 #endif
140   myReadBuffer (0),
141   myDrawBuffer (0),
142   myDefaultVao (0),
143   myIsGlDebugCtx (Standard_False)
144 {
145   // system-dependent fields
146 #if defined(HAVE_EGL)
147   myDisplay  = (Aspect_Display          )EGL_NO_DISPLAY;
148   myWindow   = (Aspect_Drawable         )EGL_NO_SURFACE;
149   myGContext = (Aspect_RenderingContext )EGL_NO_CONTEXT;
150 #elif defined(_WIN32)
151   myWindow   = NULL;
152   myWindowDC = NULL;
153   myGContext = NULL;
154 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
155   // Vendors can not extend functionality on this system
156   // and developers are limited to OpenGL support provided by Mac OS X SDK.
157   // We retrieve function pointers from system library
158   // to generalize extensions support on all platforms.
159   // In this way we also reach binary compatibility benefit between OS releases
160   // if some newest functionality is optionally used.
161   // Notice that GL version / extension availability checks are required
162   // because function pointers may be available but not functionality itself
163   // (depends on renderer).
164 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
165   myGContext    = NULL;
166   myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGLES.framework/OpenGLES", RTLD_LAZY);
167 #else
168   myGContext    = NULL;
169   myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
170 #endif
171 #else
172   myDisplay =  NULL;
173   myWindow   = 0;
174   myGContext = 0;
175 #endif
176
177   memset (myFuncs.operator->(), 0, sizeof(OpenGl_GlFunctions));
178   myShaderManager = new OpenGl_ShaderManager (this);
179 }
180
181 // =======================================================================
182 // function : ~OpenGl_Context
183 // purpose  :
184 // =======================================================================
185 OpenGl_Context::~OpenGl_Context()
186 {
187   // release clean up queue
188   ReleaseDelayed();
189
190 #if !defined(GL_ES_VERSION_2_0)
191   // release default VAO
192   if (myDefaultVao != 0
193    && IsValid()
194    && core32 != NULL)
195   {
196     core32->glDeleteVertexArrays (1, &myDefaultVao);
197   }
198   myDefaultVao = 0;
199 #endif
200
201   // release default FBO
202   if (!myDefaultFbo.IsNull())
203   {
204     myDefaultFbo->Release (this);
205     myDefaultFbo.Nullify();
206   }
207
208   // release shared resources if any
209   if (((const Handle(Standard_Transient)& )mySharedResources)->GetRefCount() <= 1)
210   {
211     myShaderManager.Nullify();
212     for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
213          anIter.More(); anIter.Next())
214     {
215       anIter.Value()->Release (this);
216     }
217
218     // release delayed resources added during deletion of shared resources
219     while (!myUnusedResources->IsEmpty())
220     {
221       myUnusedResources->First()->Release (this);
222       myUnusedResources->RemoveFirst();
223     }
224   }
225   else if (myShaderManager->IsSameContext (this))
226   {
227     myShaderManager->SetContext (NULL);
228   }
229   mySharedResources.Nullify();
230   myDelayed.Nullify();
231
232   // release sampler object
233   if (!myTexSampler.IsNull())
234   {
235     myTexSampler->Release (this);
236   }
237
238 #if !defined(GL_ES_VERSION_2_0)
239   if (arbDbg != NULL
240    && myIsGlDebugCtx
241    && IsValid())
242   {
243     // reset callback
244     void* aPtr = NULL;
245     glGetPointerv (GL_DEBUG_CALLBACK_USER_PARAM, &aPtr);
246     if (aPtr == this)
247     {
248       arbDbg->glDebugMessageCallbackARB (NULL, NULL);
249     }
250     myIsGlDebugCtx = Standard_False;
251   }
252 #endif
253 }
254
255 // =======================================================================
256 // function : forcedRelease
257 // purpose  :
258 // =======================================================================
259 void OpenGl_Context::forcedRelease()
260 {
261   ReleaseDelayed();
262   for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
263        anIter.More(); anIter.Next())
264   {
265     anIter.Value()->Release (this);
266   }
267   mySharedResources->Clear();
268   myShaderManager->clear();
269   myShaderManager->SetContext (NULL);
270
271   // release delayed resources added during deletion of shared resources
272   while (!myUnusedResources->IsEmpty())
273   {
274     myUnusedResources->First()->Release (this);
275     myUnusedResources->RemoveFirst();
276   }
277 }
278
279 #if !defined(GL_ES_VERSION_2_0)
280 inline Standard_Integer stereoToMonoBuffer (const Standard_Integer theBuffer)
281 {
282   switch (theBuffer)
283   {
284     case GL_BACK_LEFT:
285     case GL_BACK_RIGHT:
286       return GL_BACK;
287     case GL_FRONT_LEFT:
288     case GL_FRONT_RIGHT:
289       return GL_FRONT;
290     default:
291       return theBuffer;
292   }
293 }
294 #endif
295
296 // =======================================================================
297 // function : SetReadBuffer
298 // purpose  :
299 // =======================================================================
300 void OpenGl_Context::SetReadBuffer (const Standard_Integer theReadBuffer)
301 {
302 #if !defined(GL_ES_VERSION_2_0)
303   myReadBuffer = !myIsStereoBuffers ? stereoToMonoBuffer (theReadBuffer) : theReadBuffer;
304   if (myReadBuffer < GL_COLOR_ATTACHMENT0
305    && arbFBO != NULL)
306   {
307     arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
308   }
309   ::glReadBuffer (myReadBuffer);
310 #else
311   (void )theReadBuffer;
312 #endif
313 }
314
315 // =======================================================================
316 // function : SetDrawBuffer
317 // purpose  :
318 // =======================================================================
319 void OpenGl_Context::SetDrawBuffer (const Standard_Integer theDrawBuffer)
320 {
321 #if !defined(GL_ES_VERSION_2_0)
322   myDrawBuffer = !myIsStereoBuffers ? stereoToMonoBuffer (theDrawBuffer) : theDrawBuffer;
323   if (myDrawBuffer < GL_COLOR_ATTACHMENT0
324    && arbFBO != NULL)
325   {
326     arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
327   }
328   ::glDrawBuffer (myDrawBuffer);
329 #else
330   (void )theDrawBuffer;
331 #endif
332 }
333
334 // =======================================================================
335 // function : FetchState
336 // purpose  :
337 // =======================================================================
338 void OpenGl_Context::FetchState()
339 {
340 #if !defined(GL_ES_VERSION_2_0)
341   // cache feedback mode state
342   if (core11 != NULL)
343   {
344     ::glGetIntegerv (GL_RENDER_MODE, &myRenderMode);
345   }
346
347   // cache buffers state
348   ::glGetIntegerv (GL_READ_BUFFER, &myReadBuffer);
349   ::glGetIntegerv (GL_DRAW_BUFFER, &myDrawBuffer);
350 #endif
351 }
352
353 // =======================================================================
354 // function : Share
355 // purpose  :
356 // =======================================================================
357 void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
358 {
359   if (!theShareCtx.IsNull())
360   {
361     mySharedResources = theShareCtx->mySharedResources;
362     myDelayed         = theShareCtx->myDelayed;
363     myUnusedResources = theShareCtx->myUnusedResources;
364     myShaderManager   = theShareCtx->myShaderManager;
365   }
366 }
367
368 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
369
370 // =======================================================================
371 // function : IsCurrent
372 // purpose  :
373 // =======================================================================
374 Standard_Boolean OpenGl_Context::IsCurrent() const
375 {
376 #if defined(HAVE_EGL)
377   if ((EGLDisplay )myDisplay  == EGL_NO_DISPLAY
378    || (EGLSurface )myWindow   == EGL_NO_SURFACE
379    || (EGLContext )myGContext == EGL_NO_CONTEXT)
380   {
381     return Standard_False;
382   }
383
384   return (((EGLDisplay )myDisplay  == eglGetCurrentDisplay())
385        && ((EGLContext )myGContext == eglGetCurrentContext())
386        && ((EGLSurface )myWindow   == eglGetCurrentSurface (EGL_DRAW)));
387 #elif defined(_WIN32)
388   if (myWindowDC == NULL || myGContext == NULL)
389   {
390     return Standard_False;
391   }
392   return (( (HDC )myWindowDC == wglGetCurrentDC())
393       && ((HGLRC )myGContext == wglGetCurrentContext()));
394 #else
395   if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
396   {
397     return Standard_False;
398   }
399
400   return (   ((Display* )myDisplay  == glXGetCurrentDisplay())
401        &&  ((GLXContext )myGContext == glXGetCurrentContext())
402        && ((GLXDrawable )myWindow   == glXGetCurrentDrawable()));
403 #endif
404 }
405
406 // =======================================================================
407 // function : MakeCurrent
408 // purpose  :
409 // =======================================================================
410 Standard_Boolean OpenGl_Context::MakeCurrent()
411 {
412 #if defined(HAVE_EGL)
413   if ((EGLDisplay )myDisplay  == EGL_NO_DISPLAY
414    || (EGLSurface )myWindow   == EGL_NO_SURFACE
415    || (EGLContext )myGContext == EGL_NO_CONTEXT)
416   {
417     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
418     return Standard_False;
419   }
420
421   if (eglMakeCurrent ((EGLDisplay )myDisplay, (EGLSurface )myWindow, (EGLSurface )myWindow, (EGLContext )myGContext) != EGL_TRUE)
422   {
423     // if there is no current context it might be impossible to use glGetError() correctly
424     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
425                  "eglMakeCurrent() has failed!");
426     myIsInitialized = Standard_False;
427     return Standard_False;
428   }
429 #elif defined(_WIN32)
430   if (myWindowDC == NULL || myGContext == NULL)
431   {
432     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
433     return Standard_False;
434   }
435
436   // technically it should be safe to activate already bound GL context
437   // however some drivers (Intel etc.) may FAIL doing this for unknown reason
438   if (IsCurrent())
439   {
440     myShaderManager->SetContext (this);
441     return Standard_True;
442   }
443   else if (wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext) != TRUE)
444   {
445     // notice that glGetError() couldn't be used here!
446     wchar_t* aMsgBuff = NULL;
447     DWORD anErrorCode = GetLastError();
448     FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
449                     NULL, anErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (wchar_t* )&aMsgBuff, 0, NULL);
450     TCollection_ExtendedString aMsg ("wglMakeCurrent() has failed. ");
451     if (aMsgBuff != NULL)
452     {
453       aMsg += (Standard_ExtString )aMsgBuff;
454       LocalFree (aMsgBuff);
455     }
456     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM, GL_DEBUG_TYPE_ERROR, (unsigned int )anErrorCode, GL_DEBUG_SEVERITY_HIGH, aMsg);
457     myIsInitialized = Standard_False;
458     return Standard_False;
459   }
460 #else
461   if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
462   {
463     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
464     return Standard_False;
465   }
466
467   if (!glXMakeCurrent ((Display* )myDisplay, (GLXDrawable )myWindow, (GLXContext )myGContext))
468   {
469     // if there is no current context it might be impossible to use glGetError() correctly
470     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
471                  "glXMakeCurrent() has failed!");
472     myIsInitialized = Standard_False;
473     return Standard_False;
474   }
475 #endif
476   myShaderManager->SetContext (this);
477   return Standard_True;
478 }
479
480 // =======================================================================
481 // function : SwapBuffers
482 // purpose  :
483 // =======================================================================
484 void OpenGl_Context::SwapBuffers()
485 {
486 #if defined(HAVE_EGL)
487   if ((EGLSurface )myWindow != EGL_NO_SURFACE)
488   {
489     eglSwapBuffers ((EGLDisplay )myDisplay, (EGLSurface )myWindow);
490   }
491 #elif defined(_WIN32)
492   if ((HDC )myWindowDC != NULL)
493   {
494     ::SwapBuffers ((HDC )myWindowDC);
495     glFlush();
496   }
497 #else
498   if ((Display* )myDisplay != NULL)
499   {
500     glXSwapBuffers ((Display* )myDisplay, (GLXDrawable )myWindow);
501   }
502 #endif
503 }
504
505 #endif // __APPLE__
506
507 // =======================================================================
508 // function : SetSwapInterval
509 // purpose  :
510 // =======================================================================
511 Standard_Boolean OpenGl_Context::SetSwapInterval (const Standard_Integer theInterval)
512 {
513 #if defined(HAVE_EGL)
514   if (::eglSwapInterval ((EGLDisplay )myDisplay, theInterval) == EGL_TRUE)
515   {
516     return Standard_True;
517   }
518 #elif defined(_WIN32)
519   if (myFuncs->wglSwapIntervalEXT != NULL)
520   {
521     myFuncs->wglSwapIntervalEXT (theInterval);
522     return Standard_True;
523   }
524 #elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
525   //
526 #elif defined(__APPLE__)
527   if (::CGLSetParameter (CGLGetCurrentContext(), kCGLCPSwapInterval, &theInterval) == kCGLNoError)
528   {
529     return Standard_True;
530   }
531 #else
532   if (theInterval == -1
533    && myFuncs->glXSwapIntervalEXT != NULL)
534   {
535     typedef int (*glXSwapIntervalEXT_t_x)(Display* theDisplay, GLXDrawable theDrawable, int theInterval);
536     glXSwapIntervalEXT_t_x aFuncPtr = (glXSwapIntervalEXT_t_x )myFuncs->glXSwapIntervalEXT;
537     aFuncPtr ((Display* )myDisplay, (GLXDrawable )myWindow, theInterval);
538     return Standard_True;
539   }
540   else if (myFuncs->glXSwapIntervalSGI != NULL)
541   {
542     myFuncs->glXSwapIntervalSGI (theInterval);
543     return Standard_True;
544   }
545 #endif
546   return Standard_False;
547 }
548
549 // =======================================================================
550 // function : findProc
551 // purpose  :
552 // =======================================================================
553 void* OpenGl_Context::findProc (const char* theFuncName)
554 {
555 #if defined(HAVE_EGL)
556   return (void* )eglGetProcAddress (theFuncName);
557 #elif defined(_WIN32)
558   return wglGetProcAddress (theFuncName);
559 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
560   return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
561 #else
562   return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
563 #endif
564 }
565
566 // =======================================================================
567 // function : CheckExtension
568 // purpose  :
569 // =======================================================================
570 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
571 {
572   if (theExtName  == NULL)
573   {
574 #ifdef OCCT_DEBUG
575     std::cerr << "CheckExtension called with NULL string!\n";
576 #endif
577     return Standard_False;
578   }
579
580 #if !defined(GL_ES_VERSION_2_0)
581   // available since OpenGL 3.0
582   // and the ONLY way to check extensions with OpenGL 3.1+ core profile
583   if (IsGlGreaterEqual (3, 0)
584    && myFuncs->glGetStringi != NULL)
585   {
586     GLint anExtNb = 0;
587     ::glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
588     const size_t anExtNameLen = strlen (theExtName);
589     for (GLint anIter = 0; anIter < anExtNb; ++anIter)
590     {
591       const char* anExtension = (const char* )myFuncs->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
592       const size_t aTestExtNameLen = strlen (anExtension);
593       if (aTestExtNameLen == anExtNameLen
594        && strncmp (anExtension, theExtName, anExtNameLen) == 0)
595       {
596         return Standard_True;
597       }
598     }
599     return Standard_False;
600   }
601 #endif
602
603   // use old way with huge string for all extensions
604   const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
605   if (anExtString == NULL)
606   {
607     Messenger()->Send ("TKOpenGL: glGetString (GL_EXTENSIONS) has returned NULL! No GL context?", Message_Warning);
608     return Standard_False;
609   }
610   return CheckExtension (anExtString, theExtName);
611 }
612
613 // =======================================================================
614 // function : CheckExtension
615 // purpose  :
616 // =======================================================================
617 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtString,
618                                                  const char* theExtName)
619 {
620   if (theExtString == NULL)
621   {
622     return Standard_False;
623   }
624
625   // Search for theExtName in the extensions string.
626   // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
627   char* aPtrIter = (char* )theExtString;
628   const char*  aPtrEnd      = aPtrIter + strlen (theExtString);
629   const size_t anExtNameLen = strlen (theExtName);
630   while (aPtrIter < aPtrEnd)
631   {
632     const size_t n = strcspn (aPtrIter, " ");
633     if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
634     {
635       return Standard_True;
636     }
637     aPtrIter += (n + 1);
638   }
639   return Standard_False;
640 }
641
642 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
643
644 // =======================================================================
645 // function : Init
646 // purpose  :
647 // =======================================================================
648 Standard_Boolean OpenGl_Context::Init (const Standard_Boolean theIsCoreProfile)
649 {
650   if (myIsInitialized)
651   {
652     return Standard_True;
653   }
654
655 #if defined(HAVE_EGL)
656   myDisplay  = (Aspect_Display )eglGetCurrentDisplay();
657   myGContext = (Aspect_RenderingContext )eglGetCurrentContext();
658   myWindow   = (Aspect_Drawable )eglGetCurrentSurface(EGL_DRAW);
659 #elif defined(_WIN32)
660   myWindowDC = (Aspect_Handle )wglGetCurrentDC();
661   myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
662 #else
663   myDisplay  = (Aspect_Display )glXGetCurrentDisplay();
664   myGContext = (Aspect_RenderingContext )glXGetCurrentContext();
665   myWindow   = (Aspect_Drawable )glXGetCurrentDrawable();
666 #endif
667   if (myGContext == NULL)
668   {
669     return Standard_False;
670   }
671
672   init (theIsCoreProfile);
673   myIsInitialized = Standard_True;
674   return Standard_True;
675 }
676
677 #endif // __APPLE__
678
679 // =======================================================================
680 // function : Init
681 // purpose  :
682 // =======================================================================
683 #if defined(HAVE_EGL)
684 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theEglSurface,
685                                        const Aspect_Display          theEglDisplay,
686                                        const Aspect_RenderingContext theEglContext,
687                                        const Standard_Boolean        theIsCoreProfile)
688 #elif defined(_WIN32)
689 Standard_Boolean OpenGl_Context::Init (const Aspect_Handle           theWindow,
690                                        const Aspect_Handle           theWindowDC,
691                                        const Aspect_RenderingContext theGContext,
692                                        const Standard_Boolean        theIsCoreProfile)
693 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
694
695 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
696 Standard_Boolean OpenGl_Context::Init (EAGLContext*                  theGContext,
697                                        const Standard_Boolean        theIsCoreProfile)
698 #else
699 Standard_Boolean OpenGl_Context::Init (NSOpenGLContext*              theGContext,
700                                        const Standard_Boolean        theIsCoreProfile)
701 #endif
702
703 #else
704 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theWindow,
705                                        const Aspect_Display          theDisplay,
706                                        const Aspect_RenderingContext theGContext,
707                                        const Standard_Boolean        theIsCoreProfile)
708 #endif
709 {
710   Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
711 #if defined(HAVE_EGL)
712   myWindow   = theEglSurface;
713   myGContext = theEglContext;
714   myDisplay  = theEglDisplay;
715 #elif defined(_WIN32)
716   myWindow   = theWindow;
717   myGContext = theGContext;
718   myWindowDC = theWindowDC;
719 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
720   myGContext = theGContext;
721 #else
722   myWindow   = theWindow;
723   myGContext = theGContext;
724   myDisplay  = theDisplay;
725 #endif
726   if (myGContext == NULL || !MakeCurrent())
727   {
728     return Standard_False;
729   }
730
731   init (theIsCoreProfile);
732   myIsInitialized = Standard_True;
733   return Standard_True;
734 }
735
736 // =======================================================================
737 // function : ResetErrors
738 // purpose  :
739 // =======================================================================
740 void OpenGl_Context::ResetErrors (const bool theToPrintErrors)
741 {
742   int aPrevErr = 0;
743   int anErr    = ::glGetError();
744   if (!theToPrintErrors)
745   {
746     for (; anErr != GL_NO_ERROR && aPrevErr != anErr; aPrevErr = anErr, anErr = ::glGetError())
747     {
748       //
749     }
750     return;
751   }
752
753   for (; anErr != GL_NO_ERROR && aPrevErr != anErr; aPrevErr = anErr, anErr = ::glGetError())
754   {
755     TCollection_ExtendedString anErrId;
756     switch (anErr)
757     {
758       case GL_INVALID_ENUM:      anErrId = "GL_INVALID_ENUM";      break;
759       case GL_INVALID_VALUE:     anErrId = "GL_INVALID_VALUE";     break;
760       case GL_INVALID_OPERATION: anErrId = "GL_INVALID_OPERATION"; break;
761     #ifdef GL_STACK_OVERFLOW
762       case GL_STACK_OVERFLOW:    anErrId = "GL_STACK_OVERFLOW";    break;
763       case GL_STACK_UNDERFLOW:   anErrId = "GL_STACK_UNDERFLOW";   break;
764     #endif
765       case GL_OUT_OF_MEMORY:     anErrId = "GL_OUT_OF_MEMORY";     break;
766       case GL_INVALID_FRAMEBUFFER_OPERATION:
767         anErrId = "GL_INVALID_FRAMEBUFFER_OPERATION";
768         break;
769       default:
770         anErrId = TCollection_ExtendedString("#") + anErr;
771         break;
772     }
773
774     const TCollection_ExtendedString aMsg = TCollection_ExtendedString ("Unhandled GL error: ") + anErrId;
775     PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_OTHER_ARB, 0, GL_DEBUG_SEVERITY_LOW, aMsg);
776   }
777 }
778
779 // =======================================================================
780 // function : ReadGlVersion
781 // purpose  :
782 // =======================================================================
783 void OpenGl_Context::ReadGlVersion (Standard_Integer& theGlVerMajor,
784                                     Standard_Integer& theGlVerMinor)
785 {
786   // reset values
787   theGlVerMajor = 0;
788   theGlVerMinor = 0;
789
790 #ifdef GL_MAJOR_VERSION
791   // available since OpenGL 3.0 and OpenGL 3.0 ES
792   GLint aMajor = 0, aMinor = 0;
793   glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
794   glGetIntegerv (GL_MINOR_VERSION, &aMinor);
795   // glGetError() sometimes does not report an error here even if
796   // GL does not know GL_MAJOR_VERSION and GL_MINOR_VERSION constants.
797   // This happens on some renderers like e.g. Cygwin MESA.
798   // Thus checking additionally if GL has put anything to
799   // the output variables.
800   if (::glGetError() == GL_NO_ERROR && aMajor != 0 && aMinor != 0)
801   {
802     theGlVerMajor = aMajor;
803     theGlVerMinor = aMinor;
804     return;
805   }
806   for (GLenum anErr = ::glGetError(), aPrevErr = GL_NO_ERROR;; aPrevErr = anErr, anErr = ::glGetError())
807   {
808     if (anErr == GL_NO_ERROR
809      || anErr == aPrevErr)
810     {
811       break;
812     }
813   }
814 #endif
815
816   // Read version string.
817   // Notice that only first two numbers split by point '2.1 XXXXX' are significant.
818   // Following trash (after space) is vendor-specific.
819   // New drivers also returns micro version of GL like '3.3.0' which has no meaning
820   // and should be considered as vendor-specific too.
821   const char* aVerStr = (const char* )glGetString (GL_VERSION);
822   if (aVerStr == NULL || *aVerStr == '\0')
823   {
824     // invalid GL context
825     return;
826   }
827
828 //#if defined(GL_ES_VERSION_2_0)
829   // skip "OpenGL ES-** " section
830   for (; *aVerStr != '\0'; ++aVerStr)
831   {
832     if (*aVerStr >= '0' && *aVerStr <= '9')
833     {
834       break;
835     }
836   }
837 //#endif
838
839   // parse string for major number
840   char aMajorStr[32];
841   char aMinorStr[32];
842   size_t aMajIter = 0;
843   while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
844   {
845     ++aMajIter;
846   }
847   if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
848   {
849     return;
850   }
851   memcpy (aMajorStr, aVerStr, aMajIter);
852   aMajorStr[aMajIter] = '\0';
853
854   // parse string for minor number
855   aVerStr += aMajIter + 1;
856   size_t aMinIter = 0;
857   while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
858   {
859     ++aMinIter;
860   }
861   if (aMinIter == 0 || aMinIter >= sizeof(aMinorStr))
862   {
863     return;
864   }
865   memcpy (aMinorStr, aVerStr, aMinIter);
866   aMinorStr[aMinIter] = '\0';
867
868   // read numbers
869   theGlVerMajor = atoi (aMajorStr);
870   theGlVerMinor = atoi (aMinorStr);
871
872   if (theGlVerMajor <= 0)
873   {
874     theGlVerMajor = 0;
875     theGlVerMinor = 0;
876   }
877 }
878
879 static Standard_CString THE_DBGMSG_UNKNOWN = "UNKNOWN";
880 static Standard_CString THE_DBGMSG_SOURCES[] =
881 {
882   ".OpenGL",    // GL_DEBUG_SOURCE_API
883   ".WinSystem", // GL_DEBUG_SOURCE_WINDOW_SYSTEM
884   ".GLSL",      // GL_DEBUG_SOURCE_SHADER_COMPILER
885   ".3rdParty",  // GL_DEBUG_SOURCE_THIRD_PARTY
886   "",           // GL_DEBUG_SOURCE_APPLICATION
887   ".Other"      // GL_DEBUG_SOURCE_OTHER
888 };
889
890 static Standard_CString THE_DBGMSG_TYPES[] =
891 {
892   "Error",           // GL_DEBUG_TYPE_ERROR
893   "Deprecated",      // GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR
894   "Undef. behavior", // GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR
895   "Portability",     // GL_DEBUG_TYPE_PORTABILITY
896   "Performance",     // GL_DEBUG_TYPE_PERFORMANCE
897   "Other"            // GL_DEBUG_TYPE_OTHER
898 };
899
900 static Standard_CString THE_DBGMSG_SEV_HIGH   = "High";   // GL_DEBUG_SEVERITY_HIGH
901 static Standard_CString THE_DBGMSG_SEV_MEDIUM = "Medium"; // GL_DEBUG_SEVERITY_MEDIUM
902 static Standard_CString THE_DBGMSG_SEV_LOW    = "Low";    // GL_DEBUG_SEVERITY_LOW
903
904 #if !defined(GL_ES_VERSION_2_0)
905 //! Callback for GL_ARB_debug_output extension
906 static void APIENTRY debugCallbackWrap(unsigned int theSource,
907                                        unsigned int theType,
908                                        unsigned int theId,
909                                        unsigned int theSeverity,
910                                        int          /*theLength*/,
911                                        const char*  theMessage,
912                                        const void*  theUserParam)
913 {
914   OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
915   aCtx->PushMessage (theSource, theType, theId, theSeverity, theMessage);
916 }
917 #endif
918
919 // =======================================================================
920 // function : PushMessage
921 // purpose  :
922 // =======================================================================
923 void OpenGl_Context::PushMessage (const unsigned int theSource,
924                                   const unsigned int theType,
925                                   const unsigned int theId,
926                                   const unsigned int theSeverity,
927                                   const TCollection_ExtendedString& theMessage)
928 {
929   if (caps->suppressExtraMsg
930    && theSource >= GL_DEBUG_SOURCE_API
931    && theSource <= GL_DEBUG_SOURCE_OTHER
932    && myFilters[theSource - GL_DEBUG_SOURCE_API].Contains (theId))
933   {
934     return;
935   }
936
937   Standard_CString& aSrc = (theSource >= GL_DEBUG_SOURCE_API
938                         && theSource <= GL_DEBUG_SOURCE_OTHER)
939                          ? THE_DBGMSG_SOURCES[theSource - GL_DEBUG_SOURCE_API]
940                          : THE_DBGMSG_UNKNOWN;
941   Standard_CString& aType = (theType >= GL_DEBUG_TYPE_ERROR
942                          && theType <= GL_DEBUG_TYPE_OTHER)
943                           ? THE_DBGMSG_TYPES[theType - GL_DEBUG_TYPE_ERROR]
944                           : THE_DBGMSG_UNKNOWN;
945   Standard_CString& aSev = theSeverity == GL_DEBUG_SEVERITY_HIGH
946                          ? THE_DBGMSG_SEV_HIGH
947                          : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM
948                           ? THE_DBGMSG_SEV_MEDIUM
949                           : THE_DBGMSG_SEV_LOW);
950   Message_Gravity aGrav = theSeverity == GL_DEBUG_SEVERITY_HIGH
951                         ? Message_Alarm
952                         : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM
953                          ? Message_Warning
954                          : Message_Info);
955
956   TCollection_ExtendedString aMsg;
957   aMsg += "TKOpenGl"; aMsg += aSrc;
958   aMsg += " | Type: ";        aMsg += aType;
959   aMsg += " | ID: ";          aMsg += (Standard_Integer )theId;
960   aMsg += " | Severity: ";    aMsg += aSev;
961   aMsg += " | Message:\n  ";
962   aMsg += theMessage;
963   Messenger()->Send (aMsg, aGrav);
964 }
965
966 // =======================================================================
967 // function : ExcludeMessage
968 // purpose  :
969 // ======================================================================
970 Standard_Boolean OpenGl_Context::ExcludeMessage (const unsigned int theSource,
971                                                  const unsigned int theId)
972 {
973   return theSource >= GL_DEBUG_SOURCE_API
974       && theSource <= GL_DEBUG_SOURCE_OTHER
975       && myFilters[theSource - GL_DEBUG_SOURCE_API].Add (theId);
976 }
977
978 // =======================================================================
979 // function : IncludeMessage
980 // purpose  :
981 // ======================================================================
982 Standard_Boolean OpenGl_Context::IncludeMessage (const unsigned int theSource,
983                                                  const unsigned int theId)
984 {
985   return theSource >= GL_DEBUG_SOURCE_API
986       && theSource <= GL_DEBUG_SOURCE_OTHER
987       && myFilters[theSource - GL_DEBUG_SOURCE_API].Remove (theId);
988 }
989
990 // =======================================================================
991 // function : checkWrongVersion
992 // purpose  :
993 // ======================================================================
994 void OpenGl_Context::checkWrongVersion (const Standard_Integer theGlVerMajor,
995                                         const Standard_Integer theGlVerMinor)
996 {
997   if (!IsGlGreaterEqual (theGlVerMajor, theGlVerMinor))
998   {
999     return;
1000   }
1001
1002   TCollection_ExtendedString aMsg = TCollection_ExtendedString()
1003     + "Error! OpenGL context reports version "
1004     + myGlVerMajor  + "." + myGlVerMinor
1005     + " but does not export required functions for "
1006     + theGlVerMajor + "." + theGlVerMinor;
1007   PushMessage (GL_DEBUG_SOURCE_APPLICATION,
1008                GL_DEBUG_TYPE_ERROR,
1009                0,
1010                GL_DEBUG_SEVERITY_HIGH,
1011                aMsg);
1012 }
1013
1014 // =======================================================================
1015 // function : init
1016 // purpose  :
1017 // =======================================================================
1018 void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
1019 {
1020   // read version
1021   myGlVerMajor = 0;
1022   myGlVerMinor = 0;
1023   myMaxMsaaSamples = 0;
1024   ReadGlVersion (myGlVerMajor, myGlVerMinor);
1025   myVendor = (const char* )::glGetString (GL_VENDOR);
1026
1027 #if defined(GL_ES_VERSION_2_0)
1028   (void )theIsCoreProfile;
1029   const bool isCoreProfile = false;
1030 #else
1031
1032   if (myVendor.Search ("NVIDIA") != -1)
1033   {
1034     // Buffer detailed info: Buffer object 1 (bound to GL_ARRAY_BUFFER_ARB, usage hint is GL_STATIC_DRAW)
1035     // will use VIDEO memory as the source for buffer object operations.
1036     ExcludeMessage (GL_DEBUG_SOURCE_API, 131185);
1037   }
1038   if (IsGlGreaterEqual (3, 0))
1039   {
1040     // retrieve auxiliary function in advance
1041     FindProc ("glGetStringi", myFuncs->glGetStringi);
1042   }
1043
1044   bool isCoreProfile = false;
1045   if (IsGlGreaterEqual (3, 2))
1046   {
1047     isCoreProfile = (theIsCoreProfile == Standard_True);
1048
1049     // detect Core profile
1050     if (!isCoreProfile)
1051     {
1052       GLint aProfile = 0;
1053       ::glGetIntegerv (GL_CONTEXT_PROFILE_MASK, &aProfile);
1054       isCoreProfile = (aProfile & GL_CONTEXT_CORE_PROFILE_BIT) != 0;
1055     }
1056   }
1057 #endif
1058
1059   core11     = NULL;
1060   if (!isCoreProfile)
1061   {
1062     core11 = (OpenGl_GlCore11* )(&(*myFuncs));
1063   }
1064   core11fwd  = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
1065   core15     = NULL;
1066   core15fwd  = NULL;
1067   core20     = NULL;
1068   core20fwd  = NULL;
1069   core32     = NULL;
1070   core32back = NULL;
1071   core33     = NULL;
1072   core33back = NULL;
1073   core41     = NULL;
1074   core41back = NULL;
1075   core42     = NULL;
1076   core42back = NULL;
1077   core43     = NULL;
1078   core43back = NULL;
1079   core44     = NULL;
1080   core44back = NULL;
1081   arbTBO     = NULL;
1082   arbTboRGB32 = Standard_False;
1083   arbIns     = NULL;
1084   arbDbg     = NULL;
1085   arbFBO     = NULL;
1086   arbFBOBlit = NULL;
1087   extGS      = NULL;
1088   myDefaultVao = 0;
1089
1090 #if defined(GL_ES_VERSION_2_0)
1091
1092   hasTexRGBA8 = IsGlGreaterEqual (3, 0)
1093              || CheckExtension ("GL_OES_rgb8_rgba8");
1094   // NPOT textures has limited support within OpenGL ES 2.0
1095   // which are relaxed by OpenGL ES 3.0 or some extensions
1096   //arbNPTW     = IsGlGreaterEqual (3, 0)
1097   //           || CheckExtension ("GL_OES_texture_npot")
1098   //           || CheckExtension ("GL_NV_texture_npot_2D_mipmap");
1099   arbNPTW     = Standard_True;
1100   arbTexRG    = IsGlGreaterEqual (3, 0)
1101              || CheckExtension ("GL_EXT_texture_rg");
1102   extBgra     = CheckExtension ("GL_EXT_texture_format_BGRA8888");
1103   extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
1104   extPDS  = CheckExtension ("GL_OES_packed_depth_stencil");
1105
1106   core11fwd = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
1107   if (IsGlGreaterEqual (2, 0))
1108   {
1109     // enable compatible functions
1110     core20    = (OpenGl_GlCore20*    )(&(*myFuncs));
1111     core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
1112     core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
1113     arbFBO    = (OpenGl_ArbFBO*      )(&(*myFuncs));
1114   }
1115   if (IsGlGreaterEqual (3, 0)
1116    && FindProc ("glBlitFramebuffer", myFuncs->glBlitFramebuffer))
1117   {
1118     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
1119   }
1120   if (IsGlGreaterEqual (3, 1)
1121    && FindProc ("glTexStorage2DMultisample", myFuncs->glTexStorage2DMultisample))
1122   {
1123     // MSAA RenderBuffers have been defined in OpenGL ES 3.0,
1124     // but MSAA Textures - only in OpenGL ES 3.1+
1125     ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
1126   }
1127
1128   hasUintIndex = IsGlGreaterEqual (3, 0)
1129               || CheckExtension ("GL_OES_element_index_uint");
1130   hasHighp     = CheckExtension ("GL_OES_fragment_precision_high");
1131   GLint aRange[2] = {0, 0};
1132   GLint aPrec     = 0;
1133   ::glGetShaderPrecisionFormat (GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, aRange, &aPrec);
1134   if (aPrec != 0)
1135   {
1136     hasHighp = Standard_True;
1137   }
1138 #else
1139
1140   myTexClamp = IsGlGreaterEqual (1, 2) ? GL_CLAMP_TO_EDGE : GL_CLAMP;
1141
1142   hasTexRGBA8 = Standard_True;
1143   arbNPTW = CheckExtension ("GL_ARB_texture_non_power_of_two");
1144   extBgra = CheckExtension ("GL_EXT_bgra");
1145   extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
1146   extPDS  = CheckExtension ("GL_EXT_packed_depth_stencil");
1147   atiMem  = CheckExtension ("GL_ATI_meminfo");
1148   nvxMem  = CheckExtension ("GL_NVX_gpu_memory_info");
1149
1150   GLint aStereo = GL_FALSE;
1151   glGetIntegerv (GL_STEREO, &aStereo);
1152   myIsStereoBuffers = aStereo == 1;
1153
1154   // get number of maximum clipping planes
1155   glGetIntegerv (GL_MAX_CLIP_PLANES,  &myMaxClipPlanes);
1156 #endif
1157
1158   glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
1159
1160   if (extAnis)
1161   {
1162     glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
1163   }
1164
1165   myClippingState.Init (myMaxClipPlanes);
1166
1167 #if !defined(GL_ES_VERSION_2_0)
1168
1169   bool has12 = false;
1170   bool has13 = false;
1171   bool has14 = false;
1172   bool has15 = false;
1173   bool has20 = false;
1174   bool has21 = false;
1175   bool has30 = false;
1176   bool has31 = false;
1177   bool has32 = false;
1178   bool has33 = false;
1179   bool has40 = false;
1180   bool has41 = false;
1181   bool has42 = false;
1182   bool has43 = false;
1183   bool has44 = false;
1184
1185   //! Make record shorter to retrieve function pointer using variable with same name
1186   #define FindProcShort(theFunc) FindProc(#theFunc, myFuncs->theFunc)
1187
1188   // retrieve platform-dependent extensions
1189 #if defined(HAVE_EGL)
1190   //
1191 #elif defined(_WIN32)
1192   if (FindProcShort (wglGetExtensionsStringARB))
1193   {
1194     const char* aWglExts = myFuncs->wglGetExtensionsStringARB (wglGetCurrentDC());
1195     if (CheckExtension (aWglExts, "WGL_EXT_swap_control"))
1196     {
1197       FindProcShort (wglSwapIntervalEXT);
1198     }
1199     if (CheckExtension (aWglExts, "WGL_ARB_pixel_format"))
1200     {
1201       FindProcShort (wglChoosePixelFormatARB);
1202     }
1203     if (CheckExtension (aWglExts, "WGL_ARB_create_context_profile"))
1204     {
1205       FindProcShort (wglCreateContextAttribsARB);
1206     }
1207     if (CheckExtension (aWglExts, "WGL_NV_DX_interop"))
1208     {
1209       FindProcShort (wglDXSetResourceShareHandleNV);
1210       FindProcShort (wglDXOpenDeviceNV);
1211       FindProcShort (wglDXCloseDeviceNV);
1212       FindProcShort (wglDXRegisterObjectNV);
1213       FindProcShort (wglDXUnregisterObjectNV);
1214       FindProcShort (wglDXObjectAccessNV);
1215       FindProcShort (wglDXLockObjectsNV);
1216       FindProcShort (wglDXUnlockObjectsNV);
1217     }
1218   }
1219 #elif defined(__APPLE__)
1220     //
1221 #else
1222     const char* aGlxExts = ::glXQueryExtensionsString ((Display* )myDisplay, DefaultScreen ((Display* )myDisplay));
1223     if (CheckExtension (aGlxExts, "GLX_EXT_swap_control"))
1224     {
1225       FindProcShort (glXSwapIntervalEXT);
1226     }
1227     if (CheckExtension (aGlxExts, "GLX_SGI_swap_control"))
1228     {
1229       FindProcShort (glXSwapIntervalSGI);
1230     }
1231     //extSwapTear = CheckExtension (aGlxExts, "GLX_EXT_swap_control_tear");
1232 #endif
1233
1234   // initialize debug context extension
1235   if (CheckExtension ("GL_ARB_debug_output"))
1236   {
1237     arbDbg = NULL;
1238     if (FindProcShort (glDebugMessageControlARB)
1239      && FindProcShort (glDebugMessageInsertARB)
1240      && FindProcShort (glDebugMessageCallbackARB)
1241      && FindProcShort (glGetDebugMessageLogARB))
1242     {
1243       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
1244     }
1245     if (arbDbg != NULL
1246      && caps->contextDebug)
1247     {
1248       // setup default callback
1249       myIsGlDebugCtx = Standard_True;
1250       arbDbg->glDebugMessageCallbackARB (debugCallbackWrap, this);
1251       if (caps->contextSyncDebug)
1252       {
1253         ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
1254       }
1255     }
1256   }
1257
1258   // load OpenGL 1.2 new functions
1259   has12 = IsGlGreaterEqual (1, 2)
1260        && FindProcShort (glBlendColor)
1261        && FindProcShort (glBlendEquation)
1262        && FindProcShort (glDrawRangeElements)
1263        && FindProcShort (glTexImage3D)
1264        && FindProcShort (glTexSubImage3D)
1265        && FindProcShort (glCopyTexSubImage3D);
1266
1267   // load OpenGL 1.3 new functions
1268   has13 = IsGlGreaterEqual (1, 3)
1269        && FindProcShort (glActiveTexture)
1270        && FindProcShort (glSampleCoverage)
1271        && FindProcShort (glCompressedTexImage3D)
1272        && FindProcShort (glCompressedTexImage2D)
1273        && FindProcShort (glCompressedTexImage1D)
1274        && FindProcShort (glCompressedTexSubImage3D)
1275        && FindProcShort (glCompressedTexSubImage2D)
1276        && FindProcShort (glCompressedTexSubImage1D)
1277        && FindProcShort (glGetCompressedTexImage);
1278
1279   if (!isCoreProfile)
1280   {
1281     has13 = has13
1282        && FindProcShort (glClientActiveTexture)
1283        && FindProcShort (glMultiTexCoord1d)
1284        && FindProcShort (glMultiTexCoord1dv)
1285        && FindProcShort (glMultiTexCoord1f)
1286        && FindProcShort (glMultiTexCoord1fv)
1287        && FindProcShort (glMultiTexCoord1i)
1288        && FindProcShort (glMultiTexCoord1iv)
1289        && FindProcShort (glMultiTexCoord1s)
1290        && FindProcShort (glMultiTexCoord1sv)
1291        && FindProcShort (glMultiTexCoord2d)
1292        && FindProcShort (glMultiTexCoord2dv)
1293        && FindProcShort (glMultiTexCoord2f)
1294        && FindProcShort (glMultiTexCoord2fv)
1295        && FindProcShort (glMultiTexCoord2i)
1296        && FindProcShort (glMultiTexCoord2iv)
1297        && FindProcShort (glMultiTexCoord2s)
1298        && FindProcShort (glMultiTexCoord2sv)
1299        && FindProcShort (glMultiTexCoord3d)
1300        && FindProcShort (glMultiTexCoord3dv)
1301        && FindProcShort (glMultiTexCoord3f)
1302        && FindProcShort (glMultiTexCoord3fv)
1303        && FindProcShort (glMultiTexCoord3i)
1304        && FindProcShort (glMultiTexCoord3iv)
1305        && FindProcShort (glMultiTexCoord3s)
1306        && FindProcShort (glMultiTexCoord3sv)
1307        && FindProcShort (glMultiTexCoord4d)
1308        && FindProcShort (glMultiTexCoord4dv)
1309        && FindProcShort (glMultiTexCoord4f)
1310        && FindProcShort (glMultiTexCoord4fv)
1311        && FindProcShort (glMultiTexCoord4i)
1312        && FindProcShort (glMultiTexCoord4iv)
1313        && FindProcShort (glMultiTexCoord4s)
1314        && FindProcShort (glMultiTexCoord4sv)
1315        && FindProcShort (glLoadTransposeMatrixf)
1316        && FindProcShort (glLoadTransposeMatrixd)
1317        && FindProcShort (glMultTransposeMatrixf)
1318        && FindProcShort (glMultTransposeMatrixd);
1319   }
1320
1321   // load OpenGL 1.4 new functions
1322   has14 = IsGlGreaterEqual (1, 4)
1323        && FindProcShort (glBlendFuncSeparate)
1324        && FindProcShort (glMultiDrawArrays)
1325        && FindProcShort (glMultiDrawElements)
1326        && FindProcShort (glPointParameterf)
1327        && FindProcShort (glPointParameterfv)
1328        && FindProcShort (glPointParameteri)
1329        && FindProcShort (glPointParameteriv);
1330
1331   // load OpenGL 1.5 new functions
1332   has15 = IsGlGreaterEqual (1, 5)
1333        && FindProcShort (glGenQueries)
1334        && FindProcShort (glDeleteQueries)
1335        && FindProcShort (glIsQuery)
1336        && FindProcShort (glBeginQuery)
1337        && FindProcShort (glEndQuery)
1338        && FindProcShort (glGetQueryiv)
1339        && FindProcShort (glGetQueryObjectiv)
1340        && FindProcShort (glGetQueryObjectuiv)
1341        && FindProcShort (glBindBuffer)
1342        && FindProcShort (glDeleteBuffers)
1343        && FindProcShort (glGenBuffers)
1344        && FindProcShort (glIsBuffer)
1345        && FindProcShort (glBufferData)
1346        && FindProcShort (glBufferSubData)
1347        && FindProcShort (glGetBufferSubData)
1348        && FindProcShort (glMapBuffer)
1349        && FindProcShort (glUnmapBuffer)
1350        && FindProcShort (glGetBufferParameteriv)
1351        && FindProcShort (glGetBufferPointerv);
1352
1353   // load OpenGL 2.0 new functions
1354   has20 = IsGlGreaterEqual (2, 0)
1355        && FindProcShort (glBlendEquationSeparate)
1356        && FindProcShort (glDrawBuffers)
1357        && FindProcShort (glStencilOpSeparate)
1358        && FindProcShort (glStencilFuncSeparate)
1359        && FindProcShort (glStencilMaskSeparate)
1360        && FindProcShort (glAttachShader)
1361        && FindProcShort (glBindAttribLocation)
1362        && FindProcShort (glCompileShader)
1363        && FindProcShort (glCreateProgram)
1364        && FindProcShort (glCreateShader)
1365        && FindProcShort (glDeleteProgram)
1366        && FindProcShort (glDeleteShader)
1367        && FindProcShort (glDetachShader)
1368        && FindProcShort (glDisableVertexAttribArray)
1369        && FindProcShort (glEnableVertexAttribArray)
1370        && FindProcShort (glGetActiveAttrib)
1371        && FindProcShort (glGetActiveUniform)
1372        && FindProcShort (glGetAttachedShaders)
1373        && FindProcShort (glGetAttribLocation)
1374        && FindProcShort (glGetProgramiv)
1375        && FindProcShort (glGetProgramInfoLog)
1376        && FindProcShort (glGetShaderiv)
1377        && FindProcShort (glGetShaderInfoLog)
1378        && FindProcShort (glGetShaderSource)
1379        && FindProcShort (glGetUniformLocation)
1380        && FindProcShort (glGetUniformfv)
1381        && FindProcShort (glGetUniformiv)
1382        && FindProcShort (glGetVertexAttribdv)
1383        && FindProcShort (glGetVertexAttribfv)
1384        && FindProcShort (glGetVertexAttribiv)
1385        && FindProcShort (glGetVertexAttribPointerv)
1386        && FindProcShort (glIsProgram)
1387        && FindProcShort (glIsShader)
1388        && FindProcShort (glLinkProgram)
1389        && FindProcShort (glShaderSource)
1390        && FindProcShort (glUseProgram)
1391        && FindProcShort (glUniform1f)
1392        && FindProcShort (glUniform2f)
1393        && FindProcShort (glUniform3f)
1394        && FindProcShort (glUniform4f)
1395        && FindProcShort (glUniform1i)
1396        && FindProcShort (glUniform2i)
1397        && FindProcShort (glUniform3i)
1398        && FindProcShort (glUniform4i)
1399        && FindProcShort (glUniform1fv)
1400        && FindProcShort (glUniform2fv)
1401        && FindProcShort (glUniform3fv)
1402        && FindProcShort (glUniform4fv)
1403        && FindProcShort (glUniform1iv)
1404        && FindProcShort (glUniform2iv)
1405        && FindProcShort (glUniform3iv)
1406        && FindProcShort (glUniform4iv)
1407        && FindProcShort (glUniformMatrix2fv)
1408        && FindProcShort (glUniformMatrix3fv)
1409        && FindProcShort (glUniformMatrix4fv)
1410        && FindProcShort (glValidateProgram)
1411        && FindProcShort (glVertexAttrib1d)
1412        && FindProcShort (glVertexAttrib1dv)
1413        && FindProcShort (glVertexAttrib1f)
1414        && FindProcShort (glVertexAttrib1fv)
1415        && FindProcShort (glVertexAttrib1s)
1416        && FindProcShort (glVertexAttrib1sv)
1417        && FindProcShort (glVertexAttrib2d)
1418        && FindProcShort (glVertexAttrib2dv)
1419        && FindProcShort (glVertexAttrib2f)
1420        && FindProcShort (glVertexAttrib2fv)
1421        && FindProcShort (glVertexAttrib2s)
1422        && FindProcShort (glVertexAttrib2sv)
1423        && FindProcShort (glVertexAttrib3d)
1424        && FindProcShort (glVertexAttrib3dv)
1425        && FindProcShort (glVertexAttrib3f)
1426        && FindProcShort (glVertexAttrib3fv)
1427        && FindProcShort (glVertexAttrib3s)
1428        && FindProcShort (glVertexAttrib3sv)
1429        && FindProcShort (glVertexAttrib4Nbv)
1430        && FindProcShort (glVertexAttrib4Niv)
1431        && FindProcShort (glVertexAttrib4Nsv)
1432        && FindProcShort (glVertexAttrib4Nub)
1433        && FindProcShort (glVertexAttrib4Nubv)
1434        && FindProcShort (glVertexAttrib4Nuiv)
1435        && FindProcShort (glVertexAttrib4Nusv)
1436        && FindProcShort (glVertexAttrib4bv)
1437        && FindProcShort (glVertexAttrib4d)
1438        && FindProcShort (glVertexAttrib4dv)
1439        && FindProcShort (glVertexAttrib4f)
1440        && FindProcShort (glVertexAttrib4fv)
1441        && FindProcShort (glVertexAttrib4iv)
1442        && FindProcShort (glVertexAttrib4s)
1443        && FindProcShort (glVertexAttrib4sv)
1444        && FindProcShort (glVertexAttrib4ubv)
1445        && FindProcShort (glVertexAttrib4uiv)
1446        && FindProcShort (glVertexAttrib4usv)
1447        && FindProcShort (glVertexAttribPointer);
1448
1449   // load OpenGL 2.1 new functions
1450   has21 = IsGlGreaterEqual (2, 1)
1451        && FindProcShort (glUniformMatrix2x3fv)
1452        && FindProcShort (glUniformMatrix3x2fv)
1453        && FindProcShort (glUniformMatrix2x4fv)
1454        && FindProcShort (glUniformMatrix4x2fv)
1455        && FindProcShort (glUniformMatrix3x4fv)
1456        && FindProcShort (glUniformMatrix4x3fv);
1457
1458   // load GL_ARB_framebuffer_object (added to OpenGL 3.0 core)
1459   const bool hasFBO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_framebuffer_object"))
1460        && FindProcShort (glIsRenderbuffer)
1461        && FindProcShort (glBindRenderbuffer)
1462        && FindProcShort (glDeleteRenderbuffers)
1463        && FindProcShort (glGenRenderbuffers)
1464        && FindProcShort (glRenderbufferStorage)
1465        && FindProcShort (glGetRenderbufferParameteriv)
1466        && FindProcShort (glIsFramebuffer)
1467        && FindProcShort (glBindFramebuffer)
1468        && FindProcShort (glDeleteFramebuffers)
1469        && FindProcShort (glGenFramebuffers)
1470        && FindProcShort (glCheckFramebufferStatus)
1471        && FindProcShort (glFramebufferTexture1D)
1472        && FindProcShort (glFramebufferTexture2D)
1473        && FindProcShort (glFramebufferTexture3D)
1474        && FindProcShort (glFramebufferRenderbuffer)
1475        && FindProcShort (glGetFramebufferAttachmentParameteriv)
1476        && FindProcShort (glGenerateMipmap)
1477        && FindProcShort (glBlitFramebuffer)
1478        && FindProcShort (glRenderbufferStorageMultisample)
1479        && FindProcShort (glFramebufferTextureLayer);
1480
1481   // load GL_ARB_vertex_array_object (added to OpenGL 3.0 core)
1482   const bool hasVAO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_vertex_array_object"))
1483        && FindProcShort (glBindVertexArray)
1484        && FindProcShort (glDeleteVertexArrays)
1485        && FindProcShort (glGenVertexArrays)
1486        && FindProcShort (glIsVertexArray);
1487
1488   // load GL_ARB_map_buffer_range (added to OpenGL 3.0 core)
1489   const bool hasMapBufferRange = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_map_buffer_range"))
1490        && FindProcShort (glMapBufferRange)
1491        && FindProcShort (glFlushMappedBufferRange);
1492
1493   // load OpenGL 3.0 new functions
1494   has30 = IsGlGreaterEqual (3, 0)
1495        && hasFBO
1496        && hasVAO
1497        && hasMapBufferRange
1498        && FindProcShort (glColorMaski)
1499        && FindProcShort (glGetBooleani_v)
1500        && FindProcShort (glGetIntegeri_v)
1501        && FindProcShort (glEnablei)
1502        && FindProcShort (glDisablei)
1503        && FindProcShort (glIsEnabledi)
1504        && FindProcShort (glBeginTransformFeedback)
1505        && FindProcShort (glEndTransformFeedback)
1506        && FindProcShort (glBindBufferRange)
1507        && FindProcShort (glBindBufferBase)
1508        && FindProcShort (glTransformFeedbackVaryings)
1509        && FindProcShort (glGetTransformFeedbackVarying)
1510        && FindProcShort (glClampColor)
1511        && FindProcShort (glBeginConditionalRender)
1512        && FindProcShort (glEndConditionalRender)
1513        && FindProcShort (glVertexAttribIPointer)
1514        && FindProcShort (glGetVertexAttribIiv)
1515        && FindProcShort (glGetVertexAttribIuiv)
1516        && FindProcShort (glVertexAttribI1i)
1517        && FindProcShort (glVertexAttribI2i)
1518        && FindProcShort (glVertexAttribI3i)
1519        && FindProcShort (glVertexAttribI4i)
1520        && FindProcShort (glVertexAttribI1ui)
1521        && FindProcShort (glVertexAttribI2ui)
1522        && FindProcShort (glVertexAttribI3ui)
1523        && FindProcShort (glVertexAttribI4ui)
1524        && FindProcShort (glVertexAttribI1iv)
1525        && FindProcShort (glVertexAttribI2iv)
1526        && FindProcShort (glVertexAttribI3iv)
1527        && FindProcShort (glVertexAttribI4iv)
1528        && FindProcShort (glVertexAttribI1uiv)
1529        && FindProcShort (glVertexAttribI2uiv)
1530        && FindProcShort (glVertexAttribI3uiv)
1531        && FindProcShort (glVertexAttribI4uiv)
1532        && FindProcShort (glVertexAttribI4bv)
1533        && FindProcShort (glVertexAttribI4sv)
1534        && FindProcShort (glVertexAttribI4ubv)
1535        && FindProcShort (glVertexAttribI4usv)
1536        && FindProcShort (glGetUniformuiv)
1537        && FindProcShort (glBindFragDataLocation)
1538        && FindProcShort (glGetFragDataLocation)
1539        && FindProcShort (glUniform1ui)
1540        && FindProcShort (glUniform2ui)
1541        && FindProcShort (glUniform3ui)
1542        && FindProcShort (glUniform4ui)
1543        && FindProcShort (glUniform1uiv)
1544        && FindProcShort (glUniform2uiv)
1545        && FindProcShort (glUniform3uiv)
1546        && FindProcShort (glUniform4uiv)
1547        && FindProcShort (glTexParameterIiv)
1548        && FindProcShort (glTexParameterIuiv)
1549        && FindProcShort (glGetTexParameterIiv)
1550        && FindProcShort (glGetTexParameterIuiv)
1551        && FindProcShort (glClearBufferiv)
1552        && FindProcShort (glClearBufferuiv)
1553        && FindProcShort (glClearBufferfv)
1554        && FindProcShort (glClearBufferfi)
1555        && FindProcShort (glGetStringi);
1556
1557   // load GL_ARB_uniform_buffer_object (added to OpenGL 3.1 core)
1558   const bool hasUBO = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_uniform_buffer_object"))
1559        && FindProcShort (glGetUniformIndices)
1560        && FindProcShort (glGetActiveUniformsiv)
1561        && FindProcShort (glGetActiveUniformName)
1562        && FindProcShort (glGetUniformBlockIndex)
1563        && FindProcShort (glGetActiveUniformBlockiv)
1564        && FindProcShort (glGetActiveUniformBlockName)
1565        && FindProcShort (glUniformBlockBinding);
1566
1567   // load GL_ARB_copy_buffer (added to OpenGL 3.1 core)
1568   const bool hasCopyBufSubData = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_copy_buffer"))
1569        && FindProcShort (glCopyBufferSubData);
1570
1571   if (has30)
1572   {
1573     // NPOT textures are required by OpenGL 2.0 specifications
1574     // but doesn't hardware accelerated by some ancient OpenGL 2.1 hardware (GeForce FX, RadeOn 9700 etc.)
1575     arbNPTW  = Standard_True;
1576     arbTexRG = Standard_True;
1577   }
1578
1579   // load OpenGL 3.1 new functions
1580   has31 = IsGlGreaterEqual (3, 1)
1581        && hasUBO
1582        && hasCopyBufSubData
1583        && FindProcShort (glDrawArraysInstanced)
1584        && FindProcShort (glDrawElementsInstanced)
1585        && FindProcShort (glTexBuffer)
1586        && FindProcShort (glPrimitiveRestartIndex);
1587
1588   // load GL_ARB_draw_elements_base_vertex (added to OpenGL 3.2 core)
1589   const bool hasDrawElemsBaseVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_draw_elements_base_vertex"))
1590        && FindProcShort (glDrawElementsBaseVertex)
1591        && FindProcShort (glDrawRangeElementsBaseVertex)
1592        && FindProcShort (glDrawElementsInstancedBaseVertex)
1593        && FindProcShort (glMultiDrawElementsBaseVertex);
1594
1595   // load GL_ARB_provoking_vertex (added to OpenGL 3.2 core)
1596   const bool hasProvokingVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_provoking_vertex"))
1597        && FindProcShort (glProvokingVertex);
1598
1599   // load GL_ARB_sync (added to OpenGL 3.2 core)
1600   const bool hasSync = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_sync"))
1601        && FindProcShort (glFenceSync)
1602        && FindProcShort (glIsSync)
1603        && FindProcShort (glDeleteSync)
1604        && FindProcShort (glClientWaitSync)
1605        && FindProcShort (glWaitSync)
1606        && FindProcShort (glGetInteger64v)
1607        && FindProcShort (glGetSynciv);
1608
1609   // load GL_ARB_texture_multisample (added to OpenGL 3.2 core)
1610   const bool hasTextureMultisample = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_texture_multisample"))
1611        && FindProcShort (glTexImage2DMultisample)
1612        && FindProcShort (glTexImage3DMultisample)
1613        && FindProcShort (glGetMultisamplefv)
1614        && FindProcShort (glSampleMaski);
1615
1616   // load OpenGL 3.2 new functions
1617   has32 = IsGlGreaterEqual (3, 2)
1618        && hasDrawElemsBaseVert
1619        && hasProvokingVert
1620        && hasSync
1621        && hasTextureMultisample
1622        && FindProcShort (glGetInteger64i_v)
1623        && FindProcShort (glGetBufferParameteri64v)
1624        && FindProcShort (glFramebufferTexture);
1625
1626   // load GL_ARB_blend_func_extended (added to OpenGL 3.3 core)
1627   const bool hasBlendFuncExtended = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_blend_func_extended"))
1628        && FindProcShort (glBindFragDataLocationIndexed)
1629        && FindProcShort (glGetFragDataIndex);
1630
1631   // load GL_ARB_sampler_objects (added to OpenGL 3.3 core)
1632   const bool hasSamplerObjects = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_sampler_objects"))
1633        && FindProcShort (glGenSamplers)
1634        && FindProcShort (glDeleteSamplers)
1635        && FindProcShort (glIsSampler)
1636        && FindProcShort (glBindSampler)
1637        && FindProcShort (glSamplerParameteri)
1638        && FindProcShort (glSamplerParameteriv)
1639        && FindProcShort (glSamplerParameterf)
1640        && FindProcShort (glSamplerParameterfv)
1641        && FindProcShort (glSamplerParameterIiv)
1642        && FindProcShort (glSamplerParameterIuiv)
1643        && FindProcShort (glGetSamplerParameteriv)
1644        && FindProcShort (glGetSamplerParameterIiv)
1645        && FindProcShort (glGetSamplerParameterfv)
1646        && FindProcShort (glGetSamplerParameterIuiv);
1647
1648   // load GL_ARB_timer_query (added to OpenGL 3.3 core)
1649   const bool hasTimerQuery = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_timer_query"))
1650        && FindProcShort (glQueryCounter)
1651        && FindProcShort (glGetQueryObjecti64v)
1652        && FindProcShort (glGetQueryObjectui64v);
1653
1654   // load GL_ARB_vertex_type_2_10_10_10_rev (added to OpenGL 3.3 core)
1655   const bool hasVertType21010101rev = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_vertex_type_2_10_10_10_rev"))
1656        && FindProcShort (glVertexAttribP1ui)
1657        && FindProcShort (glVertexAttribP1uiv)
1658        && FindProcShort (glVertexAttribP2ui)
1659        && FindProcShort (glVertexAttribP2uiv)
1660        && FindProcShort (glVertexAttribP3ui)
1661        && FindProcShort (glVertexAttribP3uiv)
1662        && FindProcShort (glVertexAttribP4ui)
1663        && FindProcShort (glVertexAttribP4uiv);
1664
1665   if ( hasVertType21010101rev
1666    && !isCoreProfile)
1667   {
1668     // load deprecated functions
1669     const bool hasVertType21010101revExt =
1670           FindProcShort (glVertexP2ui)
1671        && FindProcShort (glVertexP2uiv)
1672        && FindProcShort (glVertexP3ui)
1673        && FindProcShort (glVertexP3uiv)
1674        && FindProcShort (glVertexP4ui)
1675        && FindProcShort (glVertexP4uiv)
1676        && FindProcShort (glTexCoordP1ui)
1677        && FindProcShort (glTexCoordP1uiv)
1678        && FindProcShort (glTexCoordP2ui)
1679        && FindProcShort (glTexCoordP2uiv)
1680        && FindProcShort (glTexCoordP3ui)
1681        && FindProcShort (glTexCoordP3uiv)
1682        && FindProcShort (glTexCoordP4ui)
1683        && FindProcShort (glTexCoordP4uiv)
1684        && FindProcShort (glMultiTexCoordP1ui)
1685        && FindProcShort (glMultiTexCoordP1uiv)
1686        && FindProcShort (glMultiTexCoordP2ui)
1687        && FindProcShort (glMultiTexCoordP2uiv)
1688        && FindProcShort (glMultiTexCoordP3ui)
1689        && FindProcShort (glMultiTexCoordP3uiv)
1690        && FindProcShort (glMultiTexCoordP4ui)
1691        && FindProcShort (glMultiTexCoordP4uiv)
1692        && FindProcShort (glNormalP3ui)
1693        && FindProcShort (glNormalP3uiv)
1694        && FindProcShort (glColorP3ui)
1695        && FindProcShort (glColorP3uiv)
1696        && FindProcShort (glColorP4ui)
1697        && FindProcShort (glColorP4uiv)
1698        && FindProcShort (glSecondaryColorP3ui)
1699        && FindProcShort (glSecondaryColorP3uiv);
1700     (void )hasVertType21010101revExt;
1701   }
1702
1703   // load OpenGL 3.3 extra functions
1704   has33 = IsGlGreaterEqual (3, 3)
1705        && hasBlendFuncExtended
1706        && hasSamplerObjects
1707        && hasTimerQuery
1708        && hasVertType21010101rev
1709        && FindProcShort (glVertexAttribDivisor);
1710
1711   // load GL_ARB_draw_indirect (added to OpenGL 4.0 core)
1712   const bool hasDrawIndirect = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_draw_indirect"))
1713        && FindProcShort (glDrawArraysIndirect)
1714        && FindProcShort (glDrawElementsIndirect);
1715
1716   // load GL_ARB_gpu_shader_fp64 (added to OpenGL 4.0 core)
1717   const bool hasShaderFP64 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_gpu_shader_fp64"))
1718        && FindProcShort (glUniform1d)
1719        && FindProcShort (glUniform2d)
1720        && FindProcShort (glUniform3d)
1721        && FindProcShort (glUniform4d)
1722        && FindProcShort (glUniform1dv)
1723        && FindProcShort (glUniform2dv)
1724        && FindProcShort (glUniform3dv)
1725        && FindProcShort (glUniform4dv)
1726        && FindProcShort (glUniformMatrix2dv)
1727        && FindProcShort (glUniformMatrix3dv)
1728        && FindProcShort (glUniformMatrix4dv)
1729        && FindProcShort (glUniformMatrix2x3dv)
1730        && FindProcShort (glUniformMatrix2x4dv)
1731        && FindProcShort (glUniformMatrix3x2dv)
1732        && FindProcShort (glUniformMatrix3x4dv)
1733        && FindProcShort (glUniformMatrix4x2dv)
1734        && FindProcShort (glUniformMatrix4x3dv)
1735        && FindProcShort (glGetUniformdv);
1736
1737   // load GL_ARB_shader_subroutine (added to OpenGL 4.0 core)
1738   const bool hasShaderSubroutine = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_shader_subroutine"))
1739        && FindProcShort (glGetSubroutineUniformLocation)
1740        && FindProcShort (glGetSubroutineIndex)
1741        && FindProcShort (glGetActiveSubroutineUniformiv)
1742        && FindProcShort (glGetActiveSubroutineUniformName)
1743        && FindProcShort (glGetActiveSubroutineName)
1744        && FindProcShort (glUniformSubroutinesuiv)
1745        && FindProcShort (glGetUniformSubroutineuiv)
1746        && FindProcShort (glGetProgramStageiv);
1747
1748   // load GL_ARB_tessellation_shader (added to OpenGL 4.0 core)
1749   const bool hasTessellationShader = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_tessellation_shader"))
1750        && FindProcShort (glPatchParameteri)
1751        && FindProcShort (glPatchParameterfv);
1752
1753   // load GL_ARB_transform_feedback2 (added to OpenGL 4.0 core)
1754   const bool hasTrsfFeedback2 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback2"))
1755        && FindProcShort (glBindTransformFeedback)
1756        && FindProcShort (glDeleteTransformFeedbacks)
1757        && FindProcShort (glGenTransformFeedbacks)
1758        && FindProcShort (glIsTransformFeedback)
1759        && FindProcShort (glPauseTransformFeedback)
1760        && FindProcShort (glResumeTransformFeedback)
1761        && FindProcShort (glDrawTransformFeedback);
1762
1763   // load GL_ARB_transform_feedback3 (added to OpenGL 4.0 core)
1764   const bool hasTrsfFeedback3 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback3"))
1765        && FindProcShort (glDrawTransformFeedbackStream)
1766        && FindProcShort (glBeginQueryIndexed)
1767        && FindProcShort (glEndQueryIndexed)
1768        && FindProcShort (glGetQueryIndexediv);
1769
1770   // load OpenGL 4.0 new functions
1771   has40 = IsGlGreaterEqual (4, 0)
1772       && hasDrawIndirect
1773       && hasShaderFP64
1774       && hasShaderSubroutine
1775       && hasTessellationShader
1776       && hasTrsfFeedback2
1777       && hasTrsfFeedback3
1778       && FindProcShort (glMinSampleShading)
1779       && FindProcShort (glBlendEquationi)
1780       && FindProcShort (glBlendEquationSeparatei)
1781       && FindProcShort (glBlendFunci)
1782       && FindProcShort (glBlendFuncSeparatei);
1783
1784   // load GL_ARB_ES2_compatibility (added to OpenGL 4.1 core)
1785   const bool hasES2Compatibility = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_ES2_compatibility"))
1786        && FindProcShort (glReleaseShaderCompiler)
1787        && FindProcShort (glShaderBinary)
1788        && FindProcShort (glGetShaderPrecisionFormat)
1789        && FindProcShort (glDepthRangef)
1790        && FindProcShort (glClearDepthf);
1791
1792   // load GL_ARB_get_program_binary (added to OpenGL 4.1 core)
1793   const bool hasGetProgramBinary = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_get_program_binary"))
1794        && FindProcShort (glGetProgramBinary)
1795        && FindProcShort (glProgramBinary)
1796        && FindProcShort (glProgramParameteri);
1797
1798
1799   // load GL_ARB_separate_shader_objects (added to OpenGL 4.1 core)
1800   const bool hasSeparateShaderObjects = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_separate_shader_objects"))
1801        && FindProcShort (glUseProgramStages)
1802        && FindProcShort (glActiveShaderProgram)
1803        && FindProcShort (glCreateShaderProgramv)
1804        && FindProcShort (glBindProgramPipeline)
1805        && FindProcShort (glDeleteProgramPipelines)
1806        && FindProcShort (glGenProgramPipelines)
1807        && FindProcShort (glIsProgramPipeline)
1808        && FindProcShort (glGetProgramPipelineiv)
1809        && FindProcShort (glProgramUniform1i)
1810        && FindProcShort (glProgramUniform1iv)
1811        && FindProcShort (glProgramUniform1f)
1812        && FindProcShort (glProgramUniform1fv)
1813        && FindProcShort (glProgramUniform1d)
1814        && FindProcShort (glProgramUniform1dv)
1815        && FindProcShort (glProgramUniform1ui)
1816        && FindProcShort (glProgramUniform1uiv)
1817        && FindProcShort (glProgramUniform2i)
1818        && FindProcShort (glProgramUniform2iv)
1819        && FindProcShort (glProgramUniform2f)
1820        && FindProcShort (glProgramUniform2fv)
1821        && FindProcShort (glProgramUniform2d)
1822        && FindProcShort (glProgramUniform2dv)
1823        && FindProcShort (glProgramUniform2ui)
1824        && FindProcShort (glProgramUniform2uiv)
1825        && FindProcShort (glProgramUniform3i)
1826        && FindProcShort (glProgramUniform3iv)
1827        && FindProcShort (glProgramUniform3f)
1828        && FindProcShort (glProgramUniform3fv)
1829        && FindProcShort (glProgramUniform3d)
1830        && FindProcShort (glProgramUniform3dv)
1831        && FindProcShort (glProgramUniform3ui)
1832        && FindProcShort (glProgramUniform3uiv)
1833        && FindProcShort (glProgramUniform4i)
1834        && FindProcShort (glProgramUniform4iv)
1835        && FindProcShort (glProgramUniform4f)
1836        && FindProcShort (glProgramUniform4fv)
1837        && FindProcShort (glProgramUniform4d)
1838        && FindProcShort (glProgramUniform4dv)
1839        && FindProcShort (glProgramUniform4ui)
1840        && FindProcShort (glProgramUniform4uiv)
1841        && FindProcShort (glProgramUniformMatrix2fv)
1842        && FindProcShort (glProgramUniformMatrix3fv)
1843        && FindProcShort (glProgramUniformMatrix4fv)
1844        && FindProcShort (glProgramUniformMatrix2dv)
1845        && FindProcShort (glProgramUniformMatrix3dv)
1846        && FindProcShort (glProgramUniformMatrix4dv)
1847        && FindProcShort (glProgramUniformMatrix2x3fv)
1848        && FindProcShort (glProgramUniformMatrix3x2fv)
1849        && FindProcShort (glProgramUniformMatrix2x4fv)
1850        && FindProcShort (glProgramUniformMatrix4x2fv)
1851        && FindProcShort (glProgramUniformMatrix3x4fv)
1852        && FindProcShort (glProgramUniformMatrix4x3fv)
1853        && FindProcShort (glProgramUniformMatrix2x3dv)
1854        && FindProcShort (glProgramUniformMatrix3x2dv)
1855        && FindProcShort (glProgramUniformMatrix2x4dv)
1856        && FindProcShort (glProgramUniformMatrix4x2dv)
1857        && FindProcShort (glProgramUniformMatrix3x4dv)
1858        && FindProcShort (glProgramUniformMatrix4x3dv)
1859        && FindProcShort (glValidateProgramPipeline)
1860        && FindProcShort (glGetProgramPipelineInfoLog);
1861
1862   // load GL_ARB_vertex_attrib_64bit (added to OpenGL 4.1 core)
1863   const bool hasVertAttrib64bit = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_vertex_attrib_64bit"))
1864        && FindProcShort (glVertexAttribL1d)
1865        && FindProcShort (glVertexAttribL2d)
1866        && FindProcShort (glVertexAttribL3d)
1867        && FindProcShort (glVertexAttribL4d)
1868        && FindProcShort (glVertexAttribL1dv)
1869        && FindProcShort (glVertexAttribL2dv)
1870        && FindProcShort (glVertexAttribL3dv)
1871        && FindProcShort (glVertexAttribL4dv)
1872        && FindProcShort (glVertexAttribLPointer)
1873        && FindProcShort (glGetVertexAttribLdv);
1874
1875   // load GL_ARB_viewport_array (added to OpenGL 4.1 core)
1876   const bool hasViewportArray = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_viewport_array"))
1877        && FindProcShort (glViewportArrayv)
1878        && FindProcShort (glViewportIndexedf)
1879        && FindProcShort (glViewportIndexedfv)
1880        && FindProcShort (glScissorArrayv)
1881        && FindProcShort (glScissorIndexed)
1882        && FindProcShort (glScissorIndexedv)
1883        && FindProcShort (glDepthRangeArrayv)
1884        && FindProcShort (glDepthRangeIndexed)
1885        && FindProcShort (glGetFloati_v)
1886        && FindProcShort (glGetDoublei_v);
1887
1888   has41 = IsGlGreaterEqual (4, 1)
1889        && hasES2Compatibility
1890        && hasGetProgramBinary
1891        && hasSeparateShaderObjects
1892        && hasVertAttrib64bit
1893        && hasViewportArray;
1894
1895   // load GL_ARB_base_instance (added to OpenGL 4.2 core)
1896   const bool hasBaseInstance = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_base_instance"))
1897        && FindProcShort (glDrawArraysInstancedBaseInstance)
1898        && FindProcShort (glDrawElementsInstancedBaseInstance)
1899        && FindProcShort (glDrawElementsInstancedBaseVertexBaseInstance);
1900
1901   // load GL_ARB_transform_feedback_instanced (added to OpenGL 4.2 core)
1902   const bool hasTrsfFeedbackInstanced = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_transform_feedback_instanced"))
1903        && FindProcShort (glDrawTransformFeedbackInstanced)
1904        && FindProcShort (glDrawTransformFeedbackStreamInstanced);
1905
1906   // load GL_ARB_internalformat_query (added to OpenGL 4.2 core)
1907   const bool hasInternalFormatQuery = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_internalformat_query"))
1908        && FindProcShort (glGetInternalformativ);
1909
1910   // load GL_ARB_shader_atomic_counters (added to OpenGL 4.2 core)
1911   const bool hasShaderAtomicCounters = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_atomic_counters"))
1912        && FindProcShort (glGetActiveAtomicCounterBufferiv);
1913
1914   // load GL_ARB_shader_image_load_store (added to OpenGL 4.2 core)
1915   const bool hasShaderImgLoadStore = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_image_load_store"))
1916        && FindProcShort (glBindImageTexture)
1917        && FindProcShort (glMemoryBarrier);
1918
1919   // load GL_ARB_texture_storage (added to OpenGL 4.2 core)
1920   const bool hasTextureStorage = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_texture_storage"))
1921        && FindProcShort (glTexStorage1D)
1922        && FindProcShort (glTexStorage2D)
1923        && FindProcShort (glTexStorage3D);
1924
1925   has42 = IsGlGreaterEqual (4, 2)
1926        && hasBaseInstance
1927        && hasTrsfFeedbackInstanced
1928        && hasInternalFormatQuery
1929        && hasShaderAtomicCounters
1930        && hasShaderImgLoadStore
1931        && hasTextureStorage;
1932
1933   has43 = IsGlGreaterEqual (4, 3)
1934        && FindProcShort (glClearBufferData)
1935        && FindProcShort (glClearBufferSubData)
1936        && FindProcShort (glDispatchCompute)
1937        && FindProcShort (glDispatchComputeIndirect)
1938        && FindProcShort (glCopyImageSubData)
1939        && FindProcShort (glFramebufferParameteri)
1940        && FindProcShort (glGetFramebufferParameteriv)
1941        && FindProcShort (glGetInternalformati64v)
1942        && FindProcShort (glInvalidateTexSubImage)
1943        && FindProcShort (glInvalidateTexImage)
1944        && FindProcShort (glInvalidateBufferSubData)
1945        && FindProcShort (glInvalidateBufferData)
1946        && FindProcShort (glInvalidateFramebuffer)
1947        && FindProcShort (glInvalidateSubFramebuffer)
1948        && FindProcShort (glMultiDrawArraysIndirect)
1949        && FindProcShort (glMultiDrawElementsIndirect)
1950        && FindProcShort (glGetProgramInterfaceiv)
1951        && FindProcShort (glGetProgramResourceIndex)
1952        && FindProcShort (glGetProgramResourceName)
1953        && FindProcShort (glGetProgramResourceiv)
1954        && FindProcShort (glGetProgramResourceLocation)
1955        && FindProcShort (glGetProgramResourceLocationIndex)
1956        && FindProcShort (glShaderStorageBlockBinding)
1957        && FindProcShort (glTexBufferRange)
1958        && FindProcShort (glTexStorage2DMultisample)
1959        && FindProcShort (glTexStorage3DMultisample)
1960        && FindProcShort (glTextureView)
1961        && FindProcShort (glBindVertexBuffer)
1962        && FindProcShort (glVertexAttribFormat)
1963        && FindProcShort (glVertexAttribIFormat)
1964        && FindProcShort (glVertexAttribLFormat)
1965        && FindProcShort (glVertexAttribBinding)
1966        && FindProcShort (glVertexBindingDivisor)
1967        && FindProcShort (glDebugMessageControl)
1968        && FindProcShort (glDebugMessageInsert)
1969        && FindProcShort (glDebugMessageCallback)
1970        && FindProcShort (glGetDebugMessageLog)
1971        && FindProcShort (glPushDebugGroup)
1972        && FindProcShort (glPopDebugGroup)
1973        && FindProcShort (glObjectLabel)
1974        && FindProcShort (glGetObjectLabel)
1975        && FindProcShort (glObjectPtrLabel)
1976        && FindProcShort (glGetObjectPtrLabel);
1977
1978   // load GL_ARB_clear_texture (added to OpenGL 4.4 core)
1979   bool arbTexClear = (IsGlGreaterEqual (4, 4) || CheckExtension ("GL_ARB_clear_texture"))
1980        && FindProcShort (glClearTexImage)
1981        && FindProcShort (glClearTexSubImage);
1982
1983   has44 = IsGlGreaterEqual (4, 4)
1984        && arbTexClear
1985        && FindProcShort (glBufferStorage)
1986        && FindProcShort (glBindBuffersBase)
1987        && FindProcShort (glBindBuffersRange)
1988        && FindProcShort (glBindTextures)
1989        && FindProcShort (glBindSamplers)
1990        && FindProcShort (glBindImageTextures)
1991        && FindProcShort (glBindVertexBuffers);
1992
1993   // initialize TBO extension (ARB)
1994   if (!has31
1995    && CheckExtension ("GL_ARB_texture_buffer_object")
1996    && FindProc ("glTexBufferARB", myFuncs->glTexBuffer))
1997   {
1998     arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
1999   }
2000   arbTboRGB32 = CheckExtension ("GL_ARB_texture_buffer_object_rgb32");
2001
2002   // initialize hardware instancing extension (ARB)
2003   if (!has31
2004    && CheckExtension ("GL_ARB_draw_instanced")
2005    && FindProc ("glDrawArraysInstancedARB",   myFuncs->glDrawArraysInstanced)
2006    && FindProc ("glDrawElementsInstancedARB", myFuncs->glDrawElementsInstanced))
2007   {
2008     arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2009   }
2010
2011   // initialize FBO extension (ARB)
2012   if (hasFBO)
2013   {
2014     arbFBO     = (OpenGl_ArbFBO*     )(&(*myFuncs));
2015     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
2016     extPDS = Standard_True; // extension for EXT, but part of ARB
2017   }
2018
2019   // initialize GS extension (EXT)
2020   if (CheckExtension ("GL_EXT_geometry_shader4")
2021    && FindProcShort (glProgramParameteriEXT))
2022   {
2023     extGS = (OpenGl_ExtGS* )(&(*myFuncs));
2024   }
2025
2026   // initialize bindless texture extension (ARB)
2027   if (CheckExtension ("GL_ARB_bindless_texture")
2028    && FindProcShort (glGetTextureHandleARB)
2029    && FindProcShort (glGetTextureSamplerHandleARB)
2030    && FindProcShort (glMakeTextureHandleResidentARB)
2031    && FindProcShort (glMakeTextureHandleNonResidentARB)
2032    && FindProcShort (glGetImageHandleARB)
2033    && FindProcShort (glMakeImageHandleResidentARB)
2034    && FindProcShort (glMakeImageHandleNonResidentARB)
2035    && FindProcShort (glUniformHandleui64ARB)
2036    && FindProcShort (glUniformHandleui64vARB)
2037    && FindProcShort (glProgramUniformHandleui64ARB)
2038    && FindProcShort (glProgramUniformHandleui64vARB)
2039    && FindProcShort (glIsTextureHandleResidentARB)
2040    && FindProcShort (glIsImageHandleResidentARB)
2041    && FindProcShort (glVertexAttribL1ui64ARB)
2042    && FindProcShort (glVertexAttribL1ui64vARB)
2043    && FindProcShort (glGetVertexAttribLui64vARB))
2044   {
2045     arbTexBindless = (OpenGl_ArbTexBindless* )(&(*myFuncs));
2046   }
2047
2048   if (!has12)
2049   {
2050     checkWrongVersion (1, 2);
2051     myGlVerMajor = 1;
2052     myGlVerMinor = 1;
2053     return;
2054   }
2055   else if (!has13)
2056   {
2057     checkWrongVersion (1, 3);
2058     myGlVerMajor = 1;
2059     myGlVerMinor = 2;
2060     return;
2061   }
2062   else if (!has14)
2063   {
2064     checkWrongVersion (1, 4);
2065     myGlVerMajor = 1;
2066     myGlVerMinor = 3;
2067     return;
2068   }
2069   else if (!has15)
2070   {
2071     checkWrongVersion (1, 5);
2072     myGlVerMajor = 1;
2073     myGlVerMinor = 4;
2074     return;
2075   }
2076   if (!isCoreProfile)
2077   {
2078     core15 = (OpenGl_GlCore15* )(&(*myFuncs));
2079   }
2080   core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
2081
2082   if (!has20)
2083   {
2084     checkWrongVersion (2, 0);
2085     myGlVerMajor = 1;
2086     myGlVerMinor = 5;
2087     return;
2088   }
2089
2090   const char* aGlslVer = (const char* )::glGetString (GL_SHADING_LANGUAGE_VERSION);
2091   if (aGlslVer == NULL
2092   || *aGlslVer == '\0')
2093   {
2094     // broken context has been detected
2095     TCollection_ExtendedString aMsg = TCollection_ExtendedString()
2096       + "Error! OpenGL context reports version "
2097       + myGlVerMajor  + "." + myGlVerMinor
2098       + " but reports wrong GLSL version";
2099     PushMessage (GL_DEBUG_SOURCE_APPLICATION,
2100                  GL_DEBUG_TYPE_ERROR,
2101                  0,
2102                  GL_DEBUG_SEVERITY_HIGH,
2103                  aMsg);
2104     myGlVerMajor = 1;
2105     myGlVerMinor = 5;
2106     return;
2107   }
2108
2109   if (!isCoreProfile)
2110   {
2111     core20  = (OpenGl_GlCore20*    )(&(*myFuncs));
2112   }
2113   core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
2114
2115   if (!has21)
2116   {
2117     checkWrongVersion (2, 1);
2118     myGlVerMajor = 2;
2119     myGlVerMinor = 0;
2120     return;
2121   }
2122
2123   if (!has30)
2124   {
2125     checkWrongVersion (3, 0);
2126     myGlVerMajor = 2;
2127     myGlVerMinor = 1;
2128     return;
2129   }
2130
2131   // MSAA RenderBuffers have been defined in OpenGL 3.0,
2132   // but MSAA Textures - only in OpenGL 3.2+
2133   if (!has32
2134    && CheckExtension ("GL_ARB_texture_multisample")
2135    && FindProcShort (glTexImage2DMultisample))
2136   {
2137     GLint aNbColorSamples = 0, aNbDepthSamples = 0;
2138     ::glGetIntegerv (GL_MAX_COLOR_TEXTURE_SAMPLES, &aNbColorSamples);
2139     ::glGetIntegerv (GL_MAX_DEPTH_TEXTURE_SAMPLES, &aNbDepthSamples);
2140     myMaxMsaaSamples = Min (aNbColorSamples, aNbDepthSamples);
2141   }
2142   if (!has43
2143    && CheckExtension ("GL_ARB_texture_storage_multisample")
2144    && FindProcShort (glTexStorage2DMultisample))
2145   {
2146     //
2147   }
2148
2149   if (!has31)
2150   {
2151     checkWrongVersion (3, 1);
2152     myGlVerMajor = 3;
2153     myGlVerMinor = 0;
2154     return;
2155   }
2156   arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2157   arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2158
2159   if (!has32)
2160   {
2161     checkWrongVersion (3, 2);
2162     myGlVerMajor = 3;
2163     myGlVerMinor = 1;
2164     return;
2165   }
2166   core32 = (OpenGl_GlCore32* )(&(*myFuncs));
2167   if (isCoreProfile)
2168   {
2169     core32->glGenVertexArrays (1, &myDefaultVao);
2170   }
2171   else
2172   {
2173     core32back = (OpenGl_GlCore32Back* )(&(*myFuncs));
2174   }
2175   ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
2176
2177   if (!has33)
2178   {
2179     checkWrongVersion (3, 3);
2180     myGlVerMajor = 3;
2181     myGlVerMinor = 2;
2182     return;
2183   }
2184   core33 = (OpenGl_GlCore33* )(&(*myFuncs));
2185   if (!isCoreProfile)
2186   {
2187     core33back = (OpenGl_GlCore33Back* )(&(*myFuncs));
2188   }
2189
2190   // initialize sampler object
2191   myTexSampler = new OpenGl_Sampler();
2192   myTexSampler->Init (*this);
2193
2194   if (!has40)
2195   {
2196     checkWrongVersion (4, 0);
2197     myGlVerMajor = 3;
2198     myGlVerMinor = 3;
2199     return;
2200   }
2201   arbTboRGB32 = Standard_True; // in core since OpenGL 4.0
2202
2203   if (!has41)
2204   {
2205     checkWrongVersion (4, 1);
2206     myGlVerMajor = 4;
2207     myGlVerMinor = 0;
2208     return;
2209   }
2210   core41 = (OpenGl_GlCore41* )(&(*myFuncs));
2211   if (!isCoreProfile)
2212   {
2213     core41back = (OpenGl_GlCore41Back* )(&(*myFuncs));
2214   }
2215
2216   if(!has42)
2217   {
2218     checkWrongVersion (4, 2);
2219     myGlVerMajor = 4;
2220     myGlVerMinor = 1;
2221     return;
2222   }
2223   core42 = (OpenGl_GlCore42* )(&(*myFuncs));
2224   if (!isCoreProfile)
2225   {
2226     core42back = (OpenGl_GlCore42Back* )(&(*myFuncs));
2227   }
2228
2229   if (!has43)
2230   {
2231     checkWrongVersion (4, 3);
2232     myGlVerMajor = 4;
2233     myGlVerMinor = 2;
2234     return;
2235   }
2236   core43 = (OpenGl_GlCore43* )(&(*myFuncs));
2237   if (!isCoreProfile)
2238   {
2239     core43back = (OpenGl_GlCore43Back* )(&(*myFuncs));
2240   }
2241
2242   if (!has44)
2243   {
2244     checkWrongVersion (4, 4);
2245     myGlVerMajor = 4;
2246     myGlVerMinor = 3;
2247     return;
2248   }
2249   core44 = (OpenGl_GlCore44* )(&(*myFuncs));
2250   if (!isCoreProfile)
2251   {
2252     core44back = (OpenGl_GlCore44Back* )(&(*myFuncs));
2253   }
2254 #endif
2255 }
2256
2257 // =======================================================================
2258 // function : MemoryInfo
2259 // purpose  :
2260 // =======================================================================
2261 Standard_Size OpenGl_Context::AvailableMemory() const
2262 {
2263 #if !defined(GL_ES_VERSION_2_0)
2264   if (atiMem)
2265   {
2266     // this is actually information for VBO pool
2267     // however because pools are mostly shared
2268     // it can be used for total GPU memory estimations
2269     GLint aMemInfo[4];
2270     aMemInfo[0] = 0;
2271     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
2272     // returned value is in KiB, however this maybe changed in future
2273     return Standard_Size(aMemInfo[0]) * 1024;
2274   }
2275   else if (nvxMem)
2276   {
2277     // current available dedicated video memory (in KiB), currently unused GPU memory
2278     GLint aMemInfo = 0;
2279     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
2280     return Standard_Size(aMemInfo) * 1024;
2281   }
2282 #endif
2283   return 0;
2284 }
2285
2286 // =======================================================================
2287 // function : MemoryInfo
2288 // purpose  :
2289 // =======================================================================
2290 TCollection_AsciiString OpenGl_Context::MemoryInfo() const
2291 {
2292   TCollection_AsciiString anInfo;
2293 #if !defined(GL_ES_VERSION_2_0)
2294   if (atiMem)
2295   {
2296     GLint aValues[4];
2297     memset (aValues, 0, sizeof(aValues));
2298     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
2299
2300     // total memory free in the pool
2301     anInfo += TCollection_AsciiString ("  GPU free memory:    ") + (aValues[0] / 1024) + " MiB\n";
2302
2303     // largest available free block in the pool
2304     anInfo += TCollection_AsciiString ("  Largest free block: ") + (aValues[1] / 1024) + " MiB\n";
2305     if (aValues[2] != aValues[0])
2306     {
2307       // total auxiliary memory free
2308       anInfo += TCollection_AsciiString ("  Free memory:        ") + (aValues[2] / 1024) + " MiB\n";
2309     }
2310   }
2311   else if (nvxMem)
2312   {
2313     //current available dedicated video memory (in KiB), currently unused GPU memory
2314     GLint aValue = 0;
2315     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
2316     anInfo += TCollection_AsciiString ("  GPU free memory:    ") + (aValue / 1024) + " MiB\n";
2317
2318     // dedicated video memory, total size (in KiB) of the GPU memory
2319     GLint aDedicated = 0;
2320     glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
2321     anInfo += TCollection_AsciiString ("  GPU memory:         ") + (aDedicated / 1024) + " MiB\n";
2322
2323     // total available memory, total size (in KiB) of the memory available for allocations
2324     glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
2325     if (aValue != aDedicated)
2326     {
2327       // different only for special configurations
2328       anInfo += TCollection_AsciiString ("  Total memory:       ") + (aValue / 1024) + " MiB\n";
2329     }
2330   }
2331 #endif
2332   return anInfo;
2333 }
2334
2335
2336 // =======================================================================
2337 // function : GetResource
2338 // purpose  :
2339 // =======================================================================
2340 const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
2341 {
2342   return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
2343 }
2344
2345 // =======================================================================
2346 // function : ShareResource
2347 // purpose  :
2348 // =======================================================================
2349 Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
2350                                                 const Handle(OpenGl_Resource)& theResource)
2351 {
2352   if (theKey.IsEmpty() || theResource.IsNull())
2353   {
2354     return Standard_False;
2355   }
2356   return mySharedResources->Bind (theKey, theResource);
2357 }
2358
2359 // =======================================================================
2360 // function : ReleaseResource
2361 // purpose  :
2362 // =======================================================================
2363 void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
2364                                       const Standard_Boolean         theToDelay)
2365 {
2366   if (!mySharedResources->IsBound (theKey))
2367   {
2368     return;
2369   }
2370   const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
2371   if (aRes->GetRefCount() > 1)
2372   {
2373     return;
2374   }
2375
2376   if (theToDelay)
2377   {
2378     myDelayed->Bind (theKey, 1);
2379   }
2380   else
2381   {
2382     aRes->Release (this);
2383     mySharedResources->UnBind (theKey);
2384   }
2385 }
2386
2387 // =======================================================================
2388 // function : DelayedRelease
2389 // purpose  :
2390 // =======================================================================
2391 void OpenGl_Context::DelayedRelease (Handle(OpenGl_Resource)& theResource)
2392 {
2393   myUnusedResources->Prepend (theResource);
2394   theResource.Nullify();
2395 }
2396
2397 // =======================================================================
2398 // function : ReleaseDelayed
2399 // purpose  :
2400 // =======================================================================
2401 void OpenGl_Context::ReleaseDelayed()
2402 {
2403   // release queued elements
2404   while (!myUnusedResources->IsEmpty())
2405   {
2406     myUnusedResources->First()->Release (this);
2407     myUnusedResources->RemoveFirst();
2408   }
2409
2410   // release delayed shared resources
2411   NCollection_Vector<TCollection_AsciiString> aDeadList;
2412   for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
2413        anIter.More(); anIter.Next())
2414   {
2415     if (++anIter.ChangeValue() <= 2)
2416     {
2417       continue; // postpone release one more frame to ensure noone use it periodically
2418     }
2419
2420     const TCollection_AsciiString& aKey = anIter.Key();
2421     if (!mySharedResources->IsBound (aKey))
2422     {
2423       // mixed unshared strategy delayed/undelayed was used!
2424       aDeadList.Append (aKey);
2425       continue;
2426     }
2427
2428     Handle(OpenGl_Resource)& aRes = mySharedResources->ChangeFind (aKey);
2429     if (aRes->GetRefCount() > 1)
2430     {
2431       // should be only 1 instance in mySharedResources
2432       // if not - resource was reused again
2433       aDeadList.Append (aKey);
2434       continue;
2435     }
2436
2437     // release resource if no one requiested it more than 2 redraw calls
2438     aRes->Release (this);
2439     mySharedResources->UnBind (aKey);
2440     aDeadList.Append (aKey);
2441   }
2442
2443   for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
2444   {
2445     myDelayed->UnBind (aDeadList.Value (anIter));
2446   }
2447 }
2448
2449 // =======================================================================
2450 // function : BindProgram
2451 // purpose  :
2452 // =======================================================================
2453 Standard_Boolean OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram)
2454 {
2455   if (core20fwd == NULL)
2456   {
2457     return Standard_False;
2458   }
2459
2460   if (theProgram.IsNull()
2461   || !theProgram->IsValid())
2462   {
2463     if (!myActiveProgram.IsNull())
2464     {
2465       core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
2466       myActiveProgram.Nullify();
2467     }
2468     return Standard_False;
2469   }
2470
2471   myActiveProgram = theProgram;
2472   core20fwd->glUseProgram (theProgram->ProgramId());
2473   return Standard_True;
2474 }
2475
2476 // =======================================================================
2477 // function : BindDefaultVao
2478 // purpose  :
2479 // =======================================================================
2480 void OpenGl_Context::BindDefaultVao()
2481 {
2482 #if !defined(GL_ES_VERSION_2_0)
2483   if (myDefaultVao == 0
2484    || core32 == NULL)
2485   {
2486     return;
2487   }
2488
2489   core32->glBindVertexArray (myDefaultVao);
2490 #endif
2491 }
2492
2493 // =======================================================================
2494 // function : SetDefaultFrameBuffer
2495 // purpose  :
2496 // =======================================================================
2497 Handle(OpenGl_FrameBuffer) OpenGl_Context::SetDefaultFrameBuffer (const Handle(OpenGl_FrameBuffer)& theFbo)
2498 {
2499   Handle(OpenGl_FrameBuffer) aFbo = myDefaultFbo;
2500   myDefaultFbo = theFbo;
2501   return aFbo;
2502 }
2503
2504 // =======================================================================
2505 // function : SetColor4fv
2506 // purpose  :
2507 // =======================================================================
2508 void OpenGl_Context::SetColor4fv (const OpenGl_Vec4& theColor)
2509 {
2510   if (!myActiveProgram.IsNull())
2511   {
2512     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_COLOR), theColor);
2513   }
2514 #if !defined(GL_ES_VERSION_2_0)
2515   else if (core11 != NULL)
2516   {
2517     core11->glColor4fv (theColor.GetData());
2518   }
2519 #endif
2520 }
2521
2522 // =======================================================================
2523 // function : SetTypeOfLine
2524 // purpose  :
2525 // =======================================================================
2526 void OpenGl_Context::SetTypeOfLine (const Aspect_TypeOfLine  theType,
2527                                     const Standard_ShortReal theFactor)
2528 {
2529   Standard_Integer aPattern = 0xFFFF;
2530   switch (theType)
2531   {
2532     case Aspect_TOL_DASH:
2533     {
2534       aPattern = 0xFFC0;
2535       break;
2536     }
2537     case Aspect_TOL_DOT:
2538     {
2539       aPattern = 0xCCCC;
2540       break;
2541     }
2542     case Aspect_TOL_DOTDASH:
2543     {
2544       aPattern = 0xFF18;
2545       break;
2546     }
2547     case Aspect_TOL_SOLID:
2548     {
2549       aPattern = 0xFFFF;
2550       break;
2551     }
2552     case Aspect_TOL_USERDEFINED:
2553     {
2554       aPattern = 0xFF24;
2555       break;
2556     }
2557   }
2558
2559   if (!myActiveProgram.IsNull())
2560   {
2561     myActiveProgram->SetUniform (this, "uPattern", aPattern);
2562     myActiveProgram->SetUniform (this, "uFactor",  theFactor);
2563     return;
2564   }
2565
2566 #if !defined(GL_ES_VERSION_2_0)
2567   if (theType != Aspect_TOL_SOLID)
2568   {
2569   #ifdef HAVE_GL2PS
2570     if (IsFeedback())
2571     {
2572       gl2psEnable (GL2PS_LINE_STIPPLE);
2573     }
2574   #endif
2575
2576     if (core11 != NULL)
2577     {
2578       core11fwd->glEnable (GL_LINE_STIPPLE);
2579
2580       core11->glLineStipple (static_cast<GLint>    (theFactor),
2581                              static_cast<GLushort> (aPattern));
2582     }
2583   }
2584   else
2585   {
2586     if (core11 != NULL)
2587     {
2588       core11fwd->glDisable (GL_LINE_STIPPLE);
2589     }
2590
2591   #ifdef HAVE_GL2PS
2592     if (IsFeedback())
2593     {
2594       gl2psDisable (GL2PS_LINE_STIPPLE);
2595     }
2596   #endif
2597   }
2598 #endif
2599 }
2600
2601 // =======================================================================
2602 // function : SetLineWidth
2603 // purpose  :
2604 // =======================================================================
2605 void OpenGl_Context::SetLineWidth (const Standard_ShortReal theWidth)
2606 {
2607   if (core11 != NULL)
2608   {
2609     // glLineWidth() is still defined within Core Profile, but has no effect with values != 1.0f
2610     core11fwd->glLineWidth (theWidth);
2611   }
2612 #ifdef HAVE_GL2PS
2613   if (IsFeedback())
2614   {
2615     gl2psLineWidth (theWidth);
2616   }
2617 #endif
2618 }
2619
2620 // =======================================================================
2621 // function : SetTextureMatrix
2622 // purpose  :
2623 // =======================================================================
2624 void OpenGl_Context::SetTextureMatrix (const Handle(Graphic3d_TextureParams)& theParams)
2625 {
2626   if (theParams.IsNull())
2627   {
2628     return;
2629   }
2630   else if (!myActiveProgram.IsNull())
2631   {
2632     const GLint aUniLoc = myActiveProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_TRSF2D);
2633     if (aUniLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
2634     {
2635       return;
2636     }
2637
2638     // pack transformation parameters
2639     OpenGl_Vec4 aTrsf[2];
2640     aTrsf[0].xy() = theParams->Translation();
2641     aTrsf[0].zw() = theParams->Scale();
2642     aTrsf[1].x()  = std::sin (-theParams->Rotation() * static_cast<float> (M_PI / 180.0));
2643     aTrsf[1].y()  = std::cos (-theParams->Rotation() * static_cast<float> (M_PI / 180.0));
2644     myActiveProgram->SetUniform (this, aUniLoc, 2, aTrsf);
2645     return;
2646   }
2647
2648 #if !defined(GL_ES_VERSION_2_0)
2649   if (core11 != NULL)
2650   {
2651     GLint aMatrixMode = GL_TEXTURE;
2652     ::glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
2653
2654     core11->glMatrixMode (GL_TEXTURE);
2655     OpenGl_Mat4 aTextureMat;
2656     const Graphic3d_Vec2& aScale = theParams->Scale();
2657     const Graphic3d_Vec2& aTrans = theParams->Translation();
2658     Graphic3d_TransformUtils::Scale     (aTextureMat,  aScale.x(),  aScale.y(), 1.0f);
2659     Graphic3d_TransformUtils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f);
2660     Graphic3d_TransformUtils::Rotate    (aTextureMat, -theParams->Rotation(), 0.0f, 0.0f, 1.0f);
2661     core11->glLoadMatrixf (aTextureMat);
2662     core11->glMatrixMode (aMatrixMode);
2663   }
2664 #endif
2665 }
2666
2667 // =======================================================================
2668 // function : SetPointSize
2669 // purpose  :
2670 // =======================================================================
2671 void OpenGl_Context::SetPointSize (const Standard_ShortReal theSize)
2672 {
2673   if (!myActiveProgram.IsNull())
2674   {
2675     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_POINT_SIZE), theSize);
2676   #if !defined(GL_ES_VERSION_2_0)
2677     //myContext->core11fwd->glEnable (GL_VERTEX_PROGRAM_POINT_SIZE);
2678   #endif
2679   }
2680 #if !defined(GL_ES_VERSION_2_0)
2681   //else
2682   {
2683     core11fwd->glPointSize (theSize);
2684     if (core20fwd != NULL)
2685     {
2686       //myContext->core11fwd->glDisable (GL_VERTEX_PROGRAM_POINT_SIZE);
2687     }
2688   }
2689 #endif
2690 }
2691
2692 // =======================================================================
2693 // function : SetGlNormalizeEnabled
2694 // purpose  :
2695 // =======================================================================
2696 Standard_Boolean OpenGl_Context::SetGlNormalizeEnabled (Standard_Boolean isEnabled)
2697 {
2698   if (isEnabled == myIsGlNormalizeEnabled)
2699   {
2700     return myIsGlNormalizeEnabled;
2701   }
2702
2703   Standard_Boolean anOldGlNormalize = myIsGlNormalizeEnabled;
2704
2705   myIsGlNormalizeEnabled = isEnabled;
2706
2707 #if !defined(GL_ES_VERSION_2_0)
2708   if (core11 != NULL)
2709   {
2710     if (isEnabled)
2711     {
2712       ::glEnable  (GL_NORMALIZE);
2713     }
2714     else
2715     {
2716       ::glDisable (GL_NORMALIZE);
2717     }
2718   }
2719 #endif
2720
2721   return anOldGlNormalize;
2722 }
2723
2724 // =======================================================================
2725 // function : ApplyModelWorldMatrix
2726 // purpose  :
2727 // =======================================================================
2728 void OpenGl_Context::ApplyModelWorldMatrix()
2729 {
2730 #if !defined(GL_ES_VERSION_2_0)
2731   if (core11 != NULL)
2732   {
2733     core11->glMatrixMode (GL_MODELVIEW);
2734     core11->glLoadMatrixf (ModelWorldState.Current());
2735   }
2736 #endif
2737
2738   if (!myShaderManager->IsEmpty())
2739   {
2740     myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
2741   }
2742 }
2743
2744 // =======================================================================
2745 // function : ApplyWorldViewMatrix
2746 // purpose  :
2747 // =======================================================================
2748 void OpenGl_Context::ApplyWorldViewMatrix()
2749 {
2750 #if !defined(GL_ES_VERSION_2_0)
2751   if (core11 != NULL)
2752   {
2753     core11->glMatrixMode (GL_MODELVIEW);
2754     core11->glLoadMatrixf (WorldViewState.Current());
2755   }
2756 #endif
2757
2758   if (!myShaderManager->IsEmpty())
2759   {
2760     myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
2761   }
2762 }
2763
2764 // =======================================================================
2765 // function : ApplyModelViewMatrix
2766 // purpose  :
2767 // =======================================================================
2768 void OpenGl_Context::ApplyModelViewMatrix()
2769 {
2770 #if !defined(GL_ES_VERSION_2_0)
2771   if (core11 != NULL)
2772   {
2773     OpenGl_Mat4 aModelView = WorldViewState.Current() * ModelWorldState.Current();
2774     core11->glMatrixMode (GL_MODELVIEW);
2775     core11->glLoadMatrixf (aModelView.GetData());
2776   }
2777 #endif
2778
2779   if (!myShaderManager->IsEmpty())
2780   {
2781     myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
2782     myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
2783   }
2784 }
2785
2786 // =======================================================================
2787 // function : ApplyProjectionMatrix
2788 // purpose  :
2789 // =======================================================================
2790 void OpenGl_Context::ApplyProjectionMatrix()
2791 {
2792 #if !defined(GL_ES_VERSION_2_0)
2793   if (core11 != NULL)
2794   {
2795     core11->glMatrixMode (GL_PROJECTION);
2796     core11->glLoadMatrixf (ProjectionState.Current().GetData());
2797   }
2798 #endif
2799
2800   if (!myShaderManager->IsEmpty())
2801   {
2802     myShaderManager->UpdateProjectionStateTo (ProjectionState.Current());
2803   }
2804 }
2805
2806
2807 // =======================================================================
2808 // function : EnableFeatures
2809 // purpose  :
2810 // =======================================================================
2811 void OpenGl_Context::EnableFeatures() const
2812 {
2813   //
2814 }
2815
2816 // =======================================================================
2817 // function : DisableFeatures
2818 // purpose  :
2819 // =======================================================================
2820 void OpenGl_Context::DisableFeatures() const
2821 {
2822 #if !defined(GL_ES_VERSION_2_0)
2823   glPixelTransferi (GL_MAP_COLOR, GL_FALSE);
2824 #endif
2825
2826   /*
2827   * Disable stuff that's likely to slow down glDrawPixels.
2828   * (Omit as much of this as possible, when you know in advance
2829   * that the OpenGL state will already be set correctly.)
2830   */
2831   glDisable(GL_DITHER);
2832   glDisable(GL_BLEND);
2833   glDisable(GL_DEPTH_TEST);
2834   glDisable(GL_TEXTURE_2D);
2835   glDisable(GL_STENCIL_TEST);
2836
2837 #if !defined(GL_ES_VERSION_2_0)
2838   glDisable(GL_LIGHTING);
2839   glDisable(GL_ALPHA_TEST);
2840   glDisable(GL_FOG);
2841   glDisable(GL_LOGIC_OP);
2842   glDisable(GL_TEXTURE_1D);
2843
2844   glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
2845   glPixelTransferi(GL_RED_SCALE, 1);
2846   glPixelTransferi(GL_RED_BIAS, 0);
2847   glPixelTransferi(GL_GREEN_SCALE, 1);
2848   glPixelTransferi(GL_GREEN_BIAS, 0);
2849   glPixelTransferi(GL_BLUE_SCALE, 1);
2850   glPixelTransferi(GL_BLUE_BIAS, 0);
2851   glPixelTransferi(GL_ALPHA_SCALE, 1);
2852   glPixelTransferi(GL_ALPHA_BIAS, 0);
2853
2854   /*
2855   * Disable extensions that could slow down glDrawPixels.
2856   * (Actually, you should check for the presence of the proper
2857   * extension before making these calls.  I've omitted that
2858   * code for simplicity.)
2859   */
2860
2861   if ((myGlVerMajor >= 1) && (myGlVerMinor >= 2))
2862   {
2863 #ifdef GL_EXT_convolution
2864     if (CheckExtension ("GL_CONVOLUTION_1D_EXT"))
2865       glDisable(GL_CONVOLUTION_1D_EXT);
2866
2867     if (CheckExtension ("GL_CONVOLUTION_2D_EXT"))
2868       glDisable(GL_CONVOLUTION_2D_EXT);
2869
2870     if (CheckExtension ("GL_SEPARABLE_2D_EXT"))
2871       glDisable(GL_SEPARABLE_2D_EXT);
2872 #endif
2873
2874 #ifdef GL_EXT_histogram
2875     if (CheckExtension ("GL_SEPARABLE_2D_EXT"))
2876       glDisable(GL_HISTOGRAM_EXT);
2877
2878     if (CheckExtension ("GL_MINMAX_EXT"))
2879       glDisable(GL_MINMAX_EXT);
2880 #endif
2881
2882 #ifdef GL_EXT_texture3D
2883     if (CheckExtension ("GL_TEXTURE_3D_EXT"))
2884       glDisable(GL_TEXTURE_3D_EXT);
2885 #endif
2886   }
2887 #endif
2888 }