Fullscreen problem

Hi,

A strange bug occurs when I try to create a fullscreen window.

The function that creates the window returns an instace of the ZWindow struct which is defined as following:


/*!
 * \brief Holds minimal window information.
 */
typedef struct ZWindow
{
    HWND      hwnd;        /*!< Window handle. */
    HINSTANCE hInstance;   /*!< Application instance. */

    HDC       hDC;         /*!< Device context. */
    HGLRC     hRC;         /*!< OpenGL rendering context. */

    BOOL      active;      /*!< Window active flag. */
    BOOL      fullscreen;  /*!< Fullscreen flag. */

    char     *title;       /*!< Title of the window. */

    int       error_code;  /*!< Holds the error code. */

    int       width;       /*!< Width  of the window. */
    int       height;      /*!< Height of the window. */

}ZWindow;

The function itself is:


/*! \param title The window title.
     * \param width Width of the window, in pixels.
     * \param height Height of the window in pixels.
     * \param bits Colordepth of the new window.
     * \param fullscreen Fullscreen flag.
     * \return A ZWindow object with the information of the newly created window.
     * \bug Fullscreen mode does NOT work...
     */
    ZWindow CreateGLWindow(const char *title, int width, int height, int bits, BOOL fullscreen)
    {
        GLuint		PixelFormat;
        DWORD		ExStyle;
        DWORD		Style;
        RECT		WindowRect;
        ZWindow     window;

        WindowRect.left   = (long)0;
        WindowRect.right  = (long)width;
        WindowRect.top    = (long)0;
        WindowRect.bottom = (long)height;

        window.title = (char *)GlobalAlloc(GMEM_FIXED, strlen(title) + 1);

        strcpy(window.title, title);
        window.width  = width;
        window.height = height;
        window.hInstance = GetModuleHandle(NULL);

        if(fullscreen)											// Attempt Fullscreen Mode?
        {
            DEVMODE ScreenSettings;								// Device Mode
            memset(&ScreenSettings, 0, sizeof(ScreenSettings));	// Makes Sure Memory's Cleared
            ScreenSettings.dmSize=sizeof(ScreenSettings);		// Size Of The Devmode Structure
            ScreenSettings.dmPelsWidth	= width;				// Selected Screen Width
            ScreenSettings.dmPelsHeight	= height;				// Selected Screen Height
            ScreenSettings.dmBitsPerPel	= bits;					// Selected Bits Per Pixel
            ScreenSettings.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(&ScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
            {
                window.error_code = ZGL_ERROR_INVALID_GRAPHICS_MODE;
                return window;
            }

            ExStyle = WS_EX_APPWINDOW;		// Window Extended Style
            Style = WS_POPUP;				// Windows Style
            ShowCursor(FALSE);				// Hide Mouse Pointer
        }
        else
        {
            ExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;			// Window Extended Style
            Style = WS_OVERLAPPEDWINDOW;							// Windows Style
        }
        window.fullscreen = fullscreen;

        AdjustWindowRectEx(&WindowRect, Style, FALSE, ExStyle);		// Adjust Window To True Requested Size

        // Create The Window
        if (!(window.hwnd=CreateWindowEx(ExStyle, ZGL_CLASS_NAME, title, Style | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
                                  0, 0,WindowRect.right-WindowRect.left, WindowRect.bottom-WindowRect.top, NULL, NULL,
                                  window.hInstance, NULL)))
        {
            if(fullscreen == TRUE)
                ChangeDisplaySettings(NULL, 0);

            window.error_code = ZGL_ERROR_CRETATION_FAILURE;
            return window;								// 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
            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
        };

        if((window.hDC = GetDC(window.hwnd)) == NULL) // Try to get a device context
        {
            window.error_code = ZGL_ERROR_DC_CREATION_FAILURE;
            return window;
        }

        if (!(PixelFormat = ChoosePixelFormat(window.hDC, &pfd)))	// Choose pixel format
        {
            window.error_code = ZGL_ERROR_INVALID_PIXEL_FORMAT;
            return window;
        }

        if(!SetPixelFormat(window.hDC, PixelFormat, &pfd))
        {
            window.error_code = ZGL_ERROR_INVALID_PIXEL_FORMAT;
            return window;
        }

        if (!(window.hRC = wglCreateContext(window.hDC))) // Create an OpenGL rendering context
        {
            window.error_code = ZGL_ERROR_RC_CREATION_FAILURE;
            return window;
        }

        ShowWindow(window.hwnd, SW_SHOW);				// Show The Window
        SetForegroundWindow(window.hwnd);				// Slightly Higher Priority
        SetFocus(window.hwnd);							// Sets Keyboard Focus To The Window

        window.error_code = ZGL_ERROR_NONE;             // Success
        return window;									// Return created window information
    }

The bug occures if the fullscreen parameter is set to TRUE. Its not easy to describe it. Try it yourself.

Thanks in advance for any help.

It might not be related, but your “ZWindow window;” will go out of scope when the function returns. You might want to change it to “static ZWindow window;”, or else declare it in the caller and pass a pointer to it to CreateGLWindow.

Thanks for the reply but, as you mentioned it is not related to the problem. The ZWindow object returned is stored by the calling procedure.

One more thing:
the function works nice when creating windows in windowed mode.

Anyone?

Unfortunately I don’t have time to try to reproduce, but what is the nature of the problem? Funky looking display?
A cursory look indicates that you might want to check the use of AdjustWindowRectEx. The height and width inputs to your function might be describing the size of the display, and running AdjustWindowRectEx would (if I remember correctly) typically modify those dimensions.
So, there are two things to consider -

  1. In fullscreen, ScreenSettings are using the original height/width inputs, but the CreateWindowEx is being handed the modified values.
  2. AdjustWindowEx may fail or give unexpected results if you hand it a height and width that reflects the entire display size.
    I would get in debugger, stop at the if statement where CreateWindowEx is called, and examine the values in WindowRect.

The problem is that the created window keeps flashing continuously. I might be wrong but it seems that the window cannot resize propebly.

Anyway, you might want to test it yourself, but be warned, you must set your test code to kill the window by a key combination.

I tested the function in the debugger as you proposed but the result where strange. The call to AdjustWindowRectEx modified the dimensions on window mode, while in fullscreen mode the dimensions where not modified.

Just a few suggestions …

Did you check the return value from AdjustWindowRectEx? Did it fail? If so, why?
Do the values that you pass to CreateWindowEx look reasonable (i.e., will they allow for the created window, including style features, borders, etc., to fit on the display)?
Also, if you are running in the debugger, what do things look like if you breakpoint/halt after calling this function?

I would look for the cause of the continuous flashing behavior. Is your function being called repeatedly? Or is that behavior related to some underlying loop in library code?

Sometimes, concentrating on where one thinks the problem is (in your case, the described function) leads to a situation that is not conducive to finding the problem. I.e., the problem may not be where you think it is - maybe it is in the calling code, maybe it is even in the library code (though less likely). God knows I’ve fallen into that trap before, and may even be suffering in it now (unintended blurs in 2D motion).

Hmm … Sure looks to me like isrufelvalis has exactly the same problem. Are you collaborating? If not, maybe you should …

First of all, sorry for late reply.

The call to the AdjustWindowRectEx function returns 1(which means success).

As for my fucntion the biggest part of it is copied from NeHe’s OpenGL tutorials(NeHe tutorials). This functions is used by many of my programs and works fine. I modified it a bit, to return an ZWindow object, to fit better in the library i’m creating.

Now about the case where the functions works fine and there’s an error in the library code. I don’t think that’s impossible, because i’ve fallen into that trap many times before.

However, I can exclude any underlying loop in the library code because window mode works fine.

I’ll test the functionb standalone tonight to see if the problem is located in the library.

I was looking at this a little closer. Unfortunately, I have not worked out how to integrate openGL with my IDE on Windows yet (I have been using Java with JOGL).

However, I was thinking that, assuming the creation of the window succeeds, along with the other calls in your create function, there might be some issue in rendering the display (which would account for your flashing). Maybe an interaction.

While debugging tonight, if possible, maybe you could try temporarily commenting out sections of code to see if you can narrow down something that affects the problem. For example, try removing the setting of the pixel format stuff, let it go to default, and see what the behavior looks like. If you could eliminate portions of code that don’t affect the problem, or find one that does, it would go a long way to nailing it down.