0025854: Visualization, TKOpenGl - add option to request Core profile 3.2+
authorkgv <kgv@opencascade.com>
Thu, 5 Mar 2015 13:00:51 +0000 (16:00 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 5 Mar 2015 13:02:32 +0000 (16:02 +0300)
OpenGl_Caps::contextCompatible - new option to request compatibility/core OpenGL profile.
OpenGl_Window - request core profile when requested (WGL and Cocoa).
OpenGl_Context::CheckExtension() - retrieve extensions using glGetStringi().
OpenGl_Context::init() - set backward-compatible functions to NULL within core profile:
core11, core15, core20, core32back, core33back, core41back, core42back, core43back, core44back.
OpenGl_Context::BindDefaultVao() - create default VAO required for core profile.
OpenGl_Context::ReadGlVersion() - make method public.
OpenGl_ShaderManager - create programs using GLSL version 150 when available.
OpenGl_VertexBuffer, OpenGl_ShaderProgram, OpenGl_ShaderObject - use
functions set from core profile instead of compatibility.

TKOpenGl - escape deprecated functionality with runtime checks.

Command vcaps - add option -compatibleProfile to request core/compatibility profile.
NIS_View - prevenr rendering within Core profile (unsupported).

Test case for issue CR25854

Aspect_GraphicCallbackStruct::IsCoreProfile - add new field to the struct for NIS

31 files changed:
src/Aspect/Aspect_GraphicCallbackProc.hxx
src/NIS/NIS_View.cxx
src/OpenGl/OpenGl_AspectFace.cxx
src/OpenGl/OpenGl_AspectLine.cxx
src/OpenGl/OpenGl_AspectMarker.cxx
src/OpenGl/OpenGl_AspectText.cxx
src/OpenGl/OpenGl_Caps.cxx
src/OpenGl/OpenGl_Caps.hxx
src/OpenGl/OpenGl_Context.cxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_Context_1.mm
src/OpenGl/OpenGl_LineAttributes.cxx
src/OpenGl/OpenGl_PrimitiveArray.cxx
src/OpenGl/OpenGl_ShaderManager.cxx
src/OpenGl/OpenGl_ShaderManager.hxx
src/OpenGl/OpenGl_ShaderObject.cxx
src/OpenGl/OpenGl_ShaderProgram.cxx
src/OpenGl/OpenGl_Text.cxx
src/OpenGl/OpenGl_Texture.cxx
src/OpenGl/OpenGl_Texture.hxx
src/OpenGl/OpenGl_TextureBufferArb.cxx
src/OpenGl/OpenGl_VertexBuffer.cxx
src/OpenGl/OpenGl_VertexBuffer.lxx
src/OpenGl/OpenGl_View_2.cxx
src/OpenGl/OpenGl_Window.cxx
src/OpenGl/OpenGl_Window_1.mm
src/OpenGl/OpenGl_Workspace.cxx
src/OpenGl/OpenGl_Workspace_5.cxx
src/ViewerTest/ViewerTest_OpenGlCommands.cxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
tests/bugs/vis/bug25854 [new file with mode: 0644]

index 52b56f2..94a9e1a 100644 (file)
@@ -40,6 +40,7 @@ typedef struct
   int reason;
   int wsID;
   int viewID;
+  bool IsCoreProfile;
   Handle(Standard_Transient) glContext;
 } Aspect_GraphicCallbackStruct;
 
index ee24237..c358945 100644 (file)
@@ -224,6 +224,11 @@ int NIS_View::MyCallback (Aspect_Drawable                /* Window ID */,
   if (callData->reason & OCC_REDRAW_ADDITIONAL_CALLBACKS)
     return 0;
 
+  if (callData->IsCoreProfile)
+  {
+    return 0; // not supported
+  }
+
   const Handle(NIS_View) thisView (static_cast<NIS_View *> (ptrData));
   NCollection_List<NIS_InteractiveContext *>::Iterator anIter;
 #ifdef CLIP
index ab4a4b3..16417be 100644 (file)
@@ -467,7 +467,7 @@ void OpenGl_AspectFace::Resources::BuildTexture (const Handle(OpenGl_Context)&
 void OpenGl_AspectFace::Resources::BuildShader (const Handle(OpenGl_Context)&          theCtx,
                                                 const Handle(Graphic3d_ShaderProgram)& theShader)
 {
-  if (!theCtx->IsGlGreaterEqual (2, 0))
+  if (theCtx->core20fwd == NULL)
   {
     return;
   }
index c7ddf98..f0351c2 100644 (file)
@@ -102,7 +102,7 @@ void OpenGl_AspectLine::Release (OpenGl_Context* theContext)
 void OpenGl_AspectLine::Resources::BuildShader (const Handle(OpenGl_Context)&          theCtx,
                                                 const Handle(Graphic3d_ShaderProgram)& theShader)
 {
-  if (!theCtx->IsGlGreaterEqual (2, 0))
+  if (theCtx->core20fwd == NULL)
   {
     return;
   }
index 4eecb22..8dd9e2d 100644 (file)
@@ -1641,7 +1641,7 @@ void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Context)&
   }
 
   if (!theCtx.IsNull()
-   &&  theCtx->IsGlGreaterEqual (2, 0)
+   &&  theCtx->core20fwd != NULL
    && !theCtx->caps->pntSpritesDisable)
   {
     // Creating texture resource for using it with point sprites
@@ -1910,7 +1910,7 @@ void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Context)&
 void OpenGl_AspectMarker::Resources::BuildShader (const Handle(OpenGl_Context)&          theCtx,
                                                   const Handle(Graphic3d_ShaderProgram)& theShader)
 {
-  if (!theCtx->IsGlGreaterEqual (2, 0))
+  if (theCtx->core20fwd == NULL)
   {
     return;
   }
index 98cc484..45d2568 100755 (executable)
@@ -120,7 +120,7 @@ void OpenGl_AspectText::Release (OpenGl_Context* theContext)
 void OpenGl_AspectText::Resources::BuildShader (const Handle(OpenGl_Context)&          theCtx,
                                                 const Handle(Graphic3d_ShaderProgram)& theShader)
 {
-  if (!theCtx->IsGlGreaterEqual (2, 0))
+  if (theCtx->core20fwd == NULL)
   {
     return;
   }
index 6389f56..cc18b6e 100755 (executable)
@@ -41,6 +41,11 @@ OpenGl_Caps::OpenGl_Caps()
   contextDebug      (Standard_False),
 #endif
   contextNoAccel    (Standard_False),
+#if !defined(GL_ES_VERSION_2_0)
+  contextCompatible (Standard_True),
+#else
+  contextCompatible (Standard_False),
+#endif
   glslWarnings      (Standard_False)
 {
   //
@@ -60,6 +65,7 @@ OpenGl_Caps& OpenGl_Caps::operator= (const OpenGl_Caps& theCopy)
   contextStereo     = theCopy.contextStereo;
   contextDebug      = theCopy.contextDebug;
   contextNoAccel    = theCopy.contextNoAccel;
+  contextCompatible = theCopy.contextCompatible;
   glslWarnings      = theCopy.glslWarnings;
   return *this;
 }
index 0b90e3e..8078e2e 100755 (executable)
@@ -74,6 +74,23 @@ public: //! @name context creation parameters
    */
   Standard_Boolean contextNoAccel;
 
+  /**
+   * Request backward-compatible GL context. This flag requires support in OpenGL driver.
+   *
+   * Backward-compatible profile includes deprecated functionality like FFP (fixed-function pipeline),
+   * and might be useful for compatibility with application OpenGL code.
+   *
+   * Most drivers support all features within backward-compatibility profile,
+   * but some limit functionality to OpenGL 2.1 (e.g. OS X) when core profile is not explicitly requested.
+   *
+   * Requires OpenGL 3.2+ drivers.
+   * Has no effect on OpenGL ES 2.0+ drivers (which do not provie FFP compatibility).
+   * Interacts with ffpEnable option, which should be disabled within core profile.
+   *
+   * ON by default.
+   */
+  Standard_Boolean contextCompatible;
+
 public: //! @name flags to activate verbose output
 
   //! Print GLSL program compilation/linkage warnings, if any. OFF by default.
index 3f47492..66e1fb9 100644 (file)
@@ -25,7 +25,7 @@
 #include <OpenGl_ArbFBO.hxx>
 #include <OpenGl_ExtGS.hxx>
 #include <OpenGl_ArbTexBindless.hxx>
-#include <OpenGl_GlCore20.hxx>
+#include <OpenGl_GlCore44.hxx>
 #include <OpenGl_Sampler.hxx>
 #include <OpenGl_ShaderManager.hxx>
 
@@ -122,9 +122,20 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
 #else
   myRenderMode (0),
 #endif
-  myDrawBuffer (0)
+  myDrawBuffer (0),
+  myDefaultVao (0),
+  myIsGlDebugCtx (Standard_False)
 {
-#if defined(__APPLE__) && !defined(MACOSX_USE_GLX)
+  // system-dependent fields
+#if defined(HAVE_EGL)
+  myDisplay  = (Aspect_Display          )EGL_NO_DISPLAY;
+  myWindow   = (Aspect_Drawable         )EGL_NO_SURFACE;
+  myGContext = (Aspect_RenderingContext )EGL_NO_CONTEXT);
+#elif defined(_WIN32)
+  myWindow   = NULL;
+  myWindowDC = NULL;
+  myGContext = NULL;
+#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
   // Vendors can not extend functionality on this system
   // and developers are limited to OpenGL support provided by Mac OS X SDK.
   // We retrieve function pointers from system library
@@ -134,7 +145,12 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
   // Notice that GL version / extension availability checks are required
   // because function pointers may be available but not functionality itself
   // (depends on renderer).
+  myGContext    = NULL;
   myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
+#else
+  myDisplay =  NULL;
+  myWindow   = 0;
+  myGContext = 0;
 #endif
   memset (myFuncs.operator->(), 0, sizeof(OpenGl_GlFunctions));
   myShaderManager = new OpenGl_ShaderManager (this);
@@ -149,6 +165,17 @@ OpenGl_Context::~OpenGl_Context()
   // release clean up queue
   ReleaseDelayed();
 
+#if !defined(GL_ES_VERSION_2_0)
+  // release default VAO
+  if (myDefaultVao != 0
+   && IsValid()
+   && core32 != NULL)
+  {
+    core32->glDeleteVertexArrays (1, &myDefaultVao);
+  }
+  myDefaultVao = 0;
+#endif
+
   // release shared resources if any
   if (((const Handle(Standard_Transient)& )mySharedResources)->GetRefCount() <= 1)
   {
@@ -174,7 +201,7 @@ OpenGl_Context::~OpenGl_Context()
 
 #if !defined(GL_ES_VERSION_2_0)
   if (arbDbg != NULL
-   && caps->contextDebug
+   && myIsGlDebugCtx
    && IsValid())
   {
     // reset callback
@@ -184,6 +211,7 @@ OpenGl_Context::~OpenGl_Context()
     {
       arbDbg->glDebugMessageCallbackARB (NULL, NULL);
     }
+    myIsGlDebugCtx = Standard_False;
   }
 #endif
 }
@@ -330,7 +358,10 @@ void OpenGl_Context::FetchState()
 {
 #if !defined(GL_ES_VERSION_2_0)
   // cache feedback mode state
-  glGetIntegerv (GL_RENDER_MODE, &myRenderMode);
+  if (core11 != NULL)
+  {
+    ::glGetIntegerv (GL_RENDER_MODE, &myRenderMode);
+  }
 
   // cache draw buffer state
   glGetIntegerv (GL_DRAW_BUFFER, &myDrawBuffer);
@@ -522,23 +553,28 @@ Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
     return Standard_False;
   }
 
+#if !defined(GL_ES_VERSION_2_0)
   // available since OpenGL 3.0
   // and the ONLY way to check extensions with OpenGL 3.1+ core profile
-  /**if (IsGlGreaterEqual (3, 0))
+  if (IsGlGreaterEqual (3, 0)
+   && myFuncs->glGetStringi != NULL)
   {
     GLint anExtNb = 0;
-    glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
+    ::glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
+    const size_t anExtNameLen = strlen (theExtName);
     for (GLint anIter = 0; anIter < anExtNb; ++anIter)
     {
-      const char* anExtension = (const char* )core30->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
-      if (anExtension[anExtNameLen] == '\0' &&
-          strncmp (anExtension, theExtName, anExtNameLen) == 0)
+      const char* anExtension = (const char* )myFuncs->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
+      const size_t aTestExtNameLen = strlen (anExtension);
+      if (aTestExtNameLen == anExtNameLen
+       && strncmp (anExtension, theExtName, anExtNameLen) == 0)
       {
         return Standard_True;
       }
     }
     return Standard_False;
-  }*/
+  }
+#endif
 
   // use old way with huge string for all extensions
   const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
@@ -585,7 +621,7 @@ Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtString,
 // function : Init
 // purpose  :
 // =======================================================================
-Standard_Boolean OpenGl_Context::Init()
+Standard_Boolean OpenGl_Context::Init (const Standard_Boolean theIsCoreProfile)
 {
   if (myIsInitialized)
   {
@@ -609,7 +645,7 @@ Standard_Boolean OpenGl_Context::Init()
     return Standard_False;
   }
 
-  init();
+  init (theIsCoreProfile);
   myIsInitialized = Standard_True;
   return Standard_True;
 }
@@ -623,17 +659,21 @@ Standard_Boolean OpenGl_Context::Init()
 #if defined(HAVE_EGL)
 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theEglSurface,
                                        const Aspect_Display          theEglDisplay,
-                                       const Aspect_RenderingContext theEglContext)
+                                       const Aspect_RenderingContext theEglContext,
+                                       const Standard_Boolean        theIsCoreProfile)
 #elif defined(_WIN32)
 Standard_Boolean OpenGl_Context::Init (const Aspect_Handle           theWindow,
                                        const Aspect_Handle           theWindowDC,
-                                       const Aspect_RenderingContext theGContext)
+                                       const Aspect_RenderingContext theGContext,
+                                       const Standard_Boolean        theIsCoreProfile)
 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
