Fake fullscreen mode

Hi,



A “trend” in recent games is to offer a “fake fullscreen” mode on top of windowed and full screen. Some games completely replace “fullscreen” by that and don’t offer real fullscreen; others call it “Fullscreen windowed” mode (Left 4 Dead 2).



Anyway, it’s simply a borderless window with the same size as the screen and that covers panels/taskbar/docks/whatever it is called on every OS. The advantage is that it is windowed, so it passes through the regular windowing system, allowing normal, glitch-less alt-tabbing. The disadvantage is slightly reduced performance due to passing through the windowing system, which most recent cards have no problem handling, so it is a worthy tradeoff.



So, would adding this mode be feasible in jMonkeyEngine?



Thanks in advance.

I don’t know if this is the best way of doing it, but you could do it via awt/swing:



Put the app inside a Frame/JFrame.



[java]setUndecorated(true);

toolkit = getToolkit();

Dimension screensize = toolkit.getScreenSize();

setLocation(0,0);

setSize(screensize);[/java]



This is taken from a vanilla java app, so i have no idea how it would work with jme.

A good idea, but it doesn’t work with JME.



I tried going from the example file of how to embed a JME3 canvas into a Swing JFrame from here:

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:swing_canvas

Source: Google Code Archive - Long-term storage for Google Code Project Hosting.



That works, but for fake fullscreen to work, the window has to be undecorated.

So I added “window.setUndecorated(true);” (right before “window.setVisible(true);”), launched, and while everything seems to run correctly in the console, there is no window on the screen at all.

windpower said:
...
Some games completely replace "fullscreen" by that and don't offer real fullscreen; others call it "Fullscreen windowed" mode (Left 4 Dead 2).
...


Good game, good game. Left 4 Dead 2 in mode survivor is my favorite.

I know another way to let a JFrame in FullScreen mode :

[java]
GraphicsDevice device = getGraphicsConfiguration().getDevice();
device.setFullScreenWindow(this);
device.setDisplayMode(new DisplayMode(800, 600, 32, DisplayMode.REFRESH_RATE_UNKNOWN));
setVisible(true);
[/java]

No, that is true fullscreen.

windpower said:
A good idea, but it doesn't work with JME.

I tried going from the example file of how to embed a JME3 canvas into a Swing JFrame from here:
https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:swing_canvas
Source: http://code.google.com/p/jmonkeyengine/source/browse/branches/jme3/src/test/jme3test/app/SwingCanvasTest.java

That works, but for fake fullscreen to work, the window has to be undecorated.
So I added "window.setUndecorated(true);" (right before "window.setVisible(true);"), launched, and while everything seems to run correctly in the console, there is no window on the screen at all.


it works in jme3 I just tried it.
jase said:
it works in jme3 I just tried it.

Can you give the sample code you used then?

here’s essentially how I’m launching everything:



[java]

public void start() {

final CanvasApplication app=((ApplicationFacade) getFacade()).getApp();

java.awt.EventQueue.invokeLater(new Runnable() {

public void run() {

// create new JME appsettings

AppSettings settings = new AppSettings(true);

settings.setWidth(width);

settings.setHeight(height);

settings.setSamples(8);

CanvasApplication canvasApplication = app;

canvasApplication.setSettings(settings);

canvasApplication.createCanvas(); // create canvas!

JmeCanvasContext ctx = (JmeCanvasContext) canvasApplication.getContext();

ctx.setSystemListener(canvasApplication);

Dimension dim = new Dimension(width, height);

ctx.getCanvas().setPreferredSize(dim);



//get Swing window

HomeUIView window=homeUIView; //extends JFrame

window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

window.getJMEPane().add(ctx.getCanvas());



window.setUndecorated(true);



// Display Swing window including JME canvas!

window.setVisible(true);

canvasApplication.startCanvas();



//finish setting up stuff that needs to wait for jme to be initialised.

//dodgy but works

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

initMVC();



//initialise bots

getFacade().sendNotification(Command.PROPERTY_CHANGED.name(),

new HashMap<String,Object>(){{

put(PropertyProxy.Props.SELECTED_BOT.name(),null);

}});



}

});

}



[/java]

Here is how I tried to modify the jME3 test with the above code:

[java]package hello;



import java.awt.Dimension;

import java.awt.Toolkit;



import javax.swing.JFrame;



import com.jme3.app.SimpleApplication;

import com.jme3.material.Material;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.shape.Box;

import com.jme3.system.AppSettings;

import com.jme3.system.JmeCanvasContext;

import com.jme3.texture.Texture;



