Skip to content

Conversation

GereonV
Copy link
Contributor

@GereonV GereonV commented Apr 14, 2023

ImGui_ImplOpenGL3_RenderDrawData() (in backends/imgui_impl_opengl3.cpp) incorrectly restores GL_POLYGON_MODE after rendering. This PR fixes that.
Relevant glGet* before setting up and rendering:

GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);

@GereonV
Copy link
Contributor Author

GereonV commented Apr 15, 2023

Update

Actually, GL_FRONT and GL_BACK have been deprecated in OpenGL3.2 core. OpenGL ES never had it. GL_POLYGON_MODE as a parameter to glGetIntegerv isn't documented anymore but hasn't been deprecated in the specification. In conclusion, the original was mostly correct and has been restored. However, a version/profile check was added, that restores the separate drawing modes when they are supported.

@GereonV GereonV closed this Apr 15, 2023
@GereonV GereonV reopened this Apr 15, 2023
@GereonV
Copy link
Contributor Author

GereonV commented Apr 15, 2023

GL_CONTEXT_PROFILE_MASK and GL_CONTEXT_COMPATIBILITY_PROFILE_BIT are poorly documented. These constants first appeared in the Specification of OpenGL 3.2 and have remained unchanged since.
(checking for macro-versions of constants is ok since IMGUI_IMPL_HAS_POLYGON_MODE is defined in terms of GL_POLYGON_MODE as well)

@ocornut
Copy link
Owner

ocornut commented Apr 18, 2023

What a mess :(
Thanks for investigating this.

On Desktop targets all the defines would be automatically existing with our loader (which needs regeneration, see https://github.com/dearimgui/gl3w_stripped)

I am thinking of turning this code into:

ImGui_ImplOpenGL3_Data::

GLint           GlProfileMask;

(Note this is zero-initialized)

ImGui_ImplOpenGL3_Init():

#if !defined(IMGUI_IMPL_OPENGL_ES2)
...
#if defined(GL_CONTEXT_PROFILE_MASK)
    glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &bd->GlProfileMask);
#endif
...
#endif

ImGui_ImplOpenGL3_RenderDrawData():

#ifdef IMGUI_IMPL_HAS_POLYGON_MODE
    // Desktop OpenGL 3.0 and OpenGL 3.1 had separate polygon draw modes for front-facing and back-facing faces of polygons
    if ((bd->GlVersion <= 310) || (bd->GlProfileMask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT))
    {
        glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]);
        glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]);
    }
    else
    {
        glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]);
    }
#endif // IMGUI_IMPL_HAS_POLYGON_MODE

Does it seem equally accurate to you?

EDIT sorry mistyped && instead of || in the version & profile mask check. It should be || afaik.

@ocornut
Copy link
Owner

ocornut commented Apr 18, 2023

Sorry mistyped && instead of || in the version && profile mask check.

 if ((bd->GlVersion <= 310) && (bd->GlProfileMask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT))

should be

 if ((bd->GlVersion <= 310) || (bd->GlProfileMask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT))

By uncommenting the #define IMGUI_IMPL_OPENGL_DEBUG at the top I have confirmed that separate restore fails with 3.2 unless GLFW_OPENGL_COMPAT_PROFILE is set.

@GereonV
Copy link
Contributor Author

GereonV commented Apr 19, 2023

Hello, if there are no compile-errors the code should indeed produce equivalent results. However, your version is (currently) error-prone to missing constant definitions. I.e. if a (custom) loader doesn't provide GL_FRONT, GL_BACK or GL_CONTEXT_COMPATIBILITY_PROFILE_BIT it won't compile. I think it would be sensible to add the checks for the macros back or define them to arbitrary values yourself #ifndef GL_CONTEXT_PROFILE_MASK.

ocornut pushed a commit that referenced this pull request Apr 19, 2023
ocornut added a commit that referenced this pull request Apr 19, 2023
@ocornut
Copy link
Owner

ocornut commented Apr 19, 2023

I have merged d0836aa (yours) + a338b78 (slight amends).

I moved the use of GL_CONTEXT_COMPATIBILITY_PROFILE_BIT in the same location as GL_CONTEXT_PROFILE_MASK in order to make the code less of a ifdef party.

#if defined(GL_CONTEXT_PROFILE_MASK)
    glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &bd->GlProfileMask);
    bd->GlProfileIsCompat = (bd->GlProfileMask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0;
#endif
#ifdef IMGUI_IMPL_HAS_POLYGON_MODE
    // Desktop OpenGL 3.0 and OpenGL 3.1 had separate polygon draw modes for front-facing and back-facing faces of polygons
    if (bd->GlVersion <= 310 || bd->GlProfileIsCompat)
    {
        glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]);
        glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]);
    }
    else
    {
        glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]);
    }
#endif // IMGUI_IMPL_HAS_POLYGON_MODE

I believe GL_FRONT and GL_BACK were defined in 1.0 era header and are unlikely to be missing from a custom loader, if it ever does I'm happy to find out and correct.

Thanks!

@ocornut ocornut closed this Apr 19, 2023
@ocornut ocornut changed the title Reset GL_POLYGON_MODE correctly Backends: OpenGL: Reset GL_POLYGON_MODE correctly Apr 19, 2023
@GereonV GereonV deleted the opengl3_fix branch April 19, 2023 10:53
ocornut added a commit that referenced this pull request Jun 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants