pythonglfwpyopenglpyimgui

Rendering Triangle using PyImgui/PyOpenGL/GLFW stack


I'm new to the intermediate GUI framework world and OpenGL. I'm trying to get this example to work:

# -*- coding: utf-8 -*-
import glfw
import OpenGL.GL as gl
import numpy as np

import imgui
from imgui.integrations.glfw import GlfwRenderer

def main():
    imgui.create_context()
    window = impl_glfw_init()
    impl = GlfwRenderer(window)

    while not glfw.window_should_close(window):
        glfw.poll_events()
        impl.process_inputs()

        imgui.new_frame()

        if imgui.begin_main_menu_bar():
            if imgui.begin_menu("File", True):

                clicked_quit, selected_quit = imgui.menu_item(
                    "Quit", 'Cmd+Q', False, True
                )

                if clicked_quit:
                    exit(1)

                imgui.end_menu()
            imgui.end_main_menu_bar()

        imgui.render()

        # show_test_window()
        # imgui.show_test_window()
        
        try:
            gl.glViewport(0, 0, int(impl.io.display_size.x), int(impl.io.display_size.y))
            gl.glClearColor(0., 0., 0., 1)
            gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)

            gl.glBegin(gl.GL_TRIANGLES)
            gl.glVertex3f(-0.5, -0.5, 0.0)
            gl.glVertex3f(0.5, -0.5, 0.0)
            gl.glVertex3f(0.0, 0.5, 0.0)
            gl.glEnd()

        except gl.GLError as glex:
            print(f"{glex.err}: {glex.result}")

        impl.render(imgui.get_draw_data())
        glfw.swap_buffers(window)

    impl.shutdown()
    glfw.terminate()


def impl_glfw_init():
    width, height = 1280, 720
    window_name = "minimal ImGui/GLFW3 example"

    if not glfw.init():
        print("Could not initialize OpenGL context")
        exit(1)

    # OS X supports only forward-compatible core profiles from 3.2
    glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
    glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
    glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)

    glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, gl.GL_TRUE)

    # Create a windowed mode window and its OpenGL context
    window = glfw.create_window(
        int(width), int(height), window_name, None, None
    )
    glfw.make_context_current(window)

    if not window:
        glfw.terminate()
        print("Could not initialize Window")
        exit(1)

    return window


if __name__ == "__main__":
    main()

Though I continue to get this error:

GLError

I'm sure I've missed something though I cannot seem to find the magic piece of documentation that gives me a hint. I could be trying to use legacy OpenGL where I should be using the modern approach, or adding my rendering code in the wrong place.

Any hints would be much appreciated.

I have tried a modern OpenGL example using buffers and shaders. Without success.


Solution

  • You are requesting an OpenGL 3.3 CORE profile:

        # OS X supports only forward-compatible core profiles from 3.2
        glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
        glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
        glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
    
        glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, gl.GL_TRUE)
    

    Some docs copied from here: https://www.glfw.org/docs/3.3/window_guide.html#GLFW_OPENGL_FORWARD_COMPAT_hint

    GLFW_OPENGL_FORWARD_COMPAT specifies whether the OpenGL context should be 
    forward-compatible, i.e. one where all functionality deprecated in the 
    requested version of OpenGL is removed. This must only be used if the 
    requested OpenGL version is 3.0 or above. If OpenGL ES is requested, this 
    hint is ignored.
    

    I've never used glfw to be honest, but I'd see if commenting out those lines fixes it? (That should enable all of the legacy OpenGL, e.g. glBegin/glEnd).

    Ideally though, you'd want to keep those window hints, remove the glBegin/glVertex/glEnd, and switch over to using glGenBuffers / glBindBuffer / glBufferData and glDrawArrays.