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

de.lessvoid.nifty.examples.lwjgl.NiftyExampleLoaderLWJGL Maven / Gradle / Ivy

Go to download

Lots of Nifty example code! You can find the source for nearly all demos/tutorials in here.

There is a newer version: 1.4.3
Show newest version
package de.lessvoid.nifty.examples.lwjgl;

import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.examples.LoggerShortFormat;
import de.lessvoid.nifty.examples.NiftyExample;
import de.lessvoid.nifty.render.batch.BatchRenderDevice;
import de.lessvoid.nifty.render.batch.CheckGL;
import de.lessvoid.nifty.render.batch.spi.GL;
import de.lessvoid.nifty.renderer.lwjgl.input.LwjglInputSystem;
import de.lessvoid.nifty.renderer.lwjgl.render.LwjglBatchRenderBackendCoreProfileFactory;
import de.lessvoid.nifty.renderer.lwjgl.render.LwjglBatchRenderBackendFactory;
import de.lessvoid.nifty.renderer.lwjgl.render.LwjglGL;
import de.lessvoid.nifty.sound.openal.OpenALSoundDevice;
import de.lessvoid.nifty.spi.time.impl.AccurateTimeProvider;

import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.opengl.*;
import org.lwjgl.util.glu.GLU;

import static org.lwjgl.opengl.GL11.glBlendFunc;
import static org.lwjgl.opengl.GL11.glClear;
import static org.lwjgl.opengl.GL11.glClearColor;
import static org.lwjgl.opengl.GL11.glEnable;
import static org.lwjgl.opengl.GL11.glViewport;

/**
 * Loads & runs any {@link de.lessvoid.nifty.examples.NiftyExample} using Nifty and LWJGL.
 *
 * @author void
 * @author Aaron Mahan <[email protected]>
 */
public class NiftyExampleLoaderLWJGL {
  private static final Logger log = Logger.getLogger(NiftyExampleLoaderLWJGL.class.getName());
  private static final boolean USE_CORE_PROFILE = true;
  private static final int WIDTH = 1024;
  private static final int HEIGHT = 768;
  private static LwjglInputSystem inputSystem;
  private static Nifty nifty;

  public interface RenderLoopCallback {
    void process(@Nonnull Nifty nifty);
  }

  /**
   * Easily run any {@link de.lessvoid.nifty.examples.NiftyExample}. Just instantiate your example and pass it to this
   * method. This method will use LWJGL to run your example, automatically creating & initializing an LWJGL application
   * for you before running the example.
   *
   * @param example The {@link de.lessvoid.nifty.examples.NiftyExample} to run.
   */
  public static void run (@Nonnull final NiftyExample example) {
    run (example, null);
  }

  /**
   * Easily run any {@link de.lessvoid.nifty.examples.NiftyExample}. Just instantiate your example and pass it along
   * with your optional custom callback to this method. This method will use LWJGL to run your example, automatically
   * creating & initializing an LWJGL application for you before running the example.
   *
   * @param example The {@link de.lessvoid.nifty.examples.NiftyExample} to run.
   * @param callback Provides access to the render loop by calling your implementation of the process method once at
   *                 the beginning of each frame. You can put any custom code here that needs to be executed every frame.
   *                 It also provides you access to the Nifty instance.
   */
  public static void run (@Nonnull final NiftyExample example, @Nullable RenderLoopCallback callback) {
    if (!initSubSystems(example.getTitle(), USE_CORE_PROFILE)) {
      System.exit(1);
    }

    try {
      example.prepareStart(nifty);
      if (example.getMainXML() != null) {
        nifty.fromXml(example.getMainXML(), example.getStartScreen());
      } else {
        nifty.gotoScreen(example.getStartScreen());
      }
    } catch (Exception e) {
      log.log(Level.SEVERE, "Unable to run Nifty example!", e);
    }

    boolean done = false;

    while (!done) {
      render(nifty, callback);
      done = true;
    }

    shutDown();
  }