-Standard_Boolean OpenGl_Context::Init (const void*                   theGContext)
+Standard_Boolean OpenGl_Context::Init (const void*                   theGContext,
+                                       const Standard_Boolean        theIsCoreProfile)
 #else
 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theWindow,
                                        const Aspect_Display          theDisplay,
-                                       const Aspect_RenderingContext theGContext)
+                                       const Aspect_RenderingContext theGContext,
+                                       const Standard_Boolean        theIsCoreProfile)
 #endif
 {
   Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
@@ -657,7 +697,7 @@ Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theWindow,
     return Standard_False;
   }
 
-  init();
+  init (theIsCoreProfile);
   myIsInitialized = Standard_True;
   return Standard_True;
 }
@@ -675,14 +715,15 @@ void OpenGl_Context::ResetErrors()
 }
 
 // =======================================================================
-// function : readGlVersion
+// function : ReadGlVersion
 // purpose  :
 // =======================================================================
-void OpenGl_Context::readGlVersion()
+void OpenGl_Context::ReadGlVersion (Standard_Integer& theGlVerMajor,
+                                    Standard_Integer& theGlVerMinor)
 {
   // reset values
-  myGlVerMajor = 0;
-  myGlVerMinor = 0;
+  theGlVerMajor = 0;
+  theGlVerMinor = 0;
 
 #ifdef GL_MAJOR_VERSION
   // available since OpenGL 3.0 and OpenGL 3.0 ES
@@ -694,13 +735,20 @@ void OpenGl_Context::readGlVersion()
   // This happens on some renderers like e.g. Cygwin MESA.
   // Thus checking additionally if GL has put anything to
   // the output variables.
-  if (glGetError() == GL_NO_ERROR && aMajor != 0 && aMinor != 0)
+  if (::glGetError() == GL_NO_ERROR && aMajor != 0 && aMinor != 0)
   {
-    myGlVerMajor = aMajor;
-    myGlVerMinor = aMinor;
+    theGlVerMajor = aMajor;
+    theGlVerMinor = aMinor;
     return;
   }
-  ResetErrors();
+  for (GLenum anErr = ::glGetError(), aPrevErr = GL_NO_ERROR;; aPrevErr = anErr, anErr = ::glGetError())
+  {
+    if (anErr == GL_NO_ERROR
+     || anErr == aPrevErr)
+    {
+      break;
+    }
+  }
 #endif
 
   // Read version string.
@@ -756,13 +804,13 @@ void OpenGl_Context::readGlVersion()
   aMinorStr[aMinIter] = '\0';
 
   // read numbers
-  myGlVerMajor = atoi (aMajorStr);
-  myGlVerMinor = atoi (aMinorStr);
+  theGlVerMajor = atoi (aMajorStr);
+  theGlVerMinor = atoi (aMinorStr);
 
-  if (myGlVerMajor <= 0)
+  if (theGlVerMajor <= 0)
   {
-    myGlVerMajor = 0;
-    myGlVerMinor = 0;
+    theGlVerMajor = 0;
+    theGlVerMinor = 0;
   }
 }
 
@@ -850,12 +898,50 @@ void OpenGl_Context::PushMessage (const unsigned int theSource,
 // function : init
 // purpose  :
 // =======================================================================
-void OpenGl_Context::init()
+void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
 {
   // read version
-  readGlVersion();
+  myGlVerMajor = 0;
+  myGlVerMinor = 0;
+  ReadGlVersion (myGlVerMajor, myGlVerMinor);
+
+#if defined(GL_ES_VERSION_2_0)
+  (void )theIsCoreProfile;
+  const bool isCoreProfile = false;
+#else
+  if (IsGlGreaterEqual (3, 0))
+  {
+    // retrieve auxiliary function in advance
+    FindProc ("glGetStringi", myFuncs->glGetStringi);
+  }
+
+  // this check would not work well due to buggy NVIDIA drivers!
+  /*GLint aProfile = 0;
+  if (IsGlGreaterEqual (3, 2))
+  {
+    ::glGetIntegerv (GL_CONTEXT_PROFILE_MASK, &aProfile);
+  }
+  const bool isCoreProfile = (aProfile & GL_CONTEXT_CORE_PROFILE_BIT) != 0;*/
+
+  // detect Core profile
+  /*for (int anErr = glGetError(), aPrevErr = GL_NO_ERROR;; aPrevErr = anErr, anErr = glGetError())
+  {
+    if (anErr == aPrevErr)
+    {
+      break;
+    }
+  }
+  const char* anExtString = (const char* )::glGetString (GL_EXTENSIONS);
+  const bool isCoreProfile = IsGlGreaterEqual (3, 2) && (glGetError() != GL_NO_ERROR);*/
+
+  const bool isCoreProfile = IsGlGreaterEqual (3, 2) && theIsCoreProfile;
+#endif
 
-  core11     = (OpenGl_GlCore11*    )(&(*myFuncs));
+  core11     = NULL;
+  if (!isCoreProfile)
+  {
+    core11 = (OpenGl_GlCore11* )(&(*myFuncs));
+  }
   core11fwd  = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
   core15     = NULL;
   core15fwd  = NULL;
@@ -880,6 +966,7 @@ void OpenGl_Context::init()
   arbFBO     = NULL;
   arbFBOBlit = NULL;
   extGS      = NULL;
+  myDefaultVao = 0;
 
 #if defined(GL_ES_VERSION_2_0)
 
@@ -970,7 +1057,7 @@ void OpenGl_Context::init()
   //! Make record shorter to retrieve function pointer using variable with same name
   #define FindProcShort(theFunc) FindProc(#theFunc, myFuncs->theFunc)
 
-    // retrieve platform-dependent extensions
+  // retrieve platform-dependent extensions
 #if defined(_WIN32) && !defined(HAVE_EGL)
   if (FindProcShort (wglGetExtensionsStringARB))
   {
@@ -1016,6 +1103,7 @@ void OpenGl_Context::init()
      && caps->contextDebug)
     {
       // setup default callback
+      myIsGlDebugCtx = Standard_True;
       arbDbg->glDebugMessageCallbackARB (debugCallbackWrap, this);
     #ifdef OCCT_DEBUG
       glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
@@ -1042,7 +1130,11 @@ void OpenGl_Context::init()
        && FindProcShort (glCompressedTexSubImage3D)
        && FindProcShort (glCompressedTexSubImage2D)
        && FindProcShort (glCompressedTexSubImage1D)
-       && FindProcShort (glGetCompressedTexImage)
+       && FindProcShort (glGetCompressedTexImage);
+
+  if (!isCoreProfile)
+  {
+    has13 = has13
        && FindProcShort (glClientActiveTexture)
        && FindProcShort (glMultiTexCoord1d)
        && FindProcShort (glMultiTexCoord1dv)
@@ -1080,6 +1172,7 @@ void OpenGl_Context::init()
        && FindProcShort (glLoadTransposeMatrixd)
        && FindProcShort (glMultTransposeMatrixf)
        && FindProcShort (glMultTransposeMatrixd);
+  }
 
   // load OpenGL 1.4 new functions
   has14 = IsGlGreaterEqual (1, 4)
@@ -1827,7 +1920,10 @@ void OpenGl_Context::init()
     myGlVerMinor = 4;
     return;
   }
-  core15    = (OpenGl_GlCore15*    )(&(*myFuncs));
+  if (!isCoreProfile)
+  {
+    core15 = (OpenGl_GlCore15* )(&(*myFuncs));
+  }
   core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
 
   if (!has20)
@@ -1837,7 +1933,10 @@ void OpenGl_Context::init()
     return;
   }
 
-  core20    = (OpenGl_GlCore20*    )(&(*myFuncs));
+  if (!isCoreProfile)
+  {
+    core20  = (OpenGl_GlCore20*    )(&(*myFuncs));
+  }
   core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
 
   if (!has21)
@@ -1869,8 +1968,15 @@ void OpenGl_Context::init()
     myGlVerMinor = 1;
     return;
   }
-  core32     = (OpenGl_GlCore32*     )(&(*myFuncs));
-  core32back = (OpenGl_GlCore32Back* )(&(*myFuncs));
+  core32 = (OpenGl_GlCore32* )(&(*myFuncs));
+  if (isCoreProfile)
+  {
+    core32->glGenVertexArrays (1, &myDefaultVao);
+  }
+  else
+  {
+    core32back = (OpenGl_GlCore32Back* )(&(*myFuncs));
+  }
 
   if (!has33)
   {
@@ -1878,8 +1984,11 @@ void OpenGl_Context::init()
     myGlVerMinor = 2;
     return;
   }
-  core33     = (OpenGl_GlCore33*     )(&(*myFuncs));
-  core33back = (OpenGl_GlCore33Back* )(&(*myFuncs));
+  core33 = (OpenGl_GlCore33* )(&(*myFuncs));
+  if (!isCoreProfile)
+  {
+    core33back = (OpenGl_GlCore33Back* )(&(*myFuncs));
+  }
 
   // initialize sampler object
   myTexSampler = new OpenGl_Sampler();
@@ -1899,8 +2008,11 @@ void OpenGl_Context::init()
     myGlVerMinor = 0;
     return;
   }
-  core41     = (OpenGl_GlCore41*     )(&(*myFuncs));
-  core41back = (OpenGl_GlCore41Back* )(&(*myFuncs));
+  core41 = (OpenGl_GlCore41* )(&(*myFuncs));
+  if (!isCoreProfile)
+  {
+    core41back = (OpenGl_GlCore41Back* )(&(*myFuncs));
+  }
 
   if(!has42)
   {
@@ -1908,17 +2020,23 @@ void OpenGl_Context::init()
     myGlVerMinor = 1;
     return;
   }
-  core42     = (OpenGl_GlCore42*     )(&(*myFuncs));
-  core42back = (OpenGl_GlCore42Back* )(&(*myFuncs));
+  core42 = (OpenGl_GlCore42* )(&(*myFuncs));
+  if (!isCoreProfile)
+  {
+    core42back = (OpenGl_GlCore42Back* )(&(*myFuncs));
+  }
 
-  if(!has43)
+  if (!has43)
   {
     myGlVerMajor = 4;
     myGlVerMinor = 2;
     return;
   }
-  core43     = (OpenGl_GlCore43*     )(&(*myFuncs));
-  core43back = (OpenGl_GlCore43Back* )(&(*myFuncs));
+  core43 = (OpenGl_GlCore43* )(&(*myFuncs));
+  if (!isCoreProfile)
+  {
+    core43back = (OpenGl_GlCore43Back* )(&(*myFuncs));
+  }
 
   if (!has44)
   {
@@ -1926,8 +2044,11 @@ void OpenGl_Context::init()
     myGlVerMinor = 3;
     return;
   }
-  core44     = (OpenGl_GlCore44*     )(&(*myFuncs));
-  core44back = (OpenGl_GlCore44Back* )(&(*myFuncs));
+  core44 = (OpenGl_GlCore44* )(&(*myFuncs));
+  if (!isCoreProfile)
+  {
+    core44back = (OpenGl_GlCore44Back* )(&(*myFuncs));
+  }
 #endif
 }
 
@@ -2151,6 +2272,23 @@ Standard_Boolean OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)
 }
 
 // =======================================================================
+// function : BindDefaultVao
+// purpose  :
+// =======================================================================
+void OpenGl_Context::BindDefaultVao()
+{
+#if !defined(GL_ES_VERSION_2_0)
+  if (myDefaultVao == 0
+   || core32 == NULL)
+  {
+    return;
+  }
+
+  core32->glBindVertexArray (myDefaultVao);
+#endif
+}
+
+// =======================================================================
 // function : SetColor4fv
 // purpose  :
 // =======================================================================
index 187a918..0cf2591 100644 (file)
@@ -110,9 +110,8 @@ typedef OpenGl_TmplCore44<OpenGl_GlCore43>     OpenGl_GlCore44;
 
 //! This class generalize access to the GL context and available extensions.
 //!
-//! Functions are grouped into structures and accessed as fields.
-//! You should check the group for NULL before usage (if group is not NULL
-//! then all functions are available):
+//! Functions related to specific OpenGL version or extension are grouped into structures which can be accessed as fields of this class.
+//! The most simple way to check that required functionality is available - is NULL check for the group:
 //! @code
 //!   if (myContext->core20 != NULL)
 //!   {
@@ -125,9 +124,24 @@ typedef OpenGl_TmplCore44<OpenGl_GlCore43>     OpenGl_GlCore44;
 //!   }
 //! @endcode
 //!
-//! Current implementation provide access to OpenGL core functionality up to 2.0 version
-//! (core12, core13, core14, core15, fields core20).
-//! within several extensions (arbTBO, arbFBO, etc.).
+//! Current implementation provide access to OpenGL core functionality up to 4.4 version (core12, core13, core14, core15, fields core20)
+//! as well as several extensions (arbTBO, arbFBO, etc.).
+//!
+//! OpenGL context might be initialized in Core Profile. In this case deprecated functionality become unavailable.
+//! To make code easily adaptable to wide range of OpenGL versions, function sets related to each version has two kinds of suffixes:
+//!  - "back" for version 3.2+.
+//!     Represents function set for Backward-Compatible Profile.
+//!     Function sets without this suffix represents core profile.
+//!  - "fwd"  for version 3.0-.
+//!     Represents non-deprecated function set of earlier OpenGL versions, which are still available within OpenGL 3.2 Core Profile.
+//!     Function sets without this suffix represents complete list of functions related to specific OpenGL version.
+//!
+//! To select which core** function set should be used in specific case:
+//!  - Determine the minimal OpenGL version required for implemented functionality and use it to access all functions.
+//!    For example, if algorithm requires OpenGL 2.1+, it is better to write core20fwd->glEnable() rather than core11fwd->glEnable() for uniformity.
+//!  - If functionality will work within Core Profile, use function sets with appropriate suffix.
+//!  - Validate minimal requirements at initialization/creation time and omit checks within code where algorithm should be already initialized.
+//!    Properly escape code incompatible with Core Profile. The simplest way to check Core Profile is "if (core11 == NULL)".
 //!
 //! Simplified extensions classification:
 //!  - prefixed with NV, AMD, ATI are vendor-specific (however may be provided by other vendors in some cases);
