package engine;
import engine.model.CTexture;
import engine.model.CTextureCube;
import engine.model.Material;
import engine.model.ObjModel;
import engine.model.Shader;
import engine.util.Timer;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.ARBShadingLanguage100;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import static org.lwjgl.opengl.GL11.*;
import org.lwjgl.util.glu.GLU;
import static org.lwjgl.util.glu.GLU.*;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;
/**
* Workname 'GfxEngine' is a game-engine.
* @author jari <rasaari@gmail.com>
* @author simo <simppak@gmail.com>
*/
public class GfxEngine {
public int DISPLAY_HEIGHT = 800;
public int DISPLAY_WIDTH = 1280;
private float zNear = 0.1f, zFar = 10000f, fov = 80f;
public static boolean RENDER_WIREFRAMES = false;
public static final Logger LOGGER = Logger.getLogger(GfxEngine.class.getName());
protected Entity camera;
public static Matrix4f viewMatrix, projectionMatrix;
protected static FloatBuffer viewMatrixBuffer, projectionMatrixBuffer;
public static HashMap<String,ObjModel> models;
public static HashMap<String,Material> materials;
public static HashMap<String,CTexture> textures;
public static HashMap<String,Shader> shaders;
protected static float [][] frustum;
private long previousTime, currentTime, frameBeginning, frameLogic, frameRender;
private Timer graphTimer;
private Vector<Long[]> processTimes = new Vector<>();
protected static float appSpeed;
static {
try {
LOGGER.addHandler(new FileHandler("errors.log",true));
}
catch(IOException ex) {
LOGGER.log(Level.WARNING,ex.toString(),ex);
}
}
protected void toggleWireframes(){
RENDER_WIREFRAMES = (RENDER_WIREFRAMES == true)?false:true;
glPolygonMode(GL_FRONT_AND_BACK,(RENDER_WIREFRAMES == true)?GL_LINE:GL_FILL);
}
public static void reloadShaders(){
if(shaders.isEmpty())
return;
Collection c = shaders.values();
Iterator itr = c.iterator();
while(itr.hasNext()){
Shader sh = (Shader)itr.next();
sh.recreate();
}
}
public static void reloadTextures(){
if(textures.isEmpty())
return;
Collection c = textures.values();
Iterator itr = c.iterator();
while(itr.hasNext()){
CTexture tex = (CTexture)itr.next();
tex.recreate();
}
}
public static Shader loadShader(String vert, String frag){
if(vert == null || frag == null || vert.isEmpty() || frag.isEmpty()) return null;
if(shaders.containsKey(vert+frag) == false){
shaders.put(vert+frag,new Shader(vert, frag));
}
return shaders.get(vert+frag);
}
/**
* Returns a reference to a CTexture when provided with the Texture's filepath.
* Loads the Texture if it doesn't already exist.
*
* @param name path to the file
* @return a CTexture or CTexture with null Texture if the file doesnt exist
*/
public static CTexture loadTexture(String name){
if(name == null || name.isEmpty()) return null;
if(textures.containsKey(name) == false){
textures.put(name, new CTexture().create(name));
}
return textures.get(name);
}
public static CTextureCube loadCubemap(String name){
if(name == null || name.isEmpty()) return null;
if(textures.containsKey(name) == false){
textures.put(name, new CTextureCube(name));
}
return (CTextureCube)textures.get(name);
}
/**
* Returns a reference to an ObjModel when provided with the Model's filepath
* Loads the Model if it doesn't already exist.
*
* @param name path to the file
* @return the ObjModel or null if the file doesnt exist
*/
public static ObjModel loadModel(String name){
if(name == null || name.isEmpty()) return null;
if(models.containsKey(name) == false){
models.put(name, new ObjModel(name));
}
return models.get(name);
}
/**
* Returns a reference to a Material when provided with the Material's filepath
* Loads the Material if it doesn't already exist.
*
* @param name path to the file
* @return the Material or null if the file doesnt exist
*/
public static Material loadMaterial(String name){
if(name == null || name.isEmpty()) return materials.get("null");
if(materials.containsKey(name) == false){
materials.put(name, new Material().create(name));
}
return materials.get(name);
}
/**
* Returns a clone of the original Material
*
* @param name path to the original material's file
* @return the Material or null if the file doesnt exist
*/
public static Material cloneMaterial(String name){
if(name == null || name.isEmpty()) return null;
if(materials.containsKey(name) == false){
return null;
}
return (Material)materials.get(name).clone();
}
public static final float distance(Vec3f one, Vec3f two){
return (float)Math.sqrt(Math.pow(one.x-two.x, 2.0) + Math.pow(one.y-two.y, 2.0) + Math.pow(one.z-two.z, 2.0));
}
public static float appSpeed(){
return appSpeed;
}
public static FloatBuffer viewMatrix(){
//System.out.println(viewMatrixBuffer.get(7));
return viewMatrixBuffer;
}
public static FloatBuffer projectionMatrix(){
//System.out.println(viewMatrixBuffer.get(7));
return projectionMatrixBuffer;
}
/**
* Default constructor. Initializes all systems.
*/
public GfxEngine() {
camera = new Entity();
viewMatrix = new Matrix4f();
projectionMatrix = new Matrix4f();
viewMatrixBuffer = BufferUtils.createFloatBuffer(16);
projectionMatrixBuffer = BufferUtils.createFloatBuffer(16);
models = new HashMap<>();
materials = new HashMap<>();
textures = new HashMap<>();
shaders = new HashMap<>();
frustum = new float[6][4];
appSpeed = 1.0f;
previousTime = 0;
currentTime = 17;
}
/**
* opens the window and start the app
*/
public void start() {
try {
this.create();
this.init();
this.run();
} catch(Exception e) {
LOGGER.log(Level.SEVERE, e.toString(), e);
} finally {
this.destroy();
}
}
protected void ExtractFrustum(){
FloatBuffer proj = BufferUtils.createFloatBuffer(16);
FloatBuffer modl = BufferUtils.createFloatBuffer(16);
FloatBuffer clip = BufferUtils.createFloatBuffer(16);
float t;
/* Get the current PROJECTION matrix from OpenGL */
glGetFloat(GL_PROJECTION_MATRIX, proj);
/* Get the current MODELVIEW matrix from OpenGL */
glGetFloat( GL_MODELVIEW_MATRIX, modl );
/* Combine the two matrices (multiply projection by modelview) */
clip.put( 0, modl.get( 0) * proj.get( 0) + modl.get( 1) * proj.get( 4) + modl.get( 2) * proj.get( 8) + modl.get( 3) * proj.get(12));
clip.put( 1, modl.get( 0) * proj.get( 1) + modl.get( 1) * proj.get( 5) + modl.get( 2) * proj.get( 9) + modl.get( 3) * proj.get(13));
clip.put( 2, modl.get( 0) * proj.get( 2) + modl.get( 1) * proj.get( 6) + modl.get( 2) * proj.get(10) + modl.get( 3) * proj.get(14));
clip.put( 3, modl.get( 0) * proj.get( 3) + modl.get( 1) * proj.get( 7) + modl.get( 2) * proj.get(11) + modl.get( 3) * proj.get(15));
clip.put( 4, modl.get( 4) * proj.get( 0) + modl.get( 5) * proj.get( 4) + modl.get( 6) * proj.get( 8) + modl.get( 7) * proj.get(12));
clip.put( 5, modl.get( 4) * proj.get( 1) + modl.get( 5) * proj.get( 5) + modl.get( 6) * proj.get( 9) + modl.get( 7) * proj.get(13));
clip.put( 6, modl.get( 4) * proj.get( 2) + modl.get( 5) * proj.get( 6) + modl.get( 6) * proj.get(10) + modl.get( 7) * proj.get(14));
clip.put( 7, modl.get( 4) * proj.get( 3) + modl.get( 5) * proj.get( 7) + modl.get( 6) * proj.get(11) + modl.get( 7) * proj.get(15));
clip.put( 8, modl.get( 8) * proj.get( 0) + modl.get( 9) * proj.get( 4) + modl.get(10) * proj.get( 8) + modl.get(11) * proj.get(12));
clip.put( 9, modl.get( 8) * proj.get( 1) + modl.get( 9) * proj.get( 5) + modl.get(10) * proj.get( 9) + modl.get(11) * proj.get(13));
clip.put(10, modl.get( 8) * proj.get( 2) + modl.get( 9) * proj.get( 6) + modl.get(10) * proj.get(10) + modl.get(11) * proj.get(14));
clip.put(11, modl.get( 8) * proj.get( 3) + modl.get( 9) * proj.get( 7) + modl.get(10) * proj.get(11) + modl.get(11) * proj.get(15));
clip.put(12, modl.get(12) * proj.get( 0) + modl.get(13) * proj.get( 4) + modl.get(14) * proj.get( 8) + modl.get(15) * proj.get(12));
clip.put(13, modl.get(12) * proj.get( 1) + modl.get(13) * proj.get( 5) + modl.get(14) * proj.get( 9) + modl.get(15) * proj.get(13));
clip.put(14, modl.get(12) * proj.get( 2) + modl.get(13) * proj.get( 6) + modl.get(14) * proj.get(10) + modl.get(15) * proj.get(14));
clip.put(15, modl.get(12) * proj.get( 3) + modl.get(13) * proj.get( 7) + modl.get(14) * proj.get(11) + modl.get(15) * proj.get(15));
/* Extract the numbers for the RIGHT plane */
frustum[0][0] = clip.get(3) - clip.get(0);
frustum[0][1] = clip.get(7) - clip.get(4);
frustum[0][2] = clip.get(11) - clip.get(8);
frustum[0][3] = clip.get(15) - clip.get(12);
/* Normalize the result */
t = (float)Math.sqrt( frustum[0][0] * frustum[0][0] + frustum[0][1] * frustum[0][1] + frustum[0][2] * frustum[0][2] );
frustum[0][0] /= t;
frustum[0][1] /= t;
frustum[0][2] /= t;
frustum[0][3] /= t;
/* Extract the numbers for the LEFT plane */
frustum[1][0] = clip.get(3) + clip.get(0);
frustum[1][1] = clip.get(7) + clip.get(4);
frustum[1][2] = clip.get(11) + clip.get(8);
frustum[1][3] = clip.get(15) + clip.get(12);
/* Normalize the result */
t = (float)Math.sqrt( frustum[1][0] * frustum[1][0] + frustum[1][1] * frustum[1][1] + frustum[1][2] * frustum[1][2] );
frustum[1][0] /= t;
frustum[1][1] /= t;
frustum[1][2] /= t;
frustum[1][3] /= t;
/* Extract the BOTTOM plane */
frustum[2][0] = clip.get(3) + clip.get(1);
frustum[2][1] = clip.get(7) + clip.get(5);
frustum[2][2] = clip.get(11) + clip.get(9);
frustum[2][3] = clip.get(15) + clip.get(13);
/* Normalize the result */
t = (float)Math.sqrt( frustum[2][0] * frustum[2][0] + frustum[2][1] * frustum[2][1] + frustum[2][2] * frustum[2][2] );
frustum[2][0] /= t;
frustum[2][1] /= t;
frustum[2][2] /= t;
frustum[2][3] /= t;
/* Extract the TOP plane */
frustum[3][0] = clip.get(3) - clip.get(1);
frustum[3][1] = clip.get(7) - clip.get(5);
frustum[3][2] = clip.get(11) - clip.get(9);
frustum[3][3] = clip.get(15) - clip.get(13);
/* Normalize the result */
t = (float)Math.sqrt( frustum[3][0] * frustum[3][0] + frustum[3][1] * frustum[3][1] + frustum[3][2] * frustum[3][2] );
frustum[3][0] /= t;
frustum[3][1] /= t;
frustum[3][2] /= t;
frustum[3][3] /= t;
/* Extract the FAR plane */
frustum[4][0] = clip.get(3) - clip.get(2);
frustum[4][1] = clip.get(7) - clip.get(6);
frustum[4][2] = clip.get(11) - clip.get(10);
frustum[4][3] = clip.get(15) - clip.get(14);
/* Normalize the result */
t = (float)Math.sqrt( frustum[4][0] * frustum[4][0] + frustum[4][1] * frustum[4][1] + frustum[4][2] * frustum[4][2] );
frustum[4][0] /= t;
frustum[4][1] /= t;
frustum[4][2] /= t;
frustum[4][3] /= t;
/* Extract the NEAR plane */
frustum[5][0] = clip.get(3) + clip.get(2);
frustum[5][1] = clip.get(7) + clip.get(6);
frustum[5][2] = clip.get(11) + clip.get(10);
frustum[5][3] = clip.get(15) + clip.get(14);
/* Normalize the result */
t = (float)Math.sqrt( frustum[5][0] * frustum[5][0] + frustum[5][1] * frustum[5][1] + frustum[5][2] * frustum[5][2] );
frustum[5][0] /= t;
frustum[5][1] /= t;
frustum[5][2] /= t;
frustum[5][3] /= t;
}
public static boolean PointInFrustum(Vec3f v, float radius){
int p;
for( p = 0; p < 6; p++ ) {
if( frustum[p][0] * v.x + frustum[p][1] * v.y + frustum[p][2] * v.z + frustum[p][3] < -radius ) {
return false;
}
}
return true;
}
/**
* Prototype pick function - doesn't work.
*
* @param mouseX mouse x coordinates
* @param mouseY mouse y coordinates
*/
public void pick(int mouseX, int mouseY){
IntBuffer selBuffer = ByteBuffer.allocateDirect(1024).order(ByteOrder.nativeOrder()).asIntBuffer();
int buffer[] = new int[256];
IntBuffer vpBuffer = ByteBuffer.allocateDirect(64).order(ByteOrder.nativeOrder()).asIntBuffer();
int[] viewport = new int[4];
int hits;
glGetInteger(GL_VIEWPORT, vpBuffer);
vpBuffer.get(viewport);
glSelectBuffer(selBuffer);
// Change to selection mode
glRenderMode(GL_SELECT);
// Initialize the name stack (used for identifying which object was selected)
glInitNames();
glPushName(0);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
/* create 5x5 pixel picking region near cursor location */
GLU.gluPickMatrix( (float) mouseX, (float) mouseY, 5.0f, 5.0f, vpBuffer);
gluPerspective(80,(float)DISPLAY_WIDTH/(float)DISPLAY_HEIGHT,0.1f,1000);
//glOrtho(0.0, 8.0, 0.0, 8.0, -0.5, 2.5);
this.drawEntities();
glPopMatrix();
// Exit selection mode and return to render mode, returns number selected
hits = glRenderMode(GL_RENDER);
System.out.println("Number: " + hits);
System.out.println("Name stack depth: "+glGetInteger(GL_NAME_STACK_DEPTH));
selBuffer.get(buffer);
// Objects Were Drawn Where The Mouse Was
if (hits > 0) {
// If There Were More Than 0 Hits
int choose = buffer[3]; // Make Our Selection The First Object
int depth = buffer[1]; // Store How Far Away It Is
for (int i = 1; i < hits; i++) {
// Loop Through All The Detected Hits
// If This Object Is Closer To Us Than The One We Have Selected
if (buffer[i * 4 + 1] < (int) depth) {
choose = buffer[i * 4 + 3]; // Select The Closer Object
depth = buffer[i * 4 + 1]; // Store How Far Away It Is
}
}
System.out.println("Chosen: " + choose);
}
}
/**
* Initializes the OpenGL renderer
*/
public void create() throws LWJGLException {
//Display
Display.setDisplayMode(new DisplayMode(DISPLAY_WIDTH,DISPLAY_HEIGHT));
Display.setFullscreen(false);
Display.setTitle("Java+GfxEngine");
Display.create();
//OpenGL version & other such things for debugging
System.out.println("OpenGL version: " + glGetString(GL_VERSION));
System.out.println("GLSL version: "+glGetString(ARBShadingLanguage100.GL_SHADING_LANGUAGE_VERSION_ARB));
System.out.println("Depth buffer: "+glGetInteger(GL_DEPTH_BITS)+"bit");
System.out.println("Name Stack max depth: "+glGetInteger(GL_MAX_NAME_STACK_DEPTH));
System.out.println("--------------------------------------------------");
//Keyboard
Keyboard.create();
//Mouse
Mouse.setGrabbed(false);
Mouse.create();
Long lo[] = {1L,1L};
for(int i=0;i<100;i++) {
this.processTimes.add(lo);
}
this.graphTimer = new Timer();
initGL();
resizeGL();
appSpeed = 1.0f;
previousTime = 0;
currentTime = 17;
materials.put("null",new Material().create(null));
}
public void destroy() {
//Methods already check if created before destroying.
Mouse.destroy();
Keyboard.destroy();
Display.destroy();
System.out.println("Bye!");
}
/**
* Sets OpenGL flags, during initialization.
*/
public void initGL() {
//2D Initialization
glClearColor(0.0f,0.0f,0.0f,0.0f);
//OpenGL
glDisable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_BLEND);
glShadeModel(GL_SMOOTH);
}
private void render2D(){
this.ready2D();
glEnable(GL_BLEND);
int yOffset = DISPLAY_HEIGHT-20;
glPushMatrix();
glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
glBegin(GL_QUADS);
glVertex2f(315f,yOffset-85);
glVertex2f(15f,yOffset-85);
glVertex2f(15f,yOffset+2);
glVertex2f(315f,yOffset+2);
glEnd();
glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
glBegin(GL_LINE_STRIP);
for(int i=0;i<this.processTimes.size();i++){
glVertex2f(i*3+15, -this.processTimes.get(i)[0]*5+yOffset);
}
glEnd();
glBegin(GL_LINE_STRIP);
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
for(int i=0;i<this.processTimes.size();i++){
glVertex2f(i*3+15, -this.processTimes.get(i)[1]*5+yOffset);
}
glEnd();
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_LINES);
glVertex2f(15f,yOffset+2);
glVertex2f(315f,yOffset+2);
glVertex2f(15f,yOffset-85);
glVertex2f(315f,yOffset-85);
glVertex2f(319f,yOffset-88);
glVertex2f(319f,yOffset-82);
glVertex2f(322f,yOffset-88);
glVertex2f(326f,yOffset-88);
glVertex2f(326f,yOffset-88);
glVertex2f(323f,yOffset-82);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2f(319f,yOffset);
glVertex2f(319f,yOffset+7);
glVertex2f(322f,yOffset+6);
glVertex2f(322f,yOffset);
glVertex2f(319f,yOffset);
glEnd();
/*
glBegin(GL_QUADS);
glColor4f(1.0f, 1.0f, 1.0f, 0.5f);
glVertex3f(50f, 50f, 0f);
glVertex3f(50f, 250f, 0f);
glVertex3f(250f, 250f, 0f);
glVertex3f(250f, 50f, 0f);
glEnd();
glBegin(GL_LINE_LOOP);
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
glVertex2f(50f, 50f);
glVertex2f(50f, 250f);
glVertex2f(250f, 250f);
glVertex2f(250f, 50f);
glEnd();
*/
glPopMatrix();
/*
glTranslatef(140f, 100f, 0f);
glPushMatrix();
this.lights();
glPopMatrix();
*/
this.drawOverlay();
glDisable(GL_BLEND);
}
private void render3D(){
this.resizeGL();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Kameran position ja rotation
glRotatef(camera.getRot().x,1.0f,0.0f,0.0f);
glRotatef(camera.getRot().y,0.0f,1.0f,0.0f);
glTranslatef(-camera.getPos().x, -camera.getPos().y, -camera.getPos().z);
// sama matriisiin
viewMatrix.setZero();
viewMatrix.setIdentity();
viewMatrix.rotate((float)Math.toRadians(camera.getRot().x), new Vector3f(1.0f, 0.0f, 0.0f));
viewMatrix.rotate((float)Math.toRadians(camera.getRot().y), new Vector3f(0.0f, 1.0f, 0.0f));
viewMatrix.rotate((float)Math.toRadians(camera.getRot().z), new Vector3f(0.0f, 0.0f, 1.0f));
viewMatrix.translate(new Vector3f(-camera.getPos().x,-camera.getPos().y,-camera.getPos().z));
viewMatrix.store(viewMatrixBuffer);
viewMatrixBuffer.flip();
//System.out.println(this.viewMatrix.toString());
/*
System.out.println(viewMatrixBuffer.get(0)+" "+viewMatrixBuffer.get(1)+" "+viewMatrixBuffer.get(2)+" "+viewMatrixBuffer.get(3));
System.out.println(viewMatrixBuffer.get(4)+" "+viewMatrixBuffer.get(5)+" "+viewMatrixBuffer.get(6)+" "+viewMatrixBuffer.get(7));
System.out.println(viewMatrixBuffer.get(8)+" "+viewMatrixBuffer.get(9)+" "+viewMatrixBuffer.get(10)+" "+viewMatrixBuffer.get(11));
System.out.println(viewMatrixBuffer.get(12)+" "+viewMatrixBuffer.get(13)+" "+viewMatrixBuffer.get(14)+" "+viewMatrixBuffer.get(15));
*/
this.lights();
this.ExtractFrustum();
this.drawEntities();
}
/**
* Clears the color and depth buffers and sets the camera position and rotation.
* All drawing happens here.
*/
public void render() {
this.render3D();
this.render2D();
}
/**
* Is called when the window is resized. It also resizes the window.. it's confusing.
*/
public void resizeGL() {
//2D Scene
glViewport(0,0,DISPLAY_WIDTH,DISPLAY_HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(this.fov,(float)DISPLAY_WIDTH/(float)DISPLAY_HEIGHT,this.zNear,this.zFar);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
}
private void ready2D() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (double)DISPLAY_WIDTH, (double)DISPLAY_HEIGHT, 0.0, -1000, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//glTranslatef(0.0f, 0.0f, 100.0f);
glDisable(GL_DEPTH_TEST);
}
/**
* The main loop. Everything after initialization happens here.
*/
public void run() {
/*
projectionMatrix.m00 = 1f/(float)(Math.tan(Math.toRadians(80 * 0.5)));
projectionMatrix.m11 = projectionMatrix.m00;
projectionMatrix.m22 = -this.zFar / (this.zFar - this.zNear);
projectionMatrix.m32 = -this.zFar * this.zNear / (this.zFar - this.zNear);
projectionMatrix.m23 = -1f;
projectionMatrix.m33 = 0;
*/
float xymax = this.zNear * (float)(Math.tan(Math.toRadians(this.fov * 0.5)));
float ymin = -xymax;
float xmin = -xymax;
float width = xymax - xmin;
float height = xymax - ymin;
float depth = this.zFar - this.zNear;
float q = -(this.zFar + this.zNear) / depth;
float qn = -2f * (this.zFar * this.zNear) / depth;
float w = 2f * (this.zNear / width);
w = w / ((float)DISPLAY_WIDTH/(float)DISPLAY_HEIGHT);
float h = 2f * this.zNear / height;
projectionMatrix.setZero();
projectionMatrix.m00 = w;
projectionMatrix.m11 = h;
projectionMatrix.m22 = q;
projectionMatrix.m23 = -1f;
projectionMatrix.m32 = qn;
projectionMatrix.store(projectionMatrixBuffer);
projectionMatrixBuffer.flip();
Display.setVSyncEnabled(true);
this.currentTime = System.currentTimeMillis();
Long times[] = new Long[2];
while(!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
this.previousTime = this.currentTime;
this.currentTime = System.currentTimeMillis();
appSpeed = 60f/(1000.0f/(float)(this.currentTime-this.previousTime));
this.graphTimer.start();
this.update();
times[0] = this.graphTimer.getElapsedTime();
if(Display.isVisible()) {
this.graphTimer.start();
render();
times[1] = this.graphTimer.getElapsedTime();
}
else {
if(Display.isDirty()) {
render();
}
try {
Thread.sleep(100);
}
catch(InterruptedException ex) {
}
}
this.processTimes.remove(0);
this.processTimes.add(times.clone());
Display.update();
Display.sync(0);
}
}
public void update(){}
public void drawEntities(){}
public void drawOverlay(){}
public void lights(){}
public void init() {}
}