org.meanworks.engine.core.Application.java Source code

Java tutorial

Introduction

Here is the source code for org.meanworks.engine.core.Application.java

Source

package org.meanworks.engine.core;

import static org.lwjgl.opengl.GL11.GL_CULL_FACE;
import static org.lwjgl.opengl.GL11.glDisable;
import static org.lwjgl.opengl.GL11.glEnable;

import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
import org.meanworks.engine.EngineConfig;
import org.meanworks.engine.RenderState;
import org.meanworks.engine.asset.AssetManager;
import org.meanworks.engine.camera.Camera;
import org.meanworks.engine.camera.FirstPersonCamera;
import org.meanworks.engine.gui.Gui;
import org.meanworks.engine.gui.impl.Console;
import org.meanworks.engine.gui.impl.PerformanceGraph;
import org.meanworks.engine.render.material.Material;
import org.meanworks.engine.render.opengl.Screen;
import org.meanworks.engine.scene.Scene;
import org.meanworks.engine.scripts.ScriptHandler;
import org.meanworks.engine.util.Timer;

/**
 * Copyright (C) 2013 Steffen Evensen
 * 
 * This program 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.
 * 
 * This program 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
 * this program. If not, see <http://www.gnu.org/licenses/>.
 * 
 * @author Meanz
 */
public abstract class Application implements Runnable {

    /*
     * The singleton for the application
     */
    private static Application application;

    /**
     * 
     * @return
     */
    public static Application getApplication() {
        return application;
    }

    /*
     * Whether the application is running or not
     */
    private boolean running = false;

    /*
     * The application window
     */
    private Screen window = null;

    /*
     * The input handler for the application
     */
    private Input inputHandler = null;

    /*
     * The asset manager for the application
     */
    private AssetManager assetManager = null;

    /*
     * The scene graph for this application
     */
    private Scene scene;

    /*
     * The gui handler for this application
     */
    private Gui guiHandler;

    /*
     * The console for this application, it's an extension of the gui handler
     */
    private Console console;

    /*
     * Not used at the moment
     */
    // private Timer timer;

    /*
     * The script handler for this application, used for external scripts like
     * JavaScript
     */
    private ScriptHandler scriptHandler;

    /*
     * Statistics
     */
    private int fps = 0;
    private int ups = 0;
    private double frameTime = 0.0d;

    /**
     * Construct a new application
     */
    public Application() {
        application = this;
    }

    /*
     * Application settings
     */
    private int targetUps = 50; // Number of updates per second

    /**
     * Get the script handler of this application
     * 
     * @return
     */
    public ScriptHandler getScriptHandler() {
        return scriptHandler;
    }

    /**
     * Forward getter from Scene.getCamera
     * 
     * @return
     */
    public Camera getCamera() {
        if (scene == null) {
            return null;
        }
        return Scene.getCamera();
    }

    /**
     * Get the gui handler of this application
     * 
     * @return
     */
    public Gui getGui() {
        return guiHandler;
    }

    /**
     * Get the scene graph of this application
     * 
     * @return
     */
    public Scene getScene() {
        return scene;
    }

    /**
     * Get the frame time for the last frame
     * 
     * @return
     */
    public double getFrameTime() {
        return frameTime;
    }

    /**
     * Get the asset manager for this application
     * 
     * @return
     */
    public AssetManager getAssetManager() {
        return assetManager;
    }

    /**
     * Get the input handler of this application
     * 
     * @return
     */
    public Input getInputHandler() {
        return inputHandler;
    }

    /**
     * @return the window
     */
    public Screen getWindow() {
        return window;
    }

    /**
     * @param window
     *            the window to set
     */
    public void setWindow(Screen window) {
        this.window = window;
    }

    /**
     * Get the console of this application
     * 
     * @return
     */
    public Console getConsole() {
        return console;
    }

    /**
     * Get the number of frames per second this application is running on
     * 
     * @return
     */
    public int getFps() {
        return fps;
    }

    /**
     * 
     * @return
     */
    public boolean isRunning() {
        return running;
    }

    /**
     * Get the number of updates per second this application is running on
     * 
     * @return
     */
    public int getUps() {
        return ups;
    }

    /**
     * Start this application
     */
    public void start() {
        /*
         * Setup
         */
        setup();

        running = true;
        run();
    }

    /**
     * Stops this application
     */
    public void stop() {
        running = false;
    }

    /**
     * A method that can be overridden so we can hook on window close events
     */
    public void onWindowClose() {
        onExit();
        stop();
    }