  private static boolean initSubSystems(final String windowTitle, final boolean useCoreProfile) {
    try {
      LoggerShortFormat.intialize();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }

    return initGraphics(windowTitle, useCoreProfile) && initInput() && initNifty (inputSystem);
  }

  private static boolean initGraphics(final String title, final boolean enableCoreProfile) {
    int width;
    int height;
    try {
      DisplayMode currentMode = Display.getDisplayMode();
      log.fine("currentmode: " + currentMode.getWidth() + ", " + currentMode.getHeight() + ", " +
          "" + currentMode.getBitsPerPixel() + ", " + currentMode.getFrequency());

      width = currentMode.getWidth();
      height = currentMode.getHeight();

      // Get available display modes.
      DisplayMode[] modes = Display.getAvailableDisplayModes();
      log.fine("Found " + modes.length + " display modes");

      List matching = new ArrayList();
      for (int i = 0; i < modes.length; i++) {
        DisplayMode mode = modes[i];
        if (mode.getWidth() == WIDTH && mode.getHeight() == HEIGHT && mode.getBitsPerPixel() == 32) {
          log.fine(mode.getWidth() + ", " + mode.getHeight() + ", " + mode.getBitsPerPixel() + ", " +
              "" + mode.getFrequency());
          matching.add(mode);
        }
      }

      DisplayMode[] matchingModes = matching.toArray(new DisplayMode[matching.size()]);

      // Find display mode with matching frequency.
      boolean found = false;
      for (final DisplayMode matchingMode : matchingModes) {
        if (matchingMode.getFrequency() == currentMode.getFrequency()) {
          log.fine("using mode: " + matchingMode.getWidth() + ", "
                  + matchingMode.getHeight() + ", "
                  + matchingMode.getBitsPerPixel() + ", "
                  + matchingMode.getFrequency());
          Display.setDisplayMode(matchingMode);
          found = true;
          break;
        }
      }

      if (!found) {
        Arrays.sort(matchingModes, new Comparator() {
          @Override
          public int compare(@Nonnull final DisplayMode o1, @Nonnull final DisplayMode o2) {
            if (o1.getFrequency() > o2.getFrequency()) {
              return 1;
            } else if (o1.getFrequency() < o2.getFrequency()) {
              return -1;
            } else {
              return 0;
            }
          }
        });

        for (int i = 0; i < matchingModes.length; i++) {
          try {
            log.fine("using fallback mode: " + matchingModes[i].getWidth() + ", "
                + matchingModes[i].getHeight() + ", "
                + matchingModes[i].getBitsPerPixel() + ", "
                + matchingModes[i].getFrequency());
            Display.setDisplayMode(matchingModes[i]);
            break;
          } catch (LWJGLException ignored) {
          }
        }
      }

      int x = (width - Display.getDisplayMode().getWidth()) / 2;
      int y = (height - Display.getDisplayMode().getHeight()) / 2;
      Display.setLocation(x, y);

      // Create the window.
      try {
        Display.setFullscreen(false);
        if (enableCoreProfile) {
          Display.create(new PixelFormat(), new ContextAttribs(3, 2).withProfileCore(true));
        } else {
          Display.create();
        }
        Display.setVSyncEnabled(false);
        Display.setTitle(title);
      } catch (Exception e) {
        e.printStackTrace();
        log.warning("Unable to create window!, exiting...");
        System.exit(-1);
      }

      log.fine(
          "Width: " + Display.getDisplayMode().getWidth()
              + ", Height: " + Display.getDisplayMode().getHeight()
              + ", Bits per pixel: " + Display.getDisplayMode().getBitsPerPixel()
              + ", Frequency: " + Display.getDisplayMode().getFrequency()
              + ", Title: " + Display.getTitle());

      log.fine("platform: " + LWJGLUtil.getPlatformName());
      log.fine("opengl version: " + GL11.glGetString(GL11.GL_VERSION));
      log.fine("opengl vendor: " + GL11.glGetString(GL11.GL_VENDOR));
      log.fine("opengl renderer: " + GL11.glGetString(GL11.GL_RENDERER));

      GL gl = new LwjglGL();

      if (enableCoreProfile) {
        String extensions = GL30.glGetStringi(GL11.GL_EXTENSIONS, 0);
        if (extensions != null) {
          String[] ext = extensions.split(" ");
          for (int i = 0; i < ext.length; i++) {
            log.finer("opengl extensions: " + ext[i]);
          }
        }
        CheckGL.checkGLError(gl, "extension check failed");

        glViewport(0, 0, Display.getDisplayMode().getWidth(), Display.getDisplayMode().getHeight());
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glClear(GL11.GL_COLOR_BUFFER_BIT);
        glEnable(GL11.GL_BLEND);
        glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
      } else {
        String extensions = GL11.glGetString(GL11.GL_EXTENSIONS);
        if (extensions != null) {
          String[] ext = extensions.split(" ");
          for (int i = 0; i < ext.length; i++) {
            log.finer("opengl extensions: " + ext[i]);
          }
        }
        CheckGL.checkGLError(gl, "extension check failed");

        IntBuffer viewportBuffer = BufferUtils.createIntBuffer(4 * 4);
        GL11.glGetInteger(GL11.GL_VIEWPORT, viewportBuffer);
        int viewportWidth = viewportBuffer.get(2);
        int viewportHeight = viewportBuffer.get(3);

        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GL11.glOrtho(0, viewportWidth, viewportHeight, 0, -9999, 9999);

        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glLoadIdentity();

        GL11.glDisable(GL11.GL_DEPTH_TEST);
        glEnable(GL11.GL_BLEND);
        GL11.glDisable(GL11.GL_CULL_FACE);

        glEnable(GL11.GL_ALPHA_TEST);
        GL11.glAlphaFunc(GL11.GL_NOTEQUAL, 0);

        GL11.glDisable(GL11.GL_LIGHTING);
        GL11.glDisable(GL11.GL_TEXTURE_2D);

        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glClear(GL11.GL_COLOR_BUFFER_BIT);
        glEnable(GL11.GL_TEXTURE_2D);
      }

      return true;
    } catch (LWJGLException e) {
      e.printStackTrace();
      return false;
    }
  }

