How to get rid of black borders in full screen? (OpenGL/Win32 API)

Started by
6 comments, last by shinypixel 9 years, 11 months ago

I'll walk you through... I have a scene in OpenGL that's {0,0,800,600}. It's resize function:


GLvoid GL_ResizeScene(GLsizei width, GLsizei height)
{
    if (height == 0)
        height = 1;

    glViewport(0, 0, width, height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    
    glOrtho(0, win.width, win.height, 0, 0, 1);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

This works fine in windowed mode. When I go to full-screen, I have two black borders: one on the left, and one on the right. This isn't what I want. I want my 800x600 screen to be stretched from left to right, without adding extra width pixels. This is for just me figuring it out, and not necessarily something I would ship with.

So, the next part of the puzzle... This is in my window init function.


    RECT wRect;

    wRect.left = 0;
    wRect.top = 0;
    wRect.right = (long)win->width;
    wRect.bottom = (long)win->height;

    // Check for full screen
    if (win->blnFullScreen)
    {
        // Full screen mode. Set dimensions to fill the screen.
        x = 0;
        y = 0;
    }
    else
    {
        // Window mode. Center the window
        x = ((GetSystemMetrics(SM_CXSCREEN) - win->width) / 2);
        y = ((GetSystemMetrics(SM_CYSCREEN) - win->height) / 2);
    }

    // Screen settings
    if (win->blnFullScreen)
    {
        DEVMODE dmScreenSettings;

        memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
        dmScreenSettings.dmSize = sizeof(dmScreenSettings);
        dmScreenSettings.dmPelsWidth = win->width;
        dmScreenSettings.dmPelsHeight = win->height;
        dmScreenSettings.dmBitsPerPel = SCREEN_BPP;  
        dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

        if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
        {
          // ...
        }

// ... 
// and just prior to the window creation
AdjustWindowRectEx(&wRect, dwStyle, FALSE, dwExStyle);
    }

And after the window is created...


    static    PIXELFORMATDESCRIPTOR pfd=                // pfd Tells Windows How We Want Things To Be
    {
        sizeof(PIXELFORMATDESCRIPTOR),                // Size Of This Pixel Format Descriptor
        1,                                            // Version Number
        PFD_DRAW_TO_WINDOW |                        // Format Must Support Window
        PFD_SUPPORT_OPENGL |                        // Format Must Support OpenGL
        PFD_DOUBLEBUFFER,                            // Must Support Double Buffering
        PFD_TYPE_RGBA,                                // Request An RGBA Format
        SCREEN_BPP,                                        // Select Our Color Depth
        0, 0, 0, 0, 0, 0,                            // Color Bits Ignored
        0,                                            // No Alpha Buffer
        0,                                            // Shift Bit Ignored
        0,                                            // No Accumulation Buffer
        0, 0, 0, 0,                                    // Accumulation Bits Ignored
        16,                                            // 16Bit Z-Buffer (Depth Buffer)  
        0,                                            // No Stencil Buffer
        0,                                            // No Auxiliary Buffer
        PFD_MAIN_PLANE,                                // Main Drawing Layer
        0,                                            // Reserved
        0, 0, 0                                        // Layer Masks Ignored
    };
 
// ... nothing gives errors when applying
// ...
win->fpGame_Resize(win->width, win->height);

What can I do to stretch 800x600 to the far left and right without black borders? Thanks.

Advertisement
Are we talking about a couple of pixels on either side or quite a large amount? Because if it's the latter it's most likely how your monitor chooses to display a 4:3 resolution as 800x600 is. Most monitors today are 16:9 or maybe 16:10. If that is the case, there is nothing you can do about that unless your monitor allows you to configure its policies.

Yeah, I was afraid of that. It's the latter. That leads to another question..

I've been seeing more games just go into a popup window and expand in fullscreen-windowed mode. I did this in SFML a while ago, and the screen just stretches. The client window just resizes but keeps the same 800x600, but it just stretches out. In OpenGL, is that taken care of with the aspect ratio and glViewport()?

It looks like this is working in resize() in fullscreen-windowed mode, though just a quick attempt.


    aspectRatio = (GLfloat)width / (GLfloat)height;
   
    glOrtho (0, width / aspectRatio, height / aspectRatio, 0.0, 0.0, 1.0);
There are probably lots of ways to deal with it, but the first thing that comes to my mind:

1) Maximimize window
2) remove all windows decorations (title bar, system menu, border, ...)
3) create an OpenGL context to render into the window
4) create an FBO at the desired resolution

All rendering is done into the FBO and the FBO is rendered into the window using whatever stretching and filtering you want.

Okay. Thanks for the help.

Just to clarify a bit more..

The "problem" is that you set the display mode.

If you do, from opengls perspective, the screen is 800x600, 4:3, and since it knows nothing else about your screen, it thinks it fills it all.

The trick is either to _not_ set the displaymode, or to set a displaymode that has the same aspect ratio as your monitors native resolution.

Create the "window" using the desktop resolution (you can get this from Windows) and pass the desktop resolution to glViewport but send 800, 600 to glOrtho. (or use 800,600 to create your own orthographic projection matrix if you use modern OpenGL)

[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!

@SimonForsman: It worked! Thanks. I did exactly that in DEVMODE/ChangeDisplaySettings(), and the borders are gone. It also has the same effect when I go into fullscreen-windowed mode.

This topic is closed to new replies.

Advertisement