package engine; import engine.input.*; import engine.math.*; import engine.object.*; import engine.sound.*; 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 objectsGl; private boolean running; private final int width; private final int height; private float viewXPos; /** * Create the engine and initial attributes use .init() to start the engine */ public Engine(int width, int height, float aspectRatio) { this.running = false; this.objectsGl = new ArrayList<>(); this.width = width; this.height = height; ObjectGl.projection = Matrix4f.orthographic(-1000, 1000, -1000 * aspectRatio, 1000 * aspectRatio, 0.1f, 100.0f); ObjectGl.view = Matrix4f.translate(new Vector3f(0.0f, 0.0f, 1.0f)); this.viewXPos = 0.0f; } /** * Start the engine * Create the window * Set the color of the background */ 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 = this.width; int height = this.height; this.setWindow(glfwCreateWindow(width, height, "Boulevard Combattant", NULL, NULL)); assert getWindow() != NULL; boolean present = glfwJoystickPresent(GLFW_JOYSTICK_1); System.out.println("Manette détectée : " + 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 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)); } /** * */ public void update() { glfwPollEvents(); } /** * */ 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 } /** * Add obj to the render queue * @param obj ObjectGl to render */ public void add_objectGl(ObjectGl obj) { objectsGl.add(obj); } public void remove_objectGl(ObjectGl obj) { objectsGl.remove(obj); } public void translateView(Vector3f vec){ ObjectGl.view = ObjectGl.view.multiply(Matrix4f.translate(vec)); viewXPos += vec.x; } 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 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é à 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); } }; public static void main(String[] args) throws Exception { /* OpenAl TEST */ SoundManager soundManager = new SoundManager(); soundManager.init(); SoundListener soundListener = new SoundListener(); soundManager.setListener(soundListener); SoundBuffer jumpSoundBuffer = new SoundBuffer("sound/jump.ogg"); SoundSource soundSource = new SoundSource(false, false); soundSource.setBuffer(jumpSoundBuffer.getBufferId()); soundManager.addSoundSource("jump", soundSource); soundManager.playSoundSource("jump"); /* Engine Init */ Engine engine = new Engine(1280, 720, 3.0f / 4.0f); int speed = 10; //vitesse d�placement Object engine.init(); // Add objects to render String path = "textures/zangief_sprite.png"; String path2 = "textures/awesomeface.png"; String pathToBG = "textures/background_beach.png"; ObjectGl zangief = new ObjectGl(10.0f, 1f, 1f, 10f, path, null); zangief.setTextureWrap(58, 0, 62, 84, ObjectGl.DEFAULT); engine.add_objectGl(zangief); zangief.translate(new Vector3f(-1000.0f, 200.0f, 0.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, 15.0f)); //Create background ObjectGl background = new ObjectGl(0f,1f,1f,10f, pathToBG, null); background.setTextureWrap(0,0,621, 224, ObjectGl.DEFAULT); background.translate(new Vector3f(-3011.0f, 1400.0f, 1.0f)); engine.add_objectGl(background); long timer = System.currentTimeMillis(); long lastFrame; int frame = 0; boolean nextFrame = false; boolean Joystick1Present = glfwJoystickPresent(GLFW_JOYSTICK_1); /* * Cr�ation des manettes / action */ GamepadInput gamepad1 = null; Button jump = null; if (Joystick1Present){ gamepad1 = new GamepadInput(GLFW_JOYSTICK_1); gamepad1.inputRefresh(); List listJump = new ArrayList<>(); listJump.add(InputConst.buttonA); jump = new Button("jump", listJump, gamepad1); } while (engine.isRunning()) { lastFrame = System.currentTimeMillis(); // Game logic should fit here if (Joystick1Present) { gamepad1.inputRefresh(); // Check si le personnage a sauté if (jump.isButtonPressed()){ // Le personnage saute System.out.println(" JE SAUTE "); } } KeyboardInput.keyboardInput(zangief, speed); Vector3f vecTransView = new Vector3f((-zangief.getXPos() - engine.viewXPos) - 250.0f,0.0f,0.0f); engine.translateView(vecTransView); /* ******************** * 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); } soundManager.cleanup(); } }