@@ -138,9 +152,8 @@ typedef OpenGl_TmplCore44<OpenGl_GlCore43>     OpenGl_GlCore44;
 //! In this case developer should be careful because different specification may differ
 //! in aspects (like enumeration values and error-handling).
 //!
-//! Notice that some systems provide mechanisms to simultaneously incorporate with GL contexts
-//! with different capabilities. Thats why OpenGl_Context should be initialized and used
-//! for each GL context individually.
+//! Notice that some systems provide mechanisms to simultaneously incorporate with GL contexts with different capabilities.
+//! For this reason OpenGl_Context should be initialized and used for each GL context independently.
 class OpenGl_Context : public Standard_Transient
 {
 public:
@@ -179,7 +192,7 @@ public:
 
   //! Initialize class from currently bound OpenGL context. Method should be called only once.
   //! @return false if no GL context is bound to the current thread
-  Standard_EXPORT Standard_Boolean Init();
+  Standard_EXPORT Standard_Boolean Init (const Standard_Boolean theIsCoreProfile = Standard_False);
 
   //! @return true if this context is valid (has been initialized)
   inline Standard_Boolean IsValid() const
@@ -192,13 +205,15 @@ public:
   //! @return false if OpenGL context can not be bound to specified surface
   Standard_EXPORT Standard_Boolean Init (const Aspect_Drawable         theEglSurface,
                                          const Aspect_Display          theEglDisplay,
-                                         const Aspect_RenderingContext theEglContext);
+                                         const Aspect_RenderingContext theEglContext,
+                                         const Standard_Boolean        theIsCoreProfile = Standard_False);
 #elif defined(_WIN32)
   //! Initialize class from specified window and rendering context. Method should be called only once.
   //! @return false if OpenGL context can not be bound to specified window
   Standard_EXPORT Standard_Boolean Init (const Aspect_Handle           theWindow,
                                          const Aspect_Handle           theWindowDC,
-                                         const Aspect_RenderingContext theGContext);
+                                         const Aspect_RenderingContext theGContext,
+                                         const Standard_Boolean        theIsCoreProfile = Standard_False);
 
   //! @return the window handle (HWND) currently bound to this OpenGL context
   inline Aspect_Handle Window() const
@@ -208,13 +223,15 @@ public:
 
 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
   //! Initialize class from specified OpenGL context (NSOpenGLContext). Method should be called only once.
-  Standard_EXPORT Standard_Boolean Init (const void*                   theGContext);
+  Standard_EXPORT Standard_Boolean Init (const void*                   theGContext,
+                                         const Standard_Boolean        theIsCoreProfile = Standard_False);
 #else
   //! Initialize class from specified window and rendering context. Method should be called only once.
   //! @return false if OpenGL context can not be bound to specified window
   Standard_EXPORT Standard_Boolean Init (const Aspect_Drawable         theWindow,
                                          const Aspect_Display          theDisplay,
-                                         const Aspect_RenderingContext theGContext);
+                                         const Aspect_RenderingContext theGContext,
+                                         const Standard_Boolean        theIsCoreProfile = Standard_False);
 
   //! @return the window handle (GLXDrawable) currently bound to this OpenGL context
   inline Aspect_Drawable Window() const
@@ -223,6 +240,10 @@ public:
   }
 #endif
 
+  //! Read OpenGL version information from active context.
+  Standard_EXPORT static void ReadGlVersion (Standard_Integer& theGlVerMajor,
+                                             Standard_Integer& theGlVerMinor);
+
   //! Check if theExtName extension is supported by active GL context.
   Standard_EXPORT Standard_Boolean CheckExtension (const char* theExtName) const;
 
@@ -477,16 +498,22 @@ public: //! @name methods to alter or retrieve current state
   //! Setup point size.
   Standard_EXPORT void SetPointSize (const Standard_ShortReal theSize);
 
+  //! Bind default Vertex Array Object
+  Standard_EXPORT void BindDefaultVao();
+
+  //! Return debug context initialization state.
+  Standard_Boolean IsDebugContext() const
+  {
+    return myIsGlDebugCtx;
+  }
+
 private:
 
   //! Wrapper to system function to retrieve GL function pointer by name.
   Standard_EXPORT void* findProc (const char* theFuncName);
 
-  //! Read OpenGL version information from active context.
-  Standard_EXPORT void readGlVersion();
-
   //! Private initialization function that should be called only once.
-  Standard_EXPORT void init();
+  Standard_EXPORT void init (const Standard_Boolean theIsCoreProfile);
 
 public: //! @name core profiles
 
@@ -586,6 +613,8 @@ private: //! @name fields tracking current state
   Handle(OpenGl_Sampler)       myTexSampler;    //!< currently active sampler object
   Standard_Integer             myRenderMode;    //!< value for active rendering mode
   Standard_Integer             myDrawBuffer;    //!< current draw buffer
+  unsigned int                 myDefaultVao;    //!< default Vertex Array Object
+  Standard_Boolean             myIsGlDebugCtx;  //!< debug context initialization state
 
 public:
 
index f5b5cf7..0d88274 100644 (file)
@@ -67,7 +67,7 @@ void OpenGl_Context::SwapBuffers()
 // function : Init
 // purpose  :
 // =======================================================================
-Standard_Boolean OpenGl_Context::Init()
+Standard_Boolean OpenGl_Context::Init (const Standard_Boolean theIsCoreProfile)
 {
   if (myIsInitialized)
   {
@@ -80,7 +80,7 @@ Standard_Boolean OpenGl_Context::Init()
     return Standard_False;
   }
 
-  init();
+  init (theIsCoreProfile);
   myIsInitialized = Standard_True;
   return Standard_True;
 }
index 409f13d..9488120 100644 (file)
@@ -552,6 +552,11 @@ void OpenGl_LineAttributes::Init (const Handle(OpenGl_Context)& theGlCtx)
   }
 
 #if !defined(GL_ES_VERSION_2_0)
+  if (theGlCtx->core11 == NULL)
+  {
+    return;
+  }
+
   myLinestyleBase = theGlCtx->core11->glGenLists (5);
 
   // Line
@@ -592,15 +597,21 @@ void OpenGl_LineAttributes::SetTypeOfLine (const Aspect_TypeOfLine theType) cons
 #if !defined(GL_ES_VERSION_2_0)
   if (theType != Aspect_TOL_SOLID)
   {
-    glCallList ((GLuint )myLinestyleBase + (GLuint )theType);
-    glEnable (GL_LINE_STIPPLE);
+    if (myLinestyleBase != 0)
+    {
+      glCallList ((GLuint )myLinestyleBase + (GLuint )theType);
+      glEnable (GL_LINE_STIPPLE);
+    }
   #ifdef HAVE_GL2PS
     gl2psEnable (GL2PS_LINE_STIPPLE);
   #endif
   }
   else
   {
-    glDisable (GL_LINE_STIPPLE);
+    if (myLinestyleBase != 0)
+    {
+      glDisable (GL_LINE_STIPPLE);
+    }
   #ifdef HAVE_GL2PS
     gl2psDisable (GL2PS_LINE_STIPPLE);
   #endif
index 593fe50..52da872 100755 (executable)
@@ -469,7 +469,7 @@ void OpenGl_PrimitiveArray::drawEdges (const TEL_COLOUR*               theEdgeCo
   glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
 #endif
 
-  if (aGlContext->IsGlGreaterEqual (2, 0))
+  if (aGlContext->core20fwd != NULL)
   {
     aGlContext->ShaderManager()->BindProgram (anAspect, NULL, Standard_False, Standard_False, anAspect->ShaderProgramRes (aGlContext));
   }
@@ -543,8 +543,11 @@ void OpenGl_PrimitiveArray::drawMarkers (const Handle(OpenGl_Workspace)& theWork
     // Textured markers will be drawn with the point sprites
     aCtx->SetPointSize (anAspectMarker->MarkerSize());
   #if !defined(GL_ES_VERSION_2_0)
-    aCtx->core11fwd->glEnable (GL_ALPHA_TEST);
-    aCtx->core11fwd->glAlphaFunc (GL_GEQUAL, 0.1f);
+    if (aCtx->core11 != NULL)
+    {
+      aCtx->core11fwd->glEnable (GL_ALPHA_TEST);
+      aCtx->core11fwd->glAlphaFunc (GL_GEQUAL, 0.1f);
+    }
   #endif
 
     aCtx->core11fwd->glEnable (GL_BLEND);
@@ -554,7 +557,10 @@ void OpenGl_PrimitiveArray::drawMarkers (const Handle(OpenGl_Workspace)& theWork
 
     aCtx->core11fwd->glDisable (GL_BLEND);
   #if !defined(GL_ES_VERSION_2_0)
-    aCtx->core11fwd->glDisable (GL_ALPHA_TEST);
+    if (aCtx->core11 != NULL)
+    {
+      aCtx->core11fwd->glDisable (GL_ALPHA_TEST);
+    }
   #endif
     aCtx->SetPointSize (1.0f);
     return;
@@ -743,13 +749,16 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
                                  &&  myVboAttribs->HasNormalAttribute();
 #if !defined(GL_ES_VERSION_2_0)
   // manage FFP lighting
-  if (!isLightOn)
-  {
-    glDisable (GL_LIGHTING);
-  }
-  else
+  if (aCtx->core11 != NULL)
   {
-    glEnable (GL_LIGHTING);
+    if (!isLightOn)
+    {
+      glDisable (GL_LIGHTING);
+    }
+    else
+    {
+      glEnable (GL_LIGHTING);
+    }
   }
 #endif
   // Temporarily disable environment mapping
@@ -767,7 +776,7 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
                                       ?  myBounds->Colors
                                       :  NULL;
     const Standard_Boolean hasVertColor = hasColorAttrib && !toHilight;
-    if (aCtx->IsGlGreaterEqual (2, 0))
+    if (aCtx->core20fwd != NULL)
     {
       switch (myDrawMode)
       {
index b63be61..96cdb1b 100644 (file)
@@ -37,11 +37,10 @@ namespace
 #define EOL "\n"
 
 //! Definition of VertColor varying.
-const char THE_VARY_VertColor[] =
-  EOL"varying vec4 VertColor;";
-
-const char THE_VARY_TexCoord[] =
-  EOL"varying vec2 TexCoord;";
+const char THE_VARY_TexCoord_OUT[] =
+  EOL"THE_SHADER_OUT vec2 TexCoord;";
+const char THE_VARY_TexCoord_IN[] =
+  EOL"THE_SHADER_IN  vec2 TexCoord;";
 
 //! Auxiliary function to transform normal
 const char THE_FUNC_transformNormal[] =
@@ -1002,24 +1001,39 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFont()
 {
   Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
   TCollection_AsciiString aSrcVert = TCollection_AsciiString()
-     + THE_VARY_TexCoord
+     + THE_VARY_TexCoord_OUT
      + EOL"void main()"
        EOL"{"
        EOL"  TexCoord = occTexCoord.st;"
        EOL"  gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
        EOL"}";
 
+  TCollection_AsciiString
+    aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, TexCoord.st).a; }";
+#if !defined(GL_ES_VERSION_2_0)
+  if (myContext->core11 == NULL)
+  {
+    aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, TexCoord.st).r; }";
+  }
+#endif
+
   TCollection_AsciiString aSrcFrag = TCollection_AsciiString() +
-     + THE_VARY_TexCoord
-     + EOL"float getAlpha(void) { return texture2D(occActiveSampler, TexCoord.st).a; }"
-       EOL"void main()"
+     + THE_VARY_TexCoord_IN
+     + aSrcGetAlpha
+     + EOL"void main()"
        EOL"{"
        EOL"  vec4 aColor = occColor;"
        EOL"  aColor.a *= getAlpha();"
        EOL"  if (aColor.a <= 0.285) discard;"
-       EOL"  gl_FragColor = aColor;"
+       EOL"  occFragColor = aColor;"
        EOL"}";
 
+#if !defined(GL_ES_VERSION_2_0)
+  if (myContext->core32 != NULL)
+  {
+    aProgramSrc->SetHeader ("#version 150");
+  }
+#endif
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX,   aSrcVert));
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
   TCollection_AsciiString aKey;
@@ -1076,8 +1090,12 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFboBlit()
       EOL"  occFragColor = occTexture2D (uColorSampler, TexCoord);"
       EOL"}";
   }
+#else
+  if (myContext->core32 != NULL)
+  {
+    aProgramSrc->SetHeader ("#version 150");
+  }
 #endif
-
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX,   aSrcVert));
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
   TCollection_AsciiString aKey;
@@ -1104,7 +1122,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
   Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
   TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain;
   TCollection_AsciiString aSrcFragGetColor     = EOL"vec4 getColor(void) { return occColor; }";
-  TCollection_AsciiString aSrcFragMainGetColor = EOL"  gl_FragColor = getColor();";
+  TCollection_AsciiString aSrcFragMainGetColor = EOL"  occFragColor = getColor();";
   if ((theBits & OpenGl_PO_Point) != 0)
   {
   #if defined(GL_ES_VERSION_2_0)
@@ -1112,9 +1130,17 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
   #endif
     if ((theBits & OpenGl_PO_TextureA) != 0)
     {
-      aSrcFragGetColor =
-        EOL"float getAlpha(void) { return texture2D(occActiveSampler, gl_PointCoord).a; }"
-        EOL"vec4  getColor(void)"
+      TCollection_AsciiString
+        aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, gl_PointCoord).a; }";
+    #if !defined(GL_ES_VERSION_2_0)
+      if (myContext->core11 == NULL)
+      {
+        aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, gl_PointCoord).r; }";
+      }
+    #endif
+
+      aSrcFragGetColor = aSrcGetAlpha
+      + EOL"vec4  getColor(void)"
         EOL"{"
         EOL"  vec4 aColor = occColor;"
         EOL"  aColor.a *= getAlpha();"
@@ -1124,46 +1150,46 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
       aSrcFragMainGetColor =
         EOL"  vec4 aColor = getColor();"
         EOL"  if (aColor.a <= 0.1) discard;"
