Java tutorial
/** * Copyright 2010-2015 The PlayN Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ package playn.java; import java.awt.image.BufferedImage; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; import java.awt.image.DataBufferInt; import java.nio.ByteBuffer; import java.util.Arrays; import org.lwjgl.LWJGLException; import org.lwjgl.opengl.Display; import org.lwjgl.opengl.DisplayMode; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; import playn.core.*; import pythagoras.f.Dimension; import pythagoras.f.IDimension; public class LWJGLGraphics extends JavaGraphics { private final Dimension screenSize = new Dimension(); public LWJGLGraphics(JavaPlatform plat) { super(plat, new LWJGLGL20(), Scale.ONE); // have to get scale after Display.create() setDisplayMode(plat.config.width, plat.config.height, plat.config.fullscreen); try { System.setProperty("org.lwjgl.opengl.Display.enableHighDPI", "true"); Display.create(); checkScaleFactor(); } catch (LWJGLException e) { throw new RuntimeException(e); } } void checkScaleFactor() { float scaleFactor = Display.getPixelScaleFactor(); if (scaleFactor != scale().factor) updateViewport(new Scale(scaleFactor), Display.getWidth(), Display.getHeight()); } @Override public void setTitle(String title) { Display.setTitle(title); } @Override public IDimension screenSize() { DisplayMode mode = Display.getDesktopDisplayMode(); screenSize.width = scale().invScaled(mode.getWidth()); screenSize.height = scale().invScaled(mode.getHeight()); return screenSize; } @Override public void setSize(int width, int height, boolean fullscreen) { setDisplayMode(width, height, fullscreen); } @Override protected void upload(BufferedImage img, Texture tex) { // Convert the bitmap into a format for quick uploading (NOOPs if already optimized) BufferedImage bitmap = convertImage(img); DataBuffer dbuf = bitmap.getRaster().getDataBuffer(); ByteBuffer bbuf; int format, type; if (bitmap.getType() == BufferedImage.TYPE_INT_ARGB_PRE) { DataBufferInt ibuf = (DataBufferInt) dbuf; int iSize = ibuf.getSize() * 4; bbuf = checkGetImageBuffer(iSize); bbuf.asIntBuffer().put(ibuf.getData()); bbuf.position(bbuf.position() + iSize); bbuf.flip(); format = GL12.GL_BGRA; type = GL12.GL_UNSIGNED_INT_8_8_8_8_REV; } else if (bitmap.getType() == BufferedImage.TYPE_4BYTE_ABGR) { DataBufferByte dbbuf = (DataBufferByte) dbuf; bbuf = checkGetImageBuffer(dbbuf.getSize()); bbuf.put(dbbuf.getData()); bbuf.flip(); format = GL11.GL_RGBA; type = GL12.GL_UNSIGNED_INT_8_8_8_8; } else { // Something went awry and convertImage thought this image was in a good form already, // except we don't know how to deal with it throw new RuntimeException("Image type wasn't converted to usable: " + bitmap.getType()); } gl.glBindTexture(GL11.GL_TEXTURE_2D, tex.id); GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, bitmap.getWidth(), bitmap.getHeight(), 0, format, type, bbuf); gl.checkError("updateTexture"); } protected void setDisplayMode(int width, int height, boolean fullscreen) { try { // check if current mode is suitable DisplayMode mode = Display.getDisplayMode(); if (fullscreen == Display.isFullscreen() && mode.getWidth() == width && mode.getHeight() == height) return; if (!fullscreen) { DisplayMode deskMode = Display.getDesktopDisplayMode(); if (width > deskMode.getWidth()) { plat.log().debug( "Capping window width at desktop width: " + width + " -> " + deskMode.getWidth()); width = deskMode.getWidth(); } if (height > deskMode.getHeight()) { plat.log().debug( "Capping window height at desktop height: " + height + " -> " + deskMode.getHeight()); height = deskMode.getHeight(); } mode = new DisplayMode(width, height); } else { // try and find a mode matching width and height DisplayMode matching = null; for (DisplayMode dm : Display.getAvailableDisplayModes()) { if (dm.getWidth() == width && dm.getHeight() == height && dm.isFullscreenCapable()) { matching = dm; } } if (matching != null) mode = matching; else plat.log().info("Could not find a matching fullscreen mode, available: " + Arrays.asList(Display.getAvailableDisplayModes())); } plat.log().debug("Updating display mode: " + mode + ", fullscreen: " + fullscreen); // TODO: fix crashes when fullscreen is toggled repeatedly Scale scale; if (fullscreen) { Display.setDisplayModeAndFullscreen(mode); scale = Scale.ONE; // TODO: fix alt-tab, maybe add a key listener or something? } else { Display.setDisplayMode(mode); scale = new Scale(Display.getPixelScaleFactor()); } updateViewport(scale, mode.getWidth(), mode.getHeight()); } catch (LWJGLException ex) { throw new RuntimeException(ex); } } private void updateViewport(Scale scale, float displayWidth, float displayHeight) { scaleChanged(scale); viewportChanged(scale.scaledCeil(displayWidth), scale.scaledCeil(displayHeight)); } }