Allow application to be a resizable window.
Also allow buffer swapping to be disabled, e.g. for Oculus Rift.
This commit is contained in:
parent
1fc730c78a
commit
809092c236
@ -129,6 +129,8 @@ public final class AppSettings extends HashMap<String, Object> {
|
||||
defaults.put("MinHeight", 0);
|
||||
defaults.put("MinWidth", 0);
|
||||
defaults.put("GammaCorrection", false);
|
||||
defaults.put("Resizable", false);
|
||||
defaults.put("SwapBuffers", true);
|
||||
// defaults.put("Icons", null);
|
||||
}
|
||||
|
||||
@ -935,4 +937,57 @@ public final class AppSettings extends HashMap<String, Object> {
|
||||
public boolean getGammaCorrection() {
|
||||
return getBoolean("GammaCorrection");
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the display window to be resized by dragging its edges.
|
||||
*
|
||||
* Only supported for {@link JmeContext.Type#Display} contexts which
|
||||
* are in windowed mode, ignored for other types.
|
||||
* The default value is <code>false</code>.
|
||||
*
|
||||
* @param resizable True to make a resizable window, false to make a fixed
|
||||
* size window.
|
||||
*/
|
||||
public void setResizable(boolean resizable) {
|
||||
putBoolean("Resizable", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the display window can be resized by dragging its edges.
|
||||
*
|
||||
* @return True if the window is resizable, false if it is fixed size.
|
||||
*
|
||||
* @see #setResizable(boolean)
|
||||
*/
|
||||
public boolean isResizable() {
|
||||
return getBoolean("Resizable");
|
||||
}
|
||||
|
||||
/**
|
||||
* When enabled the display context will swap buffers every frame.
|
||||
*
|
||||
* This may need to be disabled when integrating with an external
|
||||
* library that handles buffer swapping on its own, e.g. Oculus Rift.
|
||||
* When disabled, the engine will process window messages
|
||||
* after each frame but it will not swap buffers - note that this
|
||||
* will cause 100% CPU usage normally as there's no VSync or any framerate
|
||||
* caps (unless set via {@link #setFrameRate(int) }.
|
||||
* The default is <code>true</code>.
|
||||
*
|
||||
* @param swapBuffers True to enable buffer swapping, false to disable it.
|
||||
*/
|
||||
public void setSwapBuffers(boolean swapBuffers) {
|
||||
putBoolean("SwapBuffers", swapBuffers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the the display context will swap buffers every frame.
|
||||
*
|
||||
* @return True if buffer swapping is enabled, false otherwise.
|
||||
*
|
||||
* @see #setSwapBuffers(boolean)
|
||||
*/
|
||||
public boolean isSwapBuffers() {
|
||||
return getBoolean("SwapBuffers");
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2015 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package jme3test.app;
|
||||
|
||||
import com.jme3.app.SimpleApplication;
|
||||
import com.jme3.font.BitmapText;
|
||||
import com.jme3.font.Rectangle;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.shape.Box;
|
||||
import com.jme3.system.AppSettings;
|
||||
import jme3test.model.shape.TestBox;
|
||||
|
||||
/**
|
||||
* Tests the capability to resize the application window.
|
||||
*
|
||||
* @author Kirill Vainer
|
||||
*/
|
||||
public class TestResizableApp extends SimpleApplication {
|
||||
|
||||
private BitmapText txt;
|
||||
|
||||
public static void main(String[] args){
|
||||
TestResizableApp app = new TestResizableApp();
|
||||
AppSettings settings = new AppSettings(true);
|
||||
settings.setResizable(true);
|
||||
app.setSettings(settings);
|
||||
app.setShowSettings(false);
|
||||
app.start();
|
||||
}
|
||||
|
||||
public void reshape(int width, int height) {
|
||||
super.reshape(width, height);
|
||||
|
||||
// Need to move text relative to app height
|
||||
txt.setLocalTranslation(0, settings.getHeight(), 0);
|
||||
txt.setText("Drag the corners of the application to resize it.\n" +
|
||||
"Current Size: " + settings.getWidth() + "x" + settings.getHeight());
|
||||
}
|
||||
|
||||
public void simpleInitApp() {
|
||||
flyCam.setDragToRotate(true);
|
||||
|
||||
Box b = new Box(1, 1, 1);
|
||||
Geometry geom = new Geometry("Box", b);
|
||||
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
|
||||
mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
|
||||
geom.setMaterial(mat);
|
||||
rootNode.attachChild(geom);
|
||||
|
||||
txt = new BitmapText(loadGuiFont(), false);
|
||||
txt.setText("Drag the corners of the application to resize it.\n" +
|
||||
"Current Size: " + settings.getWidth() + "x" + settings.getHeight());
|
||||
txt.setLocalTranslation(0, settings.getHeight(), 0);
|
||||
guiNode.attachChild(txt);
|
||||
}
|
||||
|
||||
}
|
@ -59,6 +59,7 @@ public abstract class LwjglAbstractDisplay extends LwjglContext implements Runna
|
||||
protected boolean wasActive = false;
|
||||
protected int frameRate = 0;
|
||||
protected boolean autoFlush = true;
|
||||
protected boolean allowSwapBuffers = false;
|
||||
|
||||
/**
|
||||
* @return Type.Display or Type.Canvas
|
||||
@ -158,29 +159,29 @@ public abstract class LwjglAbstractDisplay extends LwjglContext implements Runna
|
||||
|
||||
// calls swap buffers, etc.
|
||||
try {
|
||||
if (autoFlush){
|
||||
if (allowSwapBuffers && autoFlush) {
|
||||
Display.update(false);
|
||||
}else{
|
||||
Display.processMessages();
|
||||
Thread.sleep(50);
|
||||
// add a small wait
|
||||
// to reduce CPU usage
|
||||
}
|
||||
} catch (Throwable ex){
|
||||
listener.handleError("Error while swapping buffers", ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (frameRate > 0)
|
||||
Display.sync(frameRate);
|
||||
int frameRateCap;
|
||||
if (autoFlush) {
|
||||
frameRateCap = frameRate;
|
||||
} else {
|
||||
frameRateCap = 20;
|
||||
}
|
||||
|
||||
if (frameRateCap > 0) {
|
||||
// Cap framerate
|
||||
Display.sync(frameRateCap);
|
||||
}
|
||||
|
||||
if (renderable.get()){
|
||||
if (autoFlush){
|
||||
// check input after we synchronize with framerate.
|
||||
// this reduces input lag.
|
||||
Display.processMessages();
|
||||
}
|
||||
}
|
||||
|
||||
// Subclasses just call GLObjectManager clean up objects here
|
||||
// it is safe .. for now.
|
||||
|
@ -435,6 +435,7 @@ public class LwjglCanvas extends LwjglAbstractDisplay implements JmeCanvasContex
|
||||
// In case canvas is not visible, we still take framerate
|
||||
// from settings to prevent "100% CPU usage"
|
||||
frameRate = settings.getFrameRate();
|
||||
allowSwapBuffers = settings.isSwapBuffers();
|
||||
|
||||
try {
|
||||
if (renderable.get()){
|
||||
|
@ -94,6 +94,7 @@ public class LwjglDisplay extends LwjglAbstractDisplay {
|
||||
settings.useStereo3D());
|
||||
|
||||
frameRate = settings.getFrameRate();
|
||||
allowSwapBuffers = settings.isSwapBuffers();
|
||||
logger.log(Level.FINE, "Selected display mode: {0}", displayMode);
|
||||
|
||||
boolean pixelFormatChanged = false;
|
||||
@ -108,6 +109,7 @@ public class LwjglDisplay extends LwjglAbstractDisplay {
|
||||
pixelFormat = pf;
|
||||
|
||||
Display.setTitle(settings.getTitle());
|
||||
Display.setResizable(settings.isResizable());
|
||||
|
||||
if (displayMode != null) {
|
||||
if (settings.isFullscreen()) {
|
||||
@ -172,14 +174,19 @@ public class LwjglDisplay extends LwjglAbstractDisplay {
|
||||
@Override
|
||||
public void runLoop(){
|
||||
// This method is overriden to do restart
|
||||
if (needRestart.getAndSet(false)){
|
||||
try{
|
||||
if (needRestart.getAndSet(false)) {
|
||||
try {
|
||||
createContext(settings);
|
||||
}catch (LWJGLException ex){
|
||||
} catch (LWJGLException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to set display settings!", ex);
|
||||
}
|
||||
listener.reshape(settings.getWidth(), settings.getHeight());
|
||||
logger.fine("Display restarted.");
|
||||
} else if (Display.wasResized()) {
|
||||
int newWidth = Display.getWidth();
|
||||
int newHeight = Display.getHeight();
|
||||
settings.setResolution(newWidth, newHeight);
|
||||
listener.reshape(newWidth, newHeight);
|
||||
}
|
||||
|
||||
super.runLoop();
|
||||
|
Loading…
x
Reference in New Issue
Block a user