0024671: TKOpenGl, OpenGl_Context - glGetPointerv might be called without GL context
[occt.git] / src / OpenGl / OpenGl_Context.cxx
index 85f7481..514ef1b 100644 (file)
@@ -1,21 +1,17 @@
 // Created on: 2012-01-26
 // Created by: Kirill GAVRILOV
-// Copyright (c) 2012 OPEN CASCADE SAS
+// Copyright (c) 2012-2014 OPEN CASCADE SAS
 //
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
 //
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
 //
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
 #if defined(_WIN32)
   #include <windows.h>
@@ -104,8 +100,10 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
   myMaxClipPlanes (6),
   myGlVerMajor (0),
   myGlVerMinor (0),
-  myIsFeedback (Standard_False),
-  myIsInitialized (Standard_False)
+  myRenderMode (GL_RENDER),
+  myIsInitialized (Standard_False),
+  myIsStereoBuffers (Standard_False),
+  myDrawBuffer (0)
 {
 #if defined(MAC_OS_X_VERSION_10_3) && !defined(MACOSX_USE_GLX)
   // Vendors can not extend functionality on this system
@@ -135,17 +133,23 @@ OpenGl_Context::~OpenGl_Context()
   // release shared resources if any
   if (((const Handle(Standard_Transient)& )mySharedResources)->GetRefCount() <= 1)
   {
+    myShaderManager.Nullify();
     for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
          anIter.More(); anIter.Next())
     {
       anIter.Value()->Release (this);
     }
   }
+  else
+  {
+    myShaderManager->SetContext (NULL);
+  }
   mySharedResources.Nullify();
   myDelayed.Nullify();
 
   if (arbDbg != NULL
-   && caps->contextDebug)
+   && caps->contextDebug
+   && IsValid())
   {
     // reset callback
     void* aPtr = NULL;
@@ -192,6 +196,103 @@ Standard_Integer OpenGl_Context::MaxClipPlanes() const
   return myMaxClipPlanes;
 }
 
+// =======================================================================
+// function : SetDrawBufferLeft
+// purpose  :
+// =======================================================================
+void OpenGl_Context::SetDrawBufferLeft()
+{
+  switch (myDrawBuffer)
+  {
+    case GL_BACK_RIGHT :
+    case GL_BACK :
+      glDrawBuffer (GL_BACK_LEFT);
+      myDrawBuffer = GL_BACK_LEFT;
+      break;
+
+    case GL_FRONT_RIGHT :
+    case GL_FRONT :
+      glDrawBuffer (GL_FRONT_LEFT);
+      myDrawBuffer = GL_FRONT_LEFT;
+      break;
+
+    case GL_FRONT_AND_BACK :
+    case GL_RIGHT :
+      glDrawBuffer (GL_LEFT);
+      myDrawBuffer = GL_LEFT;
+      break;
+  }
+}
+
+// =======================================================================
+// function : SetDrawBufferRight
+// purpose  :
+// =======================================================================
+void OpenGl_Context::SetDrawBufferRight()
+{
+  switch (myDrawBuffer)
+  {
+    case GL_BACK_LEFT :
+    case GL_BACK :
+      glDrawBuffer (GL_BACK_RIGHT);
+      myDrawBuffer = GL_BACK_RIGHT;
+      break;
+
+    case GL_FRONT_LEFT :
+    case GL_FRONT :
+      glDrawBuffer (GL_FRONT_RIGHT);
+      myDrawBuffer = GL_FRONT_RIGHT;
+      break;
+
+    case GL_FRONT_AND_BACK :
+    case GL_LEFT :
+      glDrawBuffer (GL_RIGHT);
+      myDrawBuffer = GL_RIGHT;
+      break;
+  }
+}
+
+// =======================================================================
+// function : SetDrawBufferMono
+// purpose  :
+// =======================================================================
+void OpenGl_Context::SetDrawBufferMono()
+{
+  switch (myDrawBuffer)
+  {
+    case GL_BACK_LEFT :
+    case GL_BACK_RIGHT :
+      glDrawBuffer (GL_BACK);
+      myDrawBuffer = GL_BACK;
+      break;
+
+    case GL_FRONT_LEFT :
+    case GL_FRONT_RIGHT :
+      glDrawBuffer (GL_FRONT);
+      myDrawBuffer = GL_FRONT;
+      break;
+
+    case GL_LEFT :
+    case GL_RIGHT :
+      glDrawBuffer (GL_FRONT_AND_BACK);
+      myDrawBuffer = GL_FRONT_AND_BACK;
+      break;
+  }
+}
+
+// =======================================================================
+// function : FetchState
+// purpose  :
+// =======================================================================
+void OpenGl_Context::FetchState()
+{
+  // cache feedback mode state
+  glGetIntegerv (GL_RENDER_MODE, &myRenderMode);
+
+  // cache draw buffer state
+  glGetIntegerv (GL_DRAW_BUFFER, &myDrawBuffer);
+}
+
 // =======================================================================
 // function : Share
 // purpose  :
