diff --git a/conveyor.conf b/conveyor.conf index ae24a6b..d9b6a9d 100644 --- a/conveyor.conf +++ b/conveyor.conf @@ -27,18 +27,17 @@ app { updates = aggressive jvm { - extract-native-libraries = true + extract-native-libraries = false system-properties = { - "org.lwjgl.librarypath" = +// "org.lwjgl.librarypath" = "org.lwjgl.util.Debug" = true } // Required options because module is converted to jar (https://github.com/hydraulic-software/conveyor/issues/55) - options += "--enable-native-access=ALL-UNNAMED" - options += "--add-opens=javafx.graphics/javafx.scene=ALL-UNNAMED" - modules = [javafx.base, javafx.controls, javafx.fxml] +// options += "--enable-native-access=ALL-UNNAMED" +// options += "--add-opens=javafx.graphics/javafx.scene=ALL-UNNAMED" +// modules = [javafx.base, javafx.controls, javafx.fxml] } } app.windows.console = true - conveyor.compatibility-level = 8 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e6f16f6..fae0804 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-rc-3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/com/lenis0012/oraksi/HelloController.java b/src/main/java/com/lenis0012/oraksi/HelloController.java index 61a8b95..a8910c9 100644 --- a/src/main/java/com/lenis0012/oraksi/HelloController.java +++ b/src/main/java/com/lenis0012/oraksi/HelloController.java @@ -1,8 +1,15 @@ package com.lenis0012.oraksi; +import com.lenis0012.oraksi.engine.OraksiRenderer; +import com.lenis0012.oraksi.lwjgl.LwjglNode; +import javafx.fxml.FXML; + public class HelloController { + @FXML + private LwjglNode sceneExplorer; public void initialize() { + sceneExplorer.setRenderFunction(new OraksiRenderer()); } } diff --git a/src/main/java/com/lenis0012/oraksi/engine/OraksiRenderer.java b/src/main/java/com/lenis0012/oraksi/engine/OraksiRenderer.java new file mode 100644 index 0000000..8e9462e --- /dev/null +++ b/src/main/java/com/lenis0012/oraksi/engine/OraksiRenderer.java @@ -0,0 +1,105 @@ +package com.lenis0012.oraksi.engine; + +import com.lenis0012.oraksi.lwjgl.Renderer; +import org.lwjgl.system.MemoryStack; + +import java.io.InputStream; +import java.nio.IntBuffer; +import java.nio.charset.StandardCharsets; + +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.opengl.GL15.*; +import static org.lwjgl.opengl.GL30.*; +import static org.lwjgl.system.MemoryStack.*; + +public class OraksiRenderer implements Renderer { + private static final float[] INPUT = { + -0.5f, -0.5f, 0.0f, + 0.5f, -0.5f, 0.0f, + 0.0f, 0.5f, 0.0f + }; + + private boolean initialized = false; + private int vaoId; + private int vboId; + private int shaderId; + + @Override + public void destroy() { + if(vboId != 0) { + glDeleteBuffers(vboId); + } + if(vaoId != 0) { + glDeleteVertexArrays(vaoId); + } + if(shaderId != 0) { + glDeleteProgram(shaderId); + } + } + + @Override + public void render() { + if(!initialized) { + initialize(); + } + + glUseProgram(shaderId); + glBindVertexArray(vaoId); + glDrawArrays(GL_TRIANGLES, 0, 3); + } + + public void initialize() { + this.initialized = true; + + this.vaoId = glGenVertexArrays(); + glBindVertexArray(vaoId); + + this.vboId = glGenBuffers(); + glBindBuffer(GL_ARRAY_BUFFER, vboId); + glBufferData(GL_ARRAY_BUFFER, INPUT, GL_STATIC_DRAW); + glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0); + glEnableVertexAttribArray(0); + + int vertexShader = glCreateShader(GL_VERTEX_SHADER); + try( + InputStream inputStream = OraksiRenderer.class.getResourceAsStream("/shaders/main.vert"); + MemoryStack stack = stackPush() + ) { + String source = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); + glShaderSource(vertexShader, source); + glCompileShader(vertexShader); + IntBuffer success = stack.mallocInt(1); + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, success); + if(success.get(0) == GL_FALSE) { + throw new RuntimeException("Failed to compile shader: " + glGetShaderInfoLog(vertexShader)); + } + } catch (Exception e) { + throw new RuntimeException("Failed to load shader", e); + } + + int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + try ( + InputStream inputStream = OraksiRenderer.class.getResourceAsStream("/shaders/main.frag"); + MemoryStack stack = stackPush(); + ) { + String source = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); + glShaderSource(fragmentShader, source); + glCompileShader(fragmentShader); + IntBuffer success = stack.mallocInt(1); + glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, success); + if(success.get(0) == GL_FALSE) { + throw new RuntimeException("Failed to compile shader: " + glGetShaderInfoLog(fragmentShader)); + } + } catch (Exception e) { + throw new RuntimeException("Failed to load shader", e); + } + + this.shaderId = glCreateProgram(); + glAttachShader(shaderId, vertexShader); + glAttachShader(shaderId, fragmentShader); + glLinkProgram(shaderId); + + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + } +} diff --git a/src/main/java/com/lenis0012/oraksi/lwjgl/LwjglNode.java b/src/main/java/com/lenis0012/oraksi/lwjgl/LwjglNode.java index 823de29..9fa89bb 100644 --- a/src/main/java/com/lenis0012/oraksi/lwjgl/LwjglNode.java +++ b/src/main/java/com/lenis0012/oraksi/lwjgl/LwjglNode.java @@ -33,7 +33,7 @@ public class LwjglNode extends Region { DEFAULT_WINDOW_HINTS.put(hint, value); } - private final ObjectProperty renderFunction; + private final ObjectProperty renderFunction; private final ReadOnlyLongWrapper glfwWindowWrapper; private final ObjectProperty clearColor; private BooleanExpression treeVisibleProperty; @@ -46,7 +46,19 @@ public class LwjglNode extends Region { public LwjglNode() { super(); - this.renderFunction = new SimpleObjectProperty<>(this, "renderFunction", () -> {}); + this.renderFunction = new SimpleObjectProperty<>(this, "renderFunction", new Renderer() { + @Override + public void initialize() { + } + + @Override + public void render() { + } + + @Override + public void destroy() { + } + }); this.glfwWindowWrapper = new ReadOnlyLongWrapper(this, "glfwWindow", 0); this.clearColor = new SimpleObjectProperty<>(this, "clearColor", Color.color(0.2f, 0.05f, 0.1f)); @@ -120,15 +132,15 @@ public class LwjglNode extends Region { }); } - public ObjectProperty renderFunctionProperty() { + public ObjectProperty renderFunctionProperty() { return renderFunction; } - public void setRenderFunction(Runnable renderFunction) { + public void setRenderFunction(Renderer renderFunction) { this.renderFunction.set(renderFunction); } - public Runnable getRenderFunction() { + public Renderer getRenderFunction() { return renderFunction.get(); } @@ -257,7 +269,7 @@ public class LwjglNode extends Region { } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer - renderFunction.get().run(); + renderFunction.get().render(); glfwSwapBuffers(window); // swap the color buffers // Poll for window events. The key callback above will only be @@ -267,6 +279,7 @@ public class LwjglNode extends Region { } private void cleanup() { + renderFunction.get().destroy(); Win32Api.setParent(MemorySegment.ofAddress(glfwGetWin32Window(window)), MemorySegment.NULL); glfwFreeCallbacks(window); glfwDestroyWindow(window); diff --git a/src/main/java/com/lenis0012/oraksi/lwjgl/Renderer.java b/src/main/java/com/lenis0012/oraksi/lwjgl/Renderer.java new file mode 100644 index 0000000..7b58d23 --- /dev/null +++ b/src/main/java/com/lenis0012/oraksi/lwjgl/Renderer.java @@ -0,0 +1,10 @@ +package com.lenis0012.oraksi.lwjgl; + +public interface Renderer { + + void initialize(); + + void render(); + + void destroy(); +} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index a52020f..df7bb57 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -10,9 +10,9 @@ module oraksi { requires org.lwjgl.glfw; requires org.lwjgl.opengl; -// requires org.lwjgl.natives; -// requires org.lwjgl.glfw.natives; -// requires org.lwjgl.opengl.natives; + requires org.lwjgl.natives; + requires org.lwjgl.glfw.natives; + requires org.lwjgl.opengl.natives; opens com.lenis0012.oraksi to javafx.fxml; opens com.lenis0012.oraksi.lwjgl to javafx.fxml; diff --git a/src/main/resources/shaders/main.frag b/src/main/resources/shaders/main.frag new file mode 100644 index 0000000..c296f2f --- /dev/null +++ b/src/main/resources/shaders/main.frag @@ -0,0 +1,7 @@ +#version 330 core + +out vec4 FragColor; + +void main() { + FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); +} diff --git a/src/main/resources/shaders/main.vert b/src/main/resources/shaders/main.vert new file mode 100644 index 0000000..3a321af --- /dev/null +++ b/src/main/resources/shaders/main.vert @@ -0,0 +1,7 @@ +#version 330 core + +layout (location = 0) in vec3 aPos; + +void main() { + gl_Position = vec4(aPos, 1.0); +}