-        EOL"  gl_FragColor = aColor;";
+        EOL"  occFragColor = aColor;";
     }
     else if ((theBits & OpenGl_PO_TextureRGB) != 0)
     {
       aSrcFragGetColor =
-        EOL"vec4 getColor(void) { return texture2D(occActiveSampler, gl_PointCoord); }";
+        EOL"vec4 getColor(void) { return occTexture2D(occActiveSampler, gl_PointCoord); }";
       aSrcFragMainGetColor =
         EOL"  vec4 aColor = getColor();"
         EOL"  if (aColor.a <= 0.1) discard;"
-        EOL"  gl_FragColor = aColor;";
+        EOL"  occFragColor = aColor;";
     }
   }
   else
   {
     if ((theBits & OpenGl_PO_TextureRGB) != 0)
     {
-      aSrcVertExtraOut  += THE_VARY_TexCoord;
-      aSrcFragExtraOut  += THE_VARY_TexCoord;
+      aSrcVertExtraOut  += THE_VARY_TexCoord_OUT;
+      aSrcFragExtraOut  += THE_VARY_TexCoord_IN;
       aSrcVertExtraMain +=
         EOL"  TexCoord = occTexCoord.st;";
 
       aSrcFragGetColor =
-        EOL"vec4 getColor(void) { return texture2D(occActiveSampler, TexCoord.st); }";
+        EOL"vec4 getColor(void) { return occTexture2D(occActiveSampler, TexCoord.st); }";
     }
   }
   if ((theBits & OpenGl_PO_VertColor) != 0)
   {
-    aSrcVertExtraOut  += THE_VARY_VertColor;
+    aSrcVertExtraOut  += EOL"THE_SHADER_OUT vec4 VertColor;";
     aSrcVertExtraMain += EOL"  VertColor = occVertColor;";
-    aSrcFragExtraOut  += THE_VARY_VertColor;
+    aSrcFragExtraOut  += EOL"THE_SHADER_IN  vec4 VertColor;";
     aSrcFragGetColor  =  EOL"vec4 getColor(void) { return VertColor; }";
   }
   if ((theBits & OpenGl_PO_ClipPlanes) != 0)
   {
-    const char THE_POS_VARY[] =
-      EOL"varying vec4 PositionWorld;"
-      EOL"varying vec4 Position;";
-
-    aSrcVertExtraOut  += THE_POS_VARY;
-    aSrcFragExtraOut  += THE_POS_VARY;
+    aSrcVertExtraOut +=
+      EOL"THE_SHADER_OUT vec4 PositionWorld;"
+      EOL"THE_SHADER_OUT vec4 Position;";
+    aSrcFragExtraOut +=
+      EOL"THE_SHADER_IN  vec4 PositionWorld;"
+      EOL"THE_SHADER_IN  vec4 Position;";
     aSrcVertExtraMain +=
       EOL"  PositionWorld = occModelWorldMatrix * occVertex;"
       EOL"  Position      = occWorldViewMatrix * PositionWorld;";
@@ -1187,6 +1213,12 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
     + aSrcFragMainGetColor
     + EOL"}";
 
+#if !defined(GL_ES_VERSION_2_0)
+  if (myContext->core32 != NULL)
+  {
+    aProgramSrc->SetHeader ("#version 150");
+  }
+#endif
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX,   aSrcVert));
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
 
@@ -1307,7 +1339,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
         EOL"vec4 getColor(void)"
         EOL"{"
         EOL"  vec4 aColor = gl_FrontFacing ? FrontColor : BackColor;"
-        EOL"  return texture2D(occActiveSampler, gl_PointCoord) * aColor;"
+        EOL"  return occTexture2D(occActiveSampler, gl_PointCoord) * aColor;"
         EOL"}";
     }
   }
@@ -1315,8 +1347,8 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
   {
     if ((theBits & OpenGl_PO_TextureRGB) != 0)
     {
-      aSrcVertExtraOut  += THE_VARY_TexCoord;
-      aSrcFragExtraOut  += THE_VARY_TexCoord;
+      aSrcVertExtraOut  += THE_VARY_TexCoord_OUT;
+      aSrcFragExtraOut  += THE_VARY_TexCoord_IN;
       aSrcVertExtraMain +=
         EOL"  TexCoord = occTexCoord.st;";
 
@@ -1324,18 +1356,18 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
         EOL"vec4 getColor(void)"
         EOL"{"
         EOL"  vec4 aColor = gl_FrontFacing ? FrontColor : BackColor;"
-        EOL"  return texture2D(occActiveSampler, TexCoord.st) * aColor;"
+        EOL"  return occTexture2D(occActiveSampler, TexCoord.st) * aColor;"
         EOL"}";
     }
   }
   if ((theBits & OpenGl_PO_ClipPlanes) != 0)
   {
-    const char THE_POS_VARY[] =
-      EOL"varying vec4 PositionWorld;"
-      EOL"varying vec4 Position;";
-
-    aSrcVertExtraOut  += THE_POS_VARY;
-    aSrcFragExtraOut  += THE_POS_VARY;
+    aSrcVertExtraOut +=
+      EOL"THE_SHADER_OUT vec4 PositionWorld;"
+      EOL"THE_SHADER_OUT vec4 Position;";
+    aSrcFragExtraOut +=
+      EOL"THE_SHADER_IN  vec4 PositionWorld;"
+      EOL"THE_SHADER_IN  vec4 Position;";
     aSrcVertExtraMain +=
       EOL"  PositionWorld = aPositionWorld;"
       EOL"  Position      = aPosition;";
@@ -1349,8 +1381,8 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
     + aSrcVertColor
     + aLights
     + EOL
-      EOL"varying vec4 FrontColor;"
-      EOL"varying vec4 BackColor;"
+      EOL"THE_SHADER_OUT vec4 FrontColor;"
+      EOL"THE_SHADER_OUT vec4 BackColor;"
       EOL
     + aSrcVertExtraOut
     + EOL"void main()"
@@ -1366,16 +1398,22 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
       EOL"}";
 
   aSrcFrag = TCollection_AsciiString()
-    + EOL"varying vec4 FrontColor;"
-      EOL"varying vec4 BackColor;"
+    + EOL"THE_SHADER_IN vec4 FrontColor;"
+      EOL"THE_SHADER_IN vec4 BackColor;"
     + aSrcFragExtraOut
     + aSrcFragGetColor
     + EOL"void main()"
       EOL"{"
     + aSrcFragExtraMain
-    + EOL"  gl_FragColor = getColor();"
+    + EOL"  occFragColor = getColor();"
       EOL"}";
 
+#if !defined(GL_ES_VERSION_2_0)
+  if (myContext->core32 != NULL)
+  {
+    aProgramSrc->SetHeader ("#version 150");
+  }
+#endif
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX,   aSrcVert));
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
   TCollection_AsciiString aKey;
@@ -1407,9 +1445,9 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
   }
   if ((theBits & OpenGl_PO_VertColor) != 0)
   {
-    aSrcVertExtraOut  += THE_VARY_VertColor;
+    aSrcVertExtraOut  += EOL"THE_SHADER_OUT vec4 VertColor;";
     aSrcVertExtraMain += EOL"  VertColor = occVertColor;";
-    aSrcFragGetColor   = EOL"varying vec4 VertColor;"
+    aSrcFragGetColor   = EOL"THE_SHADER_IN  vec4 VertColor;"
                          EOL"vec4 getVertColor(void) { return VertColor; }";
   }
 
@@ -1421,7 +1459,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
         EOL"vec4 getColor(void)"
         EOL"{"
         EOL"  vec4 aColor = " thePhongCompLight ";"
-        EOL"  return texture2D(occActiveSampler, gl_PointCoord) * aColor;"
+        EOL"  return occTexture2D(occActiveSampler, gl_PointCoord) * aColor;"
         EOL"}";
     }
   }
@@ -1429,8 +1467,8 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
   {
     if ((theBits & OpenGl_PO_TextureRGB) != 0)
     {
-      aSrcVertExtraOut  += THE_VARY_TexCoord;
-      aSrcFragExtraOut  += THE_VARY_TexCoord;
+      aSrcVertExtraOut  += THE_VARY_TexCoord_OUT;
+      aSrcFragExtraOut  += THE_VARY_TexCoord_IN;
       aSrcVertExtraMain +=
         EOL"  TexCoord = occTexCoord.st;";
 
@@ -1438,7 +1476,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
         EOL"vec4 getColor(void)"
         EOL"{"
         EOL"  vec4 aColor = " thePhongCompLight ";"
-        EOL"  return texture2D(occActiveSampler, TexCoord.st) * aColor;"
+        EOL"  return occTexture2D(occActiveSampler, TexCoord.st) * aColor;"
         EOL"}";
     }
   }
@@ -1451,10 +1489,10 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
   aSrcVert = TCollection_AsciiString()
     + THE_FUNC_transformNormal
     + EOL
-      EOL"varying vec4 PositionWorld;"
-      EOL"varying vec4 Position;"
-      EOL"varying vec3 Normal;"
-      EOL"varying vec3 View;"
+      EOL"THE_SHADER_OUT vec4 PositionWorld;"
+      EOL"THE_SHADER_OUT vec4 Position;"
+      EOL"THE_SHADER_OUT vec3 Normal;"
+      EOL"THE_SHADER_OUT vec3 View;"
       EOL
     + aSrcVertExtraOut
     + EOL"void main()"
@@ -1469,10 +1507,10 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
 
   const TCollection_AsciiString aLights = stdComputeLighting ((theBits & OpenGl_PO_VertColor) != 0);
   aSrcFrag = TCollection_AsciiString()
-    + EOL"varying vec4 PositionWorld;"
-      EOL"varying vec4 Position;"
-      EOL"varying vec3 Normal;"
-      EOL"varying vec3 View;"
+    + EOL"THE_SHADER_IN vec4 PositionWorld;"
+      EOL"THE_SHADER_IN vec4 Position;"
+      EOL"THE_SHADER_IN vec3 Normal;"
+      EOL"THE_SHADER_IN vec3 View;"
     + EOL
     + aSrcFragExtraOut
     + aSrcFragGetVertColor
@@ -1482,9 +1520,15 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
       EOL"void main()"
       EOL"{"
     + aSrcFragExtraMain
-    + EOL"  gl_FragColor = getColor();"
+    + EOL"  occFragColor = getColor();"
       EOL"}";
 
+#if !defined(GL_ES_VERSION_2_0)
+  if (myContext->core32 != NULL)
+  {
+    aProgramSrc->SetHeader ("#version 150");
+  }
+#endif
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX,   aSrcVert));
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
   TCollection_AsciiString aKey;
index adab135..0ef1808 100644 (file)
@@ -268,8 +268,7 @@ protected:
     }
     if (!theTexture.IsNull())
     {
-      // GL_RED to be handled
-      aBits |= theTexture->GetFormat() == GL_ALPHA ? OpenGl_PO_TextureA : OpenGl_PO_TextureRGB;
+      aBits |= theTexture->IsAlpha() ? OpenGl_PO_TextureA : OpenGl_PO_TextureRGB;
     }
     if (theHasVertColor)
     {
index 8aec5ad..d9181cb 100755 (executable)
@@ -56,7 +56,7 @@ Standard_Boolean OpenGl_ShaderObject::LoadSource (const Handle(OpenGl_Context)&
   }
 
   const GLchar* aLines = theSource.ToCString();
-  theCtx->core20->glShaderSource (myShaderID, 1, &aLines, NULL);
+  theCtx->core20fwd->glShaderSource (myShaderID, 1, &aLines, NULL);
   return Standard_True;
 }
 
@@ -72,11 +72,11 @@ Standard_Boolean OpenGl_ShaderObject::Compile (const Handle(OpenGl_Context)& the
   }
 
   // Try to compile shader
-  theCtx->core20->glCompileShader (myShaderID);
+  theCtx->core20fwd->glCompileShader (myShaderID);
 
   // Check compile status
   GLint aStatus = GL_FALSE;
-  theCtx->core20->glGetShaderiv (myShaderID, GL_COMPILE_STATUS, &aStatus);
+  theCtx->core20fwd->glGetShaderiv (myShaderID, GL_COMPILE_STATUS, &aStatus);
   return aStatus != GL_FALSE;
 }
 
@@ -94,12 +94,12 @@ Standard_Boolean OpenGl_ShaderObject::FetchInfoLog (const Handle(OpenGl_Context)
 
   // Load information log of the compiler
   GLint aLength = 0;
-  theCtx->core20->glGetShaderiv (myShaderID, GL_INFO_LOG_LENGTH, &aLength);
+  theCtx->core20fwd->glGetShaderiv (myShaderID, GL_INFO_LOG_LENGTH, &aLength);
   if (aLength > 0)
   {
     GLchar* aLog = (GLchar*) alloca (aLength);
     memset (aLog, 0, aLength);
-    theCtx->core20->glGetShaderInfoLog (myShaderID, aLength, NULL, aLog);
+    theCtx->core20fwd->glGetShaderInfoLog (myShaderID, aLength, NULL, aLog);
     theLog = aLog;
   }
 
@@ -113,9 +113,9 @@ Standard_Boolean OpenGl_ShaderObject::FetchInfoLog (const Handle(OpenGl_Context)
 Standard_Boolean OpenGl_ShaderObject::Create (const Handle(OpenGl_Context)& theCtx)
 {
   if (myShaderID == NO_SHADER
-   && theCtx->core20 != NULL)
+   && theCtx->core20fwd != NULL)
   {
-    myShaderID = theCtx->core20->glCreateShader (myType);
+    myShaderID = theCtx->core20fwd->glCreateShader (myType);
   }
 
   return myShaderID != NO_SHADER;
@@ -135,10 +135,10 @@ void OpenGl_ShaderObject::Release (OpenGl_Context* theCtx)
   Standard_ASSERT_RETURN (theCtx != NULL,
     "OpenGl_ShaderObject destroyed without GL context! Possible GPU memory leakage...",);
 
-  if (theCtx->core20 != NULL
+  if (theCtx->core20fwd != NULL
    && theCtx->IsValid())
   {
-    theCtx->core20->glDeleteShader (myShaderID);
+    theCtx->core20fwd->glDeleteShader (myShaderID);
   }
   myShaderID = NO_SHADER;
 }
index d88dc09..d654c1e 100755 (executable)
@@ -230,6 +230,8 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
                                        ? "precision highp float;\n"
                                        : "precision mediump float;\n");
         aSource = aHeader + aPrefix + aSource;
+      #else
+        aSource = aHeader + aSource;
       #endif
         break;
       }
