0

Using PyOpenGL with GLU and PyGame.

I have a VAO with a VBO and IBO behind it that provide the vertex and index data for the faces. In addition I have a simple vertex and fragment shader. Things render find.

However, I'd like to add ImGUI to my application. So I did the following:

def main():
    width = 800
    height = 800

    display = (width, height)

    pygame.init()
    pygame.display.set_caption('OpenGL VAO with pygame')
    pygame.display.set_mode(display, pygame.DOUBLEBUF | pygame.OPENGL | pygame.RESIZABLE)
    pygame.display.gl_set_attribute(pygame.GL_CONTEXT_MAJOR_VERSION, 4)
    pygame.display.gl_set_attribute(pygame.GL_CONTEXT_MINOR_VERSION, 1)
    pygame.display.gl_set_attribute(pygame.GL_CONTEXT_PROFILE_MASK, pygame.GL_CONTEXT_PROFILE_CORE)

    imgui.create_context()
    impl = PygameRenderer()
    io = imgui.get_io()
    #io.set_WantCaptureMouse(True)
    io.display_size = width, height

    init()

    clock = pygame.time.Clock()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            impl.process_event(event)

        render(time=clock, imgui_impl=impl)

        pygame.display.flip()
        pygame.time.wait(10)

if __name__ == '__main__':
    main()

There are two important functions here:

  • init() - loads and compiles the shaders into a program, creates the VBO and IBO and binds them
  • render() - clears depth and color buffers, creates and binds the VAO, turns on the shaders, renders the contents of the VAO etc.

The render() function looks similar to this:

def render(time, imgui_impl):
    glClearColor(0.0, 0.0, 0.0, 0.0)
    glClearDepth(1.0)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    
    glUseProgram(program)
    glBindVertexArray(vao)
    
    fElapsedTime = pygame.time.get_ticks() / 1000.0
    for func in g_instanceList:
        transformMatrix = func(fElapsedTime)
        
        glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, transformMatrix.transpose())
        glDrawElements(GL_TRIANGLES, len(indexData), GL_UNSIGNED_SHORT, None)
    
    glBindVertexArray(0)
    glUseProgram(0)

    imgui.new_frame()
    imgui.begin('Controls', True)
    changed, strings = imgui.input_text('Path to OBJ', '...', imgui.INPUT_TEXT_READ_ONLY)
    imgui.same_line()
    if imgui.button('Load'):
        print('Loading', strings)
    imgui.end()
    imgui.end_frame()
    imgui.render()
    print(imgui.get_draw_data().valid)
    imgui_impl.render(imgui.get_draw_data())

My problem is that ImGUI doesn't show at all. I checked the validity of the ImGui draw data object

imgui.get_draw_data().valid

and it returns True.

How should I handle the ImGUI data? I do turn of the program (shaders) so the only issue I am thinking of is the VAO and that is somehow affects the rendering of the UI.

1 Answer 1

1

I found this post that mentions an issue that appears to be similar to mine. However, the source of the problem for that OP is different. The attempt they made to solve it though worked for me, namely unbind all buffers before calling the ImGui procedures.

In my original code I am unbinding the VAO and also disabling the shader program. It appears that unbinding the VBO is enough even though I did that for the IBO too:

def render(time, imgui_impl):
    glClearColor(0.0, 0.0, 0.0, 0.0)
    glClearDepth(1.0)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    
    glUseProgram(program)
    glBindVertexArray(vao)
    
    fElapsedTime = pygame.time.get_ticks() / 1000.0
    for func in g_instanceList:
        transformMatrix = func(fElapsedTime)
        
        glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, transformMatrix.transpose())
        glDrawElements(GL_TRIANGLES, len(indexData), GL_UNSIGNED_SHORT, None)
    
    glBindVertexArray(0) # Disable the VAO
    glBindBuffer(GL_ARRAY_BUFFER, 0) # Disable the VBO
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) # Disable the IBO (not required)
    glUseProgram(0) # Disable the shader program

    imgui.new_frame()
    # Add ImGUI contents
    imgui.end_frame()
    imgui.render()
    imgui_impl.render(imgui.get_draw_data())
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.