Package ponkOut

Source Code of ponkOut.PonkOut

/* Copyright 2010-2012 Christian Matt
*
* This file is part of PonkOut.
*
* PonkOut is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PonkOut is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PonkOut.  If not, see <http://www.gnu.org/licenses/>.
*/

package ponkOut;

import java.nio.ByteBuffer;
import java.util.LinkedList;

import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.ARBMultisample;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.PixelFormat;
import org.lwjgl.util.glu.GLU;
import org.lwjgl.util.vector.Vector2f;

import ponkOut.Menu.MenuState;
import ponkOut.graphics.Font;
import ponkOut.graphics.GameGraphicsObjectsManager;
import ponkOut.graphics.GraphicsObjectsManager;
import ponkOut.graphics.HUDText;
import ponkOut.graphics.MenuGraphicsObjectsManager;
import ponkOut.graphics.Skybox;
import ponkOut.graphics.resources.Texture;
import ponkOut.input.InputManager;

/**
* the main class
*/
public final class PonkOut implements StateChangeListener {
  public static final float COMMON_RADIUS = 0.2f;

  /** game will leave game loop if true */
  private boolean exit;

  /** number of old elapsed time values included for smoothing */
  private static final int SMOOTHING_COUNT = 10;

  /** weight value i as smoothingWeight[i] (oldest first) */
  private float smoothingWeight[] = new float[SMOOTHING_COUNT];

  private LinkedList<Float> elapsedHistory = new LinkedList<Float>();
  private boolean showFPS;
  private static Settings settings = Settings.getInstance();
  private HUDText fpsText;
  private GraphicsObjectsManager goManager;
  private InputManager inputManager;
  private State currentState;

  public PonkOut() {
    exit = false;
    showFPS = false;

    initDisplay();
    initGL();

    MenuGraphicsObjectsManager.init();
    GameGraphicsObjectsManager.init();
    Font.init();
    Skybox.init();

    goManager = new GraphicsObjectsManager();
    inputManager = InputManager.getInstance();
    currentState = new MenuState(this, null);
    currentState.init();

    fpsText = new HUDText("", 10.0f, 0.8f, 0.8f, 1.0f, 0.9f, new Vector2f(1.0f, 1.0f), showFPS, goManager);

    // use Gaussian function for weighting
    float sum = 0.0f;
    for (int i = 0; i < SMOOTHING_COUNT; ++i) {
      double x = i / (SMOOTHING_COUNT - 1.0);
      smoothingWeight[i] = (float) Math.exp(-4.0 * (x - 1.0) * (x - 1.0));
      sum += smoothingWeight[i];
    }

    // normalize weights
    for (int i = 0; i < SMOOTHING_COUNT; ++i)
      smoothingWeight[i] /= sum;

    // init history
    for (int i = 0; i < SMOOTHING_COUNT; ++i)
      elapsedHistory.add(0.0167f);
  }

