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("MinHeight", 0);
|
||||||
defaults.put("MinWidth", 0);
|
defaults.put("MinWidth", 0);
|
||||||
defaults.put("GammaCorrection", false);
|
defaults.put("GammaCorrection", false);
|
||||||
|
defaults.put("Resizable", false);
|
||||||
|
defaults.put("SwapBuffers", true);
|
||||||
// defaults.put("Icons", null);
|
// defaults.put("Icons", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -935,4 +937,57 @@ public final class AppSettings extends HashMap<String, Object> {
|
|||||||
public boolean getGammaCorrection() {
|
public boolean getGammaCorrection() {
|
||||||
return getBoolean("GammaCorrection");
|
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 boolean wasActive = false;
|
||||||
protected int frameRate = 0;
|
protected int frameRate = 0;
|
||||||
protected boolean autoFlush = true;
|
protected boolean autoFlush = true;
|
||||||
|
protected boolean allowSwapBuffers = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Type.Display or Type.Canvas
|
* @return Type.Display or Type.Canvas
|
||||||
@ -158,29 +159,29 @@ public abstract class LwjglAbstractDisplay extends LwjglContext implements Runna
|
|||||||
|
|
||||||
// calls swap buffers, etc.
|
// calls swap buffers, etc.
|
||||||
try {
|
try {
|
||||||
if (autoFlush){
|
if (allowSwapBuffers && autoFlush) {
|
||||||
Display.update(false);
|
Display.update(false);
|
||||||
}else{
|
|
||||||
Display.processMessages();
|
|
||||||
Thread.sleep(50);
|
|
||||||
// add a small wait
|
|
||||||
// to reduce CPU usage
|
|
||||||
}
|
}
|
||||||
} catch (Throwable ex){
|
} catch (Throwable ex){
|
||||||
listener.handleError("Error while swapping buffers", ex);
|
listener.handleError("Error while swapping buffers", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frameRate > 0)
|
int frameRateCap;
|
||||||
Display.sync(frameRate);
|
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.
|
// check input after we synchronize with framerate.
|
||||||
// this reduces input lag.
|
// this reduces input lag.
|
||||||
Display.processMessages();
|
Display.processMessages();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subclasses just call GLObjectManager clean up objects here
|
// Subclasses just call GLObjectManager clean up objects here
|
||||||
// it is safe .. for now.
|
// 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
|
// In case canvas is not visible, we still take framerate
|
||||||
// from settings to prevent "100% CPU usage"
|
// from settings to prevent "100% CPU usage"
|
||||||
frameRate = settings.getFrameRate();
|
frameRate = settings.getFrameRate();
|
||||||
|
allowSwapBuffers = settings.isSwapBuffers();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (renderable.get()){
|
if (renderable.get()){
|
||||||
|
@ -94,6 +94,7 @@ public class LwjglDisplay extends LwjglAbstractDisplay {
|
|||||||
settings.useStereo3D());
|
settings.useStereo3D());
|
||||||
|
|
||||||
frameRate = settings.getFrameRate();
|
frameRate = settings.getFrameRate();
|
||||||
|
allowSwapBuffers = settings.isSwapBuffers();
|
||||||
logger.log(Level.FINE, "Selected display mode: {0}", displayMode);
|
logger.log(Level.FINE, "Selected display mode: {0}", displayMode);
|
||||||
|
|
||||||
boolean pixelFormatChanged = false;
|
boolean pixelFormatChanged = false;
|
||||||
@ -108,6 +109,7 @@ public class LwjglDisplay extends LwjglAbstractDisplay {
|
|||||||
pixelFormat = pf;
|
pixelFormat = pf;
|
||||||
|
|
||||||
Display.setTitle(settings.getTitle());
|
Display.setTitle(settings.getTitle());
|
||||||
|
Display.setResizable(settings.isResizable());
|
||||||
|
|
||||||
if (displayMode != null) {
|
if (displayMode != null) {
|
||||||
if (settings.isFullscreen()) {
|
if (settings.isFullscreen()) {
|
||||||
@ -172,14 +174,19 @@ public class LwjglDisplay extends LwjglAbstractDisplay {
|
|||||||
@Override
|
@Override
|
||||||
public void runLoop(){
|
public void runLoop(){
|
||||||
// This method is overriden to do restart
|
// This method is overriden to do restart
|
||||||
if (needRestart.getAndSet(false)){
|
if (needRestart.getAndSet(false)) {
|
||||||
try{
|
try {
|
||||||
createContext(settings);
|
createContext(settings);
|
||||||
}catch (LWJGLException ex){
|
} catch (LWJGLException ex) {
|
||||||
logger.log(Level.SEVERE, "Failed to set display settings!", ex);
|
logger.log(Level.SEVERE, "Failed to set display settings!", ex);
|
||||||
}
|
}
|
||||||
listener.reshape(settings.getWidth(), settings.getHeight());
|
listener.reshape(settings.getWidth(), settings.getHeight());
|
||||||
logger.fine("Display restarted.");
|
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();
|
super.runLoop();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user