@@ -203,6 +304,7 @@ void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
     mySharedResources = theShareCtx->mySharedResources;
     myDelayed         = theShareCtx->myDelayed;
     myReleaseQueue    = theShareCtx->myReleaseQueue;
+    myShaderManager   = theShareCtx->myShaderManager;
   }
 }
 
@@ -250,6 +352,7 @@ Standard_Boolean OpenGl_Context::MakeCurrent()
   // however some drivers (Intel etc.) may FAIL doing this for unknown reason
   if (IsCurrent())
   {
+    myShaderManager->SetContext (this);
     return Standard_True;
   }
   else if (wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext) != TRUE)
@@ -285,6 +388,7 @@ Standard_Boolean OpenGl_Context::MakeCurrent()
     return Standard_False;
   }
 #endif
+  myShaderManager->SetContext (this);
   return Standard_True;
 }
 
@@ -359,7 +463,7 @@ Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
   const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
   if (anExtString == NULL)
   {
-    Messanger()->Send ("TKOpenGL: glGetString (GL_EXTENSIONS) has returned NULL! No GL context?", Message_Warning);
+    Messenger()->Send ("TKOpenGL: glGetString (GL_EXTENSIONS) has returned NULL! No GL context?", Message_Warning);
     return Standard_False;
   }
   return CheckExtension (anExtString, theExtName);
@@ -588,7 +692,7 @@ static void APIENTRY debugCallbackWrap(unsigned int theSource,
                                        unsigned int theSeverity,
                                        int          /*theLength*/,
                                        const char*  theMessage,
-                                       void*        theUserParam)
+                                       const void*  theUserParam)
 {
   OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
   aCtx->PushMessage (theSource, theType, theId, theSeverity, theMessage);
@@ -632,7 +736,7 @@ void OpenGl_Context::PushMessage (const unsigned int theSource,
   aMsg += " | Message:\n  ";
   aMsg += theMessage;
 
-  Messanger()->Send (aMsg, aGrav);
+  Messenger()->Send (aMsg, aGrav);
 }
 
 // =======================================================================
@@ -654,6 +758,11 @@ void OpenGl_Context::init()
   // get number of maximum clipping planes
   glGetIntegerv (GL_MAX_CLIP_PLANES, &myMaxClipPlanes);
   glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
+
+  GLint aStereo;
+  glGetIntegerv (GL_STEREO, &aStereo);
+  myIsStereoBuffers = aStereo == 1;
+
   if (extAnis)
   {
     glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
@@ -999,23 +1108,6 @@ void OpenGl_Context::init()
     core20 = myGlCore20;
   }
 }
-// =======================================================================
-// function : IsFeedback
-// purpose  :
-// =======================================================================
-Standard_Boolean OpenGl_Context::IsFeedback() const
-{
-  return myIsFeedback;
-}
-
-// =======================================================================
-// function : SetFeedback
-// purpose  :
-// =======================================================================
-void OpenGl_Context::SetFeedback (const Standard_Boolean theFeedbackOn)
-{
-  myIsFeedback = theFeedbackOn;
-}
 
 // =======================================================================
 // function : MemoryInfo
@@ -1166,7 +1258,7 @@ void OpenGl_Context::ReleaseDelayed()
     myReleaseQueue->Pop();
   }
 
-  // release delayed shared resoruces
+  // release delayed shared resources
   NCollection_Vector<TCollection_AsciiString> aDeadList;
   for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
        anIter.More(); anIter.Next())