All Downloads are FREE. Search and download functionalities are using the official Maven repository.

playn.java.LWJGLGraphics Maven / Gradle / Ivy

There is a newer version: 2.0.8
Show newest version
/**
 * 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));
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy