Fix CGAL::draw() black rendering on OpenGL < 4.3#9399
Fix CGAL::draw() black rendering on OpenGL < 4.3#9399RajdeepKushwaha5 wants to merge 5 commits intoCGAL:mainfrom
Conversation
The source variables CGAL_CXX_FLAGS_RELEASE, CGAL_CXX_FLAGS_DEBUG, CGAL_MODULE_LINKER_FLAGS(_RELEASE|_DEBUG), CGAL_SHARED_LINKER_FLAGS_RELEASE, CGAL_SHARED_LINKER_FLAGS_DEBUG, CGAL_EXE_LINKER_FLAGS_RELEASE, and CGAL_EXE_LINKER_FLAGS_DEBUG are never set anywhere in the codebase. The uniquely_add_flags() macro is a complete no-op when its source argument is empty (ARGC == 1 skips the body). Removing these 9 dead calls. The 3 retained calls propagate variables that ARE populated: - CGAL_CXX_FLAGS (MSVC, GCC, Intel, SunPro flags) - CGAL_SHARED_LINKER_FLAGS (SunPro linker flags) - CGAL_EXE_LINKER_FLAGS (SunPro linker flags)
…s.cmake" This reverts commit d03c69d.
Fix compatibility shaders and OpenGL version detection that caused CGAL::draw() to render solid black geometry on systems with OpenGL < 4.3. Basic_shaders.h: - VERTEX_SOURCE_COLOR_COMP: change 'varying' to 'attribute' for vertex inputs (a_Pos, a_Normal, a_Color) as required by GLSL 1.10/1.20 - VERTEX_SOURCE_COLOR_COMP: replace undefined 'mv_matrix' reference with 'mat3(u_Mv) * a_Normal' matching the declared uniform - VERTEX_SOURCE_P_L_COMP: change 'varying' to 'attribute' for vertex inputs (a_Pos, a_Color) qglviewer_impl.h: - Initialize is_ogl_4_3 to false in defaultConstructor() to avoid UB - Fix version check: use major < 4 || (major == 4 && minor < 3) instead of major != 4, so OpenGL 4.0-4.2 correctly falls back and 5+ works Basic_viewer.h: - Add std::cerr warning when compatibility shaders are selected
There was a problem hiding this comment.
Pull request overview
This PR addresses incorrect rendering (solid black geometry) in CGAL::draw() on systems that don’t meet the “modern” OpenGL path requirements by fixing the compatibility GLSL shaders and adjusting OpenGL capability detection.
Changes:
- Fix compatibility vertex shader inputs (
attributevsvarying) and replace an undefined normal-transform matrix withmat3(u_Mv). - Initialize
is_ogl_4_3and update OpenGL version gating logic used to choose shader paths. - Add a diagnostic warning when compatibility shaders are selected.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
GraphicsView/include/CGAL/Qt/qglviewer_impl.h |
Initializes is_ogl_4_3 and changes OpenGL version check that drives shader-path selection. |
Basic_viewer/include/CGAL/Qt/Basic_viewer.h |
Emits a warning when the compatibility shader path is used. |
Basic_viewer/include/CGAL/Basic_shaders.h |
Fixes compatibility shader qualifiers and normal transform to avoid black rendering. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| QSurfaceFormat format = context()->format(); | ||
| context()->format().setOption(QSurfaceFormat::DebugContext); | ||
| if ( !context()->isValid() | ||
| || format.majorVersion() != 4 | ||
| || format.majorVersion() < 4 | ||
| || (format.majorVersion() == 4 && format.minorVersion() < 3) | ||
| || QCoreApplication::arguments().contains(QStringLiteral("--old"))) |
There was a problem hiding this comment.
The updated version check makes is_ogl_4_3 false for any desktop OpenGL context < 4.3 (e.g., macOS commonly provides 4.1 core via init_ogl_context), which will route execution to the compatibility shader path. Those compatibility shaders use attribute/varying and gl_FragColor without a #version, which won’t compile in core-profile desktop contexts (e.g., 4.1 core). Consider basing the decision on QSurfaceFormat::renderableType() / profile() (OpenGL ES vs desktop core) and/or GLSL version support, so desktop GL 3.2+ (including 4.1) continues using the modern #version 150 shaders.
| @@ -206,7 +207,8 @@ void CGAL::QGLViewer::initializeGL() { | |||
| QSurfaceFormat format = context()->format(); | |||
| context()->format().setOption(QSurfaceFormat::DebugContext); | |||
There was a problem hiding this comment.
context()->format().setOption(QSurfaceFormat::DebugContext); modifies a temporary QSurfaceFormat (since format() returns by value), so it has no effect. If the intent is to enable a debug context, set the option on a QSurfaceFormat instance and apply it before context creation (e.g., via QSurfaceFormat::setDefaultFormat() or context()->setFormat(...) before create()).
| context()->format().setOption(QSurfaceFormat::DebugContext); | |
| format.setOption(QSurfaceFormat::DebugContext); | |
| context()->setFormat(format); |
| if (!isOpenGL_4_3()) | ||
| { std::cerr<<"CGAL Basic_viewer: OpenGL < 4.3 detected, using compatibility shaders"<<std::endl; } |
There was a problem hiding this comment.
This adds an unconditional std::cerr message whenever compatibility shaders are selected. Since Basic_viewer.h is a public header and compile_shaders() is called during normal initialization, this can introduce noisy stderr output for end users. Consider using CGAL_warning_msg / qWarning() and/or guarding the message behind a verbosity/debug flag (or emitting it only once).
| if (!isOpenGL_4_3()) | |
| { std::cerr<<"CGAL Basic_viewer: OpenGL < 4.3 detected, using compatibility shaders"<<std::endl; } | |
| static bool s_ogl_warning_emitted = false; | |
| if (!isOpenGL_4_3() && !s_ogl_warning_emitted) | |
| { | |
| CGAL_warning_msg("CGAL Basic_viewer: OpenGL < 4.3 detected, using compatibility shaders"); | |
| s_ogl_warning_emitted = true; | |
| } |
- Version check: revert to majorVersion() < 4 instead of checking for specifically 4.3. On macOS, init_ogl_context() caps to 4.1 core profile; compat shaders (attribute/varying) would fail in core contexts. The #version 150 modern shaders work fine on any 4.x. This also correctly handles future OpenGL 5+. - Warning: use static guard so the message emits only once, even if compile_shaders() is called multiple times.
…ead g_Color, add OGL<4.3 edge fallback - Add bindAttributeLocation(a_Pos, 0) and bindAttributeLocation(a_Color, 1) before link() for rendering_program_p_l, rendering_program_line, and rendering_program_cylinder to guarantee consistent attribute locations across all OpenGL drivers. - Remove dead 'in mediump vec4 g_Color[]' from GEOMETRY_SOURCE_LINE_WIDTH geometry shader (no matching vertex shader output). - Add proper edge rendering fallback via rendering_program_p_l for OpenGL < 4.3 where the geometry shader is unavailable. - Re-add minor version check for OpenGL 4.0-4.2 in qglviewer_impl.h.
|
Hi Sir, @afabri Thanks for reporting this, and for the screenshot — very helpful. I looked into this and the missing edges you're seeing is actually a pre-existing bug on MAIN (clean
BEFORE (original PR commits only):
AFTER (PR + edge fixes):
As you can see, all three look identical on my end — edges show up fine. So I can't visually reproduce the missing edges on my hardware, but I traced the root cause in code:
The latest push adds fixes for this:
Could you give it another try with the latest push and let me know if edges show up now? |
|
You are right that it was a pre-existing bug. And you fixed it. Great. |
Thanks for confirming! Glad it's working now. |




Summary of Changes
Fixes
CGAL::draw()rendering solid black geometry on systems with OpenGL < 4.3 by correcting the compatibility GLSL shaders and improving OpenGL version detection.Compatibility shader fixes (
Basic_shaders.h):VERTEX_SOURCE_COLOR_COMP: Changedvaryingtoattributefor vertex inputs (a_Pos,a_Normal,a_Color). In GLSL 1.10/1.20, vertex shader inputs must use theattributequalifier —varyingis only for outputs passed to the fragment shader.VERTEX_SOURCE_COLOR_COMP: Replaced the undefinedmv_matrixvariable withmat3(u_Mv) * a_Normal, using the already-declaredu_Mvuniform (matching the OpenGL 4.3 shader path).VERTEX_SOURCE_P_L_COMP: Changedvaryingtoattributefor vertex inputs (a_Pos,a_Color), same fix as above.OpenGL version detection fixes (
qglviewer_impl.h):defaultConstructor(): Initializeis_ogl_4_3tofalse. Previously uninitialized, leading to undefined behavior.initializeGL(): Fixed version check fromformat.majorVersion() != 4to(format.majorVersion() < 4 || (format.majorVersion() == 4 && format.minorVersion() < 3)). The old check incorrectly classified OpenGL 4.0–4.2 as 4.3-capable and would have broken on future OpenGL 5+.Diagnostic warning (
Basic_viewer.h):std::cerrwarning incompile_shaders()when compatibility shaders are selected, to aid debugging on OpenGL < 4.3 systems.Release Management