Search code examples
c++openglglut

Objects become stretched in full screen


The problem I am having is that my objects become stretched when I use full screen. I want it to fit the full screen coordinates, so it looks exactly the same as Image A. I know that glViewport determines the portion of the window to which OpenGL is drawing to, and it can help set my objects to the entire window. However, I haven't used glViewport, instead I am used gluOrtho2D.

Click here to see the full code

Image A (screen size: 700, 600)

Original screen size

Image B (full screen size)

Full screen size

gluOrtho2D code

// this is the initialisation function, called once only
void init() {
    glClearColor(0.0, 0.0, 0.0, 0.0); // set what colour you want the background to be
    glMatrixMode(GL_PROJECTION); // set the matrix mode
    gluOrtho2D(0.0, winWidth, 0.0, winHeight); // set the projection window size in x and y.
}

I am originally using gluOrtho2D and it is used to set up a two-dimensional orthographic viewing region.


Solution

  • glViewport defines the region of the (default) framebuffer which is rendered to.

    If you don't want to render to the full screen, thn you can shrink the area which is rendered to, by glViewport. You can let some black stripes on the borders.

    The aspect ratio for your application is winWidth : winHeight

    With glutGet, using the parameters GLUT_WINDOW_WIDTH respectively GLUT_WINDOW_HEIGHT the size of the current window can be get and the current aspect ratio can be calculated:

    int currWidth = glutGet( GLUT_WINDOW_WIDTH );
    int currHeight = glutGet( GLUT_WINDOW_HEIGHT );
    
    float window_aspcet = (float)currWidth / (float)currHeight;
    

    With this information the view can be perfectly centered to the viewport:

    void display() {
    
        float app_aspcet = (float)winWidth / (float)winHeight;
    
        int currWidth = glutGet( GLUT_WINDOW_WIDTH );
        int currHeight = glutGet( GLUT_WINDOW_HEIGHT );
    
        float window_aspcet = (float)currWidth / (float)currHeight;
    
        if ( window_aspcet > app_aspcet )
        {
            int width = (int)((float)currWidth * app_aspcet / window_aspcet + 0.5f);
            glViewport((currWidth - width) / 2, 0, width, currHeight);
        }
        else
        {
            int height = (int)((float)currHeight * window_aspcet / app_aspcet + 0.5f);
            glViewport(0, (currHeight - height) / 2, currWidth, height);
        }
    
        // [...]
    
    }
    

    Or you can adept the aspect ration and the center of the orthographic projection

    void display() {
    
        float app_aspcet = (float)winWidth / (float)winHeight;
    
        int currWidth = glutGet( GLUT_WINDOW_WIDTH );
        int currHeight = glutGet( GLUT_WINDOW_HEIGHT );
    
        float window_aspcet = (float)currWidth / (float)currHeight;
    
        glViewport(0, 0, currWidth, currHeight);
    
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        if ( window_aspcet > app_aspcet )
        {
            float delta_width = (float)currWidth * (float)winHeight / (float)currHeight - (float)winWidth;
            gluOrtho2D(-delta_width/2.0f, (float)winWidth + delta_width/2.0f, 0.0, (float)winHeight);    
        }
        else
        {
            float delta_height = (float)currHeight * (float)winWidth / (float)currWidth - (float)winHeight;
            gluOrtho2D(0.0, (float)winWidth, -delta_height/2.0f, (float)winHeight + delta_height/2.0f);
        }