314 lines
8.7 KiB
Java
314 lines
8.7 KiB
Java
package engine;
|
|
|
|
import engine.camera.*;
|
|
import engine.gui.UIDummy;
|
|
import engine.input.*;
|
|
import engine.math.*;
|
|
import engine.object.*;
|
|
|
|
import org.lwjgl.glfw.GLFWFramebufferSizeCallback;
|
|
import org.lwjgl.glfw.GLFWVidMode;
|
|
import org.lwjgl.opengl.GL;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import static org.lwjgl.glfw.GLFW.*;
|
|
import static org.lwjgl.opengl.GL11.*;
|
|
import static org.lwjgl.system.MemoryUtil.NULL;
|
|
|
|
public class Engine {
|
|
|
|
private static long window;
|
|
|
|
private final List<ObjectGl> objectsGl;
|
|
public final List<UIDummy> uiElements;
|
|
|
|
private boolean running;
|
|
|
|
private final int width;
|
|
private final int height;
|
|
private final boolean fullscreen;
|
|
|
|
private float viewXPos;
|
|
private float viewYPos;
|
|
private Vector3f transformationView;
|
|
private final Camera camera;
|
|
|
|
private TrackingDummy tracking;
|
|
|
|
/*
|
|
Init Method
|
|
*/
|
|
|
|
/**
|
|
* Create the engine and initial attributes use .init() to start the engine
|
|
* Initial projection is -1000;1000 in width and -1000*aspectRatio; 1000*aspectRatio
|
|
* Initial Camera position is (0, 0, -1) //TODO vérifiez
|
|
*/
|
|
public Engine(int width, int height, boolean fullscreen, Vector3f aspectRatio) {
|
|
this.running = false;
|
|
this.objectsGl = new ArrayList<>();
|
|
this.uiElements = new ArrayList<>();
|
|
this.width = width;
|
|
this.height = height;
|
|
this.viewXPos = 0.0f;
|
|
this.viewYPos = 0.0f;
|
|
this.camera = new Camera(1000, aspectRatio, this);
|
|
ObjectGl.view = Matrix4f.translate(new Vector3f(0.0f, 0.0f, 1.0f));
|
|
this.transformationView = new Vector3f();
|
|
this.tracking = null;
|
|
this.fullscreen = fullscreen;
|
|
}
|
|
|
|
/**
|
|
* Start the engine
|
|
* Create the window
|
|
* Set the color of the background
|
|
*/
|
|
public void init() {
|
|
if (!glfwInit()){
|
|
System.exit(-1);
|
|
}
|
|
|
|
this.running = true;
|
|
|
|
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); //On utilise la version 3.3 d'openGL
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //Compatible MAC
|
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //Le core profile est l'interface 'avancé' d'openGL
|
|
|
|
int width = this.width;
|
|
int height = this.height;
|
|
if (fullscreen) {
|
|
this.setWindow(glfwCreateWindow(width, height, "Boulevard Combattant", glfwGetPrimaryMonitor(), NULL));
|
|
} else {
|
|
this.setWindow(glfwCreateWindow(width, height, "Boulevard Combattant", NULL, NULL));
|
|
}
|
|
assert getWindow() != NULL;
|
|
|
|
// On récupère les informations du moniteur principal
|
|
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
|
assert vidmode != null;
|
|
|
|
// On met la fenêtre au centre de l'écran principale
|
|
glfwSetWindowPos(getWindow(), (vidmode.width() - width) / 2, (vidmode.height() - height) / 2);
|
|
|
|
glfwSetKeyCallback(getWindow(), new KeyboardInput());
|
|
glfwSetInputMode(getWindow(), GLFW_STICKY_KEYS, GLFW_TRUE);
|
|
|
|
// Contexte = zone cible des rendus
|
|
glfwMakeContextCurrent(getWindow());
|
|
glfwShowWindow(getWindow());
|
|
GL.createCapabilities();
|
|
|
|
correctViewport(this.width, this.height);
|
|
|
|
glfwSetFramebufferSizeCallback(getWindow(), resizeWindow);
|
|
|
|
glEnable(GL_DEPTH_TEST); // Z-Buffer plus z est grand plus l'objet est proche de la camera limite à 100.0f au dela l'objet disparait
|
|
|
|
glEnable(GL_BLEND); // Transparence
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
|
System.out.println("OpenGL: " + glGetString(GL_VERSION));
|
|
}
|
|
|
|
/*
|
|
RENDER / UPDATE
|
|
*/
|
|
|
|
public void render() {
|
|
|
|
glEnable(GL_SCISSOR_TEST);
|
|
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
objectsGl.sort(new SortZ());
|
|
for (ObjectGl objectGl : objectsGl) {
|
|
objectGl.render();
|
|
}
|
|
|
|
int error = glGetError();
|
|
if (error != GL_NO_ERROR) System.out.println(error);
|
|
glfwSwapBuffers(getWindow()); //Envoie le buffer vers le moniteur
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
public void update() {
|
|
glfwPollEvents();
|
|
// METS A JOUR LA POSITION DES ELEMENTS D'INTERFACE
|
|
for (UIDummy uiElement : this.uiElements){
|
|
uiElement.update();
|
|
}
|
|
}
|
|
|
|
/*
|
|
Window / Viewport Management
|
|
*/
|
|
|
|
public static void correctViewport(int width, int height){
|
|
int heightViewport, widthViewport, x, y;
|
|
if (width >= height * 4.0f/3.0f){
|
|
heightViewport = height;
|
|
widthViewport = (int) (height * 4.0f/3.0f);
|
|
y = 0;
|
|
x = (width - widthViewport)/2;
|
|
} else {
|
|
widthViewport = width;
|
|
heightViewport = (int) (width * 3.0f/4.0f);
|
|
y = (height - heightViewport)/2;
|
|
x = 0;
|
|
}
|
|
glScissor(x, y, widthViewport, heightViewport);
|
|
glViewport(x, y, widthViewport, heightViewport);
|
|
}
|
|
|
|
public boolean shouldClose() {
|
|
return glfwWindowShouldClose(getWindow());
|
|
}
|
|
|
|
/*
|
|
ObjectGl Management
|
|
*/
|
|
|
|
/**
|
|
* Add obj to the render queue
|
|
* @param obj ObjectGl to render
|
|
*/
|
|
public void add_objectGl(ObjectGl obj) {
|
|
this.objectsGl.add(obj);
|
|
}
|
|
|
|
public void add_objectsGl(List<ObjectGl> objs) {
|
|
this.objectsGl.addAll(objs);
|
|
}
|
|
|
|
public void remove_objectGl(ObjectGl obj) {
|
|
obj.delete();
|
|
this.objectsGl.remove(obj);
|
|
}
|
|
|
|
public void remove_objectsGl(List<ObjectGl> obj) {
|
|
this.objectsGl.removeAll(obj);
|
|
}
|
|
|
|
/*
|
|
UIElement Management
|
|
*/
|
|
|
|
public void add_uiElement(UIDummy uiElement) {
|
|
uiElement.init();
|
|
this.uiElements.add(uiElement);
|
|
}
|
|
|
|
public void remove_uiElement(UIDummy uiElement) {
|
|
this.uiElements.remove(uiElement);
|
|
uiElement.delete();
|
|
}
|
|
|
|
public void setUIElementZoomFactor(float scaleFactor){
|
|
for (UIDummy uiElement : this.uiElements){
|
|
uiElement.updateScalingFactor(scaleFactor);
|
|
}
|
|
}
|
|
|
|
/*
|
|
CAMERA
|
|
*/
|
|
|
|
public void translateView(Vector3f vec){
|
|
ObjectGl.view = ObjectGl.view.multiply(Matrix4f.translate(vec));
|
|
viewXPos += vec.x;
|
|
this.transformationView = this.transformationView.addXYZ(vec);
|
|
}
|
|
|
|
/**
|
|
* Translate la camera pour avoir obj au centre de l'image, comme le cadrage se fait sur le point en haut à gauche
|
|
* de l'objet un offset peut parfois être nécessaire
|
|
* @param obj l'objectGl que la camera va suivre
|
|
* @param xOffset un offSet sur l'axe X
|
|
*/
|
|
public void cameraTrackingObjectGl(ObjectGl obj, float xOffset){
|
|
Vector3f trackingVector = new Vector3f((- obj.getXPos() - this.viewXPos) + xOffset,0.0f ,0.0f);
|
|
this.translateView(trackingVector);
|
|
}
|
|
|
|
public void setCameraTrackingBetweenTwoObjectGl(ObjectGl obj1, ObjectGl obj2, float deadZone){
|
|
// obj2 est considéré à droite probablement à modifier
|
|
this.tracking = new TrackingTore(
|
|
deadZone,
|
|
obj1,
|
|
obj2,
|
|
this);
|
|
}
|
|
|
|
public void setCameraTrackingSF3ThirdStrike(ObjectGl obj1, ObjectGl obj2){
|
|
this.tracking = new TrackingSF3ThirdStrick(obj1, obj2, this);
|
|
}
|
|
|
|
public void cameraTracking(){
|
|
if (this.tracking == null) System.out.println("Define a tracking first");
|
|
else {
|
|
Vector3f trackingVector = this.tracking.getViewVector();
|
|
this.translateView(trackingVector);
|
|
}
|
|
}
|
|
|
|
/*
|
|
CALLBACK
|
|
*/
|
|
|
|
/**
|
|
* Est appelé à chaque modification de la taille de la fenêtre, et modifie la taille de la zone de rendu
|
|
* pour quelle corresponde à la taille de la fenêtre
|
|
*/
|
|
private static final GLFWFramebufferSizeCallback resizeWindow = new GLFWFramebufferSizeCallback() {
|
|
@Override
|
|
public void invoke(long window, int width, int height) {
|
|
correctViewport(width, height);
|
|
}
|
|
};
|
|
|
|
/*
|
|
GET/SET
|
|
*/
|
|
|
|
public boolean getRunning() {
|
|
return running;
|
|
}
|
|
|
|
public void setRunning(boolean b) {
|
|
running = b;
|
|
}
|
|
|
|
public float getViewXPos(){
|
|
return viewXPos;
|
|
}
|
|
|
|
public float getViewYPos(){
|
|
return viewYPos;
|
|
}
|
|
|
|
public Vector3f getTransformationView() {
|
|
return transformationView;
|
|
}
|
|
|
|
public Camera getCamera(){
|
|
return this.camera;
|
|
}
|
|
|
|
public static long getWindow() {
|
|
return window;
|
|
}
|
|
|
|
public void setWindow(long window) {
|
|
Engine.window = window;
|
|
}
|
|
|
|
}
|