@@ -354,7 +356,7 @@ Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context
   }
 
   myShaderObjects.Append (theShader);
-  theCtx->core20->glAttachShader (myProgramID, theShader->myShaderID);
+  theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID);
   return Standard_True;
 }
 
@@ -388,7 +390,7 @@ Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context
     return Standard_False;
   }
 
-  theCtx->core20->glDetachShader (myProgramID, theShader->myShaderID);
+  theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID);
   return Standard_True;
 }
 
@@ -404,8 +406,8 @@ Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCt
   }
 
   GLint aStatus = GL_FALSE;
-  theCtx->core20->glLinkProgram (myProgramID);
-  theCtx->core20->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
+  theCtx->core20fwd->glLinkProgram (myProgramID);
+  theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
   if (aStatus == GL_FALSE)
   {
     return Standard_False;
@@ -431,12 +433,12 @@ Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context
   }
 
   GLint aLength = 0;
-  theCtx->core20->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
+  theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
   if (aLength > 0)
   {
     GLchar* aLog = (GLchar*) alloca (aLength);
     memset (aLog, 0, aLength);
-    theCtx->core20->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
+    theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
     theOutput = aLog;
   }
   return Standard_True;
@@ -496,7 +498,7 @@ GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& th
                                                 const GLchar*                 theName) const
 {
   return myProgramID != NO_PROGRAM
-       ? theCtx->core20->glGetUniformLocation (myProgramID, theName)
+       ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName)
        : INVALID_LOCATION;
 }
 
@@ -508,7 +510,7 @@ GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)&
                                                   const GLchar*                 theName) const
 {
   return myProgramID != NO_PROGRAM
-       ? theCtx->core20->glGetAttribLocation (myProgramID, theName)
+       ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName)
        : INVALID_LOCATION;
 }
 
@@ -549,7 +551,7 @@ Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glGetUniformiv (myProgramID, theLocation, theValue);
+  theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue);
   return Standard_True;
 }
 
@@ -577,7 +579,7 @@ Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glGetUniformfv (myProgramID, theLocation, theValue);
+  theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue);
   return Standard_True;
 }
 
@@ -605,7 +607,7 @@ Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context
     return Standard_False;
   }
 
-  theCtx->core20->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
+  theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
   return Standard_True;
 }
 
@@ -633,7 +635,7 @@ Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context
     return Standard_False;
   }
 
-  theCtx->core20->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
+  theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
   return Standard_True;
 }
 
@@ -785,7 +787,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform1i (theLocation, theValue);
+  theCtx->core20fwd->glUniform1i (theLocation, theValue);
   return Standard_True;
 }
 
@@ -877,7 +879,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform1f (theLocation, theValue);
+  theCtx->core20fwd->glUniform1f (theLocation, theValue);
   return Standard_True;
 }
 
@@ -905,7 +907,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform2iv (theLocation, 1, theValue);
+  theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue);
   return Standard_True;
 }
 
@@ -933,7 +935,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform3iv (theLocation, 1, theValue);
+  theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue);
   return Standard_True;
 }
 
@@ -961,7 +963,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform4iv (theLocation, 1, theValue);
+  theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue);
   return Standard_True;
 }
 
@@ -989,7 +991,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform2fv (theLocation, 1, theValue);
+  theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue);
   return Standard_True;
 }
 
@@ -1017,7 +1019,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform3fv (theLocation, 1, theValue);
+  theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue);
   return Standard_True;
 }
 
@@ -1045,7 +1047,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform4fv (theLocation, 1, theValue);
+  theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue);
   return Standard_True;
 }
 
@@ -1075,7 +1077,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
+  theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue);
   return Standard_True;
 }
 
@@ -1117,7 +1119,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform1fv (theLocation, theCount, theData);
+  theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData);
   return Standard_True;
 }
 
@@ -1135,7 +1137,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform2fv (theLocation, theCount, theData[0].GetData());
+  theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData());
   return Standard_True;
 }
 
@@ -1153,7 +1155,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform3fv (theLocation, theCount, theData[0].GetData());
+  theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData());
   return Standard_True;
 }
 
@@ -1171,7 +1173,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform4fv (theLocation, theCount, theData[0].GetData());
+  theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData());
   return Standard_True;
 }
 
@@ -1189,7 +1191,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform1iv (theLocation, theCount, theData);
+  theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData);
   return Standard_True;
 }
 
@@ -1207,7 +1209,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform2iv (theLocation, theCount, theData[0].GetData());
+  theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData());
   return Standard_True;
 }
 
@@ -1225,7 +1227,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform3iv (theLocation, theCount, theData[0].GetData());
+  theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData());
   return Standard_True;
 }
 
@@ -1243,7 +1245,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform4iv (theLocation, theCount, theData[0].GetData());
+  theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData());
   return Standard_True;
 }
 
@@ -1271,7 +1273,7 @@ Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)&
     return Standard_False;
   }
 
-  theCtx->core20->glUniform1i (theLocation, theTextureUnit);
+  theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit);
   return Standard_True;
 }
 
@@ -1282,9 +1284,9 @@ Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)&
 Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
 {
   if (myProgramID == NO_PROGRAM
-   && theCtx->core20 != NULL)
+   && theCtx->core20fwd != NULL)
   {
-    myProgramID = theCtx->core20->glCreateProgram();
+    myProgramID = theCtx->core20fwd->glCreateProgram();
   }
 
   return myProgramID != NO_PROGRAM;
@@ -1313,10 +1315,10 @@ void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx)
     }
   }
 
