diff --git a/graphics/glfw/build.gradle b/graphics/glfw/build.gradle new file mode 100644 index 0000000..e9b5436 --- /dev/null +++ b/graphics/glfw/build.gradle @@ -0,0 +1,128 @@ +/* + * STAROPENSOURCE ENGINE SOURCE FILE + * Copyright (c) 2024 The StarOpenSource Engine Contributors + * Licensed under the GNU Affero General Public License v3 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import org.gradle.internal.os.OperatingSystem + +// Plugins +plugins { + id("java") + id("io.freefair.lombok") version("${pluginLombok}") +} + +// Determine operating system and architecture +switch (OperatingSystem.current()) { + case OperatingSystem.LINUX: + project.dependencyLwjglNatives = "natives-linux" + def osArch = System.getProperty("os.arch") + if (osArch.startsWith("arm") || osArch.startsWith("aarch64")) { + project.dependencyLwjglNatives += osArch.contains("64") || osArch.startsWith("armv8") ? "-arm64" : "-arm32" + } else if (osArch.startsWith("ppc")) { + project.dependencyLwjglNatives += "-ppc64le" + } else if (osArch.startsWith("riscv")) { + project.dependencyLwjglNatives += "-riscv64" + } + break + case OperatingSystem.MAC_OS: + project.dependencyLwjglNatives = System.getProperty("os.arch").startsWith("aarch64") ? "natives-macos-arm64" : "natives-macos" + break + case OperatingSystem.WINDOWS: + def osArch = System.getProperty("os.arch") + project.dependencyLwjglNatives = osArch.contains("64") + ? "natives-windows${osArch.startsWith("aarch64") ? "-arm64" : ""}" + : "natives-windows-x86" + break +} + +// Dependencies +dependencies { + // -> Runtime <- + // Lombok + compileOnly("org.projectlombok:lombok:${dependencyLombok}") + annotationProcessor("org.projectlombok:lombok:${dependencyLombok}") + + // JetBrains Annotations + compileOnly("org.jetbrains:annotations:${dependencyJetbrainsAnnotations}") + + // LWJGL + implementation(platform("org.lwjgl:lwjgl-bom:${dependencyLwjgl}")) + implementation("org.lwjgl:lwjgl") + implementation("org.lwjgl:lwjgl-glfw") + runtimeOnly("org.lwjgl:lwjgl::${dependencyLwjglNatives}") + runtimeOnly("org.lwjgl:lwjgl-glfw::${dependencyLwjglNatives}") + if (project.dependencyLwjglNatives == "natives-macos" || project.dependencyLwjglNatives == "natives-macos-arm64") runtimeOnly("org.lwjgl:lwjgl-vulkan::${dependencyLwjglNatives}") + + // -> Testing <- + // Jetbrains Annotations + testCompileOnly("org.jetbrains:annotations:${dependencyJetbrainsAnnotations}") + + // JUnit + testImplementation(platform("org.junit:junit-bom:${dependencyJunit}")) + testImplementation("org.junit.jupiter:junit-jupiter") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") + + // -> Project <- + implementation(project(":base")) + implementation(project(":graphics")) +} + +// Fix delombok task +delombok.doFirst { + File target = file("${project.projectDir}/src/main/module-info.java") + File source = file("${project.projectDir}/src/main/java/module-info.java") + + target.delete() + source.renameTo(target) +} +delombok.doLast { + File target = file("${project.projectDir}/src/main/java/module-info.java") + File source = file("${project.projectDir}/src/main/module-info.java") + + target.delete() + source.renameTo(target) +} + +// Javadoc configuration +javadoc { + outputs.upToDateWhen { false } // Force task execution + dependsOn(delombok) // Make sure the source is delomboked first + + javadoc { + setClasspath(files(project.sourceSets.main.compileClasspath)) // Include dependencies + + options { + if (new File(projectDir, "src/main/javadoc/theme.css").exists()) + stylesheetFile = new File(projectDir, "src/main/javadoc/theme.css") // Theming is cool :3 + setMemberLevel(JavadocMemberLevel.PUBLIC) // Only display public stuff + setOverview("src/main/javadoc/overview.html") // We want a custom overview page to greet the visitor + setLocale("en_US") // 你好 + + setJFlags([ + "-Duser.language=en_US" // See above + ]) + } + } +} + +// Unit testing configuration +test { + useJUnitPlatform() + testLogging { + events("passed", "skipped", "failed") + } +} diff --git a/graphics/glfw/gradle b/graphics/glfw/gradle new file mode 120000 index 0000000..1ce6c4c --- /dev/null +++ b/graphics/glfw/gradle @@ -0,0 +1 @@ +../../gradle \ No newline at end of file diff --git a/graphics/glfw/gradlew b/graphics/glfw/gradlew new file mode 120000 index 0000000..343e0d2 --- /dev/null +++ b/graphics/glfw/gradlew @@ -0,0 +1 @@ +../../gradlew \ No newline at end of file diff --git a/graphics/glfw/gradlew.bat b/graphics/glfw/gradlew.bat new file mode 120000 index 0000000..cb5a946 --- /dev/null +++ b/graphics/glfw/gradlew.bat @@ -0,0 +1 @@ +../../gradlew.bat \ No newline at end of file diff --git a/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/GlfwSubsystem.java b/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/GlfwSubsystem.java new file mode 100644 index 0000000..ea633f7 --- /dev/null +++ b/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/GlfwSubsystem.java @@ -0,0 +1,144 @@ +/* + * STAROPENSOURCE ENGINE SOURCE FILE + * Copyright (c) 2024 The StarOpenSource Engine Contributors + * Licensed under the GNU Affero General Public License v3 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.staropensource.sosengine.graphics.glfw; + +import de.staropensource.sosengine.base.annotations.EngineSubsystem; +import de.staropensource.sosengine.base.annotations.EventListener; +import de.staropensource.sosengine.base.classes.SubsystemMainClass; +import de.staropensource.sosengine.base.data.info.EngineInformation; +import de.staropensource.sosengine.base.data.versioning.StarOpenSourceVersioningSystem; +import de.staropensource.sosengine.base.internal.events.InternalEngineShutdownEvent; +import de.staropensource.sosengine.base.logging.LoggerInstance; +import de.staropensource.sosengine.base.types.CodePart; +import de.staropensource.sosengine.base.types.DependencyVector; +import de.staropensource.sosengine.base.types.EventPriority; +import de.staropensource.sosengine.base.types.logging.LogIssuer; +import de.staropensource.sosengine.graphics.glfw.events.GraphicsErrorEvent; +import de.staropensource.sosengine.graphics.glfw.exceptions.GlfwInitializationException; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; +import org.lwjgl.glfw.GLFWErrorCallback; + +import java.util.Arrays; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * The main object of the GLFW subsystem. + * + * @since v1-alpha2 + */ +@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" }) +@EngineSubsystem +public class GlfwSubsystem implements SubsystemMainClass { + /** + * Contains the class instance. + * + * @since v1-alpha0 + * + * -- GETTER -- + * Returns the class instance. + * + * @return class instance unless the subsystem is uninitialized + * @since v1-alpha0 + */ + @Getter + private static GlfwSubsystem instance = null; + + /** + * Logger instance. + * + * @see LoggerInstance + * @since v1-alpha0 + */ + private final LoggerInstance logger = new LoggerInstance(new LogIssuer(getClass(), CodePart.ENGINE)); + + /** + * Constructs this subsystem. + * + * @since v1-alpha2 + */ + public GlfwSubsystem() { + // Check if subsystem has already initialized + if (instance == null) + instance = this; + else { + instance.logger.crash("The subsystem tried to initialize twice"); + } + } + + /** {@inheritDoc} */ + @Override + public @NotNull String getName() { + return "glfw"; + } + + /** {@inheritDoc} */ + @Override + public void initializeSubsystem() {} + + /** {@inheritDoc} */ + @NotNull + @Override + public DependencyVector getDependencyVector() { + return new DependencyVector(getName(), StarOpenSourceVersioningSystem.class, EngineInformation.getVersioningString(), Arrays.stream(new String[]{ "graphics" }).toList()); + } + + /** + * Initializes GLFW. + * + * @since v1-alpha2 + */ + public void initializeGlfw() { + // Set error callback + try (GLFWErrorCallback errorCallback = GLFWErrorCallback.create(new GraphicsErrorEvent())) { + errorCallback.set(); + } + + // Initialize GLFW + if (!glfwInit()) + throw new GlfwInitializationException(); + } + + /** + * Terminates GLFW. + * + * @since v1-alpha2 + */ + public void terminateGlfw() { + logger.verb("Terminating GLFW"); + + glfwTerminate(); + //noinspection DataFlowIssue,resource + glfwSetErrorCallback(null).free(); + } + + + /** + * Called when the engine shuts down. + * + * @since v1-alpha2 + */ + @EventListener(event = InternalEngineShutdownEvent.class, priority = EventPriority.EXTREMELY_UNIMPORTANT) + private static void shutdownApiFromEvent() { + if (instance != null) + instance.terminateGlfw(); + } +} diff --git a/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/classes/Window.java b/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/classes/Window.java new file mode 100644 index 0000000..cf52b94 --- /dev/null +++ b/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/classes/Window.java @@ -0,0 +1,154 @@ +/* + * STAROPENSOURCE ENGINE SOURCE FILE + * Copyright (c) 2024 The StarOpenSource Engine Contributors + * Licensed under the GNU Affero General Public License v3 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.staropensource.sosengine.graphics.glfw.classes; + +import de.staropensource.sosengine.base.exceptions.UnexpectedThrowableException; +import de.staropensource.sosengine.base.types.vectors.Vec2i; +import de.staropensource.sosengine.base.utility.Miscellaneous; +import de.staropensource.sosengine.graphics.events.GraphicsApiErrorEvent; +import de.staropensource.sosengine.graphics.glfw.exceptions.NotOnMainThreadException; +import de.staropensource.sosengine.graphics.glfw.exceptions.WindowCreationFailureException; +import de.staropensource.sosengine.graphics.types.VsyncMode; +import de.staropensource.sosengine.graphics.types.WindowMode; +import org.jetbrains.annotations.NotNull; +import org.lwjgl.system.MemoryUtil; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * A window on your screen. + * + * @since v1-alpha0 + */ +@SuppressWarnings({ "unused" }) +public abstract class Window extends de.staropensource.sosengine.graphics.classes.Window { + /** + * Creates a new window. + * + * @param title title + * @param size size + * @param position position + * @param windowMode window mode + * @param vsyncMode V-Sync mode + * @param resizable resizable flag + * @param borderless borderless flag + * @param focusable focusable flag + * @param onTop on top flag + * @param transparent transparency flag + * @param rendering rendering flag + * @throws UnexpectedThrowableException stuff thrown by the {@link #initializeWindow()} of the Graphics API + * @since v1-alpha2 + */ + public Window(@NotNull String title, @NotNull Vec2i size, @NotNull Vec2i position, @NotNull WindowMode windowMode, @NotNull VsyncMode vsyncMode, boolean resizable, boolean borderless, boolean focusable, boolean onTop, boolean transparent, boolean rendering) throws UnexpectedThrowableException { + super(title, size, position, windowMode, vsyncMode, resizable, borderless, focusable, onTop, transparent, rendering); + } + + /** {@inheritDoc} */ + @Override + protected void initializeWindow() throws Throwable { + // Ensure running on the main thread + if (!Miscellaneous.onMainThread()) + throw new NotOnMainThreadException(); + + // Create window + long identifier = glfwCreateWindow(getSize().getX(), getSize().getY(), getTitle(), MemoryUtil.NULL, MemoryUtil.NULL); + if (identifier == MemoryUtil.NULL) { + new GraphicsApiErrorEvent().callEvent("Unable to create window: Identifier is null"); + throw new WindowCreationFailureException(); + } + + // Set identifier + setIdentifier(String.valueOf(identifier)); + + // Call GLFW window initialization method + initializeGlfwWindow(); + } + + /** + * Initializes the GLFW window. + * + * @throws Throwable throwable + * @since v1-alpha2 + */ + protected abstract void initializeGlfwWindow() throws Throwable; + + /** {@inheritDoc} */ + @Override + public void updateState() throws Throwable { + // Ensure running on the main thread + if (!Miscellaneous.onMainThread()) + throw new NotOnMainThreadException(); + + ownContext(getIdentifierAsLong()); + + // Update window visibility + if (getWindowMode() == WindowMode.HIDDEN) + glfwHideWindow(getIdentifierAsLong()); + else + glfwShowWindow(getIdentifierAsLong()); + + updateGlfwState(); + } + + /** + * Updates the state of the GLFW window. + * + * @throws Throwable throwable + * @since v1-alpha2 + */ + protected abstract void updateGlfwState() throws Throwable; + + /** {@inheritDoc} */ + @Override + public void render() throws NotOnMainThreadException { + // Ensure running on the main thread + if (!Miscellaneous.onMainThread()) + throw new NotOnMainThreadException(); + + glfwSwapBuffers(getIdentifierAsLong()); + glfwPollEvents(); + } + + /** {@inheritDoc} */ + @Override + public boolean isClosureRequested() { + return glfwWindowShouldClose(getIdentifierAsLong()); + } + + /** + * Returns the window identifier as a long. + * + * @return window identifier as a long + * @since v1-alpha2 + */ + public long getIdentifierAsLong() { + return Long.parseLong(getIdentifier()); + } + + /** + * Updates the OpenGL context. + * + * @param identifier window to own the context of + * @since v1-alpha2 + */ + public void ownContext(long identifier) { + glfwMakeContextCurrent(identifier); + } +} diff --git a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/events/GraphicsErrorEvent.java b/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/events/GraphicsErrorEvent.java similarity index 95% rename from graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/events/GraphicsErrorEvent.java rename to graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/events/GraphicsErrorEvent.java index 812f273..ea16753 100644 --- a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/events/GraphicsErrorEvent.java +++ b/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/events/GraphicsErrorEvent.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package de.staropensource.sosengine.graphics.opengl.events; +package de.staropensource.sosengine.graphics.glfw.events; import org.lwjgl.glfw.GLFWErrorCallbackI; diff --git a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/exceptions/GlfwInitializationException.java b/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/exceptions/GlfwInitializationException.java similarity index 94% rename from graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/exceptions/GlfwInitializationException.java rename to graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/exceptions/GlfwInitializationException.java index 2c6f6a4..cc02593 100644 --- a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/exceptions/GlfwInitializationException.java +++ b/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/exceptions/GlfwInitializationException.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package de.staropensource.sosengine.graphics.opengl.exceptions; +package de.staropensource.sosengine.graphics.glfw.exceptions; /** * Thrown when GLFW fails to initialize. diff --git a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/exceptions/NotOnMainThreadException.java b/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/exceptions/NotOnMainThreadException.java similarity index 94% rename from graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/exceptions/NotOnMainThreadException.java rename to graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/exceptions/NotOnMainThreadException.java index 5870e02..f76b0c8 100644 --- a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/exceptions/NotOnMainThreadException.java +++ b/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/exceptions/NotOnMainThreadException.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package de.staropensource.sosengine.graphics.opengl.exceptions; +package de.staropensource.sosengine.graphics.glfw.exceptions; /** * Thrown when trying to communicate with the Graphics API over a non-main thread. diff --git a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/exceptions/WindowCreationFailureException.java b/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/exceptions/WindowCreationFailureException.java similarity index 95% rename from graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/exceptions/WindowCreationFailureException.java rename to graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/exceptions/WindowCreationFailureException.java index 3fb8f83..09fab4d 100644 --- a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/exceptions/WindowCreationFailureException.java +++ b/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/exceptions/WindowCreationFailureException.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package de.staropensource.sosengine.graphics.opengl.exceptions; +package de.staropensource.sosengine.graphics.glfw.exceptions; import org.jetbrains.annotations.NotNull; diff --git a/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/package-info.java b/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/package-info.java new file mode 100644 index 0000000..926d01f --- /dev/null +++ b/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/package-info.java @@ -0,0 +1,25 @@ +/* + * STAROPENSOURCE ENGINE SOURCE FILE + * Copyright (c) 2024 The StarOpenSource Engine Contributors + * Licensed under the GNU Affero General Public License v3 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +/** + * Contains the common GLFW code. + * + * @since v1-alpha2 + */ +package de.staropensource.sosengine.graphics.glfw; diff --git a/graphics/glfw/src/main/java/module-info.java b/graphics/glfw/src/main/java/module-info.java new file mode 100644 index 0000000..b49b57c --- /dev/null +++ b/graphics/glfw/src/main/java/module-info.java @@ -0,0 +1,23 @@ +module sosengine.graphics.glfw.main { + // Dependencies + // -> Subsystems + requires transitive sosengine.base; + requires transitive sosengine.graphics; + // -> Libraries + requires transitive static lombok; + requires transitive org.jetbrains.annotations; + requires org.lwjgl; + requires org.lwjgl.glfw; + + // API access + exports de.staropensource.sosengine.graphics.glfw; + exports de.staropensource.sosengine.graphics.glfw.classes; + exports de.staropensource.sosengine.graphics.glfw.events; + exports de.staropensource.sosengine.graphics.glfw.exceptions; + + // Reflection access + opens de.staropensource.sosengine.graphics.glfw; + opens de.staropensource.sosengine.graphics.glfw.classes; + opens de.staropensource.sosengine.graphics.glfw.events; + opens de.staropensource.sosengine.graphics.glfw.exceptions; +} diff --git a/graphics/glfw/src/main/javadoc/theme.css b/graphics/glfw/src/main/javadoc/theme.css new file mode 120000 index 0000000..bccac6b --- /dev/null +++ b/graphics/glfw/src/main/javadoc/theme.css @@ -0,0 +1 @@ +../../../../../src/main/javadoc/theme.css \ No newline at end of file diff --git a/graphics/opengl/build.gradle b/graphics/opengl/build.gradle index e9adfbb..349eb3d 100644 --- a/graphics/opengl/build.gradle +++ b/graphics/opengl/build.gradle @@ -83,6 +83,7 @@ dependencies { // -> Project <- implementation(project(":base")) implementation(project(":graphics")) + implementation(project(":graphics:glfw")) } // Fix delombok task diff --git a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/OpenGlSubsystem.java b/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/OpenGlSubsystem.java index 64ada5a..691b480 100644 --- a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/OpenGlSubsystem.java +++ b/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/OpenGlSubsystem.java @@ -24,23 +24,20 @@ import de.staropensource.sosengine.base.annotations.EventListener; import de.staropensource.sosengine.base.classes.helpers.EventHelper; import de.staropensource.sosengine.base.data.info.EngineInformation; import de.staropensource.sosengine.base.data.versioning.StarOpenSourceVersioningSystem; -import de.staropensource.sosengine.base.internal.events.InternalEngineShutdownEvent; import de.staropensource.sosengine.base.logging.LoggerInstance; import de.staropensource.sosengine.base.types.CodePart; import de.staropensource.sosengine.base.types.DependencyVector; import de.staropensource.sosengine.base.types.EventPriority; import de.staropensource.sosengine.base.types.logging.LogIssuer; -import de.staropensource.sosengine.base.utility.Miscellaneous; import de.staropensource.sosengine.graphics.GraphicsSubsystem; import de.staropensource.sosengine.graphics.classes.ApiInternalClass; import de.staropensource.sosengine.graphics.classes.ApiMainClass; import de.staropensource.sosengine.graphics.classes.ApiManagementClass; import de.staropensource.sosengine.graphics.events.GraphicsApiErrorEvent; -import de.staropensource.sosengine.graphics.opengl.events.GraphicsErrorEvent; -import de.staropensource.sosengine.graphics.opengl.exceptions.GlfwInitializationException; +import de.staropensource.sosengine.graphics.glfw.GlfwSubsystem; +import de.staropensource.sosengine.graphics.glfw.events.GraphicsErrorEvent; import lombok.Getter; import org.jetbrains.annotations.NotNull; -import org.lwjgl.glfw.GLFWErrorCallback; import org.lwjgl.system.MemoryUtil; import java.util.Locale; @@ -135,44 +132,17 @@ public final class OpenGlSubsystem implements ApiMainClass { /** {@inheritDoc} */ @Override public void initializeApi() { - // Set error callback - try (GLFWErrorCallback errorCallback = GLFWErrorCallback.create(new GraphicsErrorEvent())) { - errorCallback.set(); - } - - // Initialize GLFW - if (!glfwInit()) - throw new GlfwInitializationException(); + GlfwSubsystem.getInstance().initializeGlfw(); // Initialize management class internalApi = new OpenGlInternalApi(); management = new OpenGlManagement(); } - /** - * Called when the engine shuts down. - * - * @since v1-alpha2 - */ - @EventListener(event = InternalEngineShutdownEvent.class, priority = EventPriority.EXTREMELY_UNIMPORTANT) - private static void shutdownApiFromEvent() { - if (instance != null) - instance.shutdownApi(); - } - /** {@inheritDoc} */ @Override public void shutdownApi() { - logger.verb("Shutting down"); - - @SuppressWarnings("resource") - long shutdownTime = Miscellaneous.measureExecutionTime(() -> { - glfwTerminate(); - //noinspection DataFlowIssue - glfwSetErrorCallback(null).free(); - }); - - logger.info("Shut down in " + shutdownTime + "ms"); + GlfwSubsystem.getInstance().terminateGlfw(); } /** {@inheritDoc} */ diff --git a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/classes/Window.java b/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/classes/Window.java index 1a16d70..27a7de5 100644 --- a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/classes/Window.java +++ b/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/classes/Window.java @@ -21,17 +21,12 @@ package de.staropensource.sosengine.graphics.opengl.classes; import de.staropensource.sosengine.base.exceptions.UnexpectedThrowableException; import de.staropensource.sosengine.base.types.vectors.Vec2i; -import de.staropensource.sosengine.base.utility.Miscellaneous; -import de.staropensource.sosengine.graphics.events.GraphicsApiErrorEvent; -import de.staropensource.sosengine.graphics.opengl.exceptions.NotOnMainThreadException; -import de.staropensource.sosengine.graphics.opengl.exceptions.WindowCreationFailureException; +import de.staropensource.sosengine.graphics.glfw.exceptions.NotOnMainThreadException; +import de.staropensource.sosengine.graphics.glfw.exceptions.WindowCreationFailureException; import de.staropensource.sosengine.graphics.types.VsyncMode; import de.staropensource.sosengine.graphics.types.WindowMode; import org.jetbrains.annotations.NotNull; import org.lwjgl.opengl.GL; -import org.lwjgl.system.MemoryUtil; - -import static org.lwjgl.glfw.GLFW.*; /** * A window on your screen. @@ -39,7 +34,7 @@ import static org.lwjgl.glfw.GLFW.*; * @since v1-alpha0 */ @SuppressWarnings({ "unused" }) -public class Window extends de.staropensource.sosengine.graphics.classes.Window { +public class Window extends de.staropensource.sosengine.graphics.glfw.classes.Window { /** * Creates a new window. * @@ -63,59 +58,14 @@ public class Window extends de.staropensource.sosengine.graphics.classes.Window /** {@inheritDoc} */ @Override - public void initializeWindow() throws WindowCreationFailureException, NotOnMainThreadException { - // Ensure running on the main thread - if (!Miscellaneous.onMainThread()) - throw new NotOnMainThreadException(); - - // Set required version and profile - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - - // Create window - long identifier = glfwCreateWindow(getSize().getX(), getSize().getY(), getTitle(), MemoryUtil.NULL, MemoryUtil.NULL); - if (identifier == MemoryUtil.NULL) { - new GraphicsApiErrorEvent().callEvent("Unable to create window: Identifier is null"); - throw new de.staropensource.sosengine.graphics.opengl.exceptions.WindowCreationFailureException(); - } - - // Set identifier - setIdentifier(String.valueOf(identifier)); - - ownContext(identifier); // Own context + public void initializeGlfwWindow() throws WindowCreationFailureException, NotOnMainThreadException { + ownContext(getIdentifierAsLong()); // Own context GL.createCapabilities(); // Create OpenGL capabilities } /** {@inheritDoc} */ @Override - public void updateState() throws NotOnMainThreadException { - // Ensure running on the main thread - if (!Miscellaneous.onMainThread()) - throw new NotOnMainThreadException(); - - long identifier = getIdentifierAsLong(); - ownContext(identifier); - - // Update window visibility - if (getWindowMode() == WindowMode.HIDDEN) - glfwHideWindow(identifier); - else - glfwShowWindow(identifier); - } - - /** {@inheritDoc} */ - @Override - public void render() throws NotOnMainThreadException { - // Ensure running on the main thread - if (!Miscellaneous.onMainThread()) - throw new NotOnMainThreadException(); - - long identifier = getIdentifierAsLong(); - - glfwSwapBuffers(identifier); - glfwPollEvents(); - } + public void updateGlfwState() throws NotOnMainThreadException {} /** {@inheritDoc} */ @NotNull @@ -130,30 +80,4 @@ public class Window extends de.staropensource.sosengine.graphics.classes.Window public Vec2i getPositionWithDecorations() { return getPosition(); } - - /** {@inheritDoc} */ - @Override - public boolean isClosureRequested() { - return glfwWindowShouldClose(getIdentifierAsLong()); - } - - /** - * Returns the window identifier as a long. - * - * @return window identifier as a long - * @since v1-alpha2 - */ - public long getIdentifierAsLong() { - return Long.parseLong(getIdentifier()); - } - - /** - * Updates the OpenGL context. - * - * @param identifier window to own the context of - * @since v1-alpha2 - */ - public void ownContext(long identifier) { - glfwMakeContextCurrent(identifier); - } } diff --git a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/package-info.java b/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/package-info.java new file mode 100644 index 0000000..9f83649 --- /dev/null +++ b/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/package-info.java @@ -0,0 +1,25 @@ +/* + * STAROPENSOURCE ENGINE SOURCE FILE + * Copyright (c) 2024 The StarOpenSource Engine Contributors + * Licensed under the GNU Affero General Public License v3 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +/** + * Contains the OpenGL subsystem. + * + * @since v1-alpha0 + */ +package de.staropensource.sosengine.graphics.opengl; diff --git a/graphics/opengl/src/main/java/module-info.java b/graphics/opengl/src/main/java/module-info.java index 614bc31..6967285 100644 --- a/graphics/opengl/src/main/java/module-info.java +++ b/graphics/opengl/src/main/java/module-info.java @@ -14,16 +14,13 @@ module sosengine.graphics.opengl { requires org.lwjgl; requires org.lwjgl.glfw; requires org.lwjgl.opengl; + requires sosengine.graphics.glfw.main; // API access exports de.staropensource.sosengine.graphics.opengl; exports de.staropensource.sosengine.graphics.opengl.classes; - exports de.staropensource.sosengine.graphics.opengl.exceptions; - exports de.staropensource.sosengine.graphics.opengl.events; // Reflection access opens de.staropensource.sosengine.graphics.opengl; opens de.staropensource.sosengine.graphics.opengl.classes; - opens de.staropensource.sosengine.graphics.opengl.exceptions; - opens de.staropensource.sosengine.graphics.opengl.events; } diff --git a/graphics/vulkan/build.gradle b/graphics/vulkan/build.gradle index cbafbcb..eb59909 100644 --- a/graphics/vulkan/build.gradle +++ b/graphics/vulkan/build.gradle @@ -80,6 +80,7 @@ dependencies { // -> Project <- implementation(project(":base")) implementation(project(":graphics")) + implementation(project(":graphics:glfw")) } // Fix delombok task diff --git a/settings.gradle b/settings.gradle index 55b8476..6ae5f00 100644 --- a/settings.gradle +++ b/settings.gradle @@ -22,6 +22,7 @@ rootProject.name = "sosengine" include "base" include "slf4j-compat" include "graphics" +include "graphics:glfw" include "graphics:opengl" include "graphics:vulkan" include "testapp"