Force Qt 5.4 to use ANGLE OpenGL ES 2 implementation
-
Hi all,
We have a windows Qt desktop app that links to a rendering library based on OpenGL ES 2.0.
We want to assure that the app will run on as much as devices as possible, so we think that using ANGLE is a good idea.My question is: is there anything we can do to force our Qt 5.4 app to use ANGLE instead of the fallback sequence [OpenGL > 2.0 Driver] -> [ANGLE] -> [Software rasterizer] described "here":http://blog.qt.io/blog/2014/11/27/qt-weekly-21-dynamic-opengl-implementation-loading-in-qt-5-4/?
We have seleted the Qt-ANGLE Kit from QtCreator to build our app. It compiles, links, and deploys fine. I want to test the initialization sequence of the render library when ANGLE is used (we have to check the presence of some GL ES Extensions, and those have to be checked with EGL), but my dev machine has an OpenGL 4.4 capable Nvidia Graphics card, and apparently the fallback sequence is being launched, and Qt selects my OpenGL driver by default, instead of ANGLE.
I have explicitly linked to QtANGLE's implementation with -llibGLESv2 -llibEGL, and used the QtANGLE's OpenGL ES headers.
Here the startup trace with GL debugging enabled (env variable QT_LOGGING_RULES = qt.qpa.gl=true):
@qt.qpa.gl: OpenGL 2.0 entry points available
qt.qpa.gl: Qt: Using WGL and OpenGL from "opengl32.dll"
qt.qpa.gl: QOpenGLStaticContext::create OpenGL: "NVIDIA Corporation","GeForce GTX 570/PCIe/SSE2" default ContextFormat: v4.5 profile: 0 options: QFlags(0x4
),SampleBuffers, Extension-API present
Extensions: 309
qt.qpa.gl: QWindowsIntegration::createPlatformOpenGLContext QSurfaceFormat(version 2.0, options QFlags(), depthBufferSize 24, redBufferSize -1, greenBuffer
Size -1, blueBufferSize -1, alphaBufferSize -1, stencilBufferSize 8, samples -1, swapBehavior 2, swapInterval 1, profile 0)
qt.qpa.gl: "ARB::choosePixelFormat Attributes: 0x2003 , 0x2027 , 0x2010 , 0x1 , 0x2001 , 0x1 , 0x2014 , 0x18 , 0x2011 , 0x1 , 0x2022 , 0x18 , 0x2013 , 0x
202b , 0x201b , 0x8 , 0x2023 , 0x8 , 0x2041 , 0x0 ,
obtained px # 10 of 2
PIXELFORMATDESCRIPTOR dwFlags=0x8225 PFD_DRAW_TO_WINDOW PFD_SUPPORT_OPENGL PFD_SUPPORT_COMPOSITION PFD_DOUBLEBUFFER iPixelType=0 cColorBits=32 cRedBit
s=8 cRedShift=16 cGreenBits=8 cGreenShift=8 cBlueBits=8 cBlueShift=0 cDepthBits=24 cStencilBits=8 cAuxBuffers=4 iLayerType=0 cAlphaBits=8 cAlphaShift=24 cA
ccumBits=64 cAccumRedBits=16 cAccumGreenBits=16 cAccumBlueBits=16 cAccumAlphaBits=16"
qt.qpa.gl: ARB::createContext Creating context version 2 . 0 3 attributes
qt.qpa.gl: QWindowsGLContext::QWindowsGLContext 0x1179548 ARB requested: QSurfaceFormat(version 2.0, options QFlags(), depthBufferSize 24, redBufferSize
-1, greenBufferSize -1, blueBufferSize -1, alphaBufferSize -1, stencilBufferSize 8, samples -1, swapBehavior 2, swapInterval 1, profile 0)
obtained # 10 ARB QSurfaceFormat(version 4.5, options QFlags(0x4), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBuffe
rSize 8, stencilBufferSize 8, samples 0, swapBehavior 2, swapInterval 1, profile 2)
PIXELFORMATDESCRIPTOR dwFlags=0x8225 PFD_DRAW_TO_WINDOW PFD_SUPPORT_OPENGL PFD_SUPPORT_COMPOSITION PFD_DOUBLEBUFFER iPixelType=0 cColorBits=32 cRedBit
s=8 cRedShift=16 cGreenBits=8 cGreenShift=8 cBlueBits=8 cBlueShift=0 cDepthBits=24 cStencilBits=8 cAuxBuffers=4 iLayerType=0 cAlphaBits=8 cAlphaShift=24 cA
ccumBits=64 cAccumRedBits=16 cAccumGreenBits=16 cAccumBlueBits=16 cAccumAlphaBits=16 swap interval: 1
default: ContextFormat: v4.5 profile: 0 options: QFlags(0x4)
HGLRC=0x30000@So it seems that OpenGL ES 2.0 and EGL are not being used. But, if we put these lines in the very beginning of the main function of the app:
@ QSurfaceFormat format;
format.setRenderableType(QSurfaceFormat::OpenGLES);
QSurfaceFormat::setDefaultFormat(format);@Then we have the following output:
@qt.qpa.gl: OpenGL 2.0 entry points available
qt.qpa.gl: Qt: Using WGL and OpenGL from "opengl32.dll"
qt.qpa.gl: QOpenGLStaticContext::create OpenGL: "NVIDIA Corporation","GeForce GTX 570/PCIe/SSE2" default ContextFormat: v4.5 profile: 0 options: QFlags(0x4
),SampleBuffers, Extension-API present
Extensions: 309
qt.qpa.gl: QWindowsIntegration::createPlatformOpenGLContext QSurfaceFormat(version 2.0, options QFlags(), depthBufferSize 24, redBufferSize -1, greenBuffer
Size -1, blueBufferSize -1, alphaBufferSize -1, stencilBufferSize 8, samples -1, swapBehavior 2, swapInterval 1, profile 0)
Failed to create EGL context for format QSurfaceFormat(version 2.0, options QFlags(), depthBufferSize 24, redBufferSize -1, greenBufferSize -1, blueBufferS
ize -1, alphaBufferSize -1, stencilBufferSize 8, samples -1, swapBehavior 2, swapInterval 1, profile 0) .
This is most likely caused by not having the necessary graphics drivers installed.Install a driver providing OpenGL 2.0 or higher, or, if this is not possible, make sure the ANGLE Open GL ES 2.0 emulation libraries (libEGL.dll, libGLESv2
.dll and d3dcompiler_*.dll) are available in the application executable's directory or in a location listed in PATH.@In this case, in spite of saying that WGL and OpenGL from "opengl32.dll" are being used by Qt, it tries to create an EGL context, and it fails. libEGL, libGLES and d3d_compiler dlls are in the same directory as the executable.
Any ideas on how can we force GLES 2 ANGLE implementation?
Thanks,
Robert. -
Hi,
The technique is described "here":http://doc.qt.io/qt-5/windows-requirements.html#graphics-drivers
Happy coding !
-
Hi,
[quote author="SGaist" date="1423949153"]Hi,
The technique is described "here":http://doc.qt.io/qt-5/windows-requirements.html#graphics-drivers
Happy coding ![/quote]
Setting QCoreApplication::setAttribute(Qt::AA_UseOpenGLES) actually worked, thanks!
Here the debug message:@qt.qpa.gl: Qt: Using EGL from libEGLd.dll
qt.qpa.gl: Qt: Using OpenGL ES 2.0 from libGLESv2d.dll
qt.qpa.gl: QWindowsEGLStaticContext::create Created EGL display 0x4dc49c8 v 1 . 4
qt.qpa.gl: QWindowsIntegration::createPlatformOpenGLContext QSurfaceFormat(version 2.0, options QFlags(), depthBufferSize 24, redBufferSize -1, greenBufferSize -1, blueBufferSize -1, alphaBufferSize -1, stencilBufferSize 8, samples -1, swapBehavior 2, swapInterval 1, profile 0)@Now I'm having another error. We are using Glew-1.12.0 in order to load the non-Core OpenGL 1.1 functions on windows. In order to initialize Glew-1.12.0, glewInit() must be called first. it returns GLEW_OK when the initialization was successfull. It does work with Desktop OpenGL , but with GLES it returns "Missing GL Version".
Besides, functions like glGetIntegerv (GL_MAX_TEXTURE_SIZE, &maxTextureSize), are returning garbage values. It's like the OpenGL ES context was not created properly, so the the OpenGL commands don't work.
I have called @QOpenGLContext::currentContext()->makeCurrent(_appWindow);@ before our rendering library initialization, but the result is the same.
Any ideas?
-
AFAIK, rather that GLEW, you should use something like QOpenGLFunctions and it's derivative