    /**
     * The core application loop
     */
    public void run() {
        /*
         * Game Loop
         */
        int MAX_FRAMESKIP = 10;
        long last_game_tick = System.currentTimeMillis();
        long next_game_tick = last_game_tick;
        int loops;
        int fpsc = 0;
        int upsc = 0;
        long last_fps = System.currentTimeMillis();

        int SKIP_TICKS = 1000 / targetUps;

        int savedUps = 0;

        /*
         * Parse what version we are using
         */
        String s = GL11.glGetString(GL11.GL_VERSION);
        if (s.startsWith("2")) {
            // We have to use old
            EngineConfig.usingModernOpenGL = false;
        } else if (s.startsWith("3") || s.startsWith("4")) {
            EngineConfig.usingModernOpenGL = true;
        }

        // Create the timer
        // timer = new Timer();

        /*
         * Create the input handler
         */
        guiHandler = new Gui(this);
        /**
         * Add a console to the application
         */
        getGui().addComponent((console = new Console()));

        inputHandler = new Input();
        assetManager = new AssetManager();
        scene = new Scene();

        getInputHandler().addKeyListener(guiHandler);
        getInputHandler().addMouseListener(guiHandler);

        /*
         * Setup the default material
         */
        Material.DEFAULT_MATERIAL = null;

        if (EngineConfig.usingModernOpenGL) {
            Material.DEFAULT_MATERIAL = new Material("DEFAULT_MATERIAL",
                    AssetManager.loadShader("./data/shaders/colorShader"));
        } else {
            Material.DEFAULT_MATERIAL = new Material("DEFAULT_MATERIAL",
                    AssetManager.loadShader("./data/shaders/150colorShader"));
        }

        /*
         * Set camera details TODO: Cleanup here
         */
        Scene.setCamera(new FirstPersonCamera(Screen.getWidth(), Screen.getHeight(), 60, Screen.getAspect()));

        /*
         * Create our script handler
         */
        scriptHandler = new ScriptHandler();

        /*
         * Preload
         */
        preload();

        /*
         * Start the render/update loop
         */
        while (running) {
            /*
             * Logging
             */
            if (System.currentTimeMillis() - last_fps > 1000) {
                fps = fpsc;
                ups = upsc;
                upsc = 0;
                fpsc = 0;
                last_fps = System.currentTimeMillis();
                PerformanceGraph.tick(1, fps);
            }
            /*
             * Update
             */
            long renderStart = System.nanoTime();
            loops = 0;
            while (System.currentTimeMillis() > next_game_tick && loops < MAX_FRAMESKIP) {

                /*
                 * Update the updates per second
                 */
                if (savedUps != targetUps) {
                    SKIP_TICKS = 1000 / targetUps;
                    savedUps = targetUps;
                }

                /*
                 * Check if we want to close the window
                 */
                if (window.isCloseRequested()) {
                    onWindowClose();
                }

                // UPDATE OUR ASSET MANAGER
                assetManager.update();

                // TEMP LWJGL FUNCTIONS
                Display.processMessages();
                // END OF TEMP LWJGL FUNCTIONS

                // Grab input keys
                inputHandler.update();
                // Parse input keys in the gui handler
                guiHandler.update();
                // Parse updates in the application
                update(); // Call the update function
                scene.update();

                //Post update for the gui handler
                guiHandler.postUpdate();

                next_game_tick += SKIP_TICKS;

                loops++;
                upsc++;
            }
            /*
             * Render and also store the time used to render the frame (Useful
             * for analyzing performance)
             */

            /*
             * Clear the statistics for the last frame
             */
            RenderState.clearRenderedVertices();

            // Clear render state for the next render loop
            RenderState.clearState();
            render(); // Call the render function

            // Clear render state for the scene render loop
            RenderState.clearState();
            scene.render();

            // Clear render state for the gui render loop
            RenderState.clearState();

            glDisable(GL_CULL_FACE);
            guiHandler.render();
            glEnable(GL_CULL_FACE);

            fpsc++;

            window.update();

            long renderEnd = System.nanoTime();
            long deltaRender = renderEnd - renderStart;
            frameTime = (double) (deltaRender * Math.pow(10, -9));
        }
    }

    /**
     * Called when the application is exited
     */
    public abstract void onExit();

    /**
     * Setup the application
     */
    public abstract void setup();

    /**
     * Called to load the application
     */
    public abstract void preload();

    /**
     * Called every update tick
     */
    public abstract void update();

    /**
     * Called every frame
     */
    public abstract void render();

}