-  if (theCtx->core20 != NULL
+  if (theCtx->core20fwd != NULL
    && theCtx->IsValid())
   {
-    theCtx->core20->glDeleteProgram (myProgramID);
+    theCtx->core20fwd->glDeleteProgram (myProgramID);
   }
 
   myProgramID = NO_PROGRAM;
index f530593..8f3f8a4 100755 (executable)
@@ -383,7 +383,7 @@ void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
   const Handle(OpenGl_Context)& aCtx         = theWorkspace->GetGlContext();
 
   // Bind custom shader program or generate default version
-  if (aCtx->IsGlGreaterEqual (2, 0))
+  if (aCtx->core20fwd != NULL)
   {
     aCtx->ShaderManager()->BindProgram (
       aTextAspect, aTextAspect->ShaderProgramRes (aCtx));
index e5b4287..6d752b2 100644 (file)
@@ -56,6 +56,7 @@ OpenGl_Texture::OpenGl_Texture (const Handle(Graphic3d_TextureParams)& theParams
   mySizeY (0),
   myTextFormat (GL_RGBA),
   myHasMipmaps (Standard_False),
+  myIsAlpha    (false),
   myParams     (theParams)
 {
   if (myParams.IsNull())
@@ -143,7 +144,7 @@ void OpenGl_Texture::Release (OpenGl_Context* theGlCtx)
 void OpenGl_Texture::Bind (const Handle(OpenGl_Context)& theCtx,
                            const GLenum theTextureUnit) const
 {
-  if (theCtx->IsGlGreaterEqual (1, 5))
+  if (theCtx->core15fwd != NULL)
   {
     theCtx->core15fwd->glActiveTexture (theTextureUnit);
   }
@@ -157,7 +158,7 @@ void OpenGl_Texture::Bind (const Handle(OpenGl_Context)& theCtx,
 void OpenGl_Texture::Unbind (const Handle(OpenGl_Context)& theCtx,
                              const GLenum theTextureUnit) const
 {
-  if (theCtx->IsGlGreaterEqual (1, 5))
+  if (theCtx->core15fwd != NULL)
   {
     theCtx->core15fwd->glActiveTexture (theTextureUnit);
   }
@@ -359,6 +360,17 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
     Release (theCtx.operator->());
     return false;
   }
+
+  if (theImage != NULL)
+  {
+    myIsAlpha = theImage->Format() == Image_PixMap::ImgAlpha
+             || theImage->Format() == Image_PixMap::ImgAlphaF;
+  }
+  else
+  {
+    myIsAlpha = thePixelFormat == GL_ALPHA;
+  }
+
   myHasMipmaps             = Standard_False;
   myTextFormat             = thePixelFormat;
 #if !defined(GL_ES_VERSION_2_0)
index 476c4b1..b8ac42f 100644 (file)
@@ -201,6 +201,19 @@ public:
     return myTextFormat;
   }
 
+  //! Return true for GL_RED and GL_ALPHA formats.
+  bool IsAlpha() const
+  {
+    return myIsAlpha;
+  }
+
+  //! Setup to interprete the format as Alpha by Shader Manager
+  //! (should be GL_ALPHA within compatible context or GL_RED otherwise).
+  void SetAlpha (const bool theValue)
+  {
+    myIsAlpha = theValue;
+  }
+
   //! Creates Texture id if not yet generated.
   //! Data should be initialized by another method.
   Standard_EXPORT bool Create (const Handle(OpenGl_Context)& theCtx);
@@ -264,6 +277,7 @@ protected:
   GLsizei          mySizeY;      //!< texture height
   GLenum           myTextFormat; //!< texture format - GL_RGB, GL_RGBA,...
   Standard_Boolean myHasMipmaps; //!< flag indicates that texture was uploaded with mipmaps
+  bool             myIsAlpha;    //!< indicates alpha format
 
   Handle(Graphic3d_TextureParams) myParams; //!< texture parameters
 
index af41da1..2fb8a78 100644 (file)
@@ -188,7 +188,7 @@ bool OpenGl_TextureBufferArb::Init (const Handle(OpenGl_Context)& theGlCtx,
 void OpenGl_TextureBufferArb::BindTexture (const Handle(OpenGl_Context)& theGlCtx,
                                            const GLenum theTextureUnit) const
 {
-  theGlCtx->core20->glActiveTexture (theTextureUnit);
+  theGlCtx->core20fwd->glActiveTexture (theTextureUnit);
   glBindTexture (GetTarget(), myTextureId);
 }
 
@@ -199,6 +199,6 @@ void OpenGl_TextureBufferArb::BindTexture (const Handle(OpenGl_Context)& theGlCt
 void OpenGl_TextureBufferArb::UnbindTexture (const Handle(OpenGl_Context)& theGlCtx,
                                              const GLenum theTextureUnit) const
 {
-  theGlCtx->core20->glActiveTexture (theTextureUnit);
+  theGlCtx->core20fwd->glActiveTexture (theTextureUnit);
   glBindTexture (GetTarget(), NO_TEXTURE);
 }
index 9f06b96..3c7511e 100644 (file)
@@ -61,7 +61,7 @@ bool OpenGl_VertexBuffer::Create (const Handle(OpenGl_Context)& theGlCtx)
 {
   if (myBufferId == NO_BUFFER)
   {
-    theGlCtx->core15->glGenBuffers (1, &myBufferId);
+    theGlCtx->core15fwd->glGenBuffers (1, &myBufferId);
   }
   return myBufferId != NO_BUFFER;
 }
@@ -83,7 +83,7 @@ void OpenGl_VertexBuffer::Release (OpenGl_Context* theGlCtx)
 
   if (theGlCtx->IsValid())
   {
-    theGlCtx->core15->glDeleteBuffers (1, &myBufferId);
+    theGlCtx->core15fwd->glDeleteBuffers (1, &myBufferId);
   }
   myOffset   = NULL;
   myBufferId = NO_BUFFER;
@@ -95,7 +95,7 @@ void OpenGl_VertexBuffer::Release (OpenGl_Context* theGlCtx)
 // =======================================================================
 void OpenGl_VertexBuffer::Bind (const Handle(OpenGl_Context)& theGlCtx) const
 {
-  theGlCtx->core15->glBindBuffer (GetTarget(), myBufferId);
+  theGlCtx->core15fwd->glBindBuffer (GetTarget(), myBufferId);
 }
 
 // =======================================================================
@@ -104,7 +104,7 @@ void OpenGl_VertexBuffer::Bind (const Handle(OpenGl_Context)& theGlCtx) const
 // =======================================================================
 void OpenGl_VertexBuffer::Unbind (const Handle(OpenGl_Context)& theGlCtx) const
 {
-  theGlCtx->core15->glBindBuffer (GetTarget(), NO_BUFFER);
+  theGlCtx->core15fwd->glBindBuffer (GetTarget(), NO_BUFFER);
 }
 
 // =======================================================================
@@ -127,7 +127,7 @@ bool OpenGl_VertexBuffer::init (const Handle(OpenGl_Context)& theGlCtx,
   myDataType     = theDataType;
   myComponentsNb = theComponentsNb;
   myElemsNb      = theElemsNb;
-  theGlCtx->core15->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * theStride, theData, GL_STATIC_DRAW);
+  theGlCtx->core15fwd->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * theStride, theData, GL_STATIC_DRAW);
   bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY
   Unbind (theGlCtx);
   return isDone;
@@ -151,10 +151,10 @@ bool OpenGl_VertexBuffer::subData (const Handle(OpenGl_Context)& theGlCtx,
 
   Bind (theGlCtx);
   const size_t aDataSize = sizeOfGlType (theDataType);
-  theGlCtx->core15->glBufferSubData (GetTarget(),
-                                     GLintptr(theElemFrom)  * GLintptr  (myComponentsNb) * aDataSize, // offset in bytes
-                                     GLsizeiptr(theElemsNb) * GLsizeiptr(myComponentsNb) * aDataSize, // size   in bytes
-                                     theData);
+  theGlCtx->core15fwd->glBufferSubData (GetTarget(),
+                                        GLintptr(theElemFrom)  * GLintptr  (myComponentsNb) * aDataSize, // offset in bytes
+                                        GLsizeiptr(theElemsNb) * GLsizeiptr(myComponentsNb) * aDataSize, // size   in bytes
+                                        theData);
   bool isDone = (glGetError() == GL_NO_ERROR); // some dummy error
   Unbind (theGlCtx);
   return isDone;
@@ -172,8 +172,8 @@ void OpenGl_VertexBuffer::BindVertexAttrib (const Handle(OpenGl_Context)& theGlC
     return;
   }
   Bind (theGlCtx);
-  theGlCtx->core20->glEnableVertexAttribArray (theAttribLoc);
-  theGlCtx->core20->glVertexAttribPointer (theAttribLoc, GLint (myComponentsNb), myDataType, GL_FALSE, 0, myOffset);
+  theGlCtx->core20fwd->glEnableVertexAttribArray (theAttribLoc);
+  theGlCtx->core20fwd->glVertexAttribPointer (theAttribLoc, GLint (myComponentsNb), myDataType, GL_FALSE, 0, myOffset);
 }
 
 // =======================================================================
@@ -187,7 +187,7 @@ void OpenGl_VertexBuffer::UnbindVertexAttrib (const Handle(OpenGl_Context)& theG
   {
     return;
   }
-  theGlCtx->core20->glDisableVertexAttribArray (theAttribLoc);
+  theGlCtx->core20fwd->glDisableVertexAttribArray (theAttribLoc);
   Unbind (theGlCtx);
 }
 
index 9cec1ce..5545c4a 100644 (file)
@@ -26,7 +26,10 @@ inline void OpenGl_VertexBuffer::bindAttribute (const Handle(OpenGl_Context)&
   if (theCtx->ActiveProgram().IsNull())
   {
   #if !defined(GL_ES_VERSION_2_0)
-    bindFixed (theCtx, theAttribute, theNbComp, theDataType, theStride, theOffset);
+    if (theCtx->core11 != NULL)
+    {
+      bindFixed (theCtx, theAttribute, theNbComp, theDataType, theStride, theOffset);
+    }
   #endif
     return;
   }
@@ -93,7 +96,10 @@ inline void OpenGl_VertexBuffer::unbindAttribute (const Handle(OpenGl_Context)&
   if (theCtx->ActiveProgram().IsNull())
   {
   #if !defined(GL_ES_VERSION_2_0)
-    unbindFixed (theCtx, theAttribute);
+    if (theCtx->core11 != NULL)
+    {
+      unbindFixed (theCtx, theAttribute);
+    }
   #endif
     return;
   }
@@ -103,7 +109,7 @@ inline void OpenGl_VertexBuffer::unbindAttribute (const Handle(OpenGl_Context)&
 
 #if !defined(GL_ES_VERSION_2_0)
 // =======================================================================
-// function : unbindAttribute
+// function : unbindFixed
 // purpose  :
 // =======================================================================
 inline void OpenGl_VertexBuffer::unbindFixed (const Handle(OpenGl_Context)&   theCtx,
index 9fe7f64..9cad122 100644 (file)
@@ -348,7 +348,10 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
 
 #if !defined(GL_ES_VERSION_2_0)
   // Switch off lighting by default
-  glDisable(GL_LIGHTING);
+  if (aContext->core11 != NULL)
+  {
+    glDisable(GL_LIGHTING);
+  }
 #endif
 
   // =================================
@@ -393,7 +396,8 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
   }
 
   // Apply Fog
-  if ( myFog.IsOn )
+  if (myFog.IsOn
+   && aContext->core11 != NULL)
   {
     Standard_Real aFogFrontConverted = (Standard_Real )myFog.Front + myCamera->Distance();
     if (myCamera->ZFar() < aFogFrontConverted)
@@ -421,12 +425,17 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
     glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
     glEnable(GL_FOG);
   }
-  else
-    glDisable(GL_FOG);
+  else if (aContext->core11 != NULL)
+  {
+    glDisable (GL_FOG);
+  }
 
   // Apply InteriorShadingMethod
-  aContext->core11->glShadeModel (myShadingModel == Visual3d_TOM_FACET
-                               || myShadingModel == Visual3d_TOM_NONE ? GL_FLAT : GL_SMOOTH);
+  if (aContext->core11 != NULL)
+  {
+    aContext->core11->glShadeModel (myShadingModel == Visual3d_TOM_FACET
+                                 || myShadingModel == Visual3d_TOM_NONE ? GL_FLAT : GL_SMOOTH);
+  }
 #endif
 
   aManager->SetShadingModel (myShadingModel);
@@ -583,8 +592,12 @@ void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace)& AWorkspace,
   if ( myZLayers.NbStructures() <= 0 )
     return;
 
+  const Handle(OpenGl_Context)& aCtx = AWorkspace->GetGlContext();
 #if !defined(GL_ES_VERSION_2_0)
-  glPushAttrib ( GL_DEPTH_BUFFER_BIT );
+  if (aCtx->core11 != NULL)
+  {
+    aCtx->core11->glPushAttrib (GL_DEPTH_BUFFER_BIT);
+  }
 #endif
 
   //TsmPushAttri(); /* save previous graphics context */
@@ -598,7 +611,10 @@ void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace)& AWorkspace,
     if ( !myAntiAliasing )
     {
     #if !defined(GL_ES_VERSION_2_0)
-      glDisable(GL_POINT_SMOOTH);
+      if (aCtx->core11 != NULL)
+      {
+        glDisable (GL_POINT_SMOOTH);
+      }
       glDisable(GL_LINE_SMOOTH);
       if( antiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
     #endif
@@ -608,7 +624,10 @@ void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace)& AWorkspace,
     else
     {
     #if !defined(GL_ES_VERSION_2_0)
-      glEnable(GL_POINT_SMOOTH);
+      if (aCtx->core11 != NULL)
+      {
+        glEnable(GL_POINT_SMOOTH);
+      }
       glEnable(GL_LINE_SMOOTH);
       if( antiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
     #endif
@@ -620,8 +639,10 @@ void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace)& AWorkspace,
   myZLayers.Render (AWorkspace, theToDrawImmediate);
 
 #if !defined(GL_ES_VERSION_2_0)
-  //TsmPopAttri(); /* restore previous graphics context; before update lights */
-  glPopAttrib();
+  if (aCtx->core11 != NULL)
+  {
+    aCtx->core11->glPopAttrib();
+  }
 #endif
 }
 
@@ -639,6 +660,10 @@ void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintCo
    || ACLayer.ptrLayer->listIndex == 0) return;
 
   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
+  if (aContext->core11 == NULL)
+  {
+    return;
+  }
 
   GLsizei dispWidth  = (GLsizei )ACLayer.viewport[0];
   GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
@@ -1050,6 +1075,7 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
 
 #if !defined(GL_ES_VERSION_2_0)
   // Apply Lights
+  if (aContext->core11 != NULL)
   {
     // setup lights
     Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0],
index b7fb9db..2b9649b 100644 (file)
@@ -147,6 +147,8 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver,
   myBgColor.rgb[1] = theCWindow.Background.g;
   myBgColor.rgb[2] = theCWindow.Background.b;
 
+  Standard_Boolean isCoreProfile = Standard_False;
+
 #if defined(HAVE_EGL) || defined(__ANDROID__)
   EGLDisplay anEglDisplay = (EGLDisplay )theDriver->getRawGlDisplay();
   EGLContext anEglContext = (EGLContext )theDriver->getRawGlContext();
@@ -185,7 +187,7 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver,
     }
   }
 
-  myGlContext->Init ((Aspect_Drawable )anEglSurf, (Aspect_Display )anEglDisplay, (Aspect_RenderingContext )anEglContext);
+  myGlContext->Init ((Aspect_Drawable )anEglSurf, (Aspect_Display )anEglDisplay, (Aspect_RenderingContext )anEglContext, isCoreProfile);
 #elif defined(_WIN32)
   (void )theDriver;
   HWND  aWindow   = (HWND )theCWindow.XWindow;
@@ -210,6 +212,7 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver,
   int aPixelFrmtId = ChoosePixelFormat (aWindowDC, &aPixelFrmt);
 
   // in case of failure try without stereo if any
+  const Standard_Boolean hasStereo = aPixelFrmtId != 0 && theCaps->contextStereo;
   if (aPixelFrmtId == 0 && theCaps->contextStereo)
   {
     TCollection_ExtendedString aMsg ("OpenGl_Window::CreateWindow: "
@@ -248,7 +251,7 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver,
     HWND  aWinTmp     = NULL;
     HDC   aDevCtxTmp  = NULL;
     HGLRC aRendCtxTmp = NULL;
-    if ((!theCaps->contextDebug && !theCaps->contextNoAccel)
+    if ((!theCaps->contextDebug && !theCaps->contextNoAccel && theCaps->contextCompatible)
      || RegisterClassW (&aClass) == 0)
     {
       aClass.lpszClassName = NULL;
@@ -308,7 +311,7 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver,
         WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
         WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
         WGL_DOUBLE_BUFFER_ARB,  GL_TRUE,
-        WGL_STEREO_ARB,         theCaps->contextStereo ? GL_TRUE : GL_FALSE,
+        WGL_STEREO_ARB,         hasStereo ? GL_TRUE : GL_FALSE,
         WGL_PIXEL_TYPE_ARB,     WGL_TYPE_RGBA_ARB,
         //WGL_SAMPLE_BUFFERS_ARB, 1,
         //WGL_SAMPLES_ARB,        8,
@@ -336,18 +339,56 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver,
     // create GL context with extra options
     if (aCreateCtxProc != NULL)
     {
-      // Beware! NVIDIA drivers reject context creation when WGL_CONTEXT_PROFILE_MASK_ARB are specified
-      // but not WGL_CONTEXT_MAJOR_VERSION_ARB/WGL_CONTEXT_MINOR_VERSION_ARB.
-      int aCtxAttribs[] =
+      if (!theCaps->contextCompatible)
       {
-        //WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
-        //WGL_CONTEXT_MINOR_VERSION_ARB, 2,
-        //WGL_CONTEXT_PROFILE_MASK_ARB,  WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, //WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
-        WGL_CONTEXT_FLAGS_ARB,         theCaps->contextDebug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
-        0, 0
-      };
+        int aCoreCtxAttribs[] =
+        {
+          WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
+          WGL_CONTEXT_MINOR_VERSION_ARB, 2,
+          WGL_CONTEXT_PROFILE_MASK_ARB,  WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
+          WGL_CONTEXT_FLAGS_ARB,         theCaps->contextDebug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
+          0, 0
+        };
+
+        // Try to create the core profile of highest OpenGL version supported by OCCT
+        // (this will be done automatically by some drivers when requesting 3.2,
+        //  but some will not (e.g. AMD Catalyst) since WGL_ARB_create_context_profile specification allows both implementations).
+        for (int aLowVer4 = 5; aLowVer4 >= 0 && aGContext == NULL; --aLowVer4)
+        {
+          aCoreCtxAttribs[1] = 4;
+          aCoreCtxAttribs[3] = aLowVer4;
+          aGContext = aCreateCtxProc (aWindowDC, aSlaveCtx, aCoreCtxAttribs);
+        }
+        for (int aLowVer3 = 3; aLowVer3 >= 2 && aGContext == NULL; --aLowVer3)
+        {
+          aCoreCtxAttribs[1] = 3;
+          aCoreCtxAttribs[3] = aLowVer3;
+          aGContext = aCreateCtxProc (aWindowDC, aSlaveCtx, aCoreCtxAttribs);
+        }
+        isCoreProfile = aGContext != NULL;
+      }
+
+      if (aGContext == NULL)
+      {
+        int aCtxAttribs[] =
+        {
+          // Beware! NVIDIA drivers reject context creation when WGL_CONTEXT_PROFILE_MASK_ARB are specified
+          // but not WGL_CONTEXT_MAJOR_VERSION_ARB/WGL_CONTEXT_MINOR_VERSION_ARB.
+          //WGL_CONTEXT_PROFILE_MASK_ARB,  WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
+          WGL_CONTEXT_FLAGS_ARB,         theCaps->contextDebug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
+          0, 0
+        };
+        isCoreProfile = Standard_False;
+        aGContext = aCreateCtxProc (aWindowDC, aSlaveCtx, aCtxAttribs);
+
+        if (aGContext != NULL
+        && !theCaps->contextCompatible)
+        {
+          TCollection_ExtendedString aMsg("OpenGl_Window::CreateWindow: core profile creation failed.");
+          myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_PORTABILITY_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMsg);
+        }
+      }
 
-      aGContext = aCreateCtxProc (aWindowDC, aSlaveCtx, aCtxAttribs);
       if (aGContext != NULL)
       {
         aSlaveCtx = NULL;
@@ -396,7 +437,7 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver,
     return;
   }
 
-  myGlContext->Init ((Aspect_Handle )aWindow, (Aspect_Handle )aWindowDC, (Aspect_RenderingContext )aGContext);
+  myGlContext->Init ((Aspect_Handle )aWindow, (Aspect_Handle )aWindowDC, (Aspect_RenderingContext )aGContext, isCoreProfile);
 #else
   Window aParent = (Window )theCWindow.XWindow;
   Window aWindow = 0;
@@ -433,7 +474,7 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver,
   #if defined(__linux) || defined(Linux) || defined(__APPLE__)
     if (aVis != NULL)
     {
-      // check Visual for OpenGl context's parameters compability
+      // check Visual for OpenGl context's parameters compatibility
       int isGl = 0, isDoubleBuffer = 0, isRGBA = 0, isStereo = 0;
       int aDepthSize = 0, aStencilSize = 0;
 
@@ -570,7 +611,7 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver,
     }
   }
 
-  myGlContext->Init ((Aspect_Drawable )aWindow, (Aspect_Display )aDisp, (Aspect_RenderingContext )aGContext);
+  myGlContext->Init ((Aspect_Drawable )aWindow, (Aspect_Display )aDisp, (Aspect_RenderingContext )aGContext, isCoreProfile);
 #endif
   myGlContext->Share (theShareCtx);
 
@@ -763,8 +804,11 @@ void OpenGl_Window::Init()
   glDisable (GL_SCISSOR_TEST);
   glViewport (0, 0, myWidth, myHeight);
 #if !defined(GL_ES_VERSION_2_0)
-  glMatrixMode (GL_MODELVIEW);
   glDrawBuffer (GL_BACK);
+  if (myGlContext->core11 != NULL)
+  {
+    glMatrixMode (GL_MODELVIEW);
+  }
 #endif
 }
 
index db279c5..e259b0d 100644 (file)
@@ -27,6 +27,7 @@
 #include <Aspect_GraphicDeviceDefinitionError.hxx>
 #include <Cocoa_LocalPool.hxx>
 #include <TCollection_AsciiString.hxx>
+#include <TCollection_ExtendedString.hxx>
 
 #include <OpenGL/CGLRenderers.h>
 
@@ -57,31 +58,72 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver,
   Cocoa_LocalPool aLocalPool;
   //NSOpenGLContext* aGContext = (NSOpenGLContext* )theGContext;
 
-  const NSOpenGLPixelFormatAttribute aDummyAttrib = NSOpenGLPFACompliant;
-  NSOpenGLPixelFormatAttribute anAttribs[] = {
-    theCaps->contextStereo ? NSOpenGLPFAStereo : aDummyAttrib,
-    //NSOpenGLPFAColorSize,  32,
-    NSOpenGLPFADepthSize,    24,
-    NSOpenGLPFAStencilSize,  8,
-    NSOpenGLPFADoubleBuffer,
-    theCaps->contextNoAccel ? NSOpenGLPFARendererID : NSOpenGLPFAAccelerated,
-    theCaps->contextNoAccel ? (NSOpenGLPixelFormatAttribute )kCGLRendererGenericFloatID : 0,
-    0
-  };
-
   // all GL context within one OpenGl_GraphicDriver should be shared!
-  NSOpenGLContext*     aGLCtxShare = theShareCtx.IsNull() ? NULL : (NSOpenGLContext* )theShareCtx->myGContext;
-  NSOpenGLPixelFormat* aGLFormat   = [[[NSOpenGLPixelFormat alloc] initWithAttributes: anAttribs] autorelease];
-  NSOpenGLContext*     aGLContext  = [[NSOpenGLContext alloc] initWithFormat: aGLFormat
-                                                                shareContext: aGLCtxShare];
-  if (aGLContext == NULL
-   && theCaps->contextStereo)
+  NSOpenGLContext* aGLCtxShare = theShareCtx.IsNull() ? NULL : (NSOpenGLContext* )theShareCtx->myGContext;
+  NSOpenGLContext* aGLContext  = NULL;
+
+  NSOpenGLPixelFormatAttribute anAttribs[32] = {};
+  Standard_Integer aLastAttrib = 0;
+  //anAttribs[aLastAttrib++] = NSOpenGLPFAColorSize;    anAttribs[aLastAttrib++] = 32,
+  anAttribs[aLastAttrib++] = NSOpenGLPFADepthSize;    anAttribs[aLastAttrib++] = 24;
+  anAttribs[aLastAttrib++] = NSOpenGLPFAStencilSize;  anAttribs[aLastAttrib++] = 8;
+  anAttribs[aLastAttrib++] = NSOpenGLPFADoubleBuffer;
+  if (theCaps->contextNoAccel)
+  {
+    anAttribs[aLastAttrib++] = NSOpenGLPFARendererID;
+    anAttribs[aLastAttrib++] = (NSOpenGLPixelFormatAttribute )kCGLRendererGenericFloatID;
+  }
+  else
   {
-    anAttribs[0] = aDummyAttrib;
-    aGLFormat    = [[[NSOpenGLPixelFormat alloc] initWithAttributes: anAttribs] autorelease];
-    aGLContext   = [[NSOpenGLContext alloc] initWithFormat: aGLFormat
+    anAttribs[aLastAttrib++] = NSOpenGLPFAAccelerated;
+  }
+  anAttribs[aLastAttrib] = 0;
+  const Standard_Integer aLastMainAttrib = aLastAttrib;
+  Standard_Integer aTryCore   = 0;
+  Standard_Integer aTryStereo = 0;
+  for (aTryCore = 1; aTryCore >= 0; --aTryCore)
+  {
+    aLastAttrib = aLastMainAttrib;
+    if (aTryCore == 1)
+    {
+      if (theCaps->contextCompatible)
+      {
+        continue;
+      }
+
+      // supported since OS X 10.7+
+      anAttribs[aLastAttrib++] = 99;     // NSOpenGLPFAOpenGLProfile
+      anAttribs[aLastAttrib++] = 0x3200; // NSOpenGLProfileVersion3_2Core
+    }
+
+    for (aTryStereo = 1; aTryStereo >= 0; --aTryStereo)
+    {
+      if (aTryStereo == 1)
+      {
+        if (!theCaps->contextStereo)
+        {
+          continue;
+        }
+        anAttribs[aLastAttrib++] = NSOpenGLPFAStereo;
+      }
+
+      anAttribs[aLastAttrib] = 0;
+
+      NSOpenGLPixelFormat* aGLFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes: anAttribs] autorelease];
+      aGLContext = [[NSOpenGLContext alloc] initWithFormat: aGLFormat
                                               shareContext: aGLCtxShare];
+      if (aGLContext != NULL)
+      {
+        break;
+      }
+    }
+
+    if (aGLContext != NULL)
+    {
+      break;
+    }
   }
+
   if (aGLContext == NULL)
   {
     TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: NSOpenGLContext creation failed");
@@ -89,10 +131,23 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver,
     return;
   }
 
+  if (aTryStereo == 0
+   && theCaps->contextStereo)
+  {
+    TCollection_ExtendedString aMsg("OpenGl_Window::CreateWindow: QuadBuffer is unavailable!");
+    myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_OTHER_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMsg);
+  }
+  if (aTryCore == 0
+  && !theCaps->contextCompatible)
+  {
+    TCollection_ExtendedString aMsg("OpenGl_Window::CreateWindow: core profile creation failed.");
+    myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_PORTABILITY_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMsg);
+  }
+
   NSView* aView = (NSView* )theCWindow.XWindow;
   [aGLContext setView: aView];
 
-  myGlContext->Init (aGLContext);
+  myGlContext->Init (aGLContext, aTryCore == 1);
   myGlContext->Share (theShareCtx);
   Init();
 }
index 88e073d..556d66a 100644 (file)
@@ -195,13 +195,17 @@ OpenGl_Workspace::OpenGl_Workspace (const Handle(OpenGl_GraphicDriver)& theDrive
   // General initialization of the context
 
 #if !defined(GL_ES_VERSION_2_0)
-  // Eviter d'avoir les faces mal orientees en noir.
-  // Pourrait etre utiliser pour detecter les problemes d'orientation
-  glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+  if (myGlContext->core11 != NULL)
+  {
+    // Eviter d'avoir les faces mal orientees en noir.
+    // Pourrait etre utiliser pour detecter les problemes d'orientation
+    glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+
+    // Optimisation pour le Fog et l'antialiasing
+    glHint (GL_FOG_HINT,            GL_FASTEST);
+    glHint (GL_POINT_SMOOTH_HINT,   GL_FASTEST);
+  }
 
-  // Optimisation pour le Fog et l'antialiasing
-  glHint (GL_FOG_HINT,            GL_FASTEST);
-  glHint (GL_POINT_SMOOTH_HINT,   GL_FASTEST);
   glHint (GL_LINE_SMOOTH_HINT,    GL_FASTEST);
   glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
 #endif
@@ -274,6 +278,8 @@ Standard_Boolean OpenGl_Workspace::Activate()
 //=======================================================================
 void OpenGl_Workspace::ResetAppliedAspect()
 {
+  myGlContext->BindDefaultVao();
+
   NamedStatus           = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0;
   HighlightColor        = &THE_WHITE_COLOR;
   AspectLine_set        = &myDefaultAspectLine;
@@ -314,11 +320,14 @@ Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
 
 #if !defined(GL_ES_VERSION_2_0)
   // reset texture matrix because some code may expect it is identity
-  GLint aMatrixMode = GL_TEXTURE;
-  glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
-  glMatrixMode (GL_TEXTURE);
-  glLoadIdentity();
-  glMatrixMode (aMatrixMode);
+  if (myGlContext->core11 != NULL)
+  {
+    GLint aMatrixMode = GL_TEXTURE;
+    glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
+    glMatrixMode (GL_TEXTURE);
+    glLoadIdentity();
+    glMatrixMode (aMatrixMode);
+  }
 #endif
 
   myTextureBound->Unbind (myGlContext);
@@ -327,28 +336,33 @@ Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
   #if !defined(GL_ES_VERSION_2_0)
     case GL_TEXTURE_1D:
     {
-
-      if (myTextureBound->GetParams()->GenMode() != GL_NONE)
+      if (myGlContext->core11 != NULL)
       {
-        glDisable (GL_TEXTURE_GEN_S);
+        if (myTextureBound->GetParams()->GenMode() != GL_NONE)
+        {
+          glDisable (GL_TEXTURE_GEN_S);
+        }
+        glDisable (GL_TEXTURE_1D);
       }
-      glDisable (GL_TEXTURE_1D);
       break;
     }
   #endif
     case GL_TEXTURE_2D:
     {
     #if !defined(GL_ES_VERSION_2_0)
-      if (myTextureBound->GetParams()->GenMode() != GL_NONE)
+      if (myGlContext->core11 != NULL)
       {
-        glDisable (GL_TEXTURE_GEN_S);
-        glDisable (GL_TEXTURE_GEN_T);
-        if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE)
+        if (myTextureBound->GetParams()->GenMode() != GL_NONE)
         {
-          glDisable (GL_POINT_SPRITE);
+          glDisable (GL_TEXTURE_GEN_S);
+          glDisable (GL_TEXTURE_GEN_T);
+          if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE)
+          {
+            glDisable (GL_POINT_SPRITE);
+          }
         }
+        glDisable (GL_TEXTURE_2D);
       }
-      glDisable (GL_TEXTURE_2D);
     #endif
       break;
     }
@@ -375,89 +389,92 @@ void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)&
 
 #if !defined(GL_ES_VERSION_2_0)
   GLint aMatrixMode = GL_TEXTURE;
-  glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
-
-  // setup texture matrix
-  glMatrixMode (GL_TEXTURE);
-  OpenGl_Mat4 aTextureMat;
-  const Graphic3d_Vec2& aScale = aParams->Scale();
-  const Graphic3d_Vec2& aTrans = aParams->Translation();
-  OpenGl_Utils::Scale     (aTextureMat,  aScale.x(),  aScale.y(), 1.0f);
-  OpenGl_Utils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f);
-  OpenGl_Utils::Rotate    (aTextureMat, -aParams->Rotation(), 0.0f, 0.0f, 1.0f);
-  glLoadMatrixf (aTextureMat);
-
-  GLint anEnvMode = GL_MODULATE; // lighting mode
-  if (!aParams->IsModulate())
+  if (myGlContext->core11 != NULL)
   {
-    anEnvMode = GL_DECAL;
-    if (theTexture->GetFormat() == GL_ALPHA
-     || theTexture->GetFormat() == GL_LUMINANCE)
+    glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
+
+    // setup texture matrix
+    glMatrixMode (GL_TEXTURE);
+    OpenGl_Mat4 aTextureMat;
+    const Graphic3d_Vec2& aScale = aParams->Scale();
+    const Graphic3d_Vec2& aTrans = aParams->Translation();
+    OpenGl_Utils::Scale     (aTextureMat,  aScale.x(),  aScale.y(), 1.0f);
+    OpenGl_Utils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f);
+    OpenGl_Utils::Rotate    (aTextureMat, -aParams->Rotation(), 0.0f, 0.0f, 1.0f);
+    glLoadMatrixf (aTextureMat);
+
+    GLint anEnvMode = GL_MODULATE; // lighting mode
+    if (!aParams->IsModulate())
     {
-      anEnvMode = GL_REPLACE;
+      anEnvMode = GL_DECAL;
+      if (theTexture->GetFormat() == GL_ALPHA
+       || theTexture->GetFormat() == GL_LUMINANCE)
+      {
+        anEnvMode = GL_REPLACE;
+      }
     }
