Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL exclusive mode fullscreen

DirectX allows an application to take exclusive hold of a GPU and the monitor its content is sent to. This is referred to as fullscreen. When using OpenGL, fullscreen is activated using ChangeDisplaySettings(&dv, CDS_FULLSCREEN). However, the result of this is a "fake" fullscreen - a fullscreen window. There are a few differences in how the two behave, particularly when alt-tabbing out of focus.

Is there a way to create a window in fullscreen the way DirectX does it using only the Win32 api and OpenGL, or is this a feature exclusive to DirectX?

like image 592
NmdMystery Avatar asked Jul 14 '14 23:07

NmdMystery


People also ask

What is exclusive mode fullscreen?

Full-Screen Exclusive Mode. Full-screen exclusive mode is a powerful new feature that enables you to suspend the windowing system so that drawing can be done directly to the screen. Display Mode. This section describes how to choose and set the display mode.

Is Exclusive fullscreen better?

If profiling reveals the game is approaching its limit for VRAM, then Exclusive Fullscreen mode may be better, allowing users to gain a slight performance improvement.

Does Linux have exclusive fullscreen?

It seems that there is simply no support for actual/exclusive fullscreen mode on Linux. I would love for this feature to be added (for instance utilizing Vulkan's VK_EXT_full_screen_exclusive).


1 Answers

If you are willing to let GLUT do the windowing tasks for you, you can look here: Full screen in openGL

If you want to go into WIN32 detail by yourself you can do the following:

#include <stdlib.h>

#include <Windows.h>

#include "glew.h"
#include <gl/GL.h>
#include <gl/GLU.h>


int main()
{
    HWND hwnd;
    HDC hdc;
    int pixelFormat;
    PIXELFORMATDESCRIPTOR pfd;

    // First create the full screen window
    hwnd = CreateWindowEx(
        0 ,"STATIC","", WS_VISIBLE|WS_EX_TOPMOST,
        0,0,640,480, 0, 0, GetModuleHandle(NULL), 0
    );
    WINDOWPLACEMENT g_wpPrev = { sizeof(g_wpPrev) };
    DWORD dwStyle = GetWindowLong(hwnd, GWL_STYLE);
    MONITORINFO mi = { sizeof(mi) };
    if (
        GetWindowPlacement(hwnd, &g_wpPrev) &&
        GetMonitorInfo(MonitorFromWindow(hwnd,MONITOR_DEFAULTTOPRIMARY), &mi)
    ) {
        SetWindowLong(hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW);
        SetWindowPos(
            hwnd, HWND_TOP,
            mi.rcMonitor.left, mi.rcMonitor.top,
            mi.rcMonitor.right  - mi.rcMonitor.left,
            mi.rcMonitor.bottom - mi.rcMonitor.top,
            SWP_NOOWNERZORDER | SWP_FRAMECHANGED
        );
    }

    // Describe the pixel format
    memset(&pfd,0,sizeof(PIXELFORMATDESCRIPTOR));
    pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 32;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;

    // Create the device context and rendering context
    hdc = GetDC(hwnd);
    pixelFormat = ChoosePixelFormat(hdc,&pfd);
    SetPixelFormat(hdc,pixelFormat,&pfd);
    HGLRC rendering_context = wglCreateContext(hdc);
    BOOL rc = wglMakeCurrent(hdc, rendering_context);
    GLenum err = glewInit();
    if (GLEW_OK != err) { /*do something*/ }

    // Paint the back buffer red
    glClearColor(1,0,0,0);
    glClear(GL_COLOR_BUFFER_BIT);
    glFlush();

    // Show on screen
    rc = SwapBuffers(hdc);

    while (1)
    {
        // Do something ...
    }

    return 0;
}
like image 170
Gil Shapira Avatar answered Oct 04 '22 10:10

Gil Shapira