Package ae.gl.core

Source Code of ae.gl.core.GLCore

/* [LGPL] Copyright 2010, 2011, 2012 Gima, Irah

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package ae.gl.core;

import java.nio.ByteBuffer;

import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;

import ae.gl.GLMousePoint;
import ae.gl.GLValues;
import ae.routines.ListenerManager;
import ae.routines.S;
import ae.thread.DrainableExecutorService;

public abstract class GLCore {
 
  private boolean requestClose;
  private boolean lastFocusedState;
 
  private String windowTitle;
  private ByteBuffer[] windowIcon;
 
  public ListenerManager<GLKeyboardListener> keyboardListeners;
  public ListenerManager<GLMouseListener> mouseListeners;
 
  private GLMousePoint mousePoint;
 
  private final DrainableExecutorService drainableExecutorService;
 
  public GLCore() {
    requestClose = false;
    lastFocusedState = true;

    windowTitle = "Untitled";
    windowIcon = null;
   
    keyboardListeners = new ListenerManager<>();
    mouseListeners = new ListenerManager<>();
   
    mousePoint = new GLMousePoint();
   
    drainableExecutorService = new DrainableExecutorService();
  }
 
  public DrainableExecutorService getExecutorService() {
    return drainableExecutorService;
  }

  public void startGL(String title) {
    windowTitle = title;
    startGL();   
  }

  public void startGL(String title, ByteBuffer[] icon) {
    windowTitle = title;
    windowIcon = icon;
    startGL();
  }
 
  public void startGL() {
   
    requestClose = false;
    lastFocusedState = true;
   
    Keyboard.enableRepeatEvents(false);
    Display.setTitle(windowTitle);
    Display.setIcon(windowIcon);
   
    contemplateDisplayMode();
   
    GLValues.screenWidth = Display.getWidth();
    GLValues.screenHeight = Display.getHeight();
    GLValues.calculateRatios();
   
    if (glInit()) {
      while (internalLoop()) {
        // fps cap?
        // fap cap?
      }
      glTerminate();
    }

    Display.destroy();
  }
 
  public void requestClose() {
    requestClose = true;
  }
 
  /**
   * Sleep at most the specified amount milliseconds.
   */
  public void sleep(long millis) {
    try {
      Thread.sleep(millis);
    }
    catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
 
  public void swapBuffers() {
    try {
      Display.swapBuffers();
    }
    catch (LWJGLException e) {
      e.printStackTrace();
    }
  }
 
  private void contemplateDisplayMode() {
   
    DisplayModePack displayModePack;
   
    try {
      // request subclass to pick a display mode
      displayModePack = glPickDisplayMode();
      if (displayModePack == null) {
        // subclass specifically requested to let the user choose
        displayModeChooserDialog();
        return;
      }
    }
    catch (Exception e) {
      throw new Error("User class failed to pick a display mode.", e);
    }
   
    try {
      // try to use the returned display mode
      useDisplayModePack(displayModePack);
      return;
    }
    catch (LWJGLException e) {
      S.eprintf("Requested display mode could not be set. Offering the user a choice to select one of the available display modes.", e);
    }
   
    // let the user choose a display mode
    displayModeChooserDialog();
   
  }

  private void displayModeChooserDialog() {
    DisplayModePack dmpUserChosen = DisplayModeChooserDialog.dialogChooseDisplayMode();
    try {
      useDisplayModePack(dmpUserChosen);
    }
    catch (LWJGLException e) {
      throw new Error("No display mode could not be set. Exiting.");
    }
  }

  private void useDisplayModePack(DisplayModePack displayModePack) throws LWJGLException {
   
    if (displayModePack == null) throw new NullPointerException("DisplayModePack must not be null.");
   
    Display.setDisplayMode(displayModePack.getDisplayMode());
    Display.setFullscreen(displayModePack.isFullscreen());
   
//    GLValues.screenWidth = displayModePack.getDisplayMode().getWidth();
//    GLValues.screenHeight = displayModePack.getDisplayMode().getHeight();
//    GLValues.calculateRatios();
   
    if (displayModePack.getPixelFormat() == null) {
      Display.create();
    }
    else {
      Display.create(displayModePack.getPixelFormat());
    }
   
  }
 
  private boolean internalLoop() {
   
    handleKeyboardEvents();
    handleMouseEvents();
    handleFocusChange();
   
    glLoop();

    Display.processMessages();

    drainableExecutorService.executePending();
   
    return (!(Display.isCloseRequested() || requestClose));
   
  }
 
  private void handleFocusChange() {
    boolean isFocused = Display.isActive();
   
    if (lastFocusedState != isFocused) {
      glFocusChanged(isFocused);
      lastFocusedState = isFocused;
    }
  }
 
  private void handleKeyboardEvents() {
    while (Keyboard.next()) {

      if (Keyboard.getEventKeyState() == true) {
        // key changed to down
        for (GLKeyboardListener listener : keyboardListeners) {
          listener.glKeyDown(Keyboard.getEventKey());
        }
       
      }
      else {
        // key changed to up
        for (GLKeyboardListener listener : keyboardListeners) {
          listener.glKeyUp(Keyboard.getEventKey());
        }
      }
     
    } // while
  }
 
  private void handleMouseEvents() {
    while (Mouse.next()) {

      if ((Mouse.getDX() != Mouse.getX()) || (Mouse.getDY() != Mouse.getY())) {
        // mouse has moved
        float x = (float) Mouse.getX() / (float) Display.getDisplayMode().getWidth();
        float y = (float) Mouse.getY() / (float) Display.getDisplayMode().getHeight();
       
        // lwjgl is having a blast at making left-bottom 0,0 "because opengl"
        y = 1-y;
       
        mousePoint.getPoint2D().setXY(x, y);
        mousePoint.getDelta2D().setXY(Mouse.getDX(), Mouse.getDY());
       
        //TODO: 3D point get here
        float xr = GLValues.cameraPositionX + (0.5f-((float)Mouse.getX()/GLValues.screenWidth))*(GLValues.glWidth/GLValues.glHeight)*2*GLValues.cameraPositionZ;
        float yr = GLValues.cameraPositionY - (0.5f-((float)Mouse.getY()/GLValues.screenHeight))*2*GLValues.cameraPositionZ;
        float zr = -1;
       
        mousePoint.getPoint3D().setXYZ(xr, yr, zr);
       
        for (GLMouseListener listener : mouseListeners) {
          listener.glMouseMoved(mousePoint);
        }
      }
     
      if (Mouse.getEventButton() == -1) {
        // no buttons changed
        continue;
      }
     
      if (Mouse.getEventButtonState() == true) {
        // button changed to down
        for (GLMouseListener listener : mouseListeners) {
          listener.glMouseButtonDown(mousePoint, Mouse.getEventButton());
        }
      }
      else {
        // button changed to up
        for (GLMouseListener listener : mouseListeners) {
          listener.glMouseButtonUp(mousePoint, Mouse.getEventButton());
        }
      }
 
    } // while
  }

  public abstract boolean glInit();
  public abstract DisplayModePack glPickDisplayMode() throws Exception;
  public abstract void glLoop();
  public abstract void glFocusChanged(boolean isFocused);
  public abstract void glTerminate();

}
TOP

Related Classes of ae.gl.core.GLCore

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.