Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 19

Thread: Problem with displaymode switching

Hybrid View

  1. #1
    Senior Member OpenGL Pro
    Join Date
    May 2000
    Location
    Hannover, Germany
    Posts
    1,258

    Problem with displaymode switching

    Hi there.
    I've got serious problems with my code that switches the screen resolution etc.. If I'm starting the program the first time nothing unusual happens. But always while exitting the second session, the program hangs at the ChangeDisplaySettings( NULL, 0 ) command.
    I tried to set the resolution afterwards manually and the windows dialog also hangs.
    Has anybody an idea?
    I could post some code as well, if that would help.

    (Sorry, I'm usually no friend of posting the same question in both boards, but I need help badly since I would loose a whole week end and school is keeping me busy.)
    - Michael Steinberg

  2. #2
    Senior Member OpenGL Pro
    Join Date
    May 2000
    Location
    Hannover, Germany
    Posts
    1,258

    Re: Problem with displaymode switching

    Well, the NeHe guy has a word on something that seems strange to me.

    Why should one have to switch back to the normal graphics mode before destroying the window.

    In my app, I do it in the other way round, and my mouse gets corrupted and I can't get any other resolution until a restart. I've got the newest Detonator on a TNT.

    Matt, have you got any idea why? I will fix that anyway now, it's only a question.
    - Michael Steinberg

  3. #3
    Senior Member OpenGL Pro
    Join Date
    Sep 2000
    Location
    Santa Clara, CA
    Posts
    1,463

    Re: Problem with displaymode switching

    I don't have any idea. Remember, though, that changing color depths is generally not reliable, and that in general, to be totally safe, you should always tear down OpenGL completely before changing the resolution or color depth.

    - Matt

  4. #4
    Senior Member OpenGL Pro
    Join Date
    May 2000
    Location
    Hannover, Germany
    Posts
    1,258

    Re: Problem with displaymode switching

    Doh, that's really Crazy!!!
    What I am doing is this:

    On startup:
    Build a list of supported graphics modes with EnumDisplaySettings. I save them to a tree, and afterwards, I only use the saved numbers to switch to them.

    Detach OpenGL from window
    Destroy Window
    Change graphics mode
    Create window
    atach opengl

    I'm doing that in any case, just to be sure it will work if at all possible.
    After I cut-and-pasted the NeHe code, it's hanging every time I run that.

    Maybe I'm getting it all wrong with windows crap. How to destroy a window? I simply use DestroyWindow.

    It's really crap, since I can only try something once, and then I'll have to restart windows. Oh man...
    - Michael Steinberg

  5. #5
    Senior Member OpenGL Pro
    Join Date
    May 2000
    Location
    Hannover, Germany
    Posts
    1,258

    Re: Problem with displaymode switching

    Here's some code, maybe it can help:
    Code :
    /*
    ==============================
    makes up a list of all valid display-modes
    ==============================
    */
    void win_makeup_modes( void )
    {
    	display_mode_t *new_mode;
    	DEVMODE test_mode;
    	int mode_num = 0;
     
    	con_printf( "\nfetching all valid display modes..." );
     
    	while( EnumDisplaySettings( NULL, mode_num, &test_mode ) )
    	{
    		if( ChangeDisplaySettings( &test_mode, CDS_TEST ) == DISP_CHANGE_SUCCESSFUL ) {
    			new_mode = (display_mode_t*) malloc( sizeof( display_mode_t ) );
     
    			new_mode->height = test_mode.dmPelsHeight;
    			new_mode->width  = test_mode.dmPelsWidth;
    			new_mode->bpp    = test_mode.dmBitsPerPel;
    			new_mode->mode_num = mode_num;
    			new_mode->next   = root_display;
    			root_display     = new_mode;
    		}
     
    		mode_num++;
    	}
     
    	con_printf( " found %u modes", mode_num );
    	return;
    }
     
    void win_create_glwindow( void )
    {
    	WNDCLASSEX window_class;
    	int width, height, bpp, fullscreen;
     
    	get_data_from_var( current_disp_settings, &width, &height, &bpp, &fullscreen );
     
    	// Register my Window classes
    	app_instance = GetModuleHandle( NULL );
    	memset( &window_class, 0, sizeof(WNDCLASSEX) );
    	window_class.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;	//Fensterstile
    	window_class.lpfnWndProc = win_winproc;			//Fensterprozedur
        window_class.cbClsExtra  = 0;
        window_class.cbWndExtra  = 0;
    	window_class.hInstance	 = app_instance;
    	window_class.hIcon = LoadIcon( app_instance, NULL);		//Icons aus der Resourcedatei laden
    	window_class.hCursor = LoadCursor(NULL, IDC_ARROW);	//Mauszeiger laden
    	window_class.hbrBackground = NULL; 			//Hintergrundfarbe festlegen
    	window_class.lpszClassName = "win_class";				//Klassenname festlegen
    	window_class.cbSize = sizeof( WNDCLASSEX );
     
    	if ( !RegisterClassEx(&window_class) ) {		//Haupt-Fensterklasse registrieren
    		MessageBox(NULL, "Error: Unable to register window-class", "Fehler", MB_OK);
    		return;
    	}
     
    	if( fullscreen ) {
    		window_handle = CreateWindow(
    			"win_class",					//Klassenname
    			"ConsoleNT - fullscreen",				//Titel
    			WS_POPUPWINDOW|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
    			0, 0,						//Position der linken oberen Ecke
    			width, height,					//Breite, Höhe
    			NULL,						//Kein Parent
    			NULL,						//Kein Child
    			app_instance,				//Instanz
    			NULL
    			);
    	} else {
    		window_handle = CreateWindow(
    			"win_class",					//Klassenname
    			"ConsoleNT - windowed",				//Titel
    			WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
    			0, 0,						//Position der linken oberen Ecke
    			width+8, height+26,			//Breite, Höhe
    			NULL,						//Kein Parent
    			NULL,						//Kein Child
    			app_instance,				//Instanz
    			NULL
    			);
    	}
     
    	if( !window_handle ) MessageBox( NULL, "Fehler!", "Fehler", MB_OK );
     
    	PIXELFORMATDESCRIPTOR desired_format = { 
    			sizeof(PIXELFORMATDESCRIPTOR),   // size of this pfd 
    			1,                     // version number 
    			PFD_DRAW_TO_WINDOW |
    			PFD_SUPPORT_OPENGL |   // support OpenGL 
    			PFD_DOUBLEBUFFER,      // double buffered 
    			PFD_TYPE_RGBA,         // RGBA type 
    			bpp,                   // 16-bit 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,            // accum bits ignored 
    			16,                    // 16-bit z-buffer 
    			0,                     // no stencil buffer 
    			0,                     // no auxiliary buffer 
    			PFD_MAIN_PLANE,        // main layer     
    			0, 0, 0                // 0   [img]http://www.opengl.org/discussion_boards/ubb/smile.gif[/img], reserved, layer masks ignored 
    	}; 
     
    	int context_num;
    	window_context = GetDC( window_handle );	
     
    	context_num = ChoosePixelFormat( window_context, &desired_format );
    	if( !context_num ) {
    		con_printf( "\nUnable to find matching pixel-format" );
    		return;
    	}
     
    	SetPixelFormat( window_context, context_num, &desired_format);   
    	opengl_context = wglCreateContext( window_context );
     
    	if( !opengl_context ) {
    		con_printf( "\nwglCreateContext() failed" );
    	}		
    	if( !wglMakeCurrent( window_context, opengl_context ) ) {
    		con_printf( "\nwglMakeCurrent() failed" );
    	}
     
    	ShowWindow( window_handle, SW_SHOW );
    	SetForegroundWindow( window_handle );
    	SetFocus( window_handle );
    }
     
    void win_destroy_glwindow( void )
    {
    	DestroyWindow( window_handle );
    	UnregisterClass( "win_class", app_instance );
     
    	wglMakeCurrent( NULL, NULL );
    	wglDeleteContext( opengl_context );
    	ReleaseDC( window_handle, window_context );
     
    	DestroyWindow( window_handle );
    	UnregisterClass("win_class",app_instance);
    }
    And this is what I'm doing while resolution change:
    Code :
    		win_destroy_glwindow();
     
    		EnumDisplaySettings( NULL, new_disp->mode_num, &dev_mode );
    		dev_mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
     
    		result = ChangeDisplaySettings( &dev_mode, CDS_FULLSCREEN );
    		if( result != DISP_CHANGE_SUCCESSFUL ) return 0;
    		win_create_glwindow();
    I appreciate any help!!!



    [This message has been edited by Michael Steinberg (edited 12-09-2000).]
    - Michael Steinberg

  6. #6
    Junior Member Regular Contributor
    Join Date
    Dec 2000
    Location
    USA
    Posts
    223

    Re: Problem with displaymode switching

    void win_destroy_glwindow( void ){ DestroyWindow( window_handle ); UnregisterClass( "win_class", app_instance ); wglMakeCurrent( NULL, NULL ); wglDeleteContext( opengl_context ); ReleaseDC( window_handle, window_context ); DestroyWindow( window_handle ); UnregisterClass("win_class",app_instance);}
    You are destroying window and unregistering window class twice in the same function. When you use CS_OWNDC I think that UnregisterClass() automatically destroys the class DC handle for you so you don't have to call ReleaseDC().

  7. #7
    Senior Member OpenGL Pro
    Join Date
    May 2000
    Location
    Hannover, Germany
    Posts
    1,258

    Re: Problem with displaymode switching

    Thanks! I'm gonna try that out!
    - Michael Steinberg

  8. #8
    Senior Member OpenGL Pro
    Join Date
    May 2000
    Location
    Hannover, Germany
    Posts
    1,258

    Re: Problem with displaymode switching

    Though, when I do a ChangeDisplaySettings call that does nothing, ie. the new mode is the old, it will exit without error, so I think it has something to do with ow I change the graphics mode.
    - Michael Steinberg

  9. #9
    Senior Member OpenGL Pro
    Join Date
    May 2000
    Location
    Hannover, Germany
    Posts
    1,258

    Re: Problem with displaymode switching

    That little bug with two times destroying the window in the win_destroy_glwindow is just a typing mistake.
    - Michael Steinberg

  10. #10
    Junior Member Regular Contributor
    Join Date
    Dec 2000
    Location
    USA
    Posts
    223

    Re: Problem with displaymode switching

    Try changing CDS_FULLSCREEN flag to zero. Also, make sure that when you call destroy window that you DON'T process and dispatch any new messages to window procedure since your window handle will be dead at that time. Because I don't see your main loop I can't be sure what you're doing.

    This is my main loop:

    while(true)
    {
    if(PeekMessage(&msg, hWnd, NULL, NULL, PM_NOREMOVE))
    {
    // Message available
    GetMessage(&msg, hWnd, 0, 0);

    if(msg.message == WM_QUIT)
    {
    m_Destroy();
    break;
    }
    else
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    }
    else
    {
    // Draw scene
    if(!m_RenderScene())
    {
    ShowCursor(true);
    wul_ShowError("Rendering failed...", __FILE__, __LINE__);
    PostMessage(hWnd, WM_CLOSE, NULL, NULL);
    }
    }

    In m_Destroy() I do this:

    void COpenGL::m_Destroy()
    {
    HGLRC hGlrc = wglGetCurrentContext();
    HWND hWnd = FindWindow(m_strWndClassname.c_str(), m_strWndname.c_str());

    if(NULL != hGlrc)
    {
    wglMakeCurrent(NULL, NULL) ;
    wglDeleteContext(hGlrc);
    }

    // Destroy the window and unregister the window class that this window belongs to
    DestroyWindow(hWnd);
    UnregisterClass(m_strWndClassname.c_str(), GetModuleHandle(NULL));
    ShowCursor(true);
    }

    These are the steps that happen in order:

    1)I respond to WM_CLOSE message that is sent by the system when the window is closed by clicking on the X in upper right corner of the window bar.
    2)I then call PostQuitMessage(0) which will post WM_QUIT message in the message queue.
    3)I retrieve the WM_QUIT message and call my m_Destroy function. Then I break out of the main loop and exit the app.

    Hope this helps I agree completely that it's sometimes too difficult to get things right because there are too many different ways to do the same thing and no two people will have written the code the same way that's why I'm posting mine here for you to see.

    I also remembered something else. Notice in my PeekMessage(&msg, hWnd, NULL, NULL, PM_NOREMOVE) function I specify the hWnd explicitly. I could have made it NULL in which case I would be retrieving messages for all windows made from the window class. Instead I decided to listen only to the messages that were posted by my OpenGL window. I mention this because this might cause some problems too in weird situations

    [This message has been edited by JD (edited 12-10-2000).]

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •