📄 displaysystem.java
字号:
/*
* Copyright (c) 2003-2009 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 com.jme.system;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Logger;
import sun.misc.Service;
import sun.misc.ServiceConfigurationError;
import com.jme.image.Image;
import com.jme.input.joystick.JoystickInput;
import com.jme.math.Ray;
import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import com.jme.renderer.RenderContext;
import com.jme.renderer.Renderer;
import com.jme.renderer.TextureRenderer;
import com.jme.scene.state.RenderState;
import com.jme.system.canvas.CanvasConstructor;
import com.jme.system.canvas.JMECanvas;
import com.jme.system.dummy.DummySystemProvider;
import com.jme.system.jogl.JOGLSystemProvider;
import com.jme.system.lwjgl.LWJGLSystemProvider;
/**
* <code>DisplaySystem</code> defines an interface for system creation.
* Specifically, any implementing class will create a window for rendering. It
* also should create the appropriate <code>Renderer</code> object that allows
* the client to render to this window. <p/> Implementing classes should check
* for the appropriate libraries to insure these libraries are indeed installed
* on the system. This will allow users to cleanly exit if an improper library
* was chosen for rendering. <p/> Example usage: <p/> <code>
* DisplaySystem ds = DisplaySystem.getDisplaySystem();<br>
* ds.createWindow(640,480,32,60,true);<br>
* Renderer r = ds.getRenderer();<br>
* </code>
*
* @author Mark Powell
* @author Gregg Patton
* @author Joshua Slack - Optimizations, Headless rendering, RenderContexts, AWT integration
* @version $Id: DisplaySystem.java,v 1.67 2007/10/05 22:41:20 nca Exp $
* @see com.jme.renderer.Renderer
*/
public abstract class DisplaySystem {
private static final Logger LOGGER = Logger.getLogger(DisplaySystem.class.getName());
/** The display system that has been created. */
private static volatile SystemProvider system;
/**
* Width selected for the renderer.
*/
protected int width;
/**
* height selected for the renderer.
*/
protected int height;
/**
* Bit depth selected for renderer.
*/
protected int bpp;
/**
* Frequency selected for renderer.
*/
protected int frq;
/**
* Is the display full screen?
*/
protected boolean fs;
/**
* Is the display created already?
*/
protected boolean created;
/**
* Alpha bits to use for the renderer.
*/
protected int alphaBits = 0;
/**
* Depth bits to use for the renderer.
*/
protected int depthBits = 8;
/**
* Stencil bits to use for the renderer.
*/
protected int stencilBits = 0;
/**
* Number of samples to use for the multisample buffer.
*/
protected int samples = 0;
/**
* Gamma value of display - default is 1.0f. 0->infinity
*/
protected float gamma = 1.0f;
/**
* Brightness value of display - default is 0f. -1.0 -> 1.0
*/
protected float brightness = 0;
/**
* Contrast value of display - default is 1.0f. 0->infinity
*/
protected float contrast = 1;
private static final Map<String, SystemProvider> systemProviderMap = new HashMap<String, SystemProvider>();
private Map<String, Class<? extends CanvasConstructor>> canvasConstructRegistry = new HashMap<String, Class<? extends CanvasConstructor>>();
/**
* A new display system has been created. The default static display system
* is set to the newly created display system.
*/
protected DisplaySystem() {
}
/**
* <code>getDisplaySystem</code> is a factory method that creates the
* appropriate display system specified by the key parameter. If the key
* given is not a valid identifier for a specific display system, the
* fallback default is returned.
*
* @param key
* the display system to use.
* @return the appropriate display system specified by the key.
*/
public static DisplaySystem getDisplaySystem(String key) {
// force to initialize joystick input before display system as there are
// LWJGL issues with creating it afterwards.
// FIXME What about the impact on other display systems?
JoystickInput.get();
try {
setSystemProvider(getCachedSystemProvider(key));
}
catch (IllegalStateException alreadySet) {
LOGGER.warning(alreadySet.getMessage());
}
return getDisplaySystem();
}
private static SystemProvider getCachedSystemProvider(String providerId) {
return getSystemProviderMap().get(providerId);
}
private static Map<String, SystemProvider> getSystemProviderMap()
throws ServiceConfigurationError {
if (systemProviderMap.isEmpty()) {
@SuppressWarnings("unchecked")
Iterator<SystemProvider> displayProviders = Service.providers(SystemProvider.class);
while (displayProviders.hasNext()) {
SystemProvider provider = (SystemProvider) displayProviders
.next();
systemProviderMap.put(provider.getProviderIdentifier(),
provider);
}
// if the provider map is still empty (no providers found),
if (systemProviderMap.isEmpty()) {
// insert the default
SystemProvider sp = new LWJGLSystemProvider();
systemProviderMap.put(sp.getProviderIdentifier(), sp);
sp = new JOGLSystemProvider();
systemProviderMap.put(sp.getProviderIdentifier(), sp);
sp = new DummySystemProvider();
systemProviderMap.put(sp.getProviderIdentifier(), sp);
}
}
return systemProviderMap;
}
/**
* Returns all available system providers
*
* @return String array containing all available system providers
*/
public static String[] getSystemProviderIdentifiers() {
Collection<String> ids = getSystemProviderMap().keySet();
String[] names = new String[ids.size()];
ids.toArray(names);
return names;
}
/**
* Returns the currently system provider. If no system provider has been
* set, then a default LWJGL system provider is used.
*
* @return The current system provider.
*/
public static SystemProvider getSystemProvider() {
SystemProvider currentProvider = system;
if (currentProvider != null) {
return currentProvider;
}
// if none defined by Service.providers, use fallback default
synchronized (DisplaySystem.class) {
if (system == null) {
system = new LWJGLSystemProvider();
}
return system;
}
}
/**
* Sets the SystemProvider to be provider.
* <p>
* Once installed, the provider cannot be replaced.
*
* @param provider
* the SystemProvider to install. if <code>null</code>, no
* provider is set.
* @throws IllegalStateException
* if a provider was previous installed.
*
* @since 2.0
*/
public static synchronized void setSystemProvider(SystemProvider provider) throws IllegalStateException {
if (system != null) {
throw new IllegalStateException("SystemProvider already set");
}
system = provider;
}
/**
* Returns the currently created display system.
*
* @return The current display system.
*/
public static DisplaySystem getDisplaySystem() {
return getSystemProvider().getDisplaySystem();
}
/**
* Sets a new width for the display system
* @param width
*/
public void setWidth(int width) {
this.width = width;
}
/**
* Returns the set width for the display system.
*
* @return The set width.
*/
public int getWidth() {
return width;
}
/**
* Sets a new height for the display system
* @param height
*/
public void setHeight(int height) {
this.height = height;
}
/**
* Returns the set height for the display system.
*
* @return The set height.
*/
public int getHeight() {
return height;
}
/**
* Returns the set bitdepth for the display system.
*
* @return the set bit depth
*/
public int getBitDepth() {
return bpp;
}
/**
* Returns the set frequency for the display system.
*
* @return the set frequency
*/
public int getFrequency() {
return frq;
}
/**
* Returns whether or not the display system is set to be full screen.
*
* @return true if full screen
*/
public boolean isFullScreen() {
return fs;
}
/**
* <code>getAdapter</code> returns the name of the underlying system's
* graphics adapter for debugging / display purposes.
*
* @return the adapter's name as a String
*/
public abstract String getAdapter();
/**
* <code>getDriverVersion</code> returns a string representing the version
* of driver installed on the underlying system.
*
* @return the version as a String
*/
public abstract String getDriverVersion();
/**
* <code>getDisplayVendor</code> returns the vendor of the graphics
* adapter
*
* @return The adapter vendor
*/
public abstract String getDisplayVendor();
/**
* <code>getDisplayRenderer</code> returns details of the adapter
*
* @return The adapter details
*/
public abstract String getDisplayRenderer();
/**
* <code>getDisplayAPIVersion</code> returns the API version supported
*
* @return The api version supported
*/
public abstract String getDisplayAPIVersion();
/**
* <code>isValidDisplayMode</code> determines if the given parameters
* constitute a valid display mode on this system. Returning true does not
* necessarily guarantee that the system is capable of running in the
* specified display mode, merely that it <i>believes </i> it is possible.
*
* @param width
* the width/horizontal resolution of the display.
* @param height
* the height/vertical resolution of the display.
* @param bpp
* the bit depth of the display.
* @param freq
* the frequency of refresh of the display (in Hz).
*/
public abstract boolean isValidDisplayMode(int width, int height, int bpp,
int freq);
/**
* <code>setVSyncEnabled</code> attempts to enable or disable monitor
* vertical synchronization. The method is a "best attempt" to change the
* monitor vertical refresh synchronization, and is <b>not </b> guaranteed
* to be successful. This is dependant on OS.
*
* @param enabled
* <code>true</code> to synchronize, <code>false</code> to
* ignore synchronization
*/
public abstract void setVSyncEnabled(boolean enabled);
/**
* Sets the title of the display system. This is usually reflected by the
* renderer as text in the menu bar.
*
* @param title
* The new display title.
*/
public abstract void setTitle(String title);
/**
* <code>createWindow</code> creates a window with the desired settings.
* The width and height defined by w and h define the size of the window if
* fullscreen is false, otherwise it defines the resolution of the
* fullscreen display. The color depth is defined by bpp. The implementing
* class should only allow 16, 24, and 32. The monitor frequency is defined
* by the frq parameter and should not exceed the capabilities of the
* connected hardware, the implementing class should attempt to assure this
* does not happen. Lastly, the boolean flag fs determines if the display
* should be windowed or fullscreen. If false, windowed is chosen. This
* window will be placed in the center of the screen initially. If true
* fullscreen mode will be entered with the appropriate settings.
*
* @param w
* the width/horizontal resolution of the display.
* @param h
* the height/vertical resolution of the display.
* @param bpp
* the color depth of the display.
* @param frq
* the frequency of refresh of the display.
* @param fs
* flag determining if fullscreen is to be used or not. True will
* use fullscreen, false will use windowed mode.
*/
public abstract void createWindow(int w, int h, int bpp, int frq, boolean fs);
/**
* <code>createHeadlessWindow</code> creates a headless window with the
* desired settings. A headless window is a rendering target that is not
* shown on screen. It is useful for doing offline rendering, integration
* and so forth. You can not have a regular and headless window at the same
* time. The width and height defined by w and h define the size of the
* window. The color depth is defined by bpp.
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -