// commercial license or contractual agreement.
#include <OpenGl_GlCore12.hxx>
-#include <InterfaceGraphic.hxx>
#include <OpenGl_Context.hxx>
#include <OpenGl_GraphicDriver.hxx>
#include <OpenGl_Window.hxx>
+#include <OpenGl_FrameBuffer.hxx>
#include <Aspect_GraphicDeviceDefinitionError.hxx>
#include <Graphic3d_TransformUtils.hxx>
#include <TCollection_ExtendedString.hxx>
#include <Graphic3d_GraphicDriver.hxx>
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Window,MMgt_TShared)
+#include <memory>
-#if defined(HAVE_EGL) || defined(__ANDROID__) || defined(__QNX__)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Window,Standard_Transient)
+
+#if defined(HAVE_EGL)
#include <EGL/egl.h>
#endif
namespace
{
-#if defined(HAVE_EGL) || defined(__ANDROID__) || defined(__QNX__)
+#if defined(HAVE_EGL)
//
#elif defined(_WIN32)
Standard_Boolean isCoreProfile = Standard_False;
-#if defined(HAVE_EGL) || defined(__ANDROID__) || defined(__QNX__)
+#if defined(HAVE_EGL)
EGLDisplay anEglDisplay = (EGLDisplay )theDriver->getRawGlDisplay();
EGLContext anEglContext = (EGLContext )theDriver->getRawGlContext();
EGLConfig anEglConfig = (EGLConfig )theDriver->getRawGlConfig();
if (anEglDisplay == EGL_NO_DISPLAY
|| anEglContext == EGL_NO_CONTEXT
- || anEglConfig == NULL)
+ || (anEglConfig == NULL
+ && (EGLContext )theGContext == EGL_NO_CONTEXT))
{
- Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_Window, EGL does not provide compatible configurations!");
+ throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window, EGL does not provide compatible configurations!");
return;
}
EGLSurface anEglSurf = EGL_NO_SURFACE;
- if (theGContext == (EGLContext )EGL_NO_CONTEXT)
+ if ((EGLContext )theGContext == EGL_NO_CONTEXT)
{
// create new surface
anEglSurf = eglCreateWindowSurface (anEglDisplay,
NULL);
if (anEglSurf == EGL_NO_SURFACE)
{
- Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_Window, EGL is unable to create surface for window!");
+ throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window, EGL is unable to create surface for window!");
return;
}
}
else if (theGContext != anEglContext)
{
- Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_Window, EGL is used in unsupported combination!");
+ throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window, EGL is used in unsupported combination!");
return;
}
else
anEglSurf = eglGetCurrentSurface(EGL_DRAW);
if (anEglSurf == EGL_NO_SURFACE)
{
- Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_Window, EGL is unable to retrieve current surface!");
- return;
+ // window-less EGL context (off-screen)
+ //throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window, EGL is unable to retrieve current surface!");
+ if (anEglConfig != NULL)
+ {
+ const int aSurfAttribs[] =
+ {
+ EGL_WIDTH, myWidth,
+ EGL_HEIGHT, myHeight,
+ EGL_NONE
+ };
+ anEglSurf = eglCreatePbufferSurface (anEglDisplay, anEglConfig, aSurfAttribs);
+ if (anEglSurf == EGL_NO_SURFACE)
+ {
+ throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window, EGL is unable to create off-screen surface!");
+ }
+ }
+ myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW,
+ "OpenGl_Window::CreateWindow: WARNING, a Window is created without a EGL Surface!");
}
}
TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: ChoosePixelFormat failed. Error code: ");
aMsg += (int )GetLastError();
- Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
+ throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
return;
}
TCollection_AsciiString aMsg("OpenGl_Window::CreateWindow: SetPixelFormat failed. Error code: ");
aMsg += (int )GetLastError();
- Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
+ throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
return;
}
TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: wglCreateContext failed. Error code: ");
aMsg += (int )GetLastError();
- Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
+ throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
return;
}
}
{
TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: wglShareLists failed. Error code: ");
aMsg += (int )GetLastError();
- Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
+ throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
return;
}
aVisInfo.visualid = aWinAttribs.visual->visualid;
aVisInfo.screen = DefaultScreen (aDisp);
int aNbItems;
- XVisualInfo* aVis = XGetVisualInfo (aDisp, VisualIDMask | VisualScreenMask, &aVisInfo, &aNbItems);
+ std::unique_ptr<XVisualInfo, int(*)(void*)> aVis (XGetVisualInfo (aDisp, VisualIDMask | VisualScreenMask, &aVisInfo, &aNbItems), &XFree);
int isGl = 0;
- if (aVis == NULL)
+ if (aVis.get() == NULL)
{
- Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_Window::CreateWindow: XGetVisualInfo is unable to choose needed configuration in existing OpenGL context. ");
+ throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window::CreateWindow: XGetVisualInfo is unable to choose needed configuration in existing OpenGL context. ");
return;
}
- else if (glXGetConfig (aDisp, aVis, GLX_USE_GL, &isGl) != 0 || !isGl)
+ else if (glXGetConfig (aDisp, aVis.get(), GLX_USE_GL, &isGl) != 0 || !isGl)
{
- Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_Window::CreateWindow: window Visual does not support GL rendering!");
+ throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window::CreateWindow: window Visual does not support GL rendering!");
return;
}
if (myOwnGContext
&& aGContext == NULL)
{
- aGContext = glXCreateContext (aDisp, aVis, aSlaveCtx, GL_TRUE);
+ aGContext = glXCreateContext (aDisp, aVis.get(), aSlaveCtx, GL_TRUE);
if (aGContext == NULL)
{
- Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_Window::CreateWindow: glXCreateContext failed.");
+ throw Aspect_GraphicDeviceDefinitionError("OpenGl_Window::CreateWindow: glXCreateContext failed.");
return;
}
}
TCollection_ExtendedString aList;
int isDoubleBuffer = 0, isRGBA = 0, isStereo = 0;
int aDepthSize = 0, aStencilSize = 0;
- glXGetConfig (aDisp, aVis, GLX_RGBA, &isRGBA);
- glXGetConfig (aDisp, aVis, GLX_DOUBLEBUFFER, &isDoubleBuffer);
- glXGetConfig (aDisp, aVis, GLX_STEREO, &isStereo);
- glXGetConfig (aDisp, aVis, GLX_DEPTH_SIZE, &aDepthSize);
- glXGetConfig (aDisp, aVis, GLX_STENCIL_SIZE, &aStencilSize);
+ glXGetConfig (aDisp, aVis.get(), GLX_RGBA, &isRGBA);
+ glXGetConfig (aDisp, aVis.get(), GLX_DOUBLEBUFFER, &isDoubleBuffer);
+ glXGetConfig (aDisp, aVis.get(), GLX_STEREO, &isStereo);
+ glXGetConfig (aDisp, aVis.get(), GLX_DEPTH_SIZE, &aDepthSize);
+ glXGetConfig (aDisp, aVis.get(), GLX_STENCIL_SIZE, &aStencilSize);
if (aDepthSize < 1) addMsgToList (aList, "no depth buffer");
if (aStencilSize < 1) addMsgToList (aList, "no stencil buffer");
if (isRGBA == 0) addMsgToList (aList, "no RGBA color buffer");
// release "GL" context if it is owned by window
// Mesa implementation can fail to destroy GL context if it set for current thread.
// It should be safer to unset thread GL context before its destruction.
-#if defined(HAVE_EGL) || defined(__ANDROID__) || defined(__QNX__)
+#if defined(HAVE_EGL)
if ((EGLSurface )myGlContext->myWindow != EGL_NO_SURFACE)
{
eglDestroySurface ((EGLDisplay )myGlContext->myDisplay,
// =======================================================================
void OpenGl_Window::Resize()
{
-#if !defined(_WIN32) && !defined(HAVE_EGL) && !defined(__ANDROID__) && !defined(__QNX__)
+#if !defined(_WIN32) && !defined(HAVE_EGL)
Display* aDisp = (Display* )myGlContext->myDisplay;
if (aDisp == NULL)
return;
myWidth = aWidth;
myHeight = aHeight;
-#if !defined(_WIN32) && !defined(HAVE_EGL) && !defined(__ANDROID__) && !defined(__QNX__)
+#if !defined(_WIN32) && !defined(HAVE_EGL)
XResizeWindow (aDisp, myGlContext->myWindow, (unsigned int )myWidth, (unsigned int )myHeight);
XSync (aDisp, False);
#endif
if (!Activate())
return;
-#if defined(HAVE_EGL) || defined(__ANDROID__) || defined(__QNX__)
- eglQuerySurface ((EGLDisplay )myGlContext->myDisplay, (EGLSurface )myGlContext->myWindow, EGL_WIDTH, &myWidth);
- eglQuerySurface ((EGLDisplay )myGlContext->myDisplay, (EGLSurface )myGlContext->myWindow, EGL_HEIGHT, &myHeight);
+#if defined(HAVE_EGL)
+ if ((EGLSurface )myGlContext->myWindow == EGL_NO_SURFACE)
+ {
+ // define an offscreen default FBO to avoid rendering into EGL_NO_SURFACE;
+ // note that this code is currently never called, since eglCreatePbufferSurface() is used instead as more robust solution
+ // for offscreen rendering on bugged OpenGL ES drivers
+ Handle(OpenGl_FrameBuffer) aDefFbo = myGlContext->SetDefaultFrameBuffer (Handle(OpenGl_FrameBuffer)());
+ if (!aDefFbo.IsNull())
+ {
+ aDefFbo->Release (myGlContext.operator->());
+ }
+ else
+ {
+ aDefFbo = new OpenGl_FrameBuffer();
+ }
+
+ if (!aDefFbo->InitWithRB (myGlContext, myWidth, myHeight, GL_RGBA8, GL_DEPTH24_STENCIL8))
+ {
+ TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: default FBO creation failed");
+ throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
+ }
+ myGlContext->SetDefaultFrameBuffer (aDefFbo);
+ aDefFbo->BindBuffer (myGlContext);
+ }
+ else if (!myPlatformWindow->IsVirtual())
+ {
+ eglQuerySurface ((EGLDisplay )myGlContext->myDisplay, (EGLSurface )myGlContext->myWindow, EGL_WIDTH, &myWidth);
+ eglQuerySurface ((EGLDisplay )myGlContext->myDisplay, (EGLSurface )myGlContext->myWindow, EGL_HEIGHT, &myHeight);
+ }
#elif defined(_WIN32)
//
#else
glDisable (GL_DITHER);
glDisable (GL_SCISSOR_TEST);
- glViewport (0, 0, myWidth, myHeight);
+ const Standard_Integer aViewport[4] = { 0, 0, myWidth, myHeight };
+ myGlContext->ResizeViewport (aViewport);
#if !defined(GL_ES_VERSION_2_0)
- glDrawBuffer (GL_BACK);
+ myGlContext->SetDrawBuffer (GL_BACK);
if (myGlContext->core11 != NULL)
{
glMatrixMode (GL_MODELVIEW);