  public static void initDisplay() {
    int x = settings.getResolutionX();
    int y = settings.getResolutionY();
    int frequency = settings.getFrequency();

    try {
      DisplayMode modes[] = org.lwjgl.util.Display.getAvailableDisplayModes(x, y, x, y, 32, 32, frequency,
          frequency);

      DisplayMode mode = null;

      if (modes.length > 0)
        mode = modes[0];

      if (mode == null) {
        Sys.alert("Error", "Display mode not supported. Switchting to desktop display mode.");

        // use desktop display mode
        mode = Display.getDesktopDisplayMode();

        x = mode.getWidth();
        y = mode.getHeight();
        frequency = mode.getFrequency();

        modes = org.lwjgl.util.Display.getAvailableDisplayModes(x, y, x, y, 32, 32, frequency, frequency);

        if (modes.length > 0)
          mode = modes[0];
        else {
          Sys.alert("Fatal Error", "No valid display mode found.");
          System.exit(1);
        }

        // set fullscreen because we use full resolution now
        settings.setFullscreen(true);
      }

      Display.setDisplayMode(mode);
      Display.setVSyncEnabled(settings.getVSync());
      Display.setFullscreen(settings.getFullscreen());
      Display.setTitle("PonkOut");

      // load icons
      ByteBuffer[] icons = new ByteBuffer[5];
      icons[0] = Texture.getBytes("icon16.tga");
      icons[1] = Texture.getBytes("icon32.tga");
      icons[2] = Texture.getBytes("icon48.tga");
      icons[3] = Texture.getBytes("icon64.tga");
      icons[4] = Texture.getBytes("icon128.tga");

      // set icons
      Display.setIcon(icons);

      // update settings
      settings.setResolution(mode.getWidth(), mode.getHeight());
      settings.setFrequency(mode.getFrequency());

    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    // create display with at least 8 bits alpha, 24 bits color, 1 bit
    // stencil buffer and desired samples
    try {
      Display.create(new PixelFormat(8, 24, 1, settings.getSamples()));
    } catch (LWJGLException e) {
      if (settings.getSamples() > 0 || !settings.getFullscreen()) {
        // probably the desired multisampling value is not supported
        // or desktop uses 16 bit colour and therefore cannot run in
        // windowed mode
        Sys.alert("Error", "Failed creating display. Now trying without anti-aliasing and in fullscreen mode.");
        settings.setSamples(0);
        settings.setFullscreen(true);

        try {
          Display.setFullscreen(true);
          Display.create(new PixelFormat(8, 24, 1, settings.getSamples()));
        } catch (LWJGLException e1) {
          Sys.alert("Fatal Error", "Failed creating display.");
          System.exit(1);
        }
      } else {
        Sys.alert("Fatal Error", "Failed creating display.");
        System.exit(1);
      }
    }
  }

  public static void initGL() {
    // enable depth buffer
    GL11.glEnable(GL11.GL_DEPTH_TEST);
    GL11.glDepthFunc(GL11.GL_LEQUAL);

    // enable backface culling
    GL11.glEnable(GL11.GL_CULL_FACE);
    GL11.glCullFace(GL11.GL_BACK);

    // enable alpha blending
    GL11.glEnable(GL11.GL_BLEND);
    GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);

    // enable textures
    GL11.glEnable(GL11.GL_TEXTURE_2D);

    // set multisampling
    if (settings.getSamples() > 0)
      GL11.glEnable(ARBMultisample.GL_MULTISAMPLE_ARB);

    // init projection matrix
    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glLoadIdentity();
    DisplayMode displayMode = Display.getDisplayMode();
    GLU.gluPerspective(45.0f, (float) displayMode.getWidth() / (float) displayMode.getHeight(), 0.1f, 2000.0f);

    // select modelview matrix
    GL11.glMatrixMode(GL11.GL_MODELVIEW);
    GL11.glLoadIdentity();
  }

  private void gameLoop() {
    // nanoTime() much better on Windows 7 when frame rate is high
    // long lastTime = Sys.getTime();
    long lastTime = System.nanoTime();
    long lastFpsTime = 0;
    int frames = 0;

    while (!exit) {
      // long time = Sys.getTime();
      // long ticksPerSecond = Sys.getTimerResolution();

      long time = System.nanoTime();
      long ticksPerSecond = 1000000000;
      float cur = (float) (time - lastTime) / ticksPerSecond;

      // remove oldest element from list and add current
      elapsedHistory.remove();
      elapsedHistory.add(cur);

      // computed smoothed value
      float elapsedTime = 0.0f;
      int i = 0;
      for (float f : elapsedHistory) {
        elapsedTime += f * smoothingWeight[i];
        ++i;
      }

      lastTime = time;
      ++frames;

      // update fps every second
      if (time - lastFpsTime >= ticksPerSecond) {
        long fps = frames * ticksPerSecond / (time - lastFpsTime);
        fpsText.setText(fps + " fps");
        lastFpsTime = time;
        frames = 0;
      }

      currentState.render();

      // render global stuff
      goManager.drawScene();

      // update window contents
      Display.update();

      inputManager.newFrame();

      // process keyboard events
      while (Keyboard.next()) {
        if (Keyboard.getEventKeyState()) { // key down
          int key = Keyboard.getEventKey();

          // toggle showFPS when F1 is pressed
          if (key == Keyboard.KEY_F1) {
            showFPS = !showFPS;
            fpsText.setVisibility(showFPS);
          }

          // delegate to current state
          currentState.keyDown(key);
        }
      }

      currentState.update(elapsedTime);

      // closing the window exits the game
      if (Display.isCloseRequested())
        exit = true;
    }
  }

  /**
   * the main method
   */
  public static void main(String argv[]) {
    new PonkOut().run();
    System.exit(0);
  }

  /**
   * starts game loop
   */
  private void run() {
    gameLoop();
    Display.destroy();
  }

  @Override
  public void changeState(State state) {
    currentState.cleanup();
    state.init();
    currentState = state;
  }

  @Override
  public void exit() {
    exit = true;
  }
}
TOP

Related Classes of ponkOut.PonkOut

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.