Updates the renderers based on JOGL 2.0 (and JOAL 1.1.3)
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9878 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
1843916822
commit
9b9db3bd31
1107
engine/src/jogl/com/jme/audio/joal/JoalAudioRenderer.java
Normal file
1107
engine/src/jogl/com/jme/audio/joal/JoalAudioRenderer.java
Normal file
File diff suppressed because it is too large
Load Diff
1226
engine/src/jogl/com/jme3/renderer/jogl/JoglGL1Renderer.java
Normal file
1226
engine/src/jogl/com/jme3/renderer/jogl/JoglGL1Renderer.java
Normal file
File diff suppressed because it is too large
Load Diff
1877
engine/src/jogl/com/jme3/renderer/jogl/JoglRenderer.java
Normal file
1877
engine/src/jogl/com/jme3/renderer/jogl/JoglRenderer.java
Normal file
File diff suppressed because it is too large
Load Diff
386
engine/src/jogl/com/jme3/renderer/jogl/TextureUtil.java
Normal file
386
engine/src/jogl/com/jme3/renderer/jogl/TextureUtil.java
Normal file
@ -0,0 +1,386 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 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.jme3.renderer.jogl;
|
||||
|
||||
import com.jme3.renderer.RendererException;
|
||||
import com.jme3.texture.Image;
|
||||
import com.jme3.texture.Image.Format;
|
||||
import java.nio.ByteBuffer;
|
||||
import javax.media.opengl.GL;
|
||||
import javax.media.opengl.GL2;
|
||||
import javax.media.opengl.GL2ES2;
|
||||
import javax.media.opengl.GL3;
|
||||
import javax.media.opengl.GLContext;
|
||||
|
||||
public class TextureUtil {
|
||||
|
||||
public static int convertTextureFormat(Format fmt) {
|
||||
switch (fmt) {
|
||||
case Alpha16:
|
||||
case Alpha8:
|
||||
return GL.GL_ALPHA;
|
||||
case Luminance8Alpha8:
|
||||
case Luminance16Alpha16:
|
||||
return GL.GL_LUMINANCE_ALPHA;
|
||||
case Luminance8:
|
||||
case Luminance16:
|
||||
return GL.GL_LUMINANCE;
|
||||
case RGB10:
|
||||
case RGB16:
|
||||
case BGR8:
|
||||
case RGB8:
|
||||
case RGB565:
|
||||
return GL.GL_RGB;
|
||||
case RGB5A1:
|
||||
case RGBA16:
|
||||
case RGBA8:
|
||||
return GL.GL_RGBA;
|
||||
case Depth:
|
||||
return GL2ES2.GL_DEPTH_COMPONENT;
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unrecognized format: " + fmt);
|
||||
}
|
||||
}
|
||||
|
||||
public static class GLImageFormat {
|
||||
|
||||
int internalFormat;
|
||||
int format;
|
||||
int dataType;
|
||||
boolean compressed;
|
||||
|
||||
public GLImageFormat(int internalFormat, int format, int dataType, boolean compressed) {
|
||||
this.internalFormat = internalFormat;
|
||||
this.format = format;
|
||||
this.dataType = dataType;
|
||||
this.compressed = compressed;
|
||||
}
|
||||
}
|
||||
|
||||
private static final GLImageFormat[] formatToGL = new GLImageFormat[Format.values().length];
|
||||
|
||||
private static void setFormat(Format format, int glInternalFormat, int glFormat, int glDataType, boolean glCompressed){
|
||||
formatToGL[format.ordinal()] = new GLImageFormat(glInternalFormat, glFormat, glDataType, glCompressed);
|
||||
}
|
||||
|
||||
static {
|
||||
// Alpha formats
|
||||
setFormat(Format.Alpha8, GL2.GL_ALPHA8, GL.GL_ALPHA, GL.GL_UNSIGNED_BYTE, false);
|
||||
setFormat(Format.Alpha16, GL2.GL_ALPHA16, GL.GL_ALPHA, GL.GL_UNSIGNED_SHORT, false);
|
||||
|
||||
// Luminance formats
|
||||
setFormat(Format.Luminance8, GL2.GL_LUMINANCE8, GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE, false);
|
||||
setFormat(Format.Luminance16, GL2.GL_LUMINANCE16, GL.GL_LUMINANCE, GL.GL_UNSIGNED_SHORT, false);
|
||||
setFormat(Format.Luminance16F, GL2.GL_LUMINANCE16F_ARB, GL.GL_LUMINANCE, GL.GL_HALF_FLOAT, false);
|
||||
setFormat(Format.Luminance32F, GL.GL_LUMINANCE32F_ARB, GL.GL_LUMINANCE, GL.GL_FLOAT, false);
|
||||
|
||||
// Luminance alpha formats
|
||||
setFormat(Format.Luminance8Alpha8, GL2.GL_LUMINANCE8_ALPHA8, GL.GL_LUMINANCE_ALPHA, GL.GL_UNSIGNED_BYTE, false);
|
||||
setFormat(Format.Luminance16Alpha16, GL2.GL_LUMINANCE16_ALPHA16, GL.GL_LUMINANCE_ALPHA, GL.GL_UNSIGNED_SHORT, false);
|
||||
setFormat(Format.Luminance16FAlpha16F, GL2.GL_LUMINANCE_ALPHA16F_ARB, GL2.GL_LUMINANCE_ALPHA, GL2.GL_HALF_FLOAT, false);
|
||||
|
||||
// Depth formats
|
||||
setFormat(Format.Depth, GL2.GL_DEPTH_COMPONENT, GL2.GL_DEPTH_COMPONENT, GL2.GL_UNSIGNED_BYTE, false);
|
||||
setFormat(Format.Depth16, GL2.GL_DEPTH_COMPONENT16, GL2.GL_DEPTH_COMPONENT, GL2.GL_UNSIGNED_SHORT, false);
|
||||
setFormat(Format.Depth24, GL2.GL_DEPTH_COMPONENT24, GL2.GL_DEPTH_COMPONENT, GL2.GL_UNSIGNED_INT, false);
|
||||
setFormat(Format.Depth32, GL2.GL_DEPTH_COMPONENT32, GL2.GL_DEPTH_COMPONENT, GL2.GL_UNSIGNED_INT, false);
|
||||
setFormat(Format.Depth32F, GL2.GL_DEPTH_COMPONENT32F, GL2.GL_DEPTH_COMPONENT, GL2.GL_FLOAT, false);
|
||||
|
||||
// Depth stencil formats
|
||||
setFormat(Format.Depth24Stencil8, GL3.GL_DEPTH24_STENCIL8, GL3.GL_DEPTH_STENCIL, GL3.GL_UNSIGNED_INT_24_8, false);
|
||||
|
||||
// RGB formats
|
||||
setFormat(Format.BGR8, GL.GL_RGB8, GL2.GL_BGR, GL.GL_UNSIGNED_BYTE, false);
|
||||
setFormat(Format.RGB8, GL.GL_RGB8, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, false);
|
||||
// setFormat(Format.RGB10, GL11.GL_RGB10, GL11.GL_RGB, GL12.GL_UNSIGNED_INT_10_10_10_2, false);
|
||||
setFormat(Format.RGB16, GL2.GL_RGB16, GL.GL_RGB, GL.GL_UNSIGNED_SHORT, false);
|
||||
setFormat(Format.RGB16F, GL2ES2.GL_RGB16F, GL.GL_RGB, GL.GL_HALF_FLOAT, false);
|
||||
setFormat(Format.RGB32F, GL.GL_RGB32F, GL.GL_RGB, GL.GL_FLOAT, false);
|
||||
|
||||
// Special RGB formats
|
||||
setFormat(Format.RGB111110F, GL2.GL_R11F_G11F_B10F, GL.GL_RGB, GL.GL_UNSIGNED_INT_10F_11F_11F_REV, false);
|
||||
setFormat(Format.RGB9E5, GL2.GL_RGB9_E5, GL.GL_RGB, GL2.GL_UNSIGNED_INT_5_9_9_9_REV, false);
|
||||
setFormat(Format.RGB16F_to_RGB111110F, GL2.GL_R11F_G11F_B10F, GL.GL_RGB, GL.GL_HALF_FLOAT, false);
|
||||
setFormat(Format.RGB16F_to_RGB9E5, GL2.GL_RGB9_E5, GL.GL_RGB, GL.GL_HALF_FLOAT, false);
|
||||
|
||||
// RGBA formats
|
||||
setFormat(Format.ABGR8, GL.GL_RGBA8, GL2.GL_ABGR_EXT, GL.GL_UNSIGNED_BYTE, false);
|
||||
setFormat(Format.RGB5A1, GL.GL_RGB5_A1, GL.GL_RGBA, GL.GL_UNSIGNED_SHORT_5_5_5_1, false);
|
||||
setFormat(Format.ARGB4444, GL.GL_RGBA4, GL2.GL_ABGR_EXT, GL.GL_UNSIGNED_SHORT_4_4_4_4, false);
|
||||
setFormat(Format.RGBA8, GL.GL_RGBA8, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, false);
|
||||
setFormat(Format.RGBA16, GL2.GL_RGBA16, GL.GL_RGBA, GL.GL_UNSIGNED_SHORT, false); // might be incorrect
|
||||
setFormat(Format.RGBA16F, GL2.GL_RGBA16F, GL.GL_RGBA, GL.GL_HALF_FLOAT, false);
|
||||
setFormat(Format.RGBA32F, GL.GL_RGBA32F, GL.GL_RGBA, GL.GL_FLOAT, false);
|
||||
|
||||
// DXT formats
|
||||
setFormat(Format.DXT1, GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL.GL_RGB, GL2.GL_UNSIGNED_BYTE, true);
|
||||
setFormat(Format.DXT1A, GL.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL.GL_RGBA, GL2.GL_UNSIGNED_BYTE, true);
|
||||
setFormat(Format.DXT3, GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL.GL_RGBA, GL2.GL_UNSIGNED_BYTE, true);
|
||||
setFormat(Format.DXT5, GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL.GL_RGBA, GL2.GL_UNSIGNED_BYTE, true);
|
||||
|
||||
// LTC/LATC/3Dc formats
|
||||
setFormat(Format.LTC, GL2.GL_COMPRESSED_LUMINANCE_LATC1_EXT, GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE, true);
|
||||
setFormat(Format.LATC, GL2.GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL.GL_LUMINANCE_ALPHA, GL.GL_UNSIGNED_BYTE, true);
|
||||
}
|
||||
|
||||
public static GLImageFormat getImageFormat(Format fmt){
|
||||
GL gl = GLContext.getCurrentGL();
|
||||
switch (fmt){
|
||||
case ABGR8:
|
||||
if (!gl.isExtensionAvailable("GL_EXT_abgr")){
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case BGR8:
|
||||
if (!gl.isExtensionAvailable("GL_VERSION_1_2") && !gl.isExtensionAvailable("EXT_bgra")){
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case DXT1:
|
||||
case DXT1A:
|
||||
case DXT3:
|
||||
case DXT5:
|
||||
if (!gl.isExtensionAvailable("GL_EXT_texture_compression_s3tc")) {
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case Depth:
|
||||
case Depth16:
|
||||
case Depth24:
|
||||
case Depth32:
|
||||
if (!gl.isExtensionAvailable("GL_VERSION_1_4") && !gl.isExtensionAvailable("ARB_depth_texture")){
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case Depth24Stencil8:
|
||||
if (!gl.isExtensionAvailable("GL_VERSION_3_0")){
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case Luminance16F:
|
||||
case Luminance16FAlpha16F:
|
||||
case Luminance32F:
|
||||
if (!gl.isExtensionAvailable("GL_ARB_texture_float")){
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case RGB16F:
|
||||
case RGB32F:
|
||||
case RGBA16F:
|
||||
case RGBA32F:
|
||||
if (!gl.isExtensionAvailable("GL_VERSION_3_0") && !gl.isExtensionAvailable("GL_ARB_texture_float")){
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case Depth32F:
|
||||
if (!gl.isExtensionAvailable("GL_VERSION_3_0") && !gl.isExtensionAvailable("GL_NV_depth_buffer_float")){
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case LATC:
|
||||
case LTC:
|
||||
if (!gl.isExtensionAvailable("GL_EXT_texture_compression_latc")){
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case RGB9E5:
|
||||
case RGB16F_to_RGB9E5:
|
||||
if (!gl.isExtensionAvailable("GL_VERSION_3_0") && !gl.isExtensionAvailable("GL_EXT_texture_shared_exponent")){
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case RGB111110F:
|
||||
case RGB16F_to_RGB111110F:
|
||||
if (!gl.isExtensionAvailable("GL_VERSION_3_0") && !gl.isExtensionAvailable("GL_EXT_packed_float")){
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return formatToGL[fmt.ordinal()];
|
||||
}
|
||||
|
||||
public static GLImageFormat getImageFormatWithError(Format fmt) {
|
||||
GLImageFormat glFmt = getImageFormat(fmt);
|
||||
if (glFmt == null) {
|
||||
throw new RendererException("Image format '" + fmt + "' is unsupported by the video hardware.");
|
||||
}
|
||||
return glFmt;
|
||||
}
|
||||
|
||||
public static void uploadTexture(Image image,
|
||||
int target,
|
||||
int index,
|
||||
int border){
|
||||
GL gl = GLContext.getCurrentGL();
|
||||
Image.Format fmt = image.getFormat();
|
||||
GLImageFormat glFmt = getImageFormatWithError(fmt);
|
||||
|
||||
ByteBuffer data;
|
||||
if (index >= 0 && image.getData() != null && image.getData().size() > 0){
|
||||
data = image.getData(index);
|
||||
}else{
|
||||
data = null;
|
||||
}
|
||||
|
||||
int width = image.getWidth();
|
||||
int height = image.getHeight();
|
||||
int depth = image.getDepth();
|
||||
|
||||
if (data != null) {
|
||||
gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
|
||||
}
|
||||
|
||||
int[] mipSizes = image.getMipMapSizes();
|
||||
int pos = 0;
|
||||
// TODO: Remove unneccessary allocation
|
||||
if (mipSizes == null){
|
||||
if (data != null)
|
||||
mipSizes = new int[]{ data.capacity() };
|
||||
else
|
||||
mipSizes = new int[]{ width * height * fmt.getBitsPerPixel() / 8 };
|
||||
}
|
||||
|
||||
boolean subtex = false;
|
||||
int samples = image.getMultiSamples();
|
||||
|
||||
for (int i = 0; i < mipSizes.length; i++){
|
||||
int mipWidth = Math.max(1, width >> i);
|
||||
int mipHeight = Math.max(1, height >> i);
|
||||
int mipDepth = Math.max(1, depth >> i);
|
||||
|
||||
if (data != null){
|
||||
data.position(pos);
|
||||
data.limit(pos + mipSizes[i]);
|
||||
}
|
||||
|
||||
if (glFmt.compressed && data != null){
|
||||
if (target == GL2.GL_TEXTURE_3D){
|
||||
gl.getGL2().glCompressedTexImage3D(target,
|
||||
i,
|
||||
glFmt.internalFormat,
|
||||
mipWidth,
|
||||
mipHeight,
|
||||
mipDepth,
|
||||
0,
|
||||
border,
|
||||
data);
|
||||
}else{
|
||||
//all other targets use 2D: array, cubemap, 2d
|
||||
gl.getGL2().glCompressedTexImage2D(target,
|
||||
i,
|
||||
glFmt.internalFormat,
|
||||
mipWidth,
|
||||
mipHeight,
|
||||
0,
|
||||
border,
|
||||
data);
|
||||
}
|
||||
}else{
|
||||
if (target == GL2.GL_TEXTURE_3D){
|
||||
gl.getGL2().glTexImage3D(target,
|
||||
i,
|
||||
glFmt.internalFormat,
|
||||
mipWidth,
|
||||
mipHeight,
|
||||
mipDepth,
|
||||
border,
|
||||
glFmt.format,
|
||||
glFmt.dataType,
|
||||
data);
|
||||
}else if (target == GL.GL_TEXTURE_2D_ARRAY){
|
||||
// prepare data for 2D array
|
||||
// or upload slice
|
||||
if (index == -1){
|
||||
gl.getGL2().glTexImage3D(target,
|
||||
0,
|
||||
glFmt.internalFormat,
|
||||
mipWidth,
|
||||
mipHeight,
|
||||
image.getData().size(), //# of slices
|
||||
border,
|
||||
glFmt.format,
|
||||
glFmt.dataType,
|
||||
data);
|
||||
}else{
|
||||
gl.getGL2().glTexSubImage3D(target,
|
||||
i, // level
|
||||
0, // xoffset
|
||||
0, // yoffset
|
||||
index, // zoffset
|
||||
width, // width
|
||||
height, // height
|
||||
1, // depth
|
||||
glFmt.format,
|
||||
glFmt.dataType,
|
||||
data);
|
||||
}
|
||||
}else{
|
||||
if (subtex){
|
||||
if (samples > 1){
|
||||
throw new IllegalStateException("Cannot update multisample textures");
|
||||
}
|
||||
|
||||
gl.getGL2().glTexSubImage2D(target,
|
||||
i,
|
||||
0, 0,
|
||||
mipWidth, mipHeight,
|
||||
glFmt.format,
|
||||
glFmt.dataType,
|
||||
data);
|
||||
}else{
|
||||
if (samples > 1){
|
||||
gl.getGL2().glTexImage2DMultisample(target,
|
||||
samples,
|
||||
glFmt.internalFormat,
|
||||
mipWidth,
|
||||
mipHeight,
|
||||
true);
|
||||
}else{
|
||||
gl.getGL2().glTexImage2D(target,
|
||||
i,
|
||||
glFmt.internalFormat,
|
||||
mipWidth,
|
||||
mipHeight,
|
||||
border,
|
||||
glFmt.format,
|
||||
glFmt.dataType,
|
||||
data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pos += mipSizes[i];
|
||||
}
|
||||
}
|
||||
}
|
182
engine/src/jogl/com/jme3/system/jogl/JoglAbstractDisplay.java
Normal file
182
engine/src/jogl/com/jme3/system/jogl/JoglAbstractDisplay.java
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 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.jme3.system.jogl;
|
||||
|
||||
import com.jme3.input.KeyInput;
|
||||
import com.jme3.input.MouseInput;
|
||||
import com.jme3.input.TouchInput;
|
||||
import com.jme3.input.awt.AwtKeyInput;
|
||||
import com.jme3.input.awt.AwtMouseInput;
|
||||
import com.jme3.renderer.jogl.JoglRenderer;
|
||||
import com.jogamp.opengl.util.Animator;
|
||||
import com.jogamp.opengl.util.AnimatorBase;
|
||||
import com.jogamp.opengl.util.FPSAnimator;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.logging.Logger;
|
||||
import javax.media.opengl.GLAutoDrawable;
|
||||
import javax.media.opengl.GLCapabilities;
|
||||
import javax.media.opengl.GLEventListener;
|
||||
import javax.media.opengl.GLProfile;
|
||||
import javax.media.opengl.awt.GLCanvas;
|
||||
|
||||
public abstract class JoglAbstractDisplay extends JoglContext implements GLEventListener {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(JoglAbstractDisplay.class.getName());
|
||||
|
||||
protected GraphicsDevice device;
|
||||
|
||||
protected GLCanvas canvas;
|
||||
|
||||
protected AnimatorBase animator;
|
||||
|
||||
protected AtomicBoolean active = new AtomicBoolean(false);
|
||||
|
||||
protected boolean wasActive = false;
|
||||
|
||||
protected int frameRate;
|
||||
|
||||
protected boolean useAwt = true;
|
||||
|
||||
protected AtomicBoolean autoFlush = new AtomicBoolean(true);
|
||||
|
||||
protected boolean wasAnimating = false;
|
||||
|
||||
protected void initGLCanvas() {
|
||||
device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
|
||||
|
||||
GLCapabilities caps = new GLCapabilities(GLProfile.getDefault());
|
||||
caps.setHardwareAccelerated(true);
|
||||
caps.setDoubleBuffered(true);
|
||||
caps.setStencilBits(settings.getStencilBits());
|
||||
caps.setDepthBits(settings.getDepthBits());
|
||||
|
||||
if (settings.getSamples() > 1) {
|
||||
caps.setSampleBuffers(true);
|
||||
caps.setNumSamples(settings.getSamples());
|
||||
}
|
||||
|
||||
canvas = new GLCanvas(caps) {
|
||||
@Override
|
||||
public void addNotify() {
|
||||
super.addNotify();
|
||||
onCanvasAdded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNotify() {
|
||||
onCanvasRemoved();
|
||||
super.removeNotify();
|
||||
}
|
||||
};
|
||||
if (settings.isVSync()) {
|
||||
// FIXME: it is too early to get the GL instance from the canvas
|
||||
canvas.getGL().setSwapInterval(1);
|
||||
}
|
||||
canvas.setFocusable(true);
|
||||
canvas.setIgnoreRepaint(true);
|
||||
canvas.addGLEventListener(this);
|
||||
|
||||
// N.B: it is too early to get the GL instance from the canvas
|
||||
// if (false){
|
||||
// trace mode
|
||||
// jME already uses err stream, use out instead
|
||||
// gl = new TraceGL(gl, System.out);
|
||||
// }else if (false){
|
||||
// debug mode
|
||||
// gl = new DebugGL(gl);
|
||||
// }else{
|
||||
// production mode
|
||||
// }
|
||||
renderer = new JoglRenderer();
|
||||
}
|
||||
|
||||
protected void startGLCanvas() {
|
||||
if (frameRate > 0) {
|
||||
animator = new FPSAnimator(canvas, frameRate);
|
||||
// ((FPSAnimator)animator).setRunAsFastAsPossible(true);
|
||||
}
|
||||
else {
|
||||
animator = new Animator(canvas);
|
||||
((Animator) animator).setRunAsFastAsPossible(true);
|
||||
}
|
||||
|
||||
animator.start();
|
||||
wasAnimating = true;
|
||||
}
|
||||
|
||||
protected void onCanvasAdded() {
|
||||
}
|
||||
|
||||
protected void onCanvasRemoved() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyInput getKeyInput() {
|
||||
return new AwtKeyInput(/*canvas*/);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MouseInput getMouseInput() {
|
||||
return new AwtMouseInput(/*canvas*/);
|
||||
}
|
||||
|
||||
public TouchInput getTouchInput() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setAutoFlushFrames(boolean enabled) {
|
||||
autoFlush.set(enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback.
|
||||
*/
|
||||
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
|
||||
listener.reshape(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback.
|
||||
*/
|
||||
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback
|
||||
*/
|
||||
public void dispose(GLAutoDrawable drawable) {
|
||||
|
||||
}
|
||||
}
|
129
engine/src/jogl/com/jme3/system/jogl/JoglCanvas.java
Normal file
129
engine/src/jogl/com/jme3/system/jogl/JoglCanvas.java
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 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.jme3.system.jogl;
|
||||
|
||||
import com.jme3.system.JmeCanvasContext;
|
||||
import java.awt.Canvas;
|
||||
import java.util.logging.Logger;
|
||||
import javax.media.opengl.GLAutoDrawable;
|
||||
|
||||
public class JoglCanvas extends JoglAbstractDisplay implements JmeCanvasContext {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(JoglCanvas.class.getName());
|
||||
private int width, height;
|
||||
|
||||
public JoglCanvas(){
|
||||
super();
|
||||
initGLCanvas();
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return Type.Canvas;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
}
|
||||
|
||||
public void restart() {
|
||||
}
|
||||
|
||||
public void create(boolean waitFor){
|
||||
if (waitFor)
|
||||
waitFor(true);
|
||||
}
|
||||
|
||||
public void destroy(boolean waitFor){
|
||||
if (waitFor)
|
||||
waitFor(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCanvasRemoved(){
|
||||
super.onCanvasRemoved();
|
||||
created.set(false);
|
||||
waitFor(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCanvasAdded(){
|
||||
startGLCanvas();
|
||||
}
|
||||
|
||||
public void init(GLAutoDrawable drawable) {
|
||||
canvas.requestFocus();
|
||||
|
||||
super.internalCreate();
|
||||
logger.info("Display created.");
|
||||
|
||||
renderer.initialize();
|
||||
listener.initialize();
|
||||
}
|
||||
|
||||
public void display(GLAutoDrawable glad) {
|
||||
if (!created.get() && renderer != null){
|
||||
listener.destroy();
|
||||
logger.info("Canvas destroyed.");
|
||||
super.internalDestroy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (width != canvas.getWidth() || height != canvas.getHeight()){
|
||||
width = canvas.getWidth();
|
||||
height = canvas.getHeight();
|
||||
if (listener != null)
|
||||
listener.reshape(width, height);
|
||||
}
|
||||
|
||||
boolean flush = autoFlush.get();
|
||||
if (flush && !wasAnimating){
|
||||
animator.start();
|
||||
wasAnimating = true;
|
||||
}else if (!flush && wasAnimating){
|
||||
animator.stop();
|
||||
wasAnimating = false;
|
||||
}
|
||||
|
||||
listener.update();
|
||||
renderer.onFrame();
|
||||
|
||||
}
|
||||
|
||||
public Canvas getCanvas() {
|
||||
return canvas;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose(GLAutoDrawable arg0) {
|
||||
}
|
||||
|
||||
}
|
146
engine/src/jogl/com/jme3/system/jogl/JoglContext.java
Normal file
146
engine/src/jogl/com/jme3/system/jogl/JoglContext.java
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 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.jme3.system.jogl;
|
||||
|
||||
import com.jme3.input.JoyInput;
|
||||
import com.jme3.input.KeyInput;
|
||||
import com.jme3.input.MouseInput;
|
||||
import com.jme3.input.awt.AwtKeyInput;
|
||||
import com.jme3.input.awt.AwtMouseInput;
|
||||
import com.jme3.renderer.Renderer;
|
||||
import com.jme3.renderer.jogl.JoglRenderer;
|
||||
import com.jme3.system.AppSettings;
|
||||
import com.jme3.system.JmeContext;
|
||||
import com.jme3.system.NanoTimer;
|
||||
import com.jme3.system.SystemListener;
|
||||
import com.jme3.system.Timer;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public abstract class JoglContext implements JmeContext {
|
||||
|
||||
protected AtomicBoolean created = new AtomicBoolean(false);
|
||||
protected AtomicBoolean renderable = new AtomicBoolean(false);
|
||||
protected final Object createdLock = new Object();
|
||||
|
||||
protected AppSettings settings = new AppSettings(true);
|
||||
protected JoglRenderer renderer;
|
||||
protected Timer timer;
|
||||
protected SystemListener listener;
|
||||
|
||||
protected AwtKeyInput keyInput;
|
||||
protected AwtMouseInput mouseInput;
|
||||
|
||||
public void setSystemListener(SystemListener listener){
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public void setSettings(AppSettings settings) {
|
||||
this.settings.copyFrom(settings);
|
||||
}
|
||||
|
||||
public boolean isRenderable(){
|
||||
return renderable.get();
|
||||
}
|
||||
|
||||
public AppSettings getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
public Renderer getRenderer() {
|
||||
return renderer;
|
||||
}
|
||||
|
||||
public MouseInput getMouseInput() {
|
||||
return mouseInput;
|
||||
}
|
||||
|
||||
public KeyInput getKeyInput() {
|
||||
return keyInput;
|
||||
}
|
||||
|
||||
public JoyInput getJoyInput() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Timer getTimer() {
|
||||
return timer;
|
||||
}
|
||||
|
||||
public boolean isCreated() {
|
||||
return created.get();
|
||||
}
|
||||
|
||||
public void create(){
|
||||
create(false);
|
||||
}
|
||||
|
||||
public void destroy(){
|
||||
destroy(false);
|
||||
}
|
||||
|
||||
protected void waitFor(boolean createdVal){
|
||||
synchronized (createdLock){
|
||||
while (created.get() != createdVal){
|
||||
try {
|
||||
createdLock.wait();
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void internalCreate() {
|
||||
timer = new NanoTimer();
|
||||
synchronized (createdLock){
|
||||
created.set(true);
|
||||
createdLock.notifyAll();
|
||||
}
|
||||
// renderer initialization must happen in subclass.
|
||||
/*if (renderable.get()){
|
||||
initContextFirstTime();
|
||||
}else{
|
||||
assert getType() == Type.Canvas;
|
||||
}*/
|
||||
}
|
||||
|
||||
protected void internalDestroy() {
|
||||
renderer = null;
|
||||
timer = null;
|
||||
renderable.set(false);
|
||||
synchronized (createdLock){
|
||||
created.set(false);
|
||||
createdLock.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
307
engine/src/jogl/com/jme3/system/jogl/JoglDisplay.java
Normal file
307
engine/src/jogl/com/jme3/system/jogl/JoglDisplay.java
Normal file
@ -0,0 +1,307 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 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.jme3.system.jogl;
|
||||
|
||||
import com.jme3.system.AppSettings;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.DisplayMode;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.media.opengl.GLAutoDrawable;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
public class JoglDisplay extends JoglAbstractDisplay {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(JoglDisplay.class.getName());
|
||||
|
||||
protected AtomicBoolean windowCloseRequest = new AtomicBoolean(false);
|
||||
protected AtomicBoolean needClose = new AtomicBoolean(false);
|
||||
protected AtomicBoolean needRestart = new AtomicBoolean(false);
|
||||
protected boolean wasInited = false;
|
||||
protected Frame frame;
|
||||
|
||||
public Type getType() {
|
||||
return Type.Display;
|
||||
}
|
||||
|
||||
protected DisplayMode getFullscreenDisplayMode(DisplayMode[] modes, int width, int height, int bpp, int freq){
|
||||
for (DisplayMode mode : modes){
|
||||
if (mode.getWidth() == width
|
||||
&& mode.getHeight() == height
|
||||
&& (mode.getBitDepth() == DisplayMode.BIT_DEPTH_MULTI
|
||||
|| mode.getBitDepth() == bpp
|
||||
|| (mode.getBitDepth() == 32 && bpp==24))
|
||||
&& mode.getRefreshRate() == freq){
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void createGLFrame(){
|
||||
Container contentPane;
|
||||
if (useAwt){
|
||||
frame = new Frame(settings.getTitle());
|
||||
contentPane = frame;
|
||||
}else{
|
||||
frame = new JFrame(settings.getTitle());
|
||||
contentPane = ((JFrame)frame).getContentPane();
|
||||
}
|
||||
|
||||
contentPane.setLayout(new BorderLayout());
|
||||
|
||||
applySettings(settings);
|
||||
|
||||
frame.setResizable(false);
|
||||
frame.setFocusable(true);
|
||||
|
||||
// only add canvas after frame is visible
|
||||
contentPane.add(canvas, BorderLayout.CENTER);
|
||||
//frame.pack();
|
||||
// frame.setSize(contentPane.getPreferredSize());
|
||||
frame.setSize(settings.getWidth(),settings.getHeight());
|
||||
|
||||
if (device.getFullScreenWindow() == null){
|
||||
// now that canvas is attached,
|
||||
// determine optimal size to contain it
|
||||
|
||||
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
frame.setLocation((screenSize.width - frame.getWidth()) / 2,
|
||||
(screenSize.height - frame.getHeight()) / 2);
|
||||
}
|
||||
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent evt) {
|
||||
windowCloseRequest.set(true);
|
||||
}
|
||||
@Override
|
||||
public void windowActivated(WindowEvent evt) {
|
||||
active.set(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowDeactivated(WindowEvent evt) {
|
||||
active.set(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void applySettings(AppSettings settings){
|
||||
DisplayMode displayMode;
|
||||
if (settings.getWidth() <= 0 || settings.getHeight() <= 0){
|
||||
displayMode = device.getDisplayMode();
|
||||
settings.setResolution(displayMode.getWidth(), displayMode.getHeight());
|
||||
}else if (settings.isFullscreen()){
|
||||
displayMode = getFullscreenDisplayMode(device.getDisplayModes(),
|
||||
settings.getWidth(), settings.getHeight(),
|
||||
settings.getBitsPerPixel(), settings.getFrequency());
|
||||
if (displayMode == null)
|
||||
throw new RuntimeException("Unable to find fullscreen display mode matching settings");
|
||||
}else{
|
||||
displayMode = new DisplayMode(settings.getWidth(), settings.getHeight(), DisplayMode.BIT_DEPTH_MULTI, DisplayMode.REFRESH_RATE_UNKNOWN);
|
||||
}
|
||||
|
||||
// FIXME: seems to return false even though
|
||||
// it is supported..
|
||||
// if (!device.isDisplayChangeSupported()){
|
||||
// // must use current device mode if display mode change not supported
|
||||
// displayMode = device.getDisplayMode();
|
||||
// settings.setResolution(displayMode.getWidth(), displayMode.getHeight());
|
||||
// }
|
||||
|
||||
frameRate = settings.getFrameRate();
|
||||
logger.log(Level.INFO, "Selected display mode: {0}x{1}x{2} @{3}",
|
||||
new Object[]{displayMode.getWidth(),
|
||||
displayMode.getHeight(),
|
||||
displayMode.getBitDepth(),
|
||||
displayMode.getRefreshRate()});
|
||||
|
||||
canvas.setSize(displayMode.getWidth(), displayMode.getHeight());
|
||||
|
||||
DisplayMode prevDisplayMode = device.getDisplayMode();
|
||||
|
||||
if (settings.isFullscreen() && device.isFullScreenSupported()){
|
||||
frame.setUndecorated(true);
|
||||
|
||||
try{
|
||||
device.setFullScreenWindow(frame);
|
||||
if (!prevDisplayMode.equals(displayMode)
|
||||
&& device.isDisplayChangeSupported()){
|
||||
device.setDisplayMode(displayMode);
|
||||
}
|
||||
} catch (Throwable t){
|
||||
logger.log(Level.SEVERE, "Failed to enter fullscreen mode", t);
|
||||
device.setFullScreenWindow(null);
|
||||
}
|
||||
}else{
|
||||
if (!device.isFullScreenSupported()){
|
||||
logger.warning("Fullscreen not supported.");
|
||||
}else{
|
||||
frame.setUndecorated(false);
|
||||
device.setFullScreenWindow(null);
|
||||
}
|
||||
|
||||
frame.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void initInEDT(){
|
||||
initGLCanvas();
|
||||
|
||||
createGLFrame();
|
||||
|
||||
startGLCanvas();
|
||||
}
|
||||
|
||||
public void init(GLAutoDrawable drawable){
|
||||
// prevent initializing twice on restart
|
||||
if (!wasInited){
|
||||
canvas.requestFocus();
|
||||
|
||||
super.internalCreate();
|
||||
logger.info("Display created.");
|
||||
|
||||
renderer.initialize();
|
||||
listener.initialize();
|
||||
|
||||
wasInited = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void create(boolean waitFor){
|
||||
try {
|
||||
if (waitFor){
|
||||
try{
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
public void run() {
|
||||
initInEDT();
|
||||
}
|
||||
});
|
||||
} catch (InterruptedException ex) {
|
||||
listener.handleError("Interrupted", ex);
|
||||
}
|
||||
}else{
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
initInEDT();
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (InvocationTargetException ex) {
|
||||
throw new AssertionError(); // can never happen
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy(boolean waitFor){
|
||||
needClose.set(true);
|
||||
if (waitFor){
|
||||
waitFor(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void restart() {
|
||||
if (created.get()){
|
||||
needRestart.set(true);
|
||||
}else{
|
||||
throw new IllegalStateException("Display not started yet. Cannot restart");
|
||||
}
|
||||
}
|
||||
|
||||
public void setTitle(String title){
|
||||
if (frame != null)
|
||||
frame.setTitle(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback.
|
||||
*/
|
||||
public void display(GLAutoDrawable drawable) {
|
||||
if (needClose.get()) {
|
||||
listener.destroy();
|
||||
animator.stop();
|
||||
if (settings.isFullscreen()) {
|
||||
device.setFullScreenWindow(null);
|
||||
}
|
||||
frame.dispose();
|
||||
logger.info("Display destroyed.");
|
||||
super.internalDestroy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (windowCloseRequest.get()){
|
||||
listener.requestClose(false);
|
||||
windowCloseRequest.set(false);
|
||||
}
|
||||
|
||||
if (needRestart.getAndSet(false)){
|
||||
// for restarting contexts
|
||||
if (frame.isVisible()){
|
||||
animator.stop();
|
||||
frame.dispose();
|
||||
createGLFrame();
|
||||
startGLCanvas();
|
||||
}
|
||||
}
|
||||
|
||||
// boolean flush = autoFlush.get();
|
||||
// if (animator.isAnimating() != flush){
|
||||
// if (flush)
|
||||
// animator.stop();
|
||||
// else
|
||||
// animator.start();
|
||||
// }
|
||||
|
||||
if (wasActive != active.get()){
|
||||
if (!wasActive){
|
||||
listener.gainFocus();
|
||||
wasActive = true;
|
||||
}else{
|
||||
listener.loseFocus();
|
||||
wasActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
listener.update();
|
||||
renderer.onFrame();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user