intial commit

This commit is contained in:
slinky55
2026-04-10 01:45:16 -05:00
commit 38a5aa5a47
12 changed files with 721 additions and 0 deletions

36
.gitignore vendored Normal file
View File

@@ -0,0 +1,36 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
.kotlin
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

392
pom.xml Normal file
View File

@@ -0,0 +1,392 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>me.slinky</groupId>
<artifactId>Tony</artifactId>
<version>0.0.1</version>
<properties>
<maven.compiler.source>22</maven.compiler.source>
<maven.compiler.target>22</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<lwjgl.version>3.4.1</lwjgl.version>
<lwjgl.natives>natives-windows</lwjgl.natives>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-bom</artifactId>
<version>${lwjgl.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-assimp</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-bgfx</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-egl</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-fmod</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-freetype</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-glfw</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-harfbuzz</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-hwloc</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-jawt</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-jemalloc</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-ktx</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-llvm</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-lmdb</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-lz4</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-meshoptimizer</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-msdfgen</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-nanovg</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-nfd</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-nuklear</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-odbc</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-openal</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opencl</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opengl</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opengles</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-openxr</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opus</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-par</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-remotery</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-renderdoc</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-rpmalloc</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-sdl</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-shaderc</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-spng</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-spvc</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-stb</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-tinyexr</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-tinyfd</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-vma</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-vulkan</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-xxhash</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-yoga</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-zstd</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-assimp</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-bgfx</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-freetype</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-glfw</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-harfbuzz</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-hwloc</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-jemalloc</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-ktx</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-llvm</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-lmdb</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-lz4</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-meshoptimizer</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-msdfgen</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-nanovg</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-nfd</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-nuklear</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-openal</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opengl</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opengles</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-openxr</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opus</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-par</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-remotery</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-rpmalloc</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-sdl</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-shaderc</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-spng</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-spvc</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-stb</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-tinyexr</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-tinyfd</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-vma</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-xxhash</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-yoga</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-zstd</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.joml</groupId>
<artifactId>joml</artifactId>
<version>1.10.8</version>
</dependency>
</dependencies>
</project>

52
src/main/java/Mesh.java Normal file
View File

@@ -0,0 +1,52 @@
import org.lwjgl.system.MemoryStack;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Arrays;
import java.util.List;
import static org.lwjgl.opengl.GL40.*;
public class Mesh {
public static final int FLOATS_PER_VERTEX = 8;
public static final int STRIDE = FLOATS_PER_VERTEX * Float.BYTES;
private int _vao;
private int _vbo;
private int _ebo;
public void setup(float[] positions, float[] uv, float[] normals, int[] indices) {
try (MemoryStack stack = MemoryStack.stackPush()) {
_vao = glGenVertexArrays();
glBindVertexArray(_vao);
// pos
_vbo = glGenBuffers();
FloatBuffer posBuffer = stack.mallocFloat(positions.length);
posBuffer.put(positions).flip();
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, posBuffer, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
// uv
int uvVbo = glGenBuffers();
FloatBuffer uvBuffer = stack.mallocFloat(uv.length);
uvBuffer.put(uv).flip();
glBindBuffer(GL_ARRAY_BUFFER, uvVbo);
glBufferData(GL_ARRAY_BUFFER, uvBuffer, GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 0);
// indices
_ebo = glGenBuffers();
IntBuffer indexBuffer = stack.mallocInt(indices.length);
indexBuffer.put(indices).flip();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBuffer, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
}
}

View File

@@ -0,0 +1,13 @@
import org.joml.Vector2f;
import org.joml.Vector3f;
public class PrimitiveGenerator {
public static Mesh getCube() {
var mesh = new Mesh();
Vertex[] vertices = new Vertex[8];
int[] indices = new int[36];
return mesh;
}
}

5
src/main/java/Scene.java Normal file
View File

@@ -0,0 +1,5 @@
import java.util.HashMap;
public class Scene {
private HashMap<String, Mesh> meshes;
}

39
src/main/java/Shader.java Normal file
View File

@@ -0,0 +1,39 @@
import static org.lwjgl.opengl.GL40.*;
public class Shader {
private final int id;
public Shader(String vertexPath, String fragmentPath) {
id = glCreateProgram();
if (id == 0) {
throw new RuntimeException("Could not create Shader");
}
int vertex = ShaderUtils.createShader(vertexPath, GL_VERTEX_SHADER);
glAttachShader(id, vertex);
int fragment = ShaderUtils.createShader(fragmentPath, GL_FRAGMENT_SHADER);
glAttachShader(id, fragment);
glLinkProgram(id);
if (glGetProgrami(id, GL_LINK_STATUS) == 0) {
throw new RuntimeException("Error linking shader code: %s".formatted(glGetProgramInfoLog(id)));
}
glDetachShader(id, vertex);
glDetachShader(id, fragment);
glDeleteShader(vertex);
glDeleteShader(fragment);
}
public void bind() {
glUseProgram(id);
}
public void unbind() {
glUseProgram(0);
}
}

View File

@@ -0,0 +1,37 @@
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;
import static org.lwjgl.opengl.GL40.*;
public class ShaderUtils {
public static String loadShaderSource(String path) {
try (InputStream in = ShaderUtils.class.getResourceAsStream(path)) {
if (in == null) {
throw new RuntimeException("Resource not found %s".formatted(path));
}
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
return reader.lines().collect(Collectors.joining("\n"));
} catch (IOException e) {
throw new RuntimeException("Failed to load resource: %s".formatted(path), e);
}
}
public static int createShader(String path, int type) {
String source = ShaderUtils.loadShaderSource(path);
int shader = glCreateShader(type);
glShaderSource(shader, source);
glCompileShader(shader);
if (glGetShaderi(shader, GL_COMPILE_STATUS) == GL_FALSE) {
throw new RuntimeException("Error compiling shader %s: %s".formatted(path, glGetShaderInfoLog(shader)));
}
return shader;
}
}

107
src/main/java/Tony.java Normal file
View File

@@ -0,0 +1,107 @@
import org.lwjgl.*;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.system.*;
import java.nio.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL40.*;
import static org.lwjgl.system.MemoryStack.*;
import static org.lwjgl.system.MemoryUtil.*;
public class Tony {
private long window;
private Shader shader;
private static final Logger LOGGER = Logger.getLogger( Tony.class.getName() );
public void run() {
LOGGER.log(Level.INFO, "Tony version: %s".formatted(Version.getVersionString()));
LOGGER.log(Level.INFO, "LWJGL version: %s".formatted(org.lwjgl.Version.getVersion()));
init();
// setup game objects
shader = new Shader("/shaders/basic.vert", "/shaders/basic.frag");
loop();
// Free the window callbacks and destroy the window
glfwFreeCallbacks(window);
glfwDestroyWindow(window);
// Terminate GLFW and free the error callback
glfwTerminate();
glfwSetErrorCallback(null).free();
}
private void init() {
GLFWErrorCallback.createPrint(System.err).set();
if ( !glfwInit() )
throw new IllegalStateException("Unable to initialize 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
window = glfwCreateWindow(1024, 720, "Tony %s".formatted(Version.getVersionString()), NULL, NULL);
if ( window == NULL )
throw new RuntimeException("Failed to create the GLFW window");
glfwSetKeyCallback(window, this::glfwKeyCallback);
// 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 videoMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
// Center the window
glfwSetWindowPos(
window,
(videoMode.width() - pWidth.get(0)) / 2,
(videoMode.height() - pHeight.get(0)) / 2
);
} // the stack frame is popped automatically
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwShowWindow(window);
}
private void loop() {
GL.createCapabilities();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
while ( !glfwWindowShouldClose(window) ) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
}
}
private void glfwKeyCallback(long window, int key, int scancode, int action, int mods) {
if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )
glfwSetWindowShouldClose(window, true);
}
public static void main(String[] args) {
new Tony().run();
}
}

View File

@@ -0,0 +1,14 @@
public class Version {
private static String VERSION_STRING = null;
public static String getVersionString() {
if (VERSION_STRING == null) {
VERSION_STRING = "v%d.%d.%d".formatted(VERSION_MAJ, VERSION_MIN, VERSION_PATCH);
}
return VERSION_STRING;
}
public static final int VERSION_MAJ = 0;
public static final int VERSION_MIN = 0;
public static final int VERSION_PATCH = 1;
}

View File

@@ -0,0 +1,8 @@
import org.joml.Vector3f;
import org.joml.Vector2f;
public class Vertex {
public Vector3f position;
public Vector2f uv;
public Vector3f norm;
}

View File

@@ -0,0 +1,7 @@
#version 400 core
out vec4 color;
void main() {
color = vec4(1.0, 0.0, 0.0, 1.0);
}

View File

@@ -0,0 +1,11 @@
#version 400 core
layout (location = 0) in vec3 position;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main() {
gl_Position = projection * view * model * vec4(position, 1.0);
}