How to resize a GLUT window?
Asked Answered
E

1

3
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?

Ethelyn answered 18/4, 2017 at 17:12 Comment(6)
@genpfault Edited the questionEthelyn
I'm running on Mac OSX 10.12 and your implementation is properly resizing in realtime on my computer, so it likely has to do with your computer settings in Windows. Do you have the "Show window contents or outline while dragging" disabled in the Visual Effects settings?Ascription
@JustinTennant Good to know it's resizing properly on Mac OSX 10.12. Here on windows7 I got enabled the "Show window contents or outline while dragging"Ethelyn
Try calling glutPostRedisplay() at the end of reshape()Wendall
Is there an actual technical problem here? or is this just mainly preference related.Glandulous
@Vallentin: Part-part. Ultimately it should be up to the user's system settings if window contents shall be updated smoothly while moving or resizing. However if the user desires to do so, then there might be still smooth redraw / flickering issues, depending on how the main / redraw loop in the program has been implemented.Dayak
D
3

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.

Dayak answered 24/4, 2017 at 9:48 Comment(2)
Thanks for the answer, when doing Opengl stuff with other libs the resizing is done smoothly, shame on glut :)Ethelyn
@BPL: Problem is, that display may render at below interactive framerates (i.e. very complex scenes), hence that. In principle it should be easy enough to extend FreeGLUT with a reshape_display function (I propose glutReshapeDisplayFunc) which is called during resizing; a program may then register a fast (lower quality) display function for this.Dayak

© 2022 - 2024 — McMap. All rights reserved.