  private static boolean initInput() {
    try {
      inputSystem = new LwjglInputSystem();
      inputSystem.startup();
      return true;
    } catch (Exception e) {
      e.printStackTrace();
      log.warning("Unable to create keyboard!, exiting...");
      return false;
    }
  }

  private static boolean initNifty (final LwjglInputSystem inputSystem) {
    try {
      log.info ("\n\nRunning in OpenGL " + (USE_CORE_PROFILE ? "Core Profile Mode (3.2+)" : "Compatibility Mode (1.2)") + ".\n\n");
      nifty = new Nifty(
              new BatchRenderDevice(USE_CORE_PROFILE ? LwjglBatchRenderBackendCoreProfileFactory.create() : LwjglBatchRenderBackendFactory.create()),
              new OpenALSoundDevice(),
              inputSystem,
              new AccurateTimeProvider());
      return true;
    } catch (Exception e) {
      e.printStackTrace();
      log.warning("Unable to create Nifty!, exiting...");
      return false;
    }
  }

  private static void render(@Nonnull final Nifty nifty, @Nullable final RenderLoopCallback callback) {
    boolean done = false;
    while (!Display.isCloseRequested() && !done) {
      if (callback != null) {
        callback.process(nifty);
      }

      // Show rendering.
      Display.update();

      if (nifty.update()) {
        done = true;
      }

      nifty.render(true);

      // Check for OpenGL errors at least once per frame.
      int error = GL11.glGetError();
      if (error != GL11.GL_NO_ERROR) {
        String glerrmsg = GLU.gluErrorString(error);
        log.warning("OpenGL Error: (" + error + ") " + glerrmsg);
      }
    }
  }

  private static void shutDown() {
    inputSystem.shutdown();
    Display.destroy();
    System.exit(0);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy