magnum
magnum copied to clipboard
Segmentation fault with nullptr instruction in AbstractShaderProgram at Cross-Compile
With magnum and corrade 2020.06
Greetings,
when cross-compiling magnum/corrade for GLES and Aarch64, the program suddenly runs into a nullptr instruction:
#0 0x0000000000000000 in ?? ()
#1 0x0000007ff7c04efc in Magnum::GL::AbstractShaderProgram::setUniform (this=this@entry=0x7fffff87d8, location=2, values=...) at ext-corrade-dev/1/workspace/usr/include/Corrade/Containers/Pointer.h:217
#2 0x0000007ff7ae9630 in Magnum::GL::AbstractShaderProgram::setUniform (value=
Flat.cpp 136: #ifndef MAGNUM_TARGET_GLES if(!GL::Context::current().isExtensionSupportedGL::Extensions::ARB::shading_language_420pack(version)) #endif { if(flags & Flag::Textured) setUniform(uniformLocation("textureData"), TextureUnit); <--- }
AbstractShaderProgram.cpp:640: void AbstractShaderProgram::setUniform(const Int location, const Containers::ArrayView<const Int> values) { (this->*Context::current().state().shaderProgram->uniform1ivImplementation)(location, values.size(), values); }
The error is 100% reproducible. Is it possible that uniform1ivImplementation is corrupted at some point?
Regards
Hello,
the backtrace is a bit confusing, it shows setUniform()
being located in Pointer.h
, but I assume that's due to some optimizations / inlining happening (-fno-omit-stack-pointer
helps with that I think).
In general, such nasty null pointer access happens only when attempting to access GL functionality that isn't actually present in the driver. In this case it might be that GL_EXT_separate_shader_objects
is advertised by the driver but the actual functionality is not, so eglGetProcAddress("glProgramUniform1ivEXT")
returns nullptr
, which is then crashed on here.
Can you post the engine startup log it prints to the console? It should show the GL version and driver it detected, and a list of opt-in extensions it found and uses. Based on that I should be better able to figure out what's going on and how to prevent this from happening.
Another possibility when this could happen would be with some multithreading going on and a GL context attempted to be used on a thread it wasn't created on, or with some particularly interesting shared + static library setup, but I don't think either of that is the case here.
Thank you!
(By the way, the 2020.06 tag is rather old -- unfortunately I didn't have the capacity to bring the roadmap to a releaseable state since then so there's no newer tagged version, but the master
branch is kept always stable and can be relied on. So, feel free to update. I don't think that alone would fix the problem you're facing -- I don't remember encountering any library bug related to this problem -- but the library evolved and improved quite a bit since.)
Ok, some more info:
It's a nullptr access to an uninitialized function pointer to an OpenGL function who as I can tell should be initialized here:
https://github.com/mosra/magnum/blob/6394c85c06a5eb67713763c7e471e0fef3160c41/src/MagnumExternal/OpenGL/GLES3/flextGLPlatform.cpp
The nullptr are for all the core functions. For example
flextGL.ProgramUniform1ui = reinterpret_cast<void(APIENTRY*)(GLuint, GLint, GLuint)>(loader.load("glProgramUniform1ui"));
yields a nullptr on my platform. As far as I can tell OpenGLFunctionLoader uses eglGetProcAddress
https://github.com/mosra/magnum/blob/6394c85c06a5eb67713763c7e471e0fef3160c41/src/Magnum/Platform/Implementation/OpenGLFunctionLoader.cpp#L67
This function returns nullptr for core functions on my platform.
Just to clarify -- the function will return nullptr
for functions from extensions that are not supported by the driver. So if you have for example just a barebones ES 3.0 driver, almost all of these will be null. That's fine. The set of functions that should be available in GLES3 always is linked statically, and the engine "just" needs to ensure the null ones are not used by anything afterwards, which it usually does.
What I'm trying to get at is what's actually advertised as supported by the driver, which is shown in the startup log right after you run the application and before it crashes. Can you get me that? It'd be something like this and the list of extensions and workarounds is what I need:
Renderer: NVIDIA GeForce RTX 3050 Laptop GPU/PCIe/SSE2 by NVIDIA Corporation
OpenGL version: OpenGL ES 3.2 NVIDIA 535.113.01
Using optional features:
GL_EXT_texture_filter_anisotropic
GL_EXT_robustness
...
Thank you!
I have to come back for the log tomorrow when I'm back at work. But some more info:
flextGL.ProgramUniform1ui = reinterpret_cast<void(APIENTRY*)(GLuint, GLint, GLuint)>(loader.load("glProgramUniform1ui"));
yields nullptr but
flextGL.ProgramUniform1uiEXT = reinterpret_cast<void(APIENTRY*)(GLuint, GLint, GLuint)>(loader.load("glProgramUniform1uiEXT"));
returns a fully working pointer that, according to gdb, points to the very available glProgramUniform1ui .
The system with this driver supports at least GLES 3.1, I know that from other applications.
As far as I know in EGL 1.4 eglGetProcAddress does not guarantee pointers for core functions. https://registry.khronos.org/EGL/extensions/KHR/EGL_KHR_get_all_proc_addresses.txt "eglGetProcAddress is currently defined to not support the querying of non-extension EGL or client API functions."
Awesome, that's good to know, so there's at least some possible path forward.
As far as I know in EGL 1.4 eglGetProcAddress does not guarantee pointers for core functions.
Oh, that's not great. I hope I won't need to add a workaround with dlsym()
or something :/ So far the eglGetProcAddress()
approach worked for all drivers I had the chance to test in the past decade+. Though I have to admit it wasn't many of the interesting ones.
Looking forward to the log.
Do I need to set special environment variables for the log or so?
My short-term solution is to try load the ext version of a function if the core version is not returned. Don't know if this can still yield nullptr access for some stuff, I'm not seeing check in the accessing functions.
Edit: In EGL 1.5 pointers for core should be guaranteed.
Do I need to set special environment variables for the log or so?
It's printed by default unless suppressed by some log redirection, so assuming a Linux box, it should be there always. On Android it's thrown into logcat
, on Windows you'd have to build a console app to have the standard output visible.
My short-term solution is to try load the ext version of a function if the core version is not returned.
A quick patch to achieve what you need would be this:
diff --git a/src/Magnum/GL/Implementation/ShaderProgramState.cpp b/src/Magnum/GL/Implementation/ShaderProgramState.cpp
index 8a87a8b59..d49b45e95 100644
--- a/src/Magnum/GL/Implementation/ShaderProgramState.cpp
+++ b/src/Magnum/GL/Implementation/ShaderProgramState.cpp
@@ -93,7 +93,7 @@ ShaderProgramState::ShaderProgramState(Context& context, Containers::StaticArray
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::ARB::separate_shader_objects>())
#else
- if(context.isVersionSupported(Version::GLES310))
+ if(false && context.isVersionSupported(Version::GLES310))
#endif
{
#ifndef MAGNUM_TARGET_GLES
If we don't find any better solution, then I turn this into a driver-specific workaround that gets enabled automatically. But I hope we find something better :)
I'm not seeing check in the accessing functions.
There's none for perf reasons. For core functionality (like shaders, buffers, textures) it internally picks a variant that should be there, and for APIs that aren't guaranteed to be present (say, compute shaders), it's up to the application to do an extension / version check upfront.
Hmm I cannot find your logging. Can you tell me which function call in magnum supposedly triggers it? I copied the weston output if that helps:
23:00:00.478 [Warn] [user] weston@tty1: [23:00:00.474] EGL version: 1.4 23:00:00.478 [Warn] [user] weston@tty1: [23:00:00.474] EGL vendor: Imagination Technologies 23:00:00.478 [Warn] [user] weston@tty1: [23:00:00.474] EGL client APIs: OpenGL_ES 23:00:00.478 [Warn] [user] weston@tty1: [23:00:00.474] EGL extensions: EGL_KHR_image EGL_KHR_image_base 23:00:00.478 [Warn] [user] weston@tty1: EGL_KHR_gl_texture_2D_image EGL_KHR_gl_texture_cubemap_image 23:00:00.478 [Warn] [user] weston@tty1: EGL_KHR_gl_texture_3D_image EGL_KHR_gl_renderbuffer_image 23:00:00.478 [Warn] [user] weston@tty1: EGL_IMG_cl_image EGL_KHR_fence_sync EGL_KHR_wait_sync 23:00:00.478 [Warn] [user] weston@tty1: EGL_EXT_create_context_robustness EGL_IMG_image_plane_attribs 23:00:00.478 [Warn] [user] weston@tty1: EGL_EXT_swap_buffers_with_damage 23:00:00.478 [Warn] [user] weston@tty1: EGL_KHR_swap_buffers_with_damage EGL_KHR_partial_update 23:00:00.478 [Warn] [user] weston@tty1: EGL_EXT_buffer_age EGL_EXT_image_dma_buf_import 23:00:00.478 [Warn] [user] weston@tty1: EGL_EXT_image_dma_buf_import_modifiers EGL_EXT_yuv_surface 23:00:00.478 [Warn] [user] weston@tty1: EGL_IMG_context_priority EGL_KHR_create_context 23:00:00.478 [Warn] [user] weston@tty1: EGL_KHR_surfaceless_context EGL_KHR_no_config_context 23:00:00.478 [Warn] [user] weston@tty1: EGL_WL_bind_wayland_display 23:00:00.479 [Warn] [user] weston@tty1: [23:00:00.474] warning: Disabling render GPU timeline and explicit synchronization due to missing EGL_ANDROID_native_fence_sync extension 23:00:00.479 [Warn] [user] weston@tty1: [23:00:00.474] Retrieving EGL client extension string failed. 23:00:00.479 [Warn] [user] weston@tty1: [23:00:00.475] EGL_KHR_surfaceless_context available 23:00:00.508 [Warn] [user] weston@tty1: [23:00:00.503] GL version: OpenGL ES 3.2 23:00:00.508 [Warn] [user] weston@tty1: [23:00:00.504] GLSL version: OpenGL ES GLSL ES 3.20 23:00:00.508 [Warn] [user] weston@tty1: [23:00:00.504] GL vendor: Imagination Technologies 23:00:00.508 [Warn] [user] weston@tty1: [23:00:00.504] GL renderer: PowerVR Rogue GX6650 23:00:00.508 [Warn] [user] weston@tty1: [23:00:00.504] GL extensions: GL_ANDROID_extension_pack_es31a 23:00:00.508 [Warn] [user] weston@tty1: GL_APPLE_texture_format_BGRA8888 GL_EXT_blend_minmax 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_buffer_storage GL_EXT_clear_texture GL_EXT_clip_control 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_color_buffer_float GL_EXT_color_buffer_half_float 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_compressed_ETC1_RGB8_sub_texture 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_conservative_depth GL_EXT_copy_image 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_discard_framebuffer GL_EXT_draw_buffers 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_draw_buffers_indexed GL_EXT_draw_elements_base_vertex 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_EGL_image_array GL_EXT_float_blend 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_geometry_point_size GL_EXT_geometry_shader 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_gpu_shader5 GL_EXT_memory_object GL_EXT_memory_object_fd 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_multi_draw_arrays GL_EXT_multisampled_render_to_texture 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_multisampled_render_to_texture2 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_occlusion_query_boolean GL_EXT_polygon_offset_clamp 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_primitive_bounding_box GL_EXT_pvrtc_sRGB 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_read_format_bgra GL_EXT_robustness 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_separate_shader_objects GL_EXT_shader_framebuffer_fetch 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_shader_group_vote GL_EXT_shader_implicit_conversions 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_shader_io_blocks 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_shader_non_constant_global_initializers 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_shader_pixel_local_storage 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_shader_pixel_local_storage2 GL_EXT_shader_texture_lod 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_shadow_samplers GL_EXT_sparse_texture 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_sRGB_write_control GL_EXT_tessellation_point_size 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_tessellation_shader GL_EXT_texture_border_clamp 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_texture_buffer GL_EXT_texture_cube_map_array 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_texture_filter_anisotropic 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_texture_format_BGRA8888 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_texture_format_sRGB_override GL_EXT_texture_rg 23:00:00.509 [Warn] [user] weston@tty1: GL_EXT_texture_shadow_lod GL_EXT_texture_sRGB_decode 23:00:00.509 [Warn] [user] weston@tty1: GL_EXT_texture_sRGB_R8 GL_EXT_texture_sRGB_RG8 23:00:00.509 [Warn] [user] weston@tty1: GL_EXT_YUV_target GL_IMG_framebuffer_downsample 23:00:00.509 [Warn] [user] weston@tty1: GL_IMG_multisampled_render_to_texture GL_IMG_program_binary 23:00:00.509 [Warn] [user] weston@tty1: GL_IMG_read_format GL_IMG_shader_binary 23:00:00.509 [Warn] [user] weston@tty1: GL_IMG_texture_compression_pvrtc 23:00:00.509 [Warn] [user] weston@tty1: GL_IMG_texture_compression_pvrtc2 GL_IMG_texture_filter_cubic 23:00:00.509 [Warn] [user] weston@tty1: GL_IMG_texture_format_BGRA8888 GL_IMG_texture_npot 23:00:00.509 [Warn] [user] weston@tty1: GL_KHR_blend_equation_advanced 23:00:00.509 [Warn] [user] weston@tty1: GL_KHR_blend_equation_advanced_coherent GL_KHR_debug 23:00:00.509 [Warn] [user] weston@tty1: GL_KHR_robustness GL_KHR_texture_compression_astc_ldr 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_compressed_ETC1_RGB8_texture GL_OES_depth24 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_depth_texture GL_OES_draw_buffers_indexed 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_draw_elements_base_vertex GL_OES_EGL_image 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_EGL_image_external GL_OES_EGL_image_external_essl3 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_EGL_sync GL_OES_element_index_uint 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_fragment_precision_high GL_OES_geometry_point_size 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_geometry_shader GL_OES_get_program_binary 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_gpu_shader5 GL_OES_mapbuffer GL_OES_packed_depth_stencil 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_required_internalformat GL_OES_rgb8_rgba8 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_sample_shading GL_OES_sample_variables 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_shader_image_atomic GL_OES_shader_io_blocks 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_shader_multisample_interpolation 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_standard_derivatives GL_OES_surfaceless_context 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_tessellation_point_size GL_OES_tessellation_shader 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_texture_border_clamp GL_OES_texture_buffer 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_texture_cube_map_array GL_OES_texture_float 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_texture_half_float GL_OES_texture_npot 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_texture_stencil8 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_texture_storage_multisample_2d_array 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_vertex_array_object GL_OES_vertex_half_float 23:00:00.509 [Warn] [user] weston@tty1: GL_OVR_multiview GL_OVR_multiview2 23:00:00.509 [Warn] [user] weston@tty1: GL_OVR_multiview_multisampled_render_to_texture
It's printed by GL::Context::tryCreate()
, which is usually done during Platform::Application
construction, or alternatively if you use a custom windowing toolkit, then it's during Platform::GLContext
construction.
Or just show me how you initialize the application, I'll point you to where it should get printed. Alternatively you could build the magnum-gl-info
utility (MAGNUM_WITH_GL_INFO
in CMake) and post what it prints. But if everything is set up as expected, you should get the startup log in your application as well.
Platform::GLContext ctx{argc, argv};
Should this be enough to trigger the code?
Yes.
Do you get anything printed if you #include <Corrade/Utility/Debug.h>
and do Debug{} << "hello?";
? If you do, then you should get the output from the above as well. There's also an env var, MAGNUM_LOG=quiet
, that would suppress the output, but I don't suppose you have it set by accident.
Ok, so I added the Platform::GLContext ctx{argc, argv}; directly after the eglMakeCurrent of the OpenGL context I create myself. No output.
The I added the header and Debug{} << "hello?"; no output
Do I need to set up something else? Is it generally possible to combine Magnum with an existing EGContext?
Only magnum-gl-info worked:
+---------------------------------------------------------+
| Information about Magnum engine OpenGL capabilities |
+---------------------------------------------------------+
Used application: Platform::WindowlessEglApplication
Compilation flags:
CORRADE_BUILD_DEPRECATED
CORRADE_BUILD_MULTITHREADED
CORRADE_TARGET_UNIX
CORRADE_TARGET_ARM
CORRADE_TARGET_GCC
CORRADE_TARGET_LIBSTDCXX
MAGNUM_BUILD_DEPRECATED
MAGNUM_TARGET_GLES
Renderer: PowerVR Rogue GX6650 by Imagination Technologies
OpenGL version: OpenGL ES 3.2 build 1.15@6052913
Using optional features:
GL_EXT_multi_draw_arrays
GL_EXT_robustness
GL_EXT_texture_filter_anisotropic
Context flags: GL::Context::Flags{}
Detected driver: GL::Context::DetectedDrivers{}
Supported GLSL versions:
OpenGL ES GLSL ES 3.20 build 1.15@6052913
Vendor extension support:
GL_ANDROID_extension_pack_es31a SUPPORTED
GL_ANGLE_texture_compression_dxt1 -
GL_ANGLE_texture_compression_dxt3 -
GL_ANGLE_texture_compression_dxt5 -
GL_APPLE_clip_distance -
GL_APPLE_texture_format_BGRA8888 SUPPORTED
GL_ARM_shader_framebuffer_fetch -
GL_ARM_shader_framebuffer_fetch_depth_stencil -
GL_EXT_clip_cull_distance -
GL_EXT_debug_label -
GL_EXT_debug_marker -
GL_EXT_disjoint_timer_query -
GL_EXT_multi_draw_arrays SUPPORTED
GL_EXT_multisampled_render_to_texture SUPPORTED
GL_EXT_polygon_offset_clamp SUPPORTED
GL_EXT_pvrtc_sRGB SUPPORTED
GL_EXT_read_format_bgra SUPPORTED
GL_EXT_robustness SUPPORTED
GL_EXT_sRGB_write_control SUPPORTED
GL_EXT_separate_shader_objects SUPPORTED
GL_EXT_shader_framebuffer_fetch SUPPORTED
GL_EXT_shader_integer_mix -
GL_EXT_texture_compression_bptc -
GL_EXT_texture_compression_dxt1 -
GL_EXT_texture_compression_rgtc -
GL_EXT_texture_compression_s3tc -
GL_EXT_texture_compression_s3tc_srgb -
GL_EXT_texture_filter_anisotropic SUPPORTED
GL_EXT_texture_format_BGRA8888 SUPPORTED
GL_EXT_texture_sRGB_R8 SUPPORTED
GL_EXT_texture_sRGB_RG8 SUPPORTED
GL_EXT_texture_sRGB_decode SUPPORTED
GL_IMG_texture_compression_pvrtc SUPPORTED
GL_KHR_blend_equation_advanced_coherent SUPPORTED
GL_KHR_context_flush_control -
GL_KHR_no_error -
GL_KHR_texture_compression_astc_hdr -
GL_KHR_texture_compression_astc_sliced_3d -
GL_NV_fragment_shader_barycentric -
GL_NV_polygon_mode -
GL_NV_read_buffer_front -
GL_NV_read_depth -
GL_NV_read_depth_stencil -
GL_NV_read_stencil -
GL_NV_sample_locations -
GL_NV_shader_noperspective_interpolation -
GL_NV_texture_border_clamp -
GL_OES_depth32 -
GL_OES_mapbuffer SUPPORTED
GL_OES_stencil1 -
GL_OES_stencil4 -
GL_OES_texture_compression_astc -
GL_OES_texture_float_linear -
GL_OVR_multiview SUPPORTED
GL_OVR_multiview2 SUPPORTED
Thank you. The magnum-gl-info
output alone will be enough for me to make a driver-specific workaround, but I'd like to have the problem with no output solved as well :)
I have no idea what's going on. This is a Linux system, not Android or something specific, right? Can you try to reduce your application to a small self-contained repro case that compiles & runs (and crashes) on your end, and prints no output? I suspect there's something else going on that flew under the radar for me so far, and I can't really help if I can't see any code.
Does this print to stdout or stderr?
Standard output, std::cout
basically. Error{} << "foo";
will print to standard error / std::cerr
.
Just for check:
Do you see a problem with any of these cmake configure parameters?
-DWITH_GL=1 -DTARGET_GLES=ON -DTARGET_GLES2=OFF -DTARGET_GLES3=ON -DWITH_GLXCONTEXT=OFF -DWITH_EGLCONTEXT=ON -DMAGNUM_WITH_GLM=ON -DWITH_WINDOWLESSGLXAPPLICATION=OFF -DWITH_WINDOWLESSEGLXAPPLICATION=OFF -DWITH_ANYIMAGEIMPORTER=ON -DWITH_GL_INFO=ON
Everything looks fine. Can you show me some minimal code that reproduces the problem? I still know only very little about the setup you have.
Working on it. Meanwhile, another problem has arised:
It seems that some of the GL related flags like WITH_GL, TARGET_GLES, TARGET_GLES3 or WITH_EGLCONTEXT cause header conflicts with Qt6:
/usr/include/x86_64-linux-gnu/qt6/QtGui/qopenglext.h:12411:61: error: ‘GLdouble’ does not name a type; did you mean ‘double’?
12411 | typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation);
| ^~~~~~~~
| double
/usr/include/x86_64-linux-gnu/qt6/QtGui/qopenglext.h:12612:25: error: typedef ‘PFNGLGLOBALALPHAFACTORBSUNPROC’ is initialized (use ‘decltype’ instead)
12612 | typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/x86_64-linux-gnu/qt6/QtGui/qopenglext.h:12612:58: error: ‘GLbyte’ was not declared in this scope; did you mean ‘GLubyte’?
12612 | typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor);
| ^~~~~~
| GLubyte
/usr/include/x86_64-linux-gnu/qt6/QtGui/qopenglext.h:12613:25: error: typedef ‘PFNGLGLOBALALPHAFACTORSSUNPROC’ is initialized (use ‘decltype’ instead)
12613 | typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/x86_64-linux-gnu/qt6/QtGui/qopenglext.h:12613:58: error: ‘GLshort’ was not declared in this scope; did you mean ‘ushort’?
12613 | typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor);
| ^~~~~~~
Is there something special one has to do to either Magnum or Qt so the two work together?
Not sure about Qt 6 yet, but a setup that worked for Qt 5 is here -- one has to ensure a certain order of includes, and convince Qt to use external GL definitions: https://github.com/mosra/magnum-bootstrap/blob/ea8e1b0b449c3e67dee337e46d71c1735a4b7f56/src/MyApplication.cpp#L1-L23
This is the current setup. Still fails with undefined symbol in the include hierarchy of #include <QtGui/qopenglfunctions.h>
#include <Corrade/PluginManager/Manager.h>
#include <Magnum/GL/Framebuffer.h>
#include <Magnum/GL/Mesh.h>
#include <Magnum/GL/Renderer.h>
#include <Magnum/Magnum.h>
#include <Magnum/Math/Color.h>
#include <Magnum/Math/Matrix4.h>
#include <Magnum/Math/Quaternion.h>
#include <Magnum/MeshTools/Compile.h>
#include <Magnum/Platform/GLContext.h>
#include <Magnum/Primitives/Cube.h>
#include <Magnum/Shaders/Flat.h>
#include <Magnum/Shaders/Phong.h>
#include <Magnum/Trade/AbstractImporter.h>
#include <Magnum/Trade/MeshData.h>
typedef GLfloat GLclampf;
#undef __glew_h__
#undef __GLEW_H__
#include <QtGui/qopenglfunctions.h>
#define QOPENGLEXTRAFUNCTIONS_H
#include <QtGui/qopenglextrafunctions.h>
Alright, I think I know what's going on -- Qt's GL headers are the big, desktop version, while Magnum built for GLES uses the ES headers. Not really sure if anything about this can be done on Qt's side (if it can be persuaded to expose the GLES API set instead) but I managed to fix the build by adding
#define __glext_h_
typedef double GLdouble;
at the top. The #define __glext_h_
is present in GL headers of the desktop build of Magnum, but on ES the extension header uses #define __gl2ext_h_
/ #define __gl2ext_h_
because that's what <GLES3/gl3ext.h>
etc uses.
(The bootstrap project is updated with this info as of https://github.com/mosra/magnum-bootstrap/commit/195e71324bb70c521f61b5a0891647e00bf7dc56.)