windows 如何将我的 OpenGL 应用程序置于全屏模式?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1400654/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 13:06:27  来源:igfitidea点击:

How do I put my OpenGL app into fullscreen mode?

windowsopenglfullscreen

提问by I. J. Kennedy

I'm new to OpenGL but I've written a small application that runs fine in a window. Now i'd like to run it fullscreen.

There is thisfrom the FAQ, but it seems to require GLUT, which is not open source. What's a good method for putting an OpenGL app into fullscreen mode? On Windows XP for now, but I'll be porting to other platforms.

我是 OpenGL 的新手,但我编写了一个在窗口中运行良好的小应用程序。现在我想全屏运行它。FAQ中

这个,但它似乎需要GLUT,它不是开源的。将 OpenGL 应用程序置于全屏模式的好方法是什么?目前在 Windows XP 上,但我将移植到其他平台。

回答by Steve Wortham

Maciek's answer should work. You just need the full source from the NeHe tutorial.

Maciek 的回答应该有效。您只需要 NeHe 教程中的完整源代码。

There is much more source involved in taking care of all the little details like resizing the Window to fullscreen, covering up the start bar. Here's the CreateGLWindow function from one of my apps (a near-copy of NeHe's method).

处理所有小细节需要更多的资源,例如将窗口大小调整为全屏,覆盖开始栏。这是我的一个应用程序中的 CreateGLWindow 函数(NeHe 方法的近似副本)。

inline BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
    GLuint      PixelFormat;            // Holds The Results After Searching For A Match
    HINSTANCE   hInstance;              // Holds The Instance Of The Application
    WNDCLASS    wc;                     // Windows Class Structure
    DWORD       dwExStyle;              // Window Extended Style
    DWORD       dwStyle;                // Window Style
    RECT        WindowRect;             // Grabs Rectangle Upper Left / Lower Right Values
    WindowRect.left=(long)0;            // Set Left Value To 0
    WindowRect.right=(long)width;       // Set Right Value To Requested Width
    WindowRect.top=(long)0;             // Set Top Value To 0
    WindowRect.bottom=(long)height;     // Set Bottom Value To Requested Height

  SCREENWIDTH=width; 
  SCREENHEIGHT=height; 

    fullscreen=fullscreenflag;          // Set The Global Fullscreen Flag

    hInstance           = GetModuleHandle(NULL);                // Grab An Instance For Our Window
    wc.style            = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;   // Redraw On Size, And Own DC For Window.
    wc.lpfnWndProc      = (WNDPROC) WndProc;                    // WndProc Handles Messages
    wc.cbClsExtra       = 0;                                    // No Extra Window Data
    wc.cbWndExtra       = 0;                                    // No Extra Window Data
    wc.hInstance        = hInstance;                            // Set The Instance
    wc.hIcon            = LoadIcon(NULL, IDI_WINLOGO);          // Load The Default Icon
    wc.hCursor          = LoadCursor(NULL, IDC_ARROW);          // Load The Arrow Pointer
    wc.hbrBackground    = NULL;                                 // No Background Required For GL
    wc.lpszMenuName     = NULL;                                 // We Don't Want A Menu
    wc.lpszClassName    = "OpenGL";                             // Set The Class Name

    if (!RegisterClass(&wc))                                    // Attempt To Register The Window Class
    {
        MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                                           // Return FALSE
    }

    if (fullscreen)                                             // Attempt Fullscreen Mode?
    {
        DEVMODE dmScreenSettings;                               // Device Mode
        memset(&dmScreenSettings,0,sizeof(dmScreenSettings));   // Makes Sure Memory's Cleared
        dmScreenSettings.dmSize=sizeof(dmScreenSettings);       // Size Of The Devmode Structure
        dmScreenSettings.dmPelsWidth    = width;                // Selected Screen Width
        dmScreenSettings.dmPelsHeight   = height;               // Selected Screen Height
        dmScreenSettings.dmBitsPerPel   = bits;                 // Selected Bits Per Pixel
        dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

        // Try To Set Selected Mode And Get Results.  NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
        if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
        {
            // If The Mode Fails, Offer Two Options.  Quit Or Use Windowed Mode.
            if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
            {
                fullscreen=FALSE;       // Windowed Mode Selected.  Fullscreen = FALSE
            }
            else
            {
                // Pop Up A Message Box Letting User Know The Program Is Closing.
                MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);
                return FALSE;                                   // Return FALSE
            }
        }
    }

    if (fullscreen)                                             // Are We Still In Fullscreen Mode?
    {
        dwExStyle=WS_EX_APPWINDOW;                              // Window Extended Style
        dwStyle=WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;   // Windows Style
        ShowCursor(FALSE);                                      // Hide Mouse Pointer
    }
    else
    {
        dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;                       // Window Extended Style
        dwStyle=WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;    // Windows Style
    }

    AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);     // Adjust Window To True Requested Size

    // Create The Window
    if (!(hWnd=CreateWindowEx(  dwExStyle,                          // Extended Style For The Window
                                "OpenGL",                           // Class Name
                                title,                              // Window Title
                                dwStyle |                           // Defined Window Style
                                WS_CLIPSIBLINGS |                   // Required Window Style
                                WS_CLIPCHILDREN,                    // Required Window Style
                                0, 0,                               // Window Position
                                WindowRect.right-WindowRect.left,   // Calculate Window Width
                                WindowRect.bottom-WindowRect.top,   // Calculate Window Height
                                NULL,                               // No Parent Window
                                NULL,                               // No Menu
                                hInstance,                          // Instance
                                NULL)))                             // Dont Pass Anything To WM_CREATE
    {
        KillGLWindow();                             // Reset The Display
        MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                               // Return FALSE
    }

    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
        bits,                                       // 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
        32,                                         // 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
    };

    if (!(hDC=GetDC(hWnd)))                         // Did We Get A Device Context?
    {
        KillGLWindow();                             // Reset The Display
        MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                               // Return FALSE
    }

    if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) // Did Windows Find A Matching Pixel Format?
    {
        KillGLWindow();                             // Reset The Display
        MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                               // Return FALSE
    }

    if(!SetPixelFormat(hDC,PixelFormat,&pfd))       // Are We Able To Set The Pixel Format?
    {
        KillGLWindow();                             // Reset The Display
        MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                               // Return FALSE
    }

    if (!(hRC=wglCreateContext(hDC)))               // Are We Able To Get A Rendering Context?
    {
        KillGLWindow();                             // Reset The Display
        MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                               // Return FALSE
    }

    if(!wglMakeCurrent(hDC,hRC))                    // Try To Activate The Rendering Context
    {
        KillGLWindow();                             // Reset The Display
        MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                               // Return FALSE
    }

    ShowWindow(hWnd,SW_SHOW);                       // Show The Window
    SetForegroundWindow(hWnd);                      // Slightly Higher Priority
    SetFocus(hWnd);                                 // Sets Keyboard Focus To The Window
    ReSizeGLScene(width, height);                   // Set Up Our Perspective GL Screen

    if (!InitGL())                                  // Initialize Our Newly Created GL Window
    {
        KillGLWindow();                             // Reset The Display
        MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;                               // Return FALSE
    }

    return TRUE;                                    // Success
}

