Handling window resizing using OpenGL and SDL

后端 未结 2 1716
日久生厌
日久生厌 2021-02-03 14:34

From the code I have of a program that draws and moves a square around an application window, I\'m having trouble when resizing the application window. When I handle a resize an

相关标签:
2条回答
  • 2021-02-03 14:54

    One problem you probably have is, that resizing a window with SDL a new OpenGL context is created, which means that all the things you uploaded before (textures, vertex buffer objects) and state you set (like vertex array pointers) are lost. You need to reinitialize them if using SDL. If you want to keep them, don't use SDL for window management. I recommend GLFW.

    This

    void ResizeWindow()
    
    {
    
    screen_width = event.resize.w;
    screen_height = event.resize.h;
    
    SDL_SetVideoMode(screen_width, screen_height, bpp, SDL_OPENGL | SDL_RESIZABLE | SDL_DOUBLEBUF);
    
    glViewport(0, 0, screen_width, screen_height);
    glMatrixMode(GL_PROJECTION);
    glOrtho(0, screen_width, 0, screen_height, -1, 1);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();
    
    }
    

    is the most common anti pattern found in beginners OpenGL code. Drawing commands and state management that influences drawing belongs in the drawing function. That is the following:

    glViewport(0, 0, screen_width, screen_height);
    glMatrixMode(GL_PROJECTION);
    glOrtho(0, screen_width, 0, screen_height, -1, 1);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();
    

    If you want a robust OpenGL program never put them (only) into the resize handler. They belong with the other drawing commands.

    0 讨论(0)
  • 2021-02-03 15:03

    I've copy pasted your code and I'll explain what is going on line by line. It should help you see not only why the screen is going blank after a resize, but also help you remove stuff that you don't really need.

    void ResizeWindow()
    {
    

    These next lines are good! You've obtained the new screen width and height from the resize event. I'm assuming that the event is accessible at this point in your code.

        screen_width = event.resize.w;
        screen_height = event.resize.h;
    

    I doubt you need this call to SDL_SetViedoMode. I'd expect it to be used only while setting up the OpenGL window. I have no experience with using SDL currently, so I can't be certain. I did do a quick look up of the documentation and that seems to support using it the way I expected.

    SDL_SetVideoMode(screen_width, screen_height, bpp, SDL_OPENGL | SDL_RESIZABLE | SDL_DOUBLEBUF);
    

    Now we get to the interesting GL stuff. You've resized the viewport, which is necessary.

        glViewport(0, 0, screen_width, screen_height);
    

    Now, you're making a new projection matrix to maintain the aspect ration (unless I'm mistaken). You've switched the matrix mode and set up an Orthographic projection matrix, which is sensible.

        glMatrixMode(GL_PROJECTION);
        glOrtho(0, screen_width, 0, screen_height, -1, 1);
    

    Now, you set the projection matrix to identity, overwriting the old OpenGL projection matrix and undoing all the good work you did. This is the reason the screen went blank.

        glLoadIdentity();
    

    Now, you switch to the model-view matrix and set it to identity, which isn't really necessary, so long as you are setting it correctly elsewhere.

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    

    I doubt you really need this next line. Why would you want to clear the screen after a resize, anyway? You do want to redraw it, but I'm sure your draw function will clear the screen and draw the object that will be called automatically after the refresh is done.

        glClear(GL_COLOR_BUFFER_BIT);
    

    And you definitely don't need to re-set the current model-view matrix to identity for a second time. OpenGL is still in model-view mode and that matrix was already set to identity! Remember that OpenGL is a state machine!

        glLoadIdentity();
    }
    
    0 讨论(0)
提交回复
热议问题