Compare commits

...

4 Commits

9 changed files with 178 additions and 12 deletions

View File

@@ -10,7 +10,7 @@ import org.gradle.internal.os.OperatingSystem
group 'com.lenis0012' group 'com.lenis0012'
version '1.0' version '1.0'
project.ext.lwjglVersion = "3.3.2-SNAPSHOT" project.ext.lwjglVersion = "3.3.2"
switch (OperatingSystem.current()) { switch (OperatingSystem.current()) {
case OperatingSystem.LINUX: case OperatingSystem.LINUX:
project.ext.lwjglNatives = "natives-linux" project.ext.lwjglNatives = "natives-linux"
@@ -58,9 +58,9 @@ application {
mainModule = 'oraksi' mainModule = 'oraksi'
mainClass = 'com.lenis0012.oraksi.HelloApplication' mainClass = 'com.lenis0012.oraksi.HelloApplication'
applicationDefaultJvmArgs = [ applicationDefaultJvmArgs = [
'--enable-preview', '--enable-native-access=oraksi', '--enable-preview',
'--add-opens', '--enable-native-access=oraksi',
'javafx.graphics/javafx.scene=oraksi' '--add-opens=javafx.graphics/javafx.scene=oraksi'
] ]
} }

View File

@@ -8,9 +8,13 @@ app {
display-name = "Oraksi" display-name = "Oraksi"
rdns-name = "com.lenis0012.oraksi" rdns-name = "com.lenis0012.oraksi"
machines = [
"windows.amd64"
]
// Windows gets square icons, macOS and Linux icons with rounded corners. // Windows gets square icons, macOS and Linux icons with rounded corners.
icons = { icons = {
label = "FX" label = "Ok"
} }
// Ensure the icons are also included as data files so we can set the window icon. // Ensure the icons are also included as data files so we can set the window icon.
@@ -21,6 +25,19 @@ app {
// Check for and apply updates synchronously on every app launch instead of in the background. // Check for and apply updates synchronously on every app launch instead of in the background.
// Consider removing this line for your own app! // Consider removing this line for your own app!
updates = aggressive updates = aggressive
jvm {
extract-native-libraries = false
system-properties = {
// "org.lwjgl.librarypath" = <libpath>
"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]
}
} }
app.windows.console = true
conveyor.compatibility-level = 8 conveyor.compatibility-level = 8

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists 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 zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@@ -1,8 +1,15 @@
package com.lenis0012.oraksi; package com.lenis0012.oraksi;
import com.lenis0012.oraksi.engine.OraksiRenderer;
import com.lenis0012.oraksi.lwjgl.LwjglNode;
import javafx.fxml.FXML;
public class HelloController { public class HelloController {
@FXML
private LwjglNode sceneExplorer;
public void initialize() { public void initialize() {
sceneExplorer.setRenderFunction(new OraksiRenderer());
} }
} }

View File

@@ -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);
}
}

View File

@@ -33,7 +33,7 @@ public class LwjglNode extends Region {
DEFAULT_WINDOW_HINTS.put(hint, value); DEFAULT_WINDOW_HINTS.put(hint, value);
} }
private final ObjectProperty<Runnable> renderFunction; private final ObjectProperty<Renderer> renderFunction;
private final ReadOnlyLongWrapper glfwWindowWrapper; private final ReadOnlyLongWrapper glfwWindowWrapper;
private final ObjectProperty<Color> clearColor; private final ObjectProperty<Color> clearColor;
private BooleanExpression treeVisibleProperty; private BooleanExpression treeVisibleProperty;
@@ -46,7 +46,19 @@ public class LwjglNode extends Region {
public LwjglNode() { public LwjglNode() {
super(); 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.glfwWindowWrapper = new ReadOnlyLongWrapper(this, "glfwWindow", 0);
this.clearColor = new SimpleObjectProperty<>(this, "clearColor", Color.color(0.2f, 0.05f, 0.1f)); 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<Runnable> renderFunctionProperty() { public ObjectProperty<Renderer> renderFunctionProperty() {
return renderFunction; return renderFunction;
} }
public void setRenderFunction(Runnable renderFunction) { public void setRenderFunction(Renderer renderFunction) {
this.renderFunction.set(renderFunction); this.renderFunction.set(renderFunction);
} }
public Runnable getRenderFunction() { public Renderer getRenderFunction() {
return renderFunction.get(); return renderFunction.get();
} }
@@ -257,7 +269,7 @@ public class LwjglNode extends Region {
} }
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
renderFunction.get().run(); renderFunction.get().render();
glfwSwapBuffers(window); // swap the color buffers glfwSwapBuffers(window); // swap the color buffers
// Poll for window events. The key callback above will only be // Poll for window events. The key callback above will only be
@@ -267,6 +279,7 @@ public class LwjglNode extends Region {
} }
private void cleanup() { private void cleanup() {
renderFunction.get().destroy();
Win32Api.setParent(MemorySegment.ofAddress(glfwGetWin32Window(window)), MemorySegment.NULL); Win32Api.setParent(MemorySegment.ofAddress(glfwGetWin32Window(window)), MemorySegment.NULL);
glfwFreeCallbacks(window); glfwFreeCallbacks(window);
glfwDestroyWindow(window); glfwDestroyWindow(window);

View File

@@ -0,0 +1,10 @@
package com.lenis0012.oraksi.lwjgl;
public interface Renderer {
void initialize();
void render();
void destroy();
}

View File

@@ -0,0 +1,7 @@
#version 330 core
out vec4 FragColor;
void main() {
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}

View File

@@ -0,0 +1,7 @@
#version 330 core
layout (location = 0) in vec3 aPos;
void main() {
gl_Position = vec4(aPos, 1.0);
}