This is all included in NeHe Lesson 1.

这一切都包含在NeHe 第 1 课中

回答by Maciek

I'm assuming you're creating the OpenGL window the "hard way" (via win32)

我假设您正在以“困难的方式”创建 OpenGL 窗口(通过 win32)

the code below hails from NeHe, the link points to a tutorial containing OpenGL window creation with fullscreen support :

下面的代码来自NeHe,链接指向一个包含全屏支持的 OpenGL 窗口创建教程:

in case your compiler doesn't define CDS_FULLSCREEN, add :

如果您的编译器没有定义 CDS_FULLSCREEN,请添加:

#define CDS_FULLSCREEN 4

at the top of your app.

在您的应用程序的顶部。

if (fullscreen) 
    {
DEVMODE dmScreenSettings;                   // Device Mode
        memset(&dmScreenSettings,0,sizeof(dmScreenSettings));       // Makes Sure Memory's Cleared
        dmScreenSettings.dmSize=sizeof(dmScreenSettings);       // Size Of The Devmode Structure
        dmScreenSettings.dmPelsWidth    = width;            // Selected Screen Width
        dmScreenSettings.dmPelsHeight   = height;           // Selected Screen Height
        dmScreenSettings.dmBitsPerPel   = bits;             // Selected Bits Per Pixel
        dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
// Try To Set Selected Mode And Get Results.  NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
        if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
        {
// If The Mode Fails, Offer Two Options.  Quit Or Run In A Window.
            if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
            {(...)

回答by genpfault

回答by karx11erx

Here is how SDL does it (MS Windows):

以下是 SDL 的做法(MS Windows):

// query desktop video settings
DEVMODE SDL_desktop_mode;
EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &SDL_desktop_mode);

settings.dmBitsPerPel = video->format->BitsPerPixel;
settings.dmPelsWidth = width;
settings.dmPelsHeight = height;
settings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
// make sure to use monitor frequency that works in fullscreen
if (width <= (int)SDL_desktop_mode.dmPelsWidth &&
   height <= (int)SDL_desktop_mode.dmPelsHeight) {
      settings.dmDisplayFrequency = SDL_desktop_mode.dmDisplayFrequency;
      settings.dmFields |= DM_DISPLAYFREQUENCY;
      }
changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
if (! changed && (settings.dmFields & DM_DISPLAYFREQUENCY)) {
   settings.dmFields &= ~DM_DISPLAYFREQUENCY;
   changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
}

What SDL does when you set fullscreen mode and your target resolution is not the desktop resolution is to make sure you are using the proper monitor frequency for fullscreen mode by simply telling the driver to apply the frequency that the desktop has been using (which runs in fullscreen, so its refresh rate will work with any resolution in fullscreen mode).

当您设置全屏模式并且目标分辨率不是桌面分辨率时,SDL 所做的是通过简单地告诉驱动程序应用桌面已使用的频率(运行在全屏,因此其刷新率适用于全屏模式下的任何分辨率)。