From 4e1523ef0b157003f0c25f7017d72ca68ad124bd Mon Sep 17 00:00:00 2001 From: kgv Date: Thu, 5 Mar 2015 16:00:51 +0300 Subject: [PATCH] 0025854: Visualization, TKOpenGl - add option to request Core profile 3.2+ 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 --- src/Aspect/Aspect_GraphicCallbackProc.hxx | 1 + src/NIS/NIS_View.cxx | 5 + src/OpenGl/OpenGl_AspectFace.cxx | 2 +- src/OpenGl/OpenGl_AspectLine.cxx | 2 +- src/OpenGl/OpenGl_AspectMarker.cxx | 4 +- src/OpenGl/OpenGl_AspectText.cxx | 2 +- src/OpenGl/OpenGl_Caps.cxx | 6 + src/OpenGl/OpenGl_Caps.hxx | 17 ++ src/OpenGl/OpenGl_Context.cxx | 240 +++++++++++++++---- src/OpenGl/OpenGl_Context.hxx | 65 +++-- src/OpenGl/OpenGl_Context_1.mm | 4 +- src/OpenGl/OpenGl_LineAttributes.cxx | 17 +- src/OpenGl/OpenGl_PrimitiveArray.cxx | 31 ++- src/OpenGl/OpenGl_ShaderManager.cxx | 162 ++++++++----- src/OpenGl/OpenGl_ShaderManager.hxx | 3 +- src/OpenGl/OpenGl_ShaderObject.cxx | 18 +- src/OpenGl/OpenGl_ShaderProgram.cxx | 70 +++--- src/OpenGl/OpenGl_Text.cxx | 2 +- src/OpenGl/OpenGl_Texture.cxx | 16 +- src/OpenGl/OpenGl_Texture.hxx | 14 ++ src/OpenGl/OpenGl_TextureBufferArb.cxx | 4 +- src/OpenGl/OpenGl_VertexBuffer.cxx | 24 +- src/OpenGl/OpenGl_VertexBuffer.lxx | 12 +- src/OpenGl/OpenGl_View_2.cxx | 48 +++- src/OpenGl/OpenGl_Window.cxx | 78 ++++-- src/OpenGl/OpenGl_Window_1.mm | 101 ++++++-- src/OpenGl/OpenGl_Workspace.cxx | 237 ++++++++++-------- src/OpenGl/OpenGl_Workspace_5.cxx | 81 ++++--- src/ViewerTest/ViewerTest_OpenGlCommands.cxx | 13 +- src/ViewerTest/ViewerTest_ViewerCommands.cxx | 40 +++- tests/bugs/vis/bug25854 | 18 ++ 31 files changed, 924 insertions(+), 413 deletions(-) create mode 100644 tests/bugs/vis/bug25854 diff --git a/src/Aspect/Aspect_GraphicCallbackProc.hxx b/src/Aspect/Aspect_GraphicCallbackProc.hxx index 52b56f22c4..94a9e1a274 100644 --- a/src/Aspect/Aspect_GraphicCallbackProc.hxx +++ b/src/Aspect/Aspect_GraphicCallbackProc.hxx @@ -40,6 +40,7 @@ typedef struct int reason; int wsID; int viewID; + bool IsCoreProfile; Handle(Standard_Transient) glContext; } Aspect_GraphicCallbackStruct; diff --git a/src/NIS/NIS_View.cxx b/src/NIS/NIS_View.cxx index ee24237aaa..c358945da7 100644 --- a/src/NIS/NIS_View.cxx +++ b/src/NIS/NIS_View.cxx @@ -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 (ptrData)); NCollection_List::Iterator anIter; #ifdef CLIP diff --git a/src/OpenGl/OpenGl_AspectFace.cxx b/src/OpenGl/OpenGl_AspectFace.cxx index ab4a4b368e..16417bedf7 100644 --- a/src/OpenGl/OpenGl_AspectFace.cxx +++ b/src/OpenGl/OpenGl_AspectFace.cxx @@ -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; } diff --git a/src/OpenGl/OpenGl_AspectLine.cxx b/src/OpenGl/OpenGl_AspectLine.cxx index c7ddf98fe2..f0351c2035 100644 --- a/src/OpenGl/OpenGl_AspectLine.cxx +++ b/src/OpenGl/OpenGl_AspectLine.cxx @@ -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; } diff --git a/src/OpenGl/OpenGl_AspectMarker.cxx b/src/OpenGl/OpenGl_AspectMarker.cxx index 4eecb22b4f..8dd9e2dbb6 100644 --- a/src/OpenGl/OpenGl_AspectMarker.cxx +++ b/src/OpenGl/OpenGl_AspectMarker.cxx @@ -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; } diff --git a/src/OpenGl/OpenGl_AspectText.cxx b/src/OpenGl/OpenGl_AspectText.cxx index 98cc48430a..45d256859b 100755 --- a/src/OpenGl/OpenGl_AspectText.cxx +++ b/src/OpenGl/OpenGl_AspectText.cxx @@ -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; } diff --git a/src/OpenGl/OpenGl_Caps.cxx b/src/OpenGl/OpenGl_Caps.cxx index 6389f564a0..cc18b6e1c2 100755 --- a/src/OpenGl/OpenGl_Caps.cxx +++ b/src/OpenGl/OpenGl_Caps.cxx @@ -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; } diff --git a/src/OpenGl/OpenGl_Caps.hxx b/src/OpenGl/OpenGl_Caps.hxx index 0b90e3e964..8078e2ebbb 100755 --- a/src/OpenGl/OpenGl_Caps.hxx +++ b/src/OpenGl/OpenGl_Caps.hxx @@ -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. diff --git a/src/OpenGl/OpenGl_Context.cxx b/src/OpenGl/OpenGl_Context.cxx index 3f47492ff7..66e1fb91b5 100644 --- a/src/OpenGl/OpenGl_Context.cxx +++ b/src/OpenGl/OpenGl_Context.cxx @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include @@ -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); - core11 = (OpenGl_GlCore11* )(&(*myFuncs)); +#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 = 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 } @@ -2150,6 +2271,23 @@ Standard_Boolean OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram) return Standard_True; } +// ======================================================================= +// 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 : diff --git a/src/OpenGl/OpenGl_Context.hxx b/src/OpenGl/OpenGl_Context.hxx index 187a918c67..0cf2591be1 100644 --- a/src/OpenGl/OpenGl_Context.hxx +++ b/src/OpenGl/OpenGl_Context.hxx @@ -110,9 +110,8 @@ typedef OpenGl_TmplCore44 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_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_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: diff --git a/src/OpenGl/OpenGl_Context_1.mm b/src/OpenGl/OpenGl_Context_1.mm index f5b5cf723f..0d882741fc 100644 --- a/src/OpenGl/OpenGl_Context_1.mm +++ b/src/OpenGl/OpenGl_Context_1.mm @@ -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; } diff --git a/src/OpenGl/OpenGl_LineAttributes.cxx b/src/OpenGl/OpenGl_LineAttributes.cxx index 409f13d8f3..948812030c 100644 --- a/src/OpenGl/OpenGl_LineAttributes.cxx +++ b/src/OpenGl/OpenGl_LineAttributes.cxx @@ -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 diff --git a/src/OpenGl/OpenGl_PrimitiveArray.cxx b/src/OpenGl/OpenGl_PrimitiveArray.cxx index 593fe500e8..52da8723e3 100755 --- a/src/OpenGl/OpenGl_PrimitiveArray.cxx +++ b/src/OpenGl/OpenGl_PrimitiveArray.cxx @@ -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) + if (aCtx->core11 != NULL) { - glDisable (GL_LIGHTING); - } - else - { - 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) { diff --git a/src/OpenGl/OpenGl_ShaderManager.cxx b/src/OpenGl/OpenGl_ShaderManager.cxx index b63be61e45..96cdb1b1de 100644 --- a/src/OpenGl/OpenGl_ShaderManager.cxx +++ b/src/OpenGl/OpenGl_ShaderManager.cxx @@ -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; diff --git a/src/OpenGl/OpenGl_ShaderManager.hxx b/src/OpenGl/OpenGl_ShaderManager.hxx index adab135d22..0ef1808ac8 100644 --- a/src/OpenGl/OpenGl_ShaderManager.hxx +++ b/src/OpenGl/OpenGl_ShaderManager.hxx @@ -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) { diff --git a/src/OpenGl/OpenGl_ShaderObject.cxx b/src/OpenGl/OpenGl_ShaderObject.cxx index 8aec5ad431..d9181cbc4f 100755 --- a/src/OpenGl/OpenGl_ShaderObject.cxx +++ b/src/OpenGl/OpenGl_ShaderObject.cxx @@ -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; } diff --git a/src/OpenGl/OpenGl_ShaderProgram.cxx b/src/OpenGl/OpenGl_ShaderProgram.cxx index d88dc092bf..d654c1e091 100755 --- a/src/OpenGl/OpenGl_ShaderProgram.cxx +++ b/src/OpenGl/OpenGl_ShaderProgram.cxx @@ -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; diff --git a/src/OpenGl/OpenGl_Text.cxx b/src/OpenGl/OpenGl_Text.cxx index f530593e3c..8f3f8a40da 100755 --- a/src/OpenGl/OpenGl_Text.cxx +++ b/src/OpenGl/OpenGl_Text.cxx @@ -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)); diff --git a/src/OpenGl/OpenGl_Texture.cxx b/src/OpenGl/OpenGl_Texture.cxx index e5b4287228..6d752b2787 100644 --- a/src/OpenGl/OpenGl_Texture.cxx +++ b/src/OpenGl/OpenGl_Texture.cxx @@ -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) diff --git a/src/OpenGl/OpenGl_Texture.hxx b/src/OpenGl/OpenGl_Texture.hxx index 476c4b1f37..b8ac42f45b 100644 --- a/src/OpenGl/OpenGl_Texture.hxx +++ b/src/OpenGl/OpenGl_Texture.hxx @@ -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 diff --git a/src/OpenGl/OpenGl_TextureBufferArb.cxx b/src/OpenGl/OpenGl_TextureBufferArb.cxx index af41da174f..2fb8a78a9a 100644 --- a/src/OpenGl/OpenGl_TextureBufferArb.cxx +++ b/src/OpenGl/OpenGl_TextureBufferArb.cxx @@ -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); } diff --git a/src/OpenGl/OpenGl_VertexBuffer.cxx b/src/OpenGl/OpenGl_VertexBuffer.cxx index 9f06b96ba3..3c7511e447 100644 --- a/src/OpenGl/OpenGl_VertexBuffer.cxx +++ b/src/OpenGl/OpenGl_VertexBuffer.cxx @@ -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); } diff --git a/src/OpenGl/OpenGl_VertexBuffer.lxx b/src/OpenGl/OpenGl_VertexBuffer.lxx index 9cec1ce4bc..5545c4a62d 100644 --- a/src/OpenGl/OpenGl_VertexBuffer.lxx +++ b/src/OpenGl/OpenGl_VertexBuffer.lxx @@ -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, diff --git a/src/OpenGl/OpenGl_View_2.cxx b/src/OpenGl/OpenGl_View_2.cxx index 9fe7f64585..9cad122f50 100644 --- a/src/OpenGl/OpenGl_View_2.cxx +++ b/src/OpenGl/OpenGl_View_2.cxx @@ -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], diff --git a/src/OpenGl/OpenGl_Window.cxx b/src/OpenGl/OpenGl_Window.cxx index b7fb9db8ec..2b9649bafd 100644 --- a/src/OpenGl/OpenGl_Window.cxx +++ b/src/OpenGl/OpenGl_Window.cxx @@ -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 } diff --git a/src/OpenGl/OpenGl_Window_1.mm b/src/OpenGl/OpenGl_Window_1.mm index db279c5964..e259b0dc31 100644 --- a/src/OpenGl/OpenGl_Window_1.mm +++ b/src/OpenGl/OpenGl_Window_1.mm @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -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[0] = aDummyAttrib; - aGLFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes: anAttribs] autorelease]; - aGLContext = [[NSOpenGLContext alloc] initWithFormat: aGLFormat - shareContext: aGLCtxShare]; + anAttribs[aLastAttrib++] = NSOpenGLPFARendererID; + anAttribs[aLastAttrib++] = (NSOpenGLPixelFormatAttribute )kCGLRendererGenericFloatID; } + else + { + 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(); } diff --git a/src/OpenGl/OpenGl_Workspace.cxx b/src/OpenGl/OpenGl_Workspace.cxx index 88e073d850..556d66a799 100644 --- a/src/OpenGl/OpenGl_Workspace.cxx +++ b/src/OpenGl/OpenGl_Workspace.cxx @@ -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) - { - anEnvMode = GL_REPLACE; - } - } + glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode); - // setup generation of texture coordinates - switch (aParams->GenMode()) - { - case Graphic3d_TOTM_OBJECT: + // 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()) { - 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) + anEnvMode = GL_DECAL; + if (theTexture->GetFormat() == GL_ALPHA + || theTexture->GetFormat() == GL_LUMINANCE) { - glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData()); - } - break; - } - case Graphic3d_TOTM_SPHERE: - { - 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; - } - case Graphic3d_TOTM_EYE: - { - myGlContext->WorldViewState.Push(); - - myGlContext->WorldViewState.SetIdentity(); - myGlContext->ApplyWorldViewMatrix(); - - 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()); - } - - myGlContext->WorldViewState.Pop(); - - break; - } - case Graphic3d_TOTM_SPRITE: - { - if (GetGlContext()->core20 != 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; } - case Graphic3d_TOTM_MANUAL: - default: break; - } - // setup lighting - glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode); + // setup generation of texture coordinates + switch (aParams->GenMode()) + { + case Graphic3d_TOTM_OBJECT: + { + 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; + } + case Graphic3d_TOTM_SPHERE: + { + 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; + } + case Graphic3d_TOTM_EYE: + { + myGlContext->WorldViewState.Push(); + + myGlContext->WorldViewState.SetIdentity(); + myGlContext->ApplyWorldViewMatrix(); + + 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()); + } + + myGlContext->WorldViewState.Pop(); + + break; + } + case Graphic3d_TOTM_SPRITE: + { + 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; + } + case Graphic3d_TOTM_MANUAL: + default: break; + } + + // 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); } diff --git a/src/OpenGl/OpenGl_Workspace_5.cxx b/src/OpenGl/OpenGl_Workspace_5.cxx index 71d47b6cea..479fde457c 100644 --- a/src/OpenGl/OpenGl_Workspace_5.cxx +++ b/src/OpenGl/OpenGl_Workspace_5.cxx @@ -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()) + if (myGlContext->core11 != NULL) { - 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) - { - 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: diff --git a/src/ViewerTest/ViewerTest_OpenGlCommands.cxx b/src/ViewerTest/ViewerTest_OpenGlCommands.cxx index 0ae4df393d..d73b743406 100644 --- a/src/ViewerTest/ViewerTest_OpenGlCommands.cxx +++ b/src/ViewerTest/ViewerTest_OpenGlCommands.cxx @@ -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" diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index 009b8efe56..df3d13ddee 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -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 index 0000000000..45ec071183 --- /dev/null +++ b/tests/bugs/vis/bug25854 @@ -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