Package com.badlogic.gdx.backends.iosrobovm

Source Code of com.badlogic.gdx.backends.iosrobovm.IOSGraphics$IOSUIViewController

/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* 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 com.badlogic.gdx.backends.iosrobovm;

import org.robovm.cocoatouch.coregraphics.CGPoint;
import org.robovm.cocoatouch.coregraphics.CGRect;
import org.robovm.cocoatouch.coregraphics.CGSize;
import org.robovm.cocoatouch.foundation.NSObject;
import org.robovm.cocoatouch.foundation.NSSet;
import org.robovm.cocoatouch.glkit.GLKView;
import org.robovm.cocoatouch.glkit.GLKViewController;
import org.robovm.cocoatouch.glkit.GLKViewControllerDelegate;
import org.robovm.cocoatouch.glkit.GLKViewDelegate;
import org.robovm.cocoatouch.glkit.GLKViewDrawableColorFormat;
import org.robovm.cocoatouch.glkit.GLKViewDrawableDepthFormat;
import org.robovm.cocoatouch.glkit.GLKViewDrawableMultisample;
import org.robovm.cocoatouch.glkit.GLKViewDrawableStencilFormat;
import org.robovm.cocoatouch.opengles.EAGLContext;
import org.robovm.cocoatouch.opengles.EAGLRenderingAPI;
import org.robovm.cocoatouch.uikit.UIDevice;
import org.robovm.cocoatouch.uikit.UIEvent;
import org.robovm.cocoatouch.uikit.UIInterfaceOrientation;
import org.robovm.cocoatouch.uikit.UIScreen;
import org.robovm.cocoatouch.uikit.UIUserInterfaceIdiom;
import org.robovm.objc.Selector;
import org.robovm.objc.annotation.BindSelector;
import org.robovm.rt.bro.annotation.Callback;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Graphics;
import com.badlogic.gdx.LifecycleListener;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.GL11;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.GLCommon;
import com.badlogic.gdx.utils.Array;

