OpenGLComponent::switchFullscreen


#1

Hi

What about adding this to the OpenGL component ?
Currently fullscreen mode is possible by emulating the behaviour, but it’s not real full screen mode.
For linux, the idea is to rebuild the context with :

screen = getCurrentScreenIndex();
if (fullscreen)
{              
        XF86VidModeModeInfo **modes;
        int modeNum, vmMajor, vmMinor;
        XF86VidModeQueryVersion(display, &vmMajor, &vmMinor);
        XF86VidModeGetAllModeLines(display, screen, &modeNum, &modes);  
        
        // Choose visual here and try to find the attributes for the fullscreen mode
        int bestMode = [... from visual selection ...]
        
        // switch to fullscreen 
        XF86VidModeSwitchToMode(display, screen, modes[bestMode]);
        XF86VidModeSetViewPort(display, screen, 0, 0);       
        dpyWidth = modes[bestMode]->hdisplay;                     
        dpyHeight = modes[bestMode]->vdisplay;                    
        XFree(modes);                                             
 
        winAttr.override_redirect = True;
        winAttr.event_mask = ExposureMask | StructureNotifyMask;                                            
        window = XCreateWindow(display, RootWindow(display, vi->screen),    
            0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual,
            CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,   
            &winAttr);                                                       
}                                                                        
else // Actual code

Under windows, use CDS_FULLSCREEN when creating the context, like this:

	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)
		{
                     dwExStyle=WS_EX_APPWINDOW;					// Window Extended Style
		     dwStyle=WS_POPUP;						// Windows Style
		     ShowCursor(FALSE);						// Hide Mouse Pointer
                }
      } 
     else // Actual code

Under Mac, it has something to do with obj-c, but I don’t really understand this language. Anyway, the link is here:
http://developer.apple.com/mac/library/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_fullscreen/opengl_cgl.html


#2

Interesting. How do you make it exit full-screen mode though? Does it automatically exit when you delete the context?


#3

Under linux, you have to delete the window
Under windows, you can use SetWindowsLong to remove the style and call ChangeDisplaySettings(&dmScreenSettings, 0) (without deleting the windows)
Under mac, I have no idea.

On windows, the application gains 10% fps (30 to 33 fps) in my test when run FS.


#4

I’d like to do this, but it seems rather complicated to tie it in with the way components work. Would you propose adding some kind of setFullScreen() method to the OpenGLComponent? If so, what would happen if it already had a parent component?


#5

Usually, OGL/DirectX component going fullscreen means some kind of exclusive mode (just like when you start a recent game, the WM disappear for the game). The hierarchy here has no more visual meaning.
On one hand, it saves many OS/WM operation (hence the special “mode-switch” API), like clipping, z-ordering, double buffering and others. This gives more performance to the application run fullscreen.
On the other hand, the FS’s component doesn’t respect the usual windows rules, so it’s a bit pointless to expect them here.

I think it quite a common behaviour, that shouldn’t disturb client user mode too much.
Most OGL application have a Alt+Enter mode to enter/leave this mode.

Also, I’m almost sure that all platform use a heavyweight window already for OGL, am I wrong ?


#6

There’s already kiosk mode support in the Desktop class… maybe that could be hacked to use special behaviour if you give it an openglcomp?


#7

Ok, I’ll try to give it a go. In all case, the WindowGLContext must be changed to support such method.
I’ll let you know my tweaks.


#8

FYI, on Mac and Linux (at least Nvidia/X Linux), the concept of fullscreen is somewhat deprecated, afaict - specifically, on Mac.

A full-screen window has the same abilities and privileges. It also can better accomodate features like twinview and Mac virtual screens.

So - I wouldn’t advise spending too much time on this, there’s not much to gain.

Bruce


#9

It’s probably true for linux, as I don’t see where the gain could happen for a FS window due to the way X protocol is made.
It’s strange for Mac however, as Apple says the opposite (link few post above).
For windows, it’s a real gain, but they have their “exclusive” mode for this.


#10

Ah, but did you read the Mac doc? It’s typical Apple cleverness. They just have you make a normal borderless window.

They’re specifically giving you a procedure with no special fullscreen abilities, since ‘Steve knows better’.

Interesting to hear that it actually makes a difference on Windows.

Bruce


#11

I don’t have a mac yet. Still, I haven’t tried to understand obj-C too, so I haven’t read the code.
I trust you then if you’ve tried and say it doesn’t make a difference.

Under linux, there is no measurable improvement in my code (from what I’m seeing).
Probably there is some for particular code, as I don’t get why they would have implemented such thing.
My use of OGL stuff is very limited, but it must be fullscreen.