Ajout de la classe:
Scene, VertexArray, Shader, ShaderUtils, BufferUtils, FileUtils, Matrix4f, Vector3f Ajout des shaders de test: vert.vert et frag.frag dans le dossier shaders
This commit is contained in:
32
src/engine/BufferUtils.java
Normal file
32
src/engine/BufferUtils.java
Normal file
@ -0,0 +1,32 @@
|
||||
package engine;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
public class BufferUtils {
|
||||
|
||||
private BufferUtils() {
|
||||
|
||||
}
|
||||
|
||||
public static ByteBuffer createByteBuffer(byte[] array){
|
||||
ByteBuffer result = ByteBuffer.allocateDirect(array.length).order(ByteOrder.nativeOrder());
|
||||
result.put(array).flip();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static FloatBuffer createFloatBuffer(float[] array){
|
||||
FloatBuffer result = ByteBuffer.allocateDirect(array.length << 2).order(ByteOrder.nativeOrder()).asFloatBuffer();
|
||||
result.put(array).flip();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static IntBuffer createIntBuffer(int[] array){
|
||||
IntBuffer result = ByteBuffer.allocateDirect(array.length << 2).order(ByteOrder.nativeOrder()).asIntBuffer();
|
||||
result.put(array).flip();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -6,9 +6,99 @@
|
||||
* @author François Autin
|
||||
*
|
||||
*/
|
||||
|
||||
package engine;
|
||||
|
||||
import org.lwjgl.glfw.GLFWVidMode;
|
||||
import org.lwjgl.opengl.GL;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import static org.lwjgl.opengl.GL13.*;
|
||||
import static org.lwjgl.system.MemoryUtil.*;
|
||||
|
||||
public class Engine {
|
||||
|
||||
private long window;
|
||||
|
||||
private Scene scene;
|
||||
|
||||
private boolean running;
|
||||
|
||||
public Engine(){
|
||||
this.running = false;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
if(!glfwInit()){
|
||||
// TODO Erreur d'initialisation
|
||||
}
|
||||
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.window = glfwCreateWindow(width, height, "Boulevard Combattant", NULL, NULL);
|
||||
assert this.window != NULL;
|
||||
|
||||
// On récupère les informations du moniteur principale
|
||||
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
||||
assert vidmode != null;
|
||||
|
||||
glfwSetWindowPos(this.window, (vidmode.width() - width)/2, (vidmode.height() - height)/2);
|
||||
|
||||
glfwSetKeyCallback(window, new Input());
|
||||
|
||||
// Contexte = zone cible des rendus
|
||||
glfwMakeContextCurrent(this.window);
|
||||
glfwShowWindow(this.window);
|
||||
GL.createCapabilities();
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
System.out.println("OpenGL: " + glGetString(GL_VERSION));
|
||||
|
||||
|
||||
this.scene = new Scene();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
TODO gérer les input dans une autre classe
|
||||
*/
|
||||
private void processInput(){
|
||||
if(glfwGetKey(this.window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(this.window, true);
|
||||
}
|
||||
|
||||
private void update(){
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
private void render(){
|
||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT); //SWAP avec le precedent
|
||||
scene.render();
|
||||
int error = glGetError();
|
||||
if (error != GL_NO_ERROR) System.out.println(error);
|
||||
glfwSwapBuffers(window); //Envoie le buffer vers le moniteur
|
||||
}
|
||||
|
||||
public void run(){
|
||||
init();
|
||||
while(running){
|
||||
processInput();
|
||||
update();
|
||||
render();
|
||||
if(glfwWindowShouldClose(window)) running = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Engine engine = new Engine();
|
||||
engine.run();
|
||||
}
|
||||
|
||||
}
|
||||
|
29
src/engine/FileUtils.java
Normal file
29
src/engine/FileUtils.java
Normal file
@ -0,0 +1,29 @@
|
||||
package engine;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
|
||||
public class FileUtils {
|
||||
|
||||
private FileUtils() {
|
||||
|
||||
}
|
||||
|
||||
public static String loadAsString(String file){
|
||||
StringBuilder result = new StringBuilder();
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(new FileReader(file));
|
||||
String buffer = "";
|
||||
while ((buffer = reader.readLine()) != null) {
|
||||
result.append(buffer +"\n");
|
||||
}
|
||||
reader.close();
|
||||
} catch (IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
}
|
14
src/engine/Input.java
Normal file
14
src/engine/Input.java
Normal file
@ -0,0 +1,14 @@
|
||||
package engine;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWKeyCallback;
|
||||
|
||||
public class Input extends GLFWKeyCallback {
|
||||
|
||||
public static boolean[] keys = new boolean[65536];
|
||||
|
||||
@Override
|
||||
public void invoke(long window, int key, int scancode, int action, int mods) {
|
||||
keys[key] = action != GLFW.GLFW_RELEASE;
|
||||
}
|
||||
}
|
82
src/engine/Matrix4f.java
Normal file
82
src/engine/Matrix4f.java
Normal file
@ -0,0 +1,82 @@
|
||||
package engine;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
public class Matrix4f {
|
||||
|
||||
public static final int SIZE = 4 * 4;
|
||||
public float[] elements = new float[4 * 4];
|
||||
|
||||
public Matrix4f(){
|
||||
|
||||
}
|
||||
|
||||
public static Matrix4f identity(){
|
||||
Matrix4f result = new Matrix4f();
|
||||
for (int i = 0; i < SIZE; i++){
|
||||
result.elements[i] = 0.0f;
|
||||
}
|
||||
result.elements[0 + 0 * 4] = 1.0f;
|
||||
result.elements[1 + 1 * 4] = 1.0f;
|
||||
result.elements[2 + 2 * 4] = 1.0f;
|
||||
result.elements[3 + 3 * 4] = 1.0f;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Matrix4f orthographic(float left, float right, float bottom, float top, float near, float far){
|
||||
Matrix4f result = identity();
|
||||
|
||||
result.elements[0] = 2.0f / (right - left);
|
||||
result.elements[1 + 4] = 2.0f / (top - bottom);
|
||||
result.elements[2 + 2 * 4] = 2.0f / (near - far);
|
||||
|
||||
result.elements[3 * 4] = (left + right) / (left - right);
|
||||
result.elements[1 + 3 * 4] = (bottom + top) / (bottom - top);
|
||||
result.elements[2 + 3 * 4] = (far + near) / (far - near);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Matrix4f translate(Vector3f vector){
|
||||
Matrix4f result= identity();
|
||||
result.elements[0 + 3*4] = vector.x;
|
||||
result.elements[1 + 3*4] = vector.y;
|
||||
result.elements[2 + 3*4] = vector.z;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Matrix4f rotate(float angle){
|
||||
Matrix4f result = identity();
|
||||
float r = (float) Math.toRadians(angle);
|
||||
float cos = (float) Math.cos(angle);
|
||||
float sin = (float) Math.sin(angle);
|
||||
|
||||
result.elements[0 + 0 * 4] = cos;
|
||||
result.elements[1 + 0 * 4] = sin;
|
||||
|
||||
result.elements[0 + 1 * 4] = -sin;
|
||||
result.elements[1 + 1 * 4] = cos;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Matrix4f multiply(Matrix4f matrix){
|
||||
Matrix4f result = new Matrix4f();
|
||||
for (int y = 0; y< 4; y++){
|
||||
for (int x = 0; x< 4; x++){
|
||||
float sum = 0.0f;
|
||||
for (int e = 0; e< 4; e++){
|
||||
sum += this.elements[x + e * 4] * matrix.elements[e + y * 4];
|
||||
}
|
||||
result.elements[x + y * 4] = sum;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public FloatBuffer toFloatBuffer() {
|
||||
return BufferUtils.createFloatBuffer(elements);
|
||||
}
|
||||
|
||||
}
|
25
src/engine/Scene.java
Normal file
25
src/engine/Scene.java
Normal file
@ -0,0 +1,25 @@
|
||||
package engine;
|
||||
|
||||
public class Scene {
|
||||
|
||||
float[] vertices;
|
||||
|
||||
VertexArray vertexArray;
|
||||
Shader shader;
|
||||
|
||||
public Scene(){
|
||||
this.vertices = new float[] {
|
||||
-0.5f, -0.5f, 0.0f, //left
|
||||
0.5f, -0.5f, 0.0f, //right
|
||||
0.0f, 0.5f, 0.0f //top
|
||||
};
|
||||
this.shader = new Shader("shaders/vert.vert", "shaders/frag.frag");
|
||||
this.vertexArray = new VertexArray(this.vertices);
|
||||
}
|
||||
|
||||
public void render(){
|
||||
this.shader.enable();
|
||||
this.vertexArray.render();
|
||||
this.shader.disable();
|
||||
}
|
||||
}
|
66
src/engine/Shader.java
Normal file
66
src/engine/Shader.java
Normal file
@ -0,0 +1,66 @@
|
||||
package engine;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.lwjgl.opengl.GL20.*;
|
||||
|
||||
public class Shader {
|
||||
|
||||
private boolean enabled = false;
|
||||
|
||||
//Identifiant du programme resultat de la compilation des shaders
|
||||
private final int ID;
|
||||
private Map<String, Integer> locationCache = new HashMap<String, Integer>();
|
||||
|
||||
/*
|
||||
Crée le fragment et le vertex shader les lie dans un programme dont il renvoie l'identifiant.
|
||||
*/
|
||||
public Shader(String vertex, String fragment) {
|
||||
ID = ShaderUtils.load(vertex, fragment);
|
||||
}
|
||||
|
||||
public int getUniform(String name){
|
||||
if (locationCache.containsKey(name)) return locationCache.get(name);
|
||||
int result = glGetUniformLocation(ID, name);
|
||||
if (result == -1) System.err.println("Could not find uniform variable " + name);
|
||||
else locationCache.put(name, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setUniform1i(String name, int value) {
|
||||
if (!enabled) enable();
|
||||
glUniform1i(getUniform(name), value);
|
||||
}
|
||||
|
||||
public void setUniform1f(String name, float value) {
|
||||
if (!enabled) enable();
|
||||
glUniform1f(getUniform(name), value);
|
||||
}
|
||||
|
||||
public void setUniform2f(String name, float x, float y) {
|
||||
if (!enabled) enable();
|
||||
glUniform2f(getUniform(name), x, y);
|
||||
}
|
||||
|
||||
public void setUniform3f(String name, Vector3f vector) {
|
||||
if (!enabled) enable();
|
||||
glUniform3f(getUniform(name), vector.x, vector.y, vector.z);
|
||||
}
|
||||
|
||||
public void setUniformMat4f(String name, Matrix4f matrix){
|
||||
if (!enabled) enable();
|
||||
glUniformMatrix4fv(getUniform(name), false, matrix.toFloatBuffer());
|
||||
}
|
||||
|
||||
public void enable() {
|
||||
glUseProgram(ID);
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
glUseProgram(0);
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
}
|
58
src/engine/ShaderUtils.java
Normal file
58
src/engine/ShaderUtils.java
Normal file
@ -0,0 +1,58 @@
|
||||
package engine;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import static org.lwjgl.opengl.GL20.*;
|
||||
|
||||
public class ShaderUtils {
|
||||
|
||||
private ShaderUtils(){
|
||||
|
||||
}
|
||||
|
||||
public static int load(String vertPath, String fragPath){
|
||||
String vert = FileUtils.loadAsString(vertPath);
|
||||
String frag = FileUtils.loadAsString(fragPath);
|
||||
return create(vert, frag);
|
||||
}
|
||||
|
||||
public static int create(String vert, String frag){
|
||||
// On crée et compile le vertex et le fragment shader
|
||||
int vertID = glCreateShader(GL_VERTEX_SHADER);
|
||||
int fragID = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(vertID, vert);
|
||||
glShaderSource(fragID, frag);
|
||||
|
||||
glCompileShader(vertID);
|
||||
if (glGetShaderi(vertID, GL_COMPILE_STATUS) == GL_FALSE){
|
||||
System.err.println("Failed to compile vertex shader");
|
||||
System.err.println(glGetShaderInfoLog(vertID));
|
||||
return -1;
|
||||
}
|
||||
|
||||
glCompileShader(fragID);
|
||||
if (glGetShaderi(fragID, GL_COMPILE_STATUS) == GL_FALSE){
|
||||
System.err.println("Failed to compile fragment shader");
|
||||
System.err.println(glGetShaderInfoLog(fragID));
|
||||
return -1;
|
||||
}
|
||||
//on lie les shaders au programme
|
||||
int program = glCreateProgram();
|
||||
glAttachShader(program, vertID);
|
||||
glAttachShader(program, fragID);
|
||||
glLinkProgram(program);
|
||||
|
||||
if(glGetProgrami(program, GL_LINK_STATUS) == GL_FALSE) {
|
||||
System.err.println("Failed to link vertex and fragment shader");
|
||||
System.err.println(glGetShaderInfoLog(program));
|
||||
return -1;
|
||||
}
|
||||
|
||||
glValidateProgram(program);
|
||||
|
||||
glDeleteShader(vertID);
|
||||
glDeleteShader(fragID);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
}
|
19
src/engine/Vector3f.java
Normal file
19
src/engine/Vector3f.java
Normal file
@ -0,0 +1,19 @@
|
||||
package engine;
|
||||
|
||||
public class Vector3f {
|
||||
|
||||
public float x, y, z;
|
||||
|
||||
public Vector3f(){
|
||||
x = 0.0f;
|
||||
y = 0.0f;
|
||||
z = 0.0f;
|
||||
}
|
||||
|
||||
public Vector3f(float x, float y, float z){
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
}
|
47
src/engine/VertexArray.java
Normal file
47
src/engine/VertexArray.java
Normal file
@ -0,0 +1,47 @@
|
||||
package engine;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import static org.lwjgl.opengl.GL15.*;
|
||||
import static org.lwjgl.opengl.GL30.*;
|
||||
|
||||
public class VertexArray {
|
||||
|
||||
private int VAO ,VBO;
|
||||
|
||||
public VertexArray(float[] vertices){
|
||||
// VERTEX ARRAY OBJECT
|
||||
VAO = glGenVertexArrays();
|
||||
|
||||
// VERTEX BUFFER OBJECT
|
||||
VBO = glGenBuffers();
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, BufferUtils.createFloatBuffer(vertices), GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
}
|
||||
|
||||
public void bind(){
|
||||
glBindVertexArray(this.VAO);
|
||||
}
|
||||
|
||||
public void unbind(){
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
public void draw(){
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
}
|
||||
|
||||
public void render(){
|
||||
bind();
|
||||
draw();
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user