📄 jogldisplaysystem.java
字号:
/*
* Copyright (c) 2008 SRA International, Inc.
* 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.jogl;
import java.awt.Canvas;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.DisplayMode;
import java.awt.Frame;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.media.opengl.DebugGL;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import javax.media.opengl.Threading;
import javax.media.opengl.glu.GLU;
import com.jme.image.Image;
import com.jme.input.KeyInput;
import com.jme.input.MouseInput;
import com.jme.renderer.RenderContext;
import com.jme.renderer.Renderer;
import com.jme.renderer.TextureRenderer;
import com.jme.renderer.TextureRenderer.Target;
import com.jme.renderer.jogl.JOGLContextCapabilities;
import com.jme.renderer.jogl.JOGLRenderer;
import com.jme.renderer.jogl.JOGLTextureRenderer;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;
import com.jme.system.canvas.CanvasConstructor;
import com.jme.system.canvas.JMECanvas;
import com.jme.util.WeakIdentityCache;
import com.jmex.awt.input.AWTKeyInput;
import com.jmex.awt.input.AWTMouseInput;
import com.jmex.awt.jogl.JOGLAWTCanvas;
/**
* @author Steve Vaughan
*/
public class JOGLDisplaySystem extends DisplaySystem {
private static final Logger logger = Logger
.getLogger(JOGLDisplaySystem.class.getName());
private JOGLRenderer renderer;
private RenderContext<GLContext> currentContext;
private WeakIdentityCache<GLContext, RenderContext<GLContext>> contextStore = new WeakIdentityCache<GLContext, RenderContext<GLContext>>();
private Frame frame;
private GLAutoDrawable autoDrawable;
private boolean isClosing = false;
private final DisplayMode[] availableDisplayModes;
JOGLDisplaySystem() {
super();
final GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
availableDisplayModes = gd.getDisplayModes();
}
@Override
public synchronized void createWindow(int width, int height, int bpp,
int frq, boolean fs) {
// For know, ensure that only one OpenGL surface is active at a time.
if (autoDrawable != null) {
throw new IllegalStateException(
"There is already an active OpenGL canvas.");
}
// Validate window dimensions.
if (width <= 0 || height <= 0) {
throw new JmeException("Invalid resolution values: " + width + " "
+ height);
}
// Validate bit depth.
if ((bpp != 32) && (bpp != 16) && (bpp != 24)) {
throw new JmeException("Invalid pixel depth: " + bpp);
}
// Remember the window surfaces attributes.
this.width = width;
this.height = height;
this.bpp = bpp;
this.frq = frq;
this.fs = fs;
// Create the OpenGL canvas, and place it within a frame.
frame = new Frame();
// Create the singleton's status.
GLCanvas glCanvas = createGLCanvas();
glCanvas.setSize(width, height);
glCanvas.setIgnoreRepaint(true);
glCanvas.setAutoSwapBufferMode(false);
// GLContext glContext = glCanvas.getContext();
// glContext.makeCurrent();
frame.add(glCanvas);
final boolean isDisplayModeModified;
final GraphicsDevice gd = GraphicsEnvironment
.getLocalGraphicsEnvironment().getDefaultScreenDevice();
// Get the current display mode
final DisplayMode previousDisplayMode=gd.getDisplayMode();
// Handle full screen mode if requested.
if (fs) {
frame.setUndecorated(true);
// Check if the full-screen mode is supported by the OS
boolean isFullScreenSupported = gd.isFullScreenSupported();
if (isFullScreenSupported) {
gd.setFullScreenWindow(frame);
// Check if display mode changes are supported by the OS
if (gd.isDisplayChangeSupported()) {
// Get all available display modes
DisplayMode[] displayModes = gd.getDisplayModes();
DisplayMode multiBitsDepthSupportedDisplayMode = null;
DisplayMode refreshRateUnknownDisplayMode = null;
DisplayMode multiBitsDepthSupportedAndRefreshRateUnknownDisplayMode = null;
DisplayMode matchingDisplayMode = null;
DisplayMode currentDisplayMode;
// Look for the display mode that matches with our parameters
// Look for some display modes that are close to these parameters
// and that could be used as substitutes
// On some machines, the refresh rate is unknown and/or multi bit
// depths are supported. If you try to force a particular refresh
// rate or a bit depth, you might find no available display mode
// that matches exactly with your parameters
for (int i = 0; i < displayModes.length && matchingDisplayMode == null; i++) {
currentDisplayMode = displayModes[i];
if (currentDisplayMode.getWidth() == width &&
currentDisplayMode.getHeight() == height) {
if (currentDisplayMode.getBitDepth() == bpp) {
if (currentDisplayMode.getRefreshRate() == frq) {
matchingDisplayMode = currentDisplayMode;
} else if (currentDisplayMode.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN) {
refreshRateUnknownDisplayMode = currentDisplayMode;
}
} else if (currentDisplayMode.getBitDepth() == DisplayMode.BIT_DEPTH_MULTI) {
if (currentDisplayMode.getRefreshRate() == frq) {
multiBitsDepthSupportedDisplayMode = currentDisplayMode;
} else if (currentDisplayMode.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN) {
multiBitsDepthSupportedAndRefreshRateUnknownDisplayMode = currentDisplayMode;
}
}
}
}
DisplayMode nextDisplayMode = null;
if (matchingDisplayMode != null) {
nextDisplayMode = matchingDisplayMode;
} else if (multiBitsDepthSupportedDisplayMode != null) {
nextDisplayMode = multiBitsDepthSupportedDisplayMode;
} else if (refreshRateUnknownDisplayMode != null) {
nextDisplayMode = refreshRateUnknownDisplayMode;
} else if (multiBitsDepthSupportedAndRefreshRateUnknownDisplayMode != null) {
nextDisplayMode = multiBitsDepthSupportedAndRefreshRateUnknownDisplayMode;
} else {
isFullScreenSupported = false;
}
// If we have found a display mode that approximatively matches
// with the input parameters, use it
if (nextDisplayMode != null) {
gd.setDisplayMode(nextDisplayMode);
isDisplayModeModified = true;
} else {
isDisplayModeModified = false;
}
} else {
isDisplayModeModified = false;
// Resize the canvas if the display mode cannot be changed
// and the screen size is not equal to the canvas size
Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
if (screenSize.width != width || screenSize.height != height) {
this.width = screenSize.width;
this.height = screenSize.height;
glCanvas.setSize(screenSize);
}
}
} else {
isDisplayModeModified = false;
}
// Software windowed full-screen mode
if (!isFullScreenSupported) {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
// Resize the canvas
glCanvas.setSize(screenSize);
this.width = screenSize.width;
this.height = screenSize.height;
// Resize the frame so that it occupies the whole screen
frame.setSize(screenSize);
// Set its location at the top left corner
frame.setLocation(0, 0);
}
}
// Otherwise, center the window on the screen.
else {
isDisplayModeModified = false;
frame.pack();
int x, y;
x = (Toolkit.getDefaultToolkit().getScreenSize().width - width) / 2;
y = (Toolkit.getDefaultToolkit().getScreenSize().height - height) / 2;
frame.setLocation(x, y);
}
frame.addWindowListener(new WindowAdapter() {
@Override
public final void windowClosing(WindowEvent e) {
isClosing = true;
// If required, restore the previous display mode
if (isDisplayModeModified) {
gd.setDisplayMode(previousDisplayMode);
}
// If required, get back to the windowed mode
if (gd.getFullScreenWindow() == frame) {
gd.setFullScreenWindow(null);
}
}
});
// Make the window visible to realize the OpenGL surface.
frame.setVisible(true);
// Make the GLContext the current.
GLContext glContext = glCanvas.getContext();
while (glContext.makeCurrent() == GLContext.CONTEXT_NOT_CURRENT) {
try {
Thread.sleep(500);
} catch (InterruptedException interruption) {
logger.warning("Interruped while waiting for makeCurrent()");
}
}
// Now it is time to request the focus because the canvas
// is displayable, focusable, visible and its ancestor is
// visible too
glCanvas.requestFocusInWindow();
// Store singleton OpenGL canvas.
autoDrawable = glCanvas;
created = true;
// Initialize the display system.
initForWindow(width, height);
}
@Override
public JMECanvas createCanvas(int width, int height) {
return this.createCanvas(width, height, "AWT",
new HashMap<String, Object>());
}
@Override
public synchronized JMECanvas createCanvas(int width, int height,
String type, HashMap<String, Object> props) {
// For know, ensure that only one OpenGL surface is active at a time.
if (autoDrawable != null) {
throw new IllegalStateException(
"There is already an active OpenGL canvas.");
}
// Validate window dimensions.
if (width <= 0 || height <= 0) {
throw new JmeException("Invalid resolution values: " + width + " "
+ height);
}
// Retrieve registered constructor, or throw an exception.
CanvasConstructor constructor = makeCanvasConstructor(type);
// Remember the window surfaces attributes.
this.width = width;
this.height = height;
// FIXME this.bpp = bpp;
// FIXME this.frq = frq;
this.fs = false;
// Create the new canvas.
JMECanvas glCanvas = constructor.makeCanvas(props);
// Configure the canvas.
((Canvas) glCanvas).setSize(width, height);
// Store singleton OpenGL canvas.
autoDrawable = (GLAutoDrawable) glCanvas;
created = true;
return glCanvas;
}
@Override
public void createHeadlessWindow(int w, int h, int bpp) {
// TODOX Auto-generated method stub
}
@Override
public TextureRenderer createTextureRenderer(final int width,
final int height, final Target target) {
if (!isCreated()) {
return null;
}
return new JOGLTextureRenderer(width, height, this, renderer);
}
public static JOGLAWTCanvas createGLCanvas() {
// Initialize the OpenGL requested capabilities.
final GLCapabilities caps = new GLCapabilities();
caps.setHardwareAccelerated(true);
caps.setDoubleBuffered(true);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -