massive refactor

This commit is contained in:
JISAUAY committed 2024-09-24 17:00:18 -05:00
1 parent 26c0f433ae
commit e71a1a9b0b
14 files changed
+441 -274

No files matched your search

-149
View File
@@ -1,149 +0,0 @@
package org.example;
import org.joml.*;
import org.lwjgl.*;
import org.lwjgl.Version;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.system.*;
import java.lang.Math;
import java.nio.*;
import java.io.*;
import java.text.MessageFormat;
import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.system.MemoryStack.*;
import static org.lwjgl.system.MemoryUtil.*;
import com.mokiat.data.front.parser.*;
import org.lwjgl.system.MemoryStack;
public class Game
{
public static final float Z_FAR = 1000.0f;
public static final float Z_NEAR = 0.1f;
public static final float FOV = (float) Math.toRadians(90.0f);
private long window;
private Matrix4f projection_matrix;
public void run()
{
System.out.println("Running LWJGL Version " + Version.getVersion() + ".");
init();
loop();
// Free the window callbacks and destroy the window
glfwFreeCallbacks(window);
glfwDestroyWindow(window);
// Terminate GLFW and free the error callback
glfwTerminate();
glfwSetErrorCallback(null).free();
}
public void init()
{
GLFWErrorCallback.createPrint(System.err).set();
if (!glfwInit())
throw new IllegalStateException("Unable to Initialize GLFW");
// Configure GLFW
glfwDefaultWindowHints(); // optional, the current window hints are already the default
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable
// Create the window
window = glfwCreateWindow(300, 300, "Hello World!", NULL, NULL);
if ( window == NULL )
throw new RuntimeException("Failed to create the GLFW window");
// Setup a key callback. It will be called every time a key is pressed, repeated or released.
glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )
glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
});
// Get the thread stack and push a new frame
try ( MemoryStack stack = stackPush() ) {
IntBuffer pWidth = stack.mallocInt(1); // int*
IntBuffer pHeight = stack.mallocInt(1); // int*
// Get the window size passed to glfwCreateWindow
glfwGetWindowSize(window, pWidth, pHeight);
// Get the resolution of the primary monitor
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
// Center the window
glfwSetWindowPos(
window,
(vidmode.width() - pWidth.get(0)) / 2,
(vidmode.height() - pHeight.get(0)) / 2
);
} // the stack frame is popped automatically
// Make the OpenGL context current
glfwMakeContextCurrent(window);
// Enable v-sync
glfwSwapInterval(1);
// Make the window visible
glfwShowWindow(window);
}
private void loop()
{
// Setup world
World world = new World();
// Do open gl stuff
GL.createCapabilities();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// Add stuff to world
world.addEntity(new Entity("/objs/cube.obj", "/shaders/shader.frag", "/shaders/shader.vert"));
// Calculate Perspective Matrix
int w, h;
glfwGetWindowSize(window, w, h);
float aspect_ratio = (float) ;
this.projection_matrix = new Matrix4f().perspective(FOV, )
// Main loop or something
while ( !glfwWindowShouldClose(window) )
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glfwSwapBuffers(window);
for (Entity entity : world.entities)
render(entity);
glfwPollEvents();
}
}
public void render(Entity entity) {
entity.shader.bind();
glBindVertexArray(entity.mesh.vao_id);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glDrawElements(GL_TRIANGLES, entity.mesh.vertex_count, GL_UNSIGNED_INT, 0);
}
public static void main(String[] args)
{
new Game().run();
}
}
-24
View File
@@ -1,24 +0,0 @@
package org.example;
import org.lwjgl.glfw.*;
import org.lwjgl.system.MemoryUtil;
import java.util.concurrent.Callable;
import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.NULL;
public class Window {
public long window_handle;
public int height;
public int width;
private Callable<Void> resize_func;
public Window(String title, Callable<Void> resize_func) {
}
}
+95
View File
@@ -0,0 +1,95 @@
package org.xfe.engine;
import org.joml.*;
import java.lang.Math;
public class Engine
{
public static final int TARGET_UPS = 30;
private final GameLogic gameLogic;
private final Render render;
private final Window window;
private final World world;
private int target_fps;
private int target_ups;
private boolean running;
public static final float Z_FAR = 1000.0f;
public static final float Z_NEAR = 0.1f;
public static final float FOV = (float) Math.toRadians(90.0f);
public Engine(String window_title, Window.WindowOptions opts, GameLogic gameLogic) {
window = new Window(window_title, opts, () -> {
resize();
return null;
});
target_fps = opts.fps;
target_ups = opts.ups;
this.gameLogic = gameLogic;
this.render = new Render();
this.world = new World();
gameLogic.init(window, world, render);
this.running = true;
}
private void cleanup() {
this.gameLogic.cleanup();
this.render.cleanup();
this.world.cleanup();
this.window.cleanup();
}
private void resize() {
}
private void run() {
long initialTime = System.currentTimeMillis();
float timeU = 1000.0f / target_ups;
float timeR = target_fps > 0 ? 1000.0f / target_fps : 0;
float deltaUpdate = 0;
float deltaFps = 0;
long updateTime = initialTime;
while (running && !window.windowShouldClose()) {
window.pollEvents();
long now = System.currentTimeMillis();
deltaUpdate += (now - initialTime) / timeU;
deltaFps += (now - initialTime) / timeR;
if (target_fps <= 0 || deltaFps >= 1) {
gameLogic.input(window, world, now - initialTime);
}
if (deltaUpdate >= 1) {
long diffTimeMillis = now - updateTime;
gameLogic.update(window, world, diffTimeMillis);
updateTime = now;
deltaUpdate--;
}
if (target_fps <= 0 || deltaFps >= 1) {
render.render(window, world);
deltaFps--;
window.update();
}
initialTime = now;
}
cleanup();
}
public void start() {
running = true;
run();
}
public void stop() {
running = false;
}
}
@@ -1,13 +1,5 @@
package org.example;
package org.xfe.engine;
import com.mokiat.data.front.parser.IOBJParser;
import com.mokiat.data.front.parser.OBJModel;
import com.mokiat.data.front.parser.OBJParser;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.Scanner;
public class Entity
@@ -44,5 +36,19 @@ public class Entity
System.out.println("ERROR Initializing the fragment shader");
e.printStackTrace();
}
try {
shader.link();
} catch (Exception e) {
System.out.println("Error linking shader program");
e.printStackTrace();
}
try {
shader.createUniform("projection");
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,11 @@
package org.xfe.engine;
public interface GameLogic {
void cleanup();
void init(Window window, World world, Render render);
void input(Window window, World world, long diffTimeMillis);
void update(Window window, World world, long diffTimeMillis);
}
+17
View File
@@ -0,0 +1,17 @@
package org.xfe.engine;
import org.joml.Vector3f;
public class Light {
Vector3f position;
float power;
Vector3f color;
public Light(Vector3f position, float power, Vector3f color) {
this.position = position;
this.power = power;
this.color = color;
}
}
@@ -1,11 +1,13 @@
package org.example;
package org.xfe.engine;
import org.apache.commons.lang3.ArrayUtils;
import org.lwjgl.system.MemoryUtil;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.Scanner;
@@ -19,6 +21,7 @@ public class Mesh {
public int vertex_count;
public int vao_id;
public int vbo_id;
public int ebo_id;
Float[] vertices;
Float[] normals;
@@ -38,7 +41,7 @@ public class Mesh {
ArrayList<Integer> temp_normal_indices = new ArrayList<>();
Scanner scanner;
File obj;
InputStream obj;
String line;
String[] face_data_temp;
@@ -47,9 +50,9 @@ public class Mesh {
// Try to open the file
try {
obj = new File(file_path);
obj = this.getClass().getResourceAsStream(file_path);
scanner = new Scanner(obj);
} catch (FileNotFoundException e) {
} catch (Exception e) {
System.out.println("ERROR: OBJ File \"" + file_path + "\" not found.");
e.printStackTrace();
return;
@@ -98,11 +101,13 @@ public class Mesh {
FloatBuffer vertices_buffer = null;
try {
// Bind our vertices into the VBO
vertices_buffer = MemoryUtil.memAllocFloat(this.vertices.length);
vertex_count = this.vertices.length / 3;
// Convert from our object list to the primitive float array
vertices_buffer.put(ArrayUtils.toPrimitive(this.vertices)).flip();
vertices_buffer.put(ArrayUtils.toPrimitive(this.vertices));
this.vao_id = glGenVertexArrays();
glBindVertexArray(this.vao_id);
@@ -112,6 +117,18 @@ public class Mesh {
glBufferData(GL_ARRAY_BUFFER, vertices_buffer, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
// Bind indices in EBO
if (this.vertice_indices.length > 0)
{
// TODO : @0x01fe probably should free this (memory leaks are like bad or smthng)
IntBuffer indice_buffer = MemoryUtil.memAllocInt(vertice_indices.length);
indice_buffer.put(ArrayUtils.toPrimitive(vertice_indices));
ebo_id = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo_id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indice_buffer, GL_STATIC_DRAW);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
} finally {
if (vertices_buffer != null) {
+50
View File
@@ -0,0 +1,50 @@
package org.xfe.engine;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.lwjgl.opengl.GL;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;
public class Render {
private Matrix4f projection_matrix;
public Render() {
GL.createCapabilities();
}
public void cleanup() {
// Nothing to be done here yet
}
public void render(Window window, World world) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glfwSwapBuffers(window.getWindowHandle());
float aspect_ratio = (float) window.getWidth() / window.getHeight();
projection_matrix = new Matrix4f().perspective(Engine.FOV, aspect_ratio, Engine.Z_FAR, Engine.Z_NEAR);
for (Entity entity : world.entities) {
entity.shader.bind();
entity.shader.setUniform("projection", projection_matrix);
// entity.shader.setUniform("model", new Matrix4f().identity());
// entity.shader.setUniform("view", new Matrix4f().identity());
// entity.shader.setUniform("lightPos", world.lights.get(0).position);
// entity.shader.setUniform("light_power", world.lights.get(0).power);
// entity.shader.setUniform("lightColor", world.lights.get(0).color);
// entity.shader.setUniform("objectColor", new Vector3f(1.0f, 1.0f, 1.0f));
// entity.shader.setUniform("viewPos", new Vector3f(0.0f, 0.0f, 0.0f));
glBindVertexArray(entity.mesh.ebo_id);
glEnableVertexAttribArray(0);
// glEnableVertexAttribArray(1);
glDrawElements(GL_TRIANGLES, entity.mesh.vertice_indices.length, GL_UNSIGNED_INT, 0);
}
}
}
@@ -1,4 +1,12 @@
package org.example;
package org.xfe.engine;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.lwjgl.system.MemoryStack;
import java.nio.FloatBuffer;
import java.util.HashMap;
import java.util.Map;
import static org.lwjgl.opengl.GL20.*;
@@ -6,11 +14,14 @@ public class ShaderProgram {
private final int programId;
private final Map<String, Integer> uniforms;
private int vertexShaderId;
private int fragmentShaderId;
public ShaderProgram() throws Exception {
uniforms = new HashMap<>();
programId = glCreateProgram();
if (programId == 0) {
throw new Exception("Could not create Shader");
@@ -79,51 +90,32 @@ public class ShaderProgram {
}
// Set stuff
public void setFloat(String name, float value) {
glUniform1f(glGetUniformLocation(programId, name), value);
public void createUniform(String uniform_name) throws Exception {
int uniform_location = glGetUniformLocation(this.programId, uniform_name);
if (uniform_location < 0)
throw new Exception("Could not find uniform: " + uniform_name);
uniforms.put(uniform_name, uniform_location);
}
public void setBool(String name, boolean value) {
glUniform1i(glGetUniformLocation(programId, name), value ? 1 : 0);
public void setUniform(String uniform_name, Matrix4f value) {
// Dump the matrix into a float buffer
try (MemoryStack stack = MemoryStack.stackPush()) {
FloatBuffer floatBuffer = stack.mallocFloat(16);
value.get(floatBuffer);
glUniformMatrix4fv(uniforms.get(uniform_name), false, floatBuffer);
}
}
public void setInt(String name, int value) {
glUniform1i(glGetUniformLocation(programId, name), value);
public void setUniform(String uniform_name, float value) {
glUniform1f(uniforms.get(uniform_name), value);
}
public void setVec2(String name, float[] value) {
glUniform2fv(glGetUniformLocation(programId, name), value);
public void setUniform(String uniform_name, Vector3f value) {
try (MemoryStack stack = MemoryStack.stackPush()) {
FloatBuffer floatBuffer = stack.mallocFloat(3);
value.get(floatBuffer);
glUniform3fv(uniforms.get(uniform_name), floatBuffer);
}
public void setVec2(String name, float x, float y) {
glUniform2f(glGetUniformLocation(programId, name), x, y);
}
public void setVec3(String name, float[] value) {
glUniform3fv(glGetUniformLocation(programId, name), value);
}
public void setVec3(String name, float x, float y, float z) {
glUniform3f(glGetUniformLocation(programId, name), x, y, z);
}
public void setVec4(String name, float[] value) {
glUniform4fv(glGetUniformLocation(programId, name), value);
}
public void setVec4(String name, float x, float y, float z, float w) {
glUniform4f(glGetUniformLocation(programId, name), x, y, z, w);
}
public void setMat2(String name, float[] mat) {
glUniformMatrix2fv(glGetUniformLocation(programId, name), false, mat);
}
public void setMat3(String name, float[] mat) {
glUniformMatrix3fv(glGetUniformLocation(programId, name), false, mat);
}
public void setMat4(String name, float[] mat) {
glUniformMatrix4fv(glGetUniformLocation(programId, name), false, mat);
}
}
+137
View File
@@ -0,0 +1,137 @@
package org.xfe.engine;
import org.lwjgl.glfw.*;
import java.util.concurrent.Callable;
import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.NULL;
public class Window {
private final long windowHandle;
private int height;
private Callable<Void> resizeFunc;
private int width;
public Window(String title, WindowOptions opts, Callable<Void> resizeFunc) {
this.resizeFunc = resizeFunc;
if (!glfwInit()) {
throw new IllegalStateException("Unable to initialize GLFW");
}
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
if (opts.compatibleProfile) {
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
} else {
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
}
if (opts.width > 0 && opts.height > 0) {
this.width = opts.width;
this.height = opts.height;
} else {
glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
GLFWVidMode vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
width = vidMode.width();
height = vidMode.height();
}
windowHandle = glfwCreateWindow(width, height, title, NULL, NULL);
if (windowHandle == NULL) {
throw new RuntimeException("Failed to create the GLFW window");
}
glfwSetFramebufferSizeCallback(windowHandle, (window, w, h) -> resized(w, h));
glfwSetKeyCallback(windowHandle, (window, key, scancode, action, mods) -> {
keyCallBack(key, action);
});
glfwMakeContextCurrent(windowHandle);
if (opts.fps > 0) {
glfwSwapInterval(0);
} else {
glfwSwapInterval(1);
}
glfwShowWindow(windowHandle);
int[] arrWidth = new int[1];
int[] arrHeight = new int[1];
glfwGetFramebufferSize(windowHandle, arrWidth, arrHeight);
width = arrWidth[0];
height = arrHeight[0];
}
public void cleanup() {
glfwFreeCallbacks(windowHandle);
glfwDestroyWindow(windowHandle);
glfwTerminate();
GLFWErrorCallback callback = glfwSetErrorCallback(null);
if (callback != null) {
callback.free();
}
}
public int getHeight() {
return height;
}
public int getWidth() {
return width;
}
public long getWindowHandle() {
return windowHandle;
}
public boolean isKeyPressed(int keyCode) {
return glfwGetKey(windowHandle, keyCode) == GLFW_PRESS;
}
public void keyCallBack(int key, int action) {
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) {
glfwSetWindowShouldClose(windowHandle, true); // We will detect this in the rendering loop
}
}
public void pollEvents() {
glfwPollEvents();
}
protected void resized(int width, int height) {
this.width = width;
this.height = height;
try {
resizeFunc.call();
} catch (Exception excp) {
excp.printStackTrace();
}
}
public void update() {
glfwSwapBuffers(windowHandle);
}
public boolean windowShouldClose() {
return glfwWindowShouldClose(windowHandle);
}
public static class WindowOptions {
public boolean compatibleProfile;
public int fps;
public int height;
public int ups = Engine.TARGET_UPS;
public int width;
}
}
@@ -1,4 +1,6 @@
package org.example;
package org.xfe.engine;
import org.joml.Vector3f;
import java.util.ArrayList;
@@ -6,14 +8,22 @@ public class World
{
ArrayList<Entity> entities;
ArrayList<Light> lights;
public World()
{
this.entities = new ArrayList<>();
this.lights = new ArrayList<>();
}
public void addEntity(Entity e)
{
this.entities.add(e);
}
public void addLight(Light l) {
this.lights.add(l);
}
public void cleanup() {}
}
+33
View File
@@ -0,0 +1,33 @@
package org.xfe.game;
import org.xfe.engine.*;
public class Main implements GameLogic {
public static void main(String[] args) {
Main main = new Main();
Engine engine = new Engine("Test", new Window.WindowOptions(), main);
engine.start();
}
@Override
public void cleanup() {
}
@Override
public void init(Window window, World world, Render render) {
Entity cube = new Entity("/objs/cube.obj", "/shaders/shader.frag", "/shaders/shader.vert");
world.addEntity(cube);
}
@Override
public void input(Window window, World world, long diffTimeMillis) {
}
@Override
public void update(Window window, World world, long diffTimeMillis) {
}
}
+7 -36
View File
@@ -2,14 +2,14 @@
out vec4 FragColor;
uniform float light_power;
uniform vec3 lightColor;
uniform vec3 objectColor;
uniform vec3 viewPos;
//uniform float light_power;
//uniform vec3 lightColor;
//uniform vec3 objectColor;
//uniform vec3 viewPos;
in vec3 FragPos;
in vec3 Normal;
in vec3 LightPos;
//in vec3 Normal;
//in vec3 LightPos;
// const float light_power = 12.0;
const float ambientStrength = 0.2;
@@ -18,35 +18,6 @@ const float screenGamma = 2.2; // Assume the monitor is calibrated to the sRGB c
void main()
{
// FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
vec3 lightDir = LightPos - FragPos;
float distance = length(lightDir);
vec3 norm = normalize(Normal);
vec3 ambient = ambientStrength * lightColor;
distance = distance * distance;
lightDir = normalize(lightDir);
float lambertian = max(dot(norm, lightDir), 0.0);
vec3 diffuse = lambertian * lightColor;
float specular = 0.0;
if (lambertian > 0.0)
{
vec3 viewDir = normalize(-FragPos);
vec3 halfDir = normalize(lightDir + viewDir);
float specAngle = max(dot(halfDir, norm), 0.0);
specular = pow(specAngle, shininess);
}
vec3 colorLinear = (ambient + (diffuse * light_power) + (specular * light_power)) * objectColor;
// vec3 colorGammaCorrected = pow(colorLinear, vec3(1.0 / screenGamma));
FragColor = vec4(colorLinear, 1.0);
// vec3 norm = normalize(Normal);
FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
+11 -10
View File
@@ -1,22 +1,23 @@
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
// layout (location = 1) in vec3 aNormal;
//layout (location = 1) in vec3 aColor;
uniform mat4 model;
uniform mat4 view;
// uniform mat4 model;
// uniform mat4 view;
uniform mat4 projection;
uniform vec3 lightPos;
// uniform vec3 lightPos;
out vec3 FragPos;
out vec3 Normal;
out vec3 LightPos;
// out vec3 Normal;
// out vec3 LightPos;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
FragPos = vec3(view * model * vec4(aPos, 1.0));
Normal = mat3(transpose(inverse(view * model))) * aNormal;
LightPos = vec3(view * vec4(lightPos, 1.0));
// * view * model
gl_Position = projection * vec4(aPos, 1.0);
FragPos = vec3(vec4(aPos, 1.0));
// Normal = mat3(transpose(inverse(view * model))) * aNormal;
// LightPos = vec3(view * vec4(lightPos, 1.0));
}