/**

  • you can embed a jme canvas inside a swing application

    *
  • @author pgi

    */

    public class SwingCanvasTest extends SimpleApplication

    {

    public static void main(final String[] args)

    {

    final Dimension screenSize = Toolkit.getDefaultToolkit()

    .getScreenSize();

    final SimpleApplication app = new SwingCanvasTest();

    java.awt.EventQueue.invokeLater(new Runnable()

    {

    @Override

    public void run()

    {

    // create new JME appsettings

    final AppSettings settings = new AppSettings(true);

    settings.setWidth(screenSize.width);

    settings.setHeight(screenSize.height);

    settings.setSamples(8);

    final SimpleApplication canvasApplication = app;

    canvasApplication.setSettings(settings);

    canvasApplication.createCanvas(); // create canvas!

    final JmeCanvasContext ctx = (JmeCanvasContext) canvasApplication

    .getContext();

    ctx.setSystemListener(canvasApplication);

    final Dimension dim = screenSize;

    ctx.getCanvas().setPreferredSize(dim);

    // get Swing window

    final JFrame window = new JFrame(); // extends JFrame

    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    window.getContentPane().add(ctx.getCanvas());

    window.setUndecorated(true);

    // Display Swing window including JME canvas!

    window.setVisible(true);

    canvasApplication.startCanvas();

    }

    });

    }



    @Override

    public void simpleInitApp()

    {

    // activate windowed input behaviour

    flyCam.setDragToRotate(true);

    // display a cube

    final Box boxshape1 = new Box(new Vector3f(-3f, 1.1f, 0f), 1f, 1f, 1f);

    final Geometry cube = new Geometry(“My Textured Box”, boxshape1);

    final Material mat_stl = new Material(assetManager,

    “Common/MatDefs/Misc/SimpleTextured.j3md”);

    final Texture tex_ml = assetManager

    .loadTexture(“Interface/Logo/Monkey.jpg”);

    mat_stl.setTexture(“m_ColorMap”, tex_ml);

    cube.setMaterial(mat_stl);

    rootNode.attachChild(cube);

    }

    }[/java]



    Note: I made some assumptions about the code (changed “CanvasApplication” to “SimpleApplication” because I can’t find CanvasApplication, and switched the homeUIView with a JFrame)



    But no, still no dice, no window is shown at all. When I launch it, the Eclipse window loses focus (so there really is something happening) and the log does show jME3 being initialized and objects being added to the scenegraph, but no visible window is opened, no new window in alt-tab, no new taskbar entry, etc. It might be a windowing bug or something. I’m using Windows 7 64-bit, jME3 nightly from December 26.

well since you arent explicitly setting the window size, you still need to.

just call window.pack() after window.setVisible(true); and it will work.

Well, that did help. Indeed, the frame showed up fine with an added window.pack();, but now alt-tabbing is impossible. Alt-tabbing actually switches to Eclipse but not visibly. If I press Alt+Tab after I launch the application, then I can see my cursor and it turns into the “text cursor” whenever the mouse is at a position where there would be text if the Eclipse window was visible. So Eclipse does get focus when Alt-Tabbing, except the JFrame is still on top and takes the whole screen. So, the problem is that the resulting frame is “on top” of everything (even the alt-tab switcher); the only way I’ve found to exit it is to do Ctrl+Alt+Delete.



This actually might be more of a Windows bug than anything, but it kind of ruins the point of fake fullscreen mode in the first place (quick alt-tabbing).



One little extra quirk I noticed. When I do Ctrl+Alt+Delete and open the Task Manager (so that I can quit the program), the JFrame does behave like a fake fullscreen window. It does appear in the taskbar, and it does work with alt-tabbing. So opening the task manager in front of the JFrame somehow makes it back into a normal window. So, maybe by trying to open a second JFrame in front of the first one, then destroying that second JFrame, the first one will turn into a normal window?



I hope this made sense…

alt-tab works perfectly for me for all apps I’m running (except that the headless fake full screen app doesnt get listed of course) -(running windows XP). I cant speak for windows 7, never used it.

You can quit the app simply by hitting stop within eclipse. once its running independently though you’ll obviously need to provide your own shutdown

ui somewhere.

jase said:
alt-tab works perfectly for me for all apps I'm running (except that the headless fake full screen app doesnt get listed of course) -(running windows XP). I cant speak for windows 7, never used it.
You can quit the app simply by hitting stop within eclipse. once its running independently though you'll obviously need to provide your own shutdown
ui somewhere.

Well that's the thing, I can't alt-tab to Eclipse and press Stop since the fake fullscreen window is in the way and hiding everything.
(I can press Alt+F4 though...)