package engine; import engine.math.*; import engine.object.*; import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFWFramebufferSizeCallback; import org.lwjgl.glfw.GLFWVidMode; import org.lwjgl.opengl.GL; import java.nio.ByteBuffer; import java.nio.FloatBuffer; 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 objectsGl; private boolean running; /** * Create the engine and initial attributes use .init() to start the engine */ public Engine() { this.running = false; this.objectsGl = new ArrayList<>(); float width = 1280.0f; ObjectGl.projection = Matrix4f.orthographic(-width, width, -width * 9.0f / 16.0f, width * 9.0f / 16.0f, 0.1f, 100.0f); ObjectGl.view = Matrix4f.translate(new Vector3f(0.0f,0.0f,1.0f)); } /** * Start the engine * Create the window */ public void init() { glfwInit(); 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 = 1280; int height = 720; this.setWindow(glfwCreateWindow(width, height, "Boulevard Combattant", NULL, NULL)); assert getWindow() != NULL; boolean present = glfwJoystickPresent(GLFW_JOYSTICK_1); System.out.println(present); // 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 Input()); glfwSetInputMode(getWindow(), GLFW_STICKY_KEYS, GLFW_TRUE); // Contexte = zone cible des rendus glfwMakeContextCurrent(getWindow()); glfwShowWindow(getWindow()); GL.createCapabilities(); 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)); } /** * */ public void update(){ glfwPollEvents(); } /** * */ public void render(){ 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 add_objectGl(ObjectGl obj){ objectsGl.add(obj); } public void remove_objectGl(ObjectGl obj){ objectsGl.remove(obj); } public boolean isRunning(){ return running; } public void setRunning(boolean b){ running = b; } public boolean shouldClose(){ return glfwWindowShouldClose(getWindow()); } public static long getWindow() { return window; } public void setWindow(long window) { Engine.window = window; } /** * Est appelé àa 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){ glViewport(0,0,width,height); } }; public static void main(String[] args) { Engine engine = new Engine(); int speed = 10 ; //vitesse déplacement Object engine.init(); // Add objects to render String path = "textures/zangief_sprite.png"; String path2 = "textures/awesomeface.png"; ObjectGl zangief = new ObjectGl(0f,60f,80f,10f, path, null); engine.add_objectGl(zangief); // zangief.translate(new Vector3f(-600.0f,100,10.0f)); ObjectGl smiley2 = new ObjectGl(0.0f,500.0f,500.0f, 1f, path2, null); engine.add_objectGl(smiley2); smiley2.translate(new Vector3f(0.0f,0.0f,5.0f)); long timer = System.currentTimeMillis(); long lastFrame; int frame = 0; boolean nextFrame = false; while(engine.isRunning()){ lastFrame = System.currentTimeMillis(); // Game logic should fit here zangief.setTextureWrap(58,0,62,84); gamepadInput(zangief, speed); input(zangief, speed); // input(smiley2, speed); /* ******************** * essential part v * ******************** */ engine.update(); engine.render(); frame++; if (System.currentTimeMillis() - timer > 1000) { timer += 1000; System.out.println("FPS: " + frame); frame = 0; } while(!nextFrame){ nextFrame = System.currentTimeMillis() - lastFrame >= 16.66f; } nextFrame = false; if(engine.shouldClose()) engine.setRunning(false); } } private static void gamepadInput(ObjectGl token, int speed) { ByteBuffer gamepadButton = glfwGetJoystickButtons(GLFW_JOYSTICK_1); FloatBuffer gamepadAxes = glfwGetJoystickAxes(GLFW_JOYSTICK_1); assert gamepadAxes != null; assert gamepadButton != null; String name = GLFW.glfwGetJoystickName(GLFW_JOYSTICK_1); //System.out.println("GamePad Name :" + name); // for (int i =0 ; i < gamepadAxes.capacity(); i++) { // System.out.println(i + " :" + gamepadAxes.get(i)); // } if (gamepadButton.get(0) ==1 ) { // appuie sur croix(PlayStation) A (Xbox) token.translate(new Vector3f ( 0.0f, speed * 5.0f, 0.0f)); } if ( (gamepadAxes.get(2) < -0.1 || gamepadAxes.get(2) > 0.1) ) { // de droite à gauche //joystick gauche token.translate(new Vector3f (5*speed * gamepadAxes.get(2), 0.0f, 0.0f)); if ( gamepadAxes.get(2) < -0.1 ){ token.setTextureWrap(121,0,57,80); }else if (gamepadAxes.get(2) > 0.1) { token.setTextureWrap(178,0,62,82); } } if ( (gamepadAxes.get(3) < -0.1 || gamepadAxes.get(3) > 0.1) ) { // de haut en bas //joystick gauche token.translate(new Vector3f (0.0f, -5* speed * gamepadAxes.get(3), 0.0f)); } /* Buttons 0 : Croix / A 1: rond /B 2: carré / X 3: triangle / Y 4: L1 / LB 5: R1 / RB 6:select 7:start 8:L3 9:R3 10: haut 11: droite 12: bas 13: gauche */ /* Axes 0 : left X axe ( right : 1 left -1) 1: left Y axe ( down : 1 , Up -1) 2: right X axe ( right : 1 left -1) 3: right Y axe ( down : 1 , Up -1) 4:L2 / LT : 1 active, -1 unactive 5: R2 /RT : 1 active, -1 unactive */ } public static void input(ObjectGl token, int speed) { if (Input.isKeyDown(GLFW.GLFW_KEY_W)) { token.scale(new Vector3f (1.01f, 1.01f, 0.0f)); } if (Input.isKeyDown(GLFW.GLFW_KEY_A)) { token.translate(new Vector3f (speed *-5.0f, 0.0f, 0.0f)); token.setTextureWrap(121,0,57,80); } if (Input.isKeyDown(GLFW.GLFW_KEY_S)) { token.setTextureWrap(161,260,56,59); } if (Input.isKeyDown(GLFW.GLFW_KEY_D)) { token.translate(new Vector3f (speed * 5.0f, 0.0f, 0.0f)); token.setTextureWrap(178,0,62,82); } } }