【问题标题】:How do I put my OpenGL app into fullscreen mode? [closed]如何将我的 OpenGL 应用程序置于全屏模式? [关闭]
【发布时间】:2010-11-26 21:42:23
【问题描述】:

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

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

【问题讨论】:

  • 我很确定 FreeGLUT 是开源的。

标签: windows opengl fullscreen


【解决方案1】:

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

处理所有小细节(例如将窗口大小调整为全屏、遮盖开始栏)涉及更多资源。这是我的一个应用程序中的 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
}

这都包含在NeHe Lesson 1中。

【讨论】:

    【解决方案2】:

    以下是 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);
    }
    

    当您设置全屏模式并且您的目标分辨率不是桌面分辨率时,SDL 的作用是确保您在全屏模式下使用正确的显示器频率,只需告诉驱动程序应用桌面一直使用的频率 (它以全屏模式运行,因此它的刷新率适用于全屏模式下的任何分辨率)。

    【讨论】:

      【解决方案3】:
      【解决方案4】:

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

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

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

      #define CDS_FULLSCREEN 4
      

      在您的应用顶部。

      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)
                  {(...)
      

      【讨论】:

      • 谢谢!试过了......工作,有点。我使用了 (width, height) = (640, 480),确实 Windows 确实进入了 640x480 模式,但是我的窗口并没有占据整个屏幕,尽管代码 sn-p 中有注释,但开始栏仍然显示。
      • 正如我提到的,它只将屏幕置于 640x480 模式。它没有做任何类似于“全屏”的事情。不过这只是一个开始。
      • 这只是教程的摘录。我会从教程中下载项目并获取整个 CreateGLWindow 函数。
      • 澄清一下——这个 sn-p 中没有包含一些步骤,例如调用 AdjustWindowRectEx() 将窗口大小调整为请求的分辨率。如果您复制完整源代码,则应注意所有这些小细节。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-01
      • 2011-06-19
      • 2014-10-07
      • 2020-10-20
      • 2012-06-13
      • 2012-09-22
      • 1970-01-01
      相关资源
      最近更新 更多