// FIXME add GL 1.x support by ripping Android's classes
public class IOSGraphics extends NSObject implements Graphics, GLKViewDelegate,
    GLKViewControllerDelegate {

  private static final String tag = "IOSGraphics";

  static class IOSUIViewController extends GLKViewController {
    final IOSApplication app;
    final IOSGraphics graphics;
    boolean created = false;

    IOSUIViewController(IOSApplication app, IOSGraphics graphics) {
      this.app = app;
      this.graphics = graphics;
    }

    @Override
    public void didRotate(UIInterfaceOrientation orientation) {
      super.didRotate(orientation);
      // get the view size and update graphics
      // FIXME: supporting BOTH (landscape+portrait at same time) is
      // currently not working correctly (needs fix)
      // FIXME screen orientation needs to be stored for
      // Input#getNativeOrientation
      CGSize bounds = app.getBounds(this);
      graphics.width = (int) bounds.width();
      graphics.height = (int) bounds.height();
      graphics.makeCurrent();
      app.listener.resize(graphics.width, graphics.height);
    }

    public boolean shouldAutorotateToInterfaceOrientation(
        UIInterfaceOrientation orientation) {
      // we return "true" if we support the orientation
      switch (orientation) {
      case LandscapeLeft:
      case LandscapeRight:
        return app.config.orientationLandscape;
      default:
        // assume portrait
        return app.config.orientationPortrait;
      }
    }

    @Callback
    @BindSelector("shouldAutorotateToInterfaceOrientation:")
    private static boolean shouldAutorotateToInterfaceOrientation(
        IOSUIViewController self, Selector sel,
        UIInterfaceOrientation orientation) {
      return self.shouldAutorotateToInterfaceOrientation(orientation);
    }
  }

  static class IOSUIView extends GLKView {

    public IOSUIView(CGRect frame, EAGLContext context) {
      super(frame, context);
    }
  }

  IOSApplication app;
  IOSInput input;
  GL20 gl20;
  int width;
  int height;
  long lastFrameTime;
  float deltaTime;
  long framesStart;
  int frames;
  int fps;
  BufferFormat bufferFormat;
  String extensions;

  private float ppiX = 0;
  private float ppiY = 0;
  private float ppcX = 0;
  private float ppcY = 0;
  private float density = 1;

  volatile boolean paused;
  boolean wasPaused;

  IOSApplicationConfiguration config;
  EAGLContext context;
  GLKView view;
  IOSUIViewController viewController;

  public IOSGraphics(CGSize bounds, IOSApplication app, IOSApplicationConfiguration config, IOSInput input, GL20 gl20) {
    this.config = config;
    // setup view and OpenGL
    width = (int) bounds.width();
    height = (int) bounds.height();
    app.debug(tag, bounds.width() + "x" + bounds.height() + ", " + UIScreen.getMainScreen().getScale());
    this.gl20 = gl20;

    context = new EAGLContext(EAGLRenderingAPI.OpenGLES2);

    view = new GLKView(new CGRect(new CGPoint(0, 0), bounds), context) {
      @Override
      public void touchesBegan(NSSet touches, UIEvent event) {
        super.touchesBegan(touches, event);
        IOSGraphics.this.input.touchDown(touches, event);
      }

      @Override
      public void touchesCancelled(NSSet touches, UIEvent event) {
        super.touchesCancelled(touches, event);
        IOSGraphics.this.input.touchUp(touches, event);
      }

      @Override
      public void touchesEnded(NSSet touches, UIEvent event) {
        super.touchesEnded(touches, event);
        IOSGraphics.this.input.touchUp(touches, event);
      }

      @Override
      public void touchesMoved(NSSet touches, UIEvent event) {
        super.touchesMoved(touches, event);
        IOSGraphics.this.input.touchMoved(touches, event);
      }

      @Override
      public void draw(CGRect rect) {
        IOSGraphics.this.draw(this, rect);
      }

    };
    view.setDelegate(this);
    view.setDrawableColorFormat(config.colorFormat);
    view.setDrawableDepthFormat(config.depthFormat);
    view.setDrawableStencilFormat(config.stencilFormat);
    view.setDrawableMultisample(config.multisample);
    view.setMultipleTouchEnabled(true);

    viewController = new IOSUIViewController(app, this);
    viewController.setView(view);
    viewController.setDelegate(this);
    viewController.setPreferredFramesPerSecond(config.preferredFramesPerSecond);

    this.app = app;
    this.input = input;

    // FIXME fix this if we add rgba/depth/stencil flags to
    // IOSApplicationConfiguration
    int r = 0, g = 0, b = 0, a = 0, depth = 0, stencil = 0, samples = 0;
    if(config.colorFormat == GLKViewDrawableColorFormat.RGB565) {
      r = 5; g = 6; b = 5; a = 0;
    } else {
      r = g = b = a = 8;
    }
    if(config.depthFormat == GLKViewDrawableDepthFormat.Format16) {
      depth = 16;
    } else if (config.depthFormat == GLKViewDrawableDepthFormat.Format24) {
      depth = 24;
    } else {
      depth = 0;
    }
    if(config.stencilFormat == GLKViewDrawableStencilFormat.Format8) {
      stencil = 8;
    }
    if(config.multisample == GLKViewDrawableMultisample.Sample4X) {
      samples = 4;
    }
    bufferFormat = new BufferFormat(r, g, b, a, depth, stencil, samples, false);
    this.gl20 = gl20;

    // determine display density and PPI (PPI values via Wikipedia!)
    density = 1f;

    // if ((UIScreen.getMainScreen().respondsToSelector(new
    // Selector("scale")))) {
    float scale = UIScreen.getMainScreen().getScale();
    app.debug(tag, "Calculating density, UIScreen.mainScreen.scale: " + scale);
    if (scale == 2f) density = 2f;

    int ppi;
    if (UIDevice.getCurrentDevice().getUserInterfaceIdiom() == UIUserInterfaceIdiom.Pad) {
      // iPad
      ppi = Math.round(density * 132);
    } else {
      // iPhone or iPodTouch
      ppi = Math.round(density * 163);
    }
    ppiX = ppi;
    ppiY = ppi;
    ppcX = ppiX / 2.54f;
    ppcY = ppiY / 2.54f;
    app.debug(tag, "Display: ppi=" + ppi + ", density=" + density);

    // time + FPS
    lastFrameTime = System.nanoTime();
    framesStart = lastFrameTime;

    paused = false;
    wasPaused = true;
  }

  public void resume() {
    paused = false;
  }

  public void pause() {
    paused = true;
  }

  boolean created = false;
  @Override
  public void draw(GLKView view, CGRect rect) {
    if(!created) {
      app.graphics.makeCurrent();
      app.listener.create();
      app.listener.resize(width, height);
      created = true;
    }
    if (paused) {
      if (!wasPaused) {
        Array<LifecycleListener> listeners = app.lifecycleListeners;
        synchronized (listeners) {
          for (LifecycleListener listener : listeners) {
            listener.pause();
          }
        }
        app.listener.pause();
        wasPaused = true;
      }
      return;
    } else {
      if (wasPaused) {
        Array<LifecycleListener> listeners = app.lifecycleListeners;
        synchronized (listeners) {
          for (LifecycleListener listener : listeners) {
            listener.resume();
          }
        }
        app.listener.resume();
        wasPaused = false;
      }
    }

    long time = System.nanoTime();
    deltaTime = (time - lastFrameTime) / 1000000000.0f;
    lastFrameTime = time;

    frames++;
    if (time - framesStart >= 1000000000l) {
      framesStart = time;
      fps = frames;
      frames = 0;
    }

    makeCurrent();
    input.processEvents();
    app.listener.render();
  }

  void makeCurrent() {
    EAGLContext.setCurrentContext(context);
  }

  @Override
  public void update(GLKViewController controller) {
    makeCurrent();
    app.processRunnables();
  }

  @Override
  public void willPause(GLKViewController controller, boolean pause) {
    if (pause) {
      pause();
    } else {
      resume();
    }
  }

  @Override
  public boolean isGL11Available() {
    return false;
  }

  @Override
  public boolean isGL20Available() {
    return true;
  }

  @Override
  public GLCommon getGLCommon() {
    return gl20;
  }

  @Override
  public GL10 getGL10() {
    return null;
  }

  @Override
  public GL11 getGL11() {
    return null;
  }

  @Override
  public GL20 getGL20() {
    return gl20;
  }

  @Override
  public int getWidth() {
    return width;
  }

  @Override
  public int getHeight() {
    return height;
  }

  @Override
  public float getDeltaTime() {
    return deltaTime;
  }

  @Override
  public float getRawDeltaTime() {
    return deltaTime;
  }

  @Override
  public int getFramesPerSecond() {
    return fps;
  }

  @Override
  public GraphicsType getType() {
    return GraphicsType.iOSGL;
  }

  @Override
  public float getPpiX() {
    return ppiX;
  }

  @Override
  public float getPpiY() {
    return ppiY;
  }

  @Override
  public float getPpcX() {
    return ppcX;
  }

  @Override
  public float getPpcY() {
    return ppcY;
  }

  /**
   * Returns the display density.
   *
   * @return 1.0f for non-retina devices, 2.0f for retina devices.
   */
  @Override
  public float getDensity() {
    return density;
  }

  @Override
  public boolean supportsDisplayModeChange() {
    return false;
  }

  @Override
  public DisplayMode[] getDisplayModes() {
    return new DisplayMode[] { getDesktopDisplayMode() };
  }

  @Override
  public DisplayMode getDesktopDisplayMode() {
    return new IOSDisplayMode(getWidth(), getHeight(), config.preferredFramesPerSecond, bufferFormat.r + bufferFormat.g + bufferFormat.b + bufferFormat.a);
  }

  private class IOSDisplayMode extends DisplayMode {
    protected IOSDisplayMode(int width, int height, int refreshRate,
        int bitsPerPixel) {
      super(width, height, refreshRate, bitsPerPixel);
    }
  }

  @Override
  public boolean setDisplayMode(DisplayMode displayMode) {
    return false;
  }

  @Override
  public boolean setDisplayMode(int width, int height, boolean fullscreen) {
    return false;
  }

  @Override
  public void setTitle(String title) {
  }

  @Override
  public void setVSync(boolean vsync) {
  }

  @Override
  public BufferFormat getBufferFormat() {
    return bufferFormat;
  }

  @Override
  public boolean supportsExtension(String extension) {
    if (extensions == null)
      extensions = Gdx.gl.glGetString(GL10.GL_EXTENSIONS);
    return extensions.contains(extension);
  }

  @Override
  public void setContinuousRendering(boolean isContinuous) {
    // FIXME implement this if possible
  }

  @Override
  public boolean isContinuousRendering() {
    // FIXME implement this if possible
    return true;
  }

  @Override
  public void requestRendering() {
    // FIXME implement this if possible
  }

  @Override
  public boolean isFullscreen() {
    return true;
  }
}
TOP

Related Classes of com.badlogic.gdx.backends.iosrobovm.IOSGraphics$IOSUIViewController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.