-  }
 
-  // setup generation of texture coordinates
-  switch (aParams->GenMode())
-  {
-    case Graphic3d_TOTM_OBJECT:
+    // setup generation of texture coordinates
+    switch (aParams->GenMode())
     {
-      glTexGeni  (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
-      glTexGenfv (GL_S, GL_OBJECT_PLANE,     aParams->GenPlaneS().GetData());
-      if (theTexture->GetTarget() != GL_TEXTURE_1D)
+      case Graphic3d_TOTM_OBJECT:
       {
-        glTexGeni  (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
-        glTexGenfv (GL_T, GL_OBJECT_PLANE,     aParams->GenPlaneT().GetData());
+        glTexGeni  (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+        glTexGenfv (GL_S, GL_OBJECT_PLANE,     aParams->GenPlaneS().GetData());
+        if (theTexture->GetTarget() != GL_TEXTURE_1D)
+        {
+          glTexGeni  (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+          glTexGenfv (GL_T, GL_OBJECT_PLANE,     aParams->GenPlaneT().GetData());
+        }
+        break;
       }
-      break;
-    }
-    case Graphic3d_TOTM_SPHERE:
-    {
-      glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
-      if (theTexture->GetTarget() != GL_TEXTURE_1D)
+      case Graphic3d_TOTM_SPHERE:
       {
-        glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+        glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+        if (theTexture->GetTarget() != GL_TEXTURE_1D)
+        {
+          glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+        }
+        break;
       }
-      break;
-    }
-    case Graphic3d_TOTM_EYE:
-    {
-      myGlContext->WorldViewState.Push();
+      case Graphic3d_TOTM_EYE:
+      {
+        myGlContext->WorldViewState.Push();
 
-      myGlContext->WorldViewState.SetIdentity();
-      myGlContext->ApplyWorldViewMatrix();
+        myGlContext->WorldViewState.SetIdentity();
+        myGlContext->ApplyWorldViewMatrix();
 
-      glTexGeni  (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
-      glTexGenfv (GL_S, GL_EYE_PLANE,        aParams->GenPlaneS().GetData());
+        glTexGeni  (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+        glTexGenfv (GL_S, GL_EYE_PLANE,        aParams->GenPlaneS().GetData());
 
-      if (theTexture->GetTarget() != GL_TEXTURE_1D)
-      {
-        glTexGeni  (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
-        glTexGenfv (GL_T, GL_EYE_PLANE,        aParams->GenPlaneT().GetData());
-      }
+        if (theTexture->GetTarget() != GL_TEXTURE_1D)
+        {
+          glTexGeni  (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+          glTexGenfv (GL_T, GL_EYE_PLANE,        aParams->GenPlaneT().GetData());
+        }
 
-      myGlContext->WorldViewState.Pop();
+        myGlContext->WorldViewState.Pop();
 
-      break;
-    }
-    case Graphic3d_TOTM_SPRITE:
-    {
-      if (GetGlContext()->core20 != NULL)
+        break;
+      }
+      case Graphic3d_TOTM_SPRITE:
       {
-        glEnable  (GL_POINT_SPRITE);
-        glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
-        anEnvMode = GL_REPLACE;
-        GetGlContext()->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
+        if (GetGlContext()->core20fwd != NULL)
+        {
+          glEnable  (GL_POINT_SPRITE);
+          glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
+          anEnvMode = GL_REPLACE;
+          GetGlContext()->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
+        }
+        break;
       }
-      break;
+      case Graphic3d_TOTM_MANUAL:
+      default: break;
     }
-    case Graphic3d_TOTM_MANUAL:
-    default: break;
-  }
 
-  // setup lighting
-  glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
+    // setup lighting
+    glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
+  }
 #endif
 
   // get active sampler object to override default texture parameters
@@ -569,23 +586,29 @@ void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)&
   #if !defined(GL_ES_VERSION_2_0)
     case GL_TEXTURE_1D:
     {
-      if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
+      if (myGlContext->core11 != NULL)
       {
-        glEnable (GL_TEXTURE_GEN_S);
+        if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
+        {
+          glEnable (GL_TEXTURE_GEN_S);
+        }
+        glEnable (GL_TEXTURE_1D);
       }
-      glEnable (GL_TEXTURE_1D);
       break;
     }
   #endif
     case GL_TEXTURE_2D:
     {
     #if !defined(GL_ES_VERSION_2_0)
-      if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
+      if (myGlContext->core11 != NULL)
       {
-        glEnable (GL_TEXTURE_GEN_S);
-        glEnable (GL_TEXTURE_GEN_T);
+        if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
+        {
+          glEnable (GL_TEXTURE_GEN_S);
+          glEnable (GL_TEXTURE_GEN_T);
+        }
+        glEnable (GL_TEXTURE_2D);
       }
-      glEnable (GL_TEXTURE_2D);
     #endif
       break;
     }
@@ -593,7 +616,10 @@ void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)&
   }
 
 #if !defined(GL_ES_VERSION_2_0)
-  glMatrixMode (aMatrixMode); // turn back active matrix
+  if (myGlContext->core11 != NULL)
+  {
+    glMatrixMode (aMatrixMode); // turn back active matrix
+  }
 #endif
   theTexture->SetParams (aParams);
 }
@@ -924,9 +950,10 @@ void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& theCView,
 
   Aspect_GraphicCallbackStruct aCallData;
   aCallData.reason    = theReason;
-  aCallData.glContext = GetGlContext();
+  aCallData.glContext = myGlContext;
   aCallData.wsID      = theCView.WsId;
   aCallData.viewID    = theCView.ViewId;
+  aCallData.IsCoreProfile = (myGlContext->core11 == NULL);
   theCView.GDisplayCB (theCView.DefWindow.XWindow, theCView.GClientData, &aCallData);
 }
 
index 71d47b6..479fde4 100644 (file)
@@ -150,11 +150,14 @@ void OpenGl_Workspace::updateMaterial (const int theFlag)
   if (NamedStatus & OPENGL_NS_RESMAT)
   {
   #if !defined(GL_ES_VERSION_2_0)
-    glMaterialfv (aFace, GL_AMBIENT,   myMatTmp.Ambient.GetData());
-    glMaterialfv (aFace, GL_DIFFUSE,   myMatTmp.Diffuse.GetData());
-    glMaterialfv (aFace, GL_SPECULAR,  myMatTmp.Specular.GetData());
-    glMaterialfv (aFace, GL_EMISSION,  myMatTmp.Emission.GetData());
-    glMaterialf  (aFace, GL_SHININESS, myMatTmp.Shine());
+    if (myGlContext->core11 != NULL)
+    {
+      myGlContext->core11->glMaterialfv (aFace, GL_AMBIENT,   myMatTmp.Ambient.GetData());
+      myGlContext->core11->glMaterialfv (aFace, GL_DIFFUSE,   myMatTmp.Diffuse.GetData());
+      myGlContext->core11->glMaterialfv (aFace, GL_SPECULAR,  myMatTmp.Specular.GetData());
+      myGlContext->core11->glMaterialfv (aFace, GL_EMISSION,  myMatTmp.Emission.GetData());
+      myGlContext->core11->glMaterialf  (aFace, GL_SHININESS, myMatTmp.Shine());
+    }
   #endif
 
     if (theFlag == TEL_FRONT_MATERIAL)
@@ -176,34 +179,37 @@ void OpenGl_Workspace::updateMaterial (const int theFlag)
                          ? myMatFront
                          : myMatBack;
 #if !defined(GL_ES_VERSION_2_0)
-  if (myMatTmp.Ambient.r() != anOld.Ambient.r()
-   || myMatTmp.Ambient.g() != anOld.Ambient.g()
-   || myMatTmp.Ambient.b() != anOld.Ambient.b())
-  {
-    glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
-  }
-  if (myMatTmp.Diffuse.r() != anOld.Diffuse.r()
-   || myMatTmp.Diffuse.g() != anOld.Diffuse.g()
-   || myMatTmp.Diffuse.b() != anOld.Diffuse.b()
-   || fabs (myMatTmp.Diffuse.a() - anOld.Diffuse.a()) > 0.01f)
+  if (myGlContext->core11 != NULL)
   {
-    glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
-  }
-  if (myMatTmp.Specular.r() != anOld.Specular.r()
-   || myMatTmp.Specular.g() != anOld.Specular.g()
-   || myMatTmp.Specular.b() != anOld.Specular.b())
-  {
-    glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
-  }
-  if (myMatTmp.Emission.r() != anOld.Emission.r()
-   || myMatTmp.Emission.g() != anOld.Emission.g()
-   || myMatTmp.Emission.b() != anOld.Emission.b())
-  {
-    glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
-  }
-  if (myMatTmp.Shine() != anOld.Shine())
-  {
-    glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
+    if (myMatTmp.Ambient.r() != anOld.Ambient.r()
+     || myMatTmp.Ambient.g() != anOld.Ambient.g()
+     || myMatTmp.Ambient.b() != anOld.Ambient.b())
+    {
+      myGlContext->core11->glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
+    }
+    if (myMatTmp.Diffuse.r() != anOld.Diffuse.r()
+     || myMatTmp.Diffuse.g() != anOld.Diffuse.g()
+     || myMatTmp.Diffuse.b() != anOld.Diffuse.b()
+     || fabs (myMatTmp.Diffuse.a() - anOld.Diffuse.a()) > 0.01f)
+    {
+      myGlContext->core11->glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
+    }
+    if (myMatTmp.Specular.r() != anOld.Specular.r()
+     || myMatTmp.Specular.g() != anOld.Specular.g()
+     || myMatTmp.Specular.b() != anOld.Specular.b())
+    {
+      myGlContext->core11->glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
+    }
+    if (myMatTmp.Emission.r() != anOld.Emission.r()
+     || myMatTmp.Emission.g() != anOld.Emission.g()
+     || myMatTmp.Emission.b() != anOld.Emission.b())
+    {
+      myGlContext->core11->glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
+    }
+    if (myMatTmp.Shine() != anOld.Shine())
+    {
+      myGlContext->core11->glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
+    }
   }
 #endif
   anOld = myMatTmp;
@@ -255,11 +261,7 @@ const OpenGl_AspectLine * OpenGl_Workspace::AspectLine(const Standard_Boolean Wi
 {
   if ( WithApply && (AspectLine_set != AspectLine_applied) )
   {
-    const GLfloat* anRgb = AspectLine_set->Color().rgb;
-  #if !defined(GL_ES_VERSION_2_0)
-    glColor3fv(anRgb);
-  #endif
-
+    myGlContext->SetColor4fv (*(const OpenGl_Vec4* )AspectLine_set->Color().rgb);
     if ( !AspectLine_applied || (AspectLine_set->Type() != AspectLine_applied->Type() ) )
     {
       myLineAttribs->SetTypeOfLine (AspectLine_set->Type());
@@ -357,7 +359,10 @@ const OpenGl_AspectFace* OpenGl_Workspace::AspectFace (const Standard_Boolean th
       case Aspect_IS_HIDDENLINE:
       {
         glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
-        glDisable (GL_POLYGON_STIPPLE);
+        if (myGlContext->core11 != NULL)
+        {
+          glDisable (GL_POLYGON_STIPPLE);
+        }
         break;
       }
       case Aspect_IS_POINT:
index 0ae4df3..d73b743 100644 (file)
@@ -451,9 +451,16 @@ static int VGlInfo (Draw_Interpretor& theDI,
 
   if (theArgNb <= 1)
   {
-    Standard_CString aDebugInfo = OpenGl_Context::CheckExtension ((const char* )glGetString (GL_EXTENSIONS),
-                                                                  "GL_ARB_debug_output")
-                                ? "  GLdebug     =  ON\n" : "";
+    Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aView->View()->GraphicDriver());
+    if (aDriver.IsNull())
+    {
+      std::cerr << "Error: view does not use OpenGL.\n";
+      return 1;
+    }
+    Handle(OpenGl_Context) aCtx = aDriver->GetSharedContext();
+    Standard_CString aDebugInfo = !aCtx.IsNull() && aCtx->IsDebugContext()
+                                ? "  GLdebug     =  ON\n"
+                                : "";
     theDI << "OpenGL info:\n"
           << "  GLvendor    = '" << (const char* )glGetString(GL_VENDOR)   << "'\n"
           << "  GLdevice    = '" << (const char* )glGetString(GL_RENDERER) << "'\n"
index 009b8ef..df3d13d 100644 (file)
@@ -4723,6 +4723,7 @@ static int VCaps (Draw_Interpretor& theDI,
     theDI << "Sprites: " << (aCaps->pntSpritesDisable ? "0" : "1") << "\n";
     theDI << "SoftMode:" << (aCaps->contextNoAccel    ? "1" : "0") << "\n";
     theDI << "FFP:     " << (aCaps->ffpEnable         ? "1" : "0") << "\n";
+    theDI << "Compatible:" << (aCaps->contextCompatible ? "1" : "0") << "\n";
     return 0;
   }
 
@@ -4788,6 +4789,38 @@ static int VCaps (Draw_Interpretor& theDI,
       }
       aCaps->contextNoAccel = !toEnable;
     }
+    else if (anArgCase == "-compat"
+          || anArgCase == "-compatprofile"
+          || anArgCase == "-compatible"
+          || anArgCase == "-compatibleprofile")
+    {
+      Standard_Boolean toEnable = Standard_True;
+      if (++anArgIter < theArgNb
+      && !parseOnOff (theArgVec[anArgIter], toEnable))
+      {
+        --anArgIter;
+      }
+      aCaps->contextCompatible = toEnable;
+      if (!aCaps->contextCompatible)
+      {
+        aCaps->ffpEnable = Standard_False;
+      }
+    }
+    else if (anArgCase == "-core"
+          || anArgCase == "-coreprofile")
+    {
+      Standard_Boolean toEnable = Standard_True;
+      if (++anArgIter < theArgNb
+      && !parseOnOff (theArgVec[anArgIter], toEnable))
+      {
+        --anArgIter;
+      }
+      aCaps->contextCompatible = !toEnable;
+      if (!aCaps->contextCompatible)
+      {
+        aCaps->ffpEnable = Standard_False;
+      }
+    }
     else
     {
       std::cout << "Error: unknown argument '" << anArg << "'\n";
@@ -7828,15 +7861,18 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     __FILE__, VStereo, group);
   theCommands.Add ("vcaps",
             "vcaps [-vbo {0|1}] [-sprites {0|1}] [-ffp {0|1}]"
+    "\n\t\t:       [-compatibleContext {0|1}]"
     "\n\t\t:       [-softMode {0|1}] [-noupdate|-update]"
     "\n\t\t: Modify particular graphic driver options:"
     "\n\t\t:  FFP      - use fixed-function pipeline instead of"
     "\n\t\t:             built-in GLSL programs"
+    "\n\t\t:            (requires compatible profile)"
     "\n\t\t:  VBO      - use Vertex Buffer Object (copy vertex"
     "\n\t\t:             arrays to GPU memory)"
     "\n\t\t:  sprite   - use textured sprites instead of bitmaps"
-    "\n\t\t:  softMode - use software OpenGL implementation,"
-    "\n\t\t:             should be set BEFORE viewer creation"
+    "\n\t\t: Context creation options:"
+    "\n\t\t:  softMode          - software OpenGL implementation"
+    "\n\t\t:  compatibleProfile - backward-compatible profile"
     "\n\t\t: Unlike vrenderparams, these parameters control alternative"
     "\n\t\t: rendering paths producing the same visual result when"
     "\n\t\t: possible."
diff --git a/tests/bugs/vis/bug25854 b/tests/bugs/vis/bug25854
new file mode 100644 (file)
index 0000000..45ec071
--- /dev/null
@@ -0,0 +1,18 @@
+puts "============"
+puts "CR25854"
+puts "============"
+puts ""
+
+############################################################
+# Visualization, TKOpenGl - add option to request Core profile 3.2+
+############################################################
+
+vcaps -coreProfile
+vcaps
+vinit
+vglinfo
+box b 1 2 3
+vdisplay b
+vfit
+
+vdump $imagedir/${casename}.png