How to resize a GLUT window?

2019-07-13 16:30发布

from OpenGL.extensions import alternate
from OpenGL.GL import *
from OpenGL.GL.ARB.multitexture import *
from OpenGL.GLU import *
from OpenGL.GLUT import *


class TestTexture():

    def __init__(self):
        self.window_width = 800
        self.window_height = 800

    def init(self):
        glClearColor(0.0, 0.0, 0.0, 0.0)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        glEnable(GL_TEXTURE_2D)

    def display(self):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glLoadIdentity()

        glBegin(GL_TRIANGLES)
        glVertex3f(-1.0, 0.0, 0.0)
        glVertex3f(1.0, 0.0, 0.0)
        glVertex3f(0.0, 1.0, 0.0)
        glEnd()

        glFlush()
        glutSwapBuffers()

    def reshape(self, w, h):
        self.window_width = w
        self.window_height = h
        glViewport(0, 0, self.window_width, self.window_height)

    def animate(self):
        glutPostRedisplay()

    def visible(self, vis):
        if (vis == GLUT_VISIBLE):
            glutIdleFunc(self.animate)
        else:
            glutIdleFunc(0)

    def key_pressed(self, *args):
        if args[0] == b"\x1b":
            sys.exit()

    def run(self):
        glutInit(sys.argv)
        glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)
        glutInitWindowSize(self.window_width, self.window_height)
        glutInitWindowPosition(800, 100)
        glutCreateWindow(b'MCVE')
        glutDisplayFunc(self.display)
        glutReshapeFunc(self.reshape)
        glutIdleFunc(self.animate)
        glutVisibilityFunc(self.visible)
        glutKeyboardFunc(self.key_pressed)

        self.init()
        glutMainLoop()

if __name__ == "__main__":
    TestTexture().run()

I've already tried few things in order to resize&refresh properly this window but no luck so far. When the window is resized the scene should be rendered properly on real-time but it's not, instead the scene is updated only when you release the mouse (reshape function is not called) or maybe when it's being resized it gets a little chance to update but the final result is definitely not cool at all.

Worth mentioning that a pyqt opengl app is resizing ok and the show window contents while dragging option is enabled.

The test has been made on windows7, PyOpenGL==3.1.1 and python3.5.1_x86

So the question would be, how can I resize&refresh a glut window properly on realtime?

1条回答
欢心
2楼-- · 2019-07-13 16:33

First things first glViewport does not belong into the reshape handler (if I had a cent for every time I wrote this…).

The problem you're running into is not something you can easily address from the "outside" of GLUT because it essentially boils down to how the innards of the main loop are implemented. For smooth updates of the window's contents during resize technically the main loop has to accommodate for this situation, by smoothly interleaving resize events with calls of the display function. The way glutPostRedisplay flags the main loop for redraw will call the display function every few resize steps, but it may accompanied by flicker and jerky redraws.

Your best bet is to do something that's normally frowned upon: Call the display function (including buffer swap) at the end of the resize handler and do not call glutPostRedisplay. However this might be still prone to flicker, depending on how WSI background erasure is implemented. The problem with that is, that resize events may queue up and resize steps long begone show up lagging behind user action.

For truly smooth resize updates an appropriately written main loop is required, that coalesces input/resize events to avoid queue-lag issues and allows for on-resize drawing operation without automatic background erasure to support smooth updates. Current implementations of GLUT don't do this.

查看更多
登录 后发表回答