Move common GLFW code to new 'glfw' subsystem

This commit is contained in:
JeremyStar™ 2024-07-21 23:19:02 +02:00
parent bca45488d1
commit 071534eb1c
Signed by: JeremyStarTM
GPG key ID: E366BAEF67E4704D
20 changed files with 521 additions and 124 deletions

128
graphics/glfw/build.gradle Normal file
View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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")
}
}

1
graphics/glfw/gradle Symbolic link
View file

@ -0,0 +1 @@
../../gradle

1
graphics/glfw/gradlew vendored Symbolic link
View file

@ -0,0 +1 @@
../../gradlew

1
graphics/glfw/gradlew.bat vendored Symbolic link
View file

@ -0,0 +1 @@
../../gradlew.bat

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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();
}
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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);
}
}

View file

@ -17,7 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.sosengine.graphics.opengl.events; package de.staropensource.sosengine.graphics.glfw.events;
import org.lwjgl.glfw.GLFWErrorCallbackI; import org.lwjgl.glfw.GLFWErrorCallbackI;

View file

@ -17,7 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.sosengine.graphics.opengl.exceptions; package de.staropensource.sosengine.graphics.glfw.exceptions;
/** /**
* Thrown when GLFW fails to initialize. * Thrown when GLFW fails to initialize.

View file

@ -17,7 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
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. * Thrown when trying to communicate with the Graphics API over a non-main thread.

View file

@ -17,7 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.sosengine.graphics.opengl.exceptions; package de.staropensource.sosengine.graphics.glfw.exceptions;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
/**
* Contains the common GLFW code.
*
* @since v1-alpha2
*/
package de.staropensource.sosengine.graphics.glfw;

View file

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

View file

@ -0,0 +1 @@
../../../../../src/main/javadoc/theme.css

View file

@ -83,6 +83,7 @@ dependencies {
// -> Project <- // -> Project <-
implementation(project(":base")) implementation(project(":base"))
implementation(project(":graphics")) implementation(project(":graphics"))
implementation(project(":graphics:glfw"))
} }
// Fix delombok task // Fix delombok task

View file

@ -24,23 +24,20 @@ import de.staropensource.sosengine.base.annotations.EventListener;
import de.staropensource.sosengine.base.classes.helpers.EventHelper; import de.staropensource.sosengine.base.classes.helpers.EventHelper;
import de.staropensource.sosengine.base.data.info.EngineInformation; import de.staropensource.sosengine.base.data.info.EngineInformation;
import de.staropensource.sosengine.base.data.versioning.StarOpenSourceVersioningSystem; 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.logging.LoggerInstance;
import de.staropensource.sosengine.base.types.CodePart; import de.staropensource.sosengine.base.types.CodePart;
import de.staropensource.sosengine.base.types.DependencyVector; import de.staropensource.sosengine.base.types.DependencyVector;
import de.staropensource.sosengine.base.types.EventPriority; import de.staropensource.sosengine.base.types.EventPriority;
import de.staropensource.sosengine.base.types.logging.LogIssuer; 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.GraphicsSubsystem;
import de.staropensource.sosengine.graphics.classes.ApiInternalClass; import de.staropensource.sosengine.graphics.classes.ApiInternalClass;
import de.staropensource.sosengine.graphics.classes.ApiMainClass; import de.staropensource.sosengine.graphics.classes.ApiMainClass;
import de.staropensource.sosengine.graphics.classes.ApiManagementClass; import de.staropensource.sosengine.graphics.classes.ApiManagementClass;
import de.staropensource.sosengine.graphics.events.GraphicsApiErrorEvent; import de.staropensource.sosengine.graphics.events.GraphicsApiErrorEvent;
import de.staropensource.sosengine.graphics.opengl.events.GraphicsErrorEvent; import de.staropensource.sosengine.graphics.glfw.GlfwSubsystem;
import de.staropensource.sosengine.graphics.opengl.exceptions.GlfwInitializationException; import de.staropensource.sosengine.graphics.glfw.events.GraphicsErrorEvent;
import lombok.Getter; import lombok.Getter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.MemoryUtil;
import java.util.Locale; import java.util.Locale;
@ -135,44 +132,17 @@ public final class OpenGlSubsystem implements ApiMainClass {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public void initializeApi() { public void initializeApi() {
// Set error callback GlfwSubsystem.getInstance().initializeGlfw();
try (GLFWErrorCallback errorCallback = GLFWErrorCallback.create(new GraphicsErrorEvent())) {
errorCallback.set();
}
// Initialize GLFW
if (!glfwInit())
throw new GlfwInitializationException();
// Initialize management class // Initialize management class
internalApi = new OpenGlInternalApi(); internalApi = new OpenGlInternalApi();
management = new OpenGlManagement(); 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} */ /** {@inheritDoc} */
@Override @Override
public void shutdownApi() { public void shutdownApi() {
logger.verb("Shutting down"); GlfwSubsystem.getInstance().terminateGlfw();
@SuppressWarnings("resource")
long shutdownTime = Miscellaneous.measureExecutionTime(() -> {
glfwTerminate();
//noinspection DataFlowIssue
glfwSetErrorCallback(null).free();
});
logger.info("Shut down in " + shutdownTime + "ms");
} }
/** {@inheritDoc} */ /** {@inheritDoc} */

View file

@ -21,17 +21,12 @@ package de.staropensource.sosengine.graphics.opengl.classes;
import de.staropensource.sosengine.base.exceptions.UnexpectedThrowableException; import de.staropensource.sosengine.base.exceptions.UnexpectedThrowableException;
import de.staropensource.sosengine.base.types.vectors.Vec2i; import de.staropensource.sosengine.base.types.vectors.Vec2i;
import de.staropensource.sosengine.base.utility.Miscellaneous; import de.staropensource.sosengine.graphics.glfw.exceptions.NotOnMainThreadException;
import de.staropensource.sosengine.graphics.events.GraphicsApiErrorEvent; import de.staropensource.sosengine.graphics.glfw.exceptions.WindowCreationFailureException;
import de.staropensource.sosengine.graphics.opengl.exceptions.NotOnMainThreadException;
import de.staropensource.sosengine.graphics.opengl.exceptions.WindowCreationFailureException;
import de.staropensource.sosengine.graphics.types.VsyncMode; import de.staropensource.sosengine.graphics.types.VsyncMode;
import de.staropensource.sosengine.graphics.types.WindowMode; import de.staropensource.sosengine.graphics.types.WindowMode;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GL;
import org.lwjgl.system.MemoryUtil;
import static org.lwjgl.glfw.GLFW.*;
/** /**
* A window on your screen. * A window on your screen.
@ -39,7 +34,7 @@ import static org.lwjgl.glfw.GLFW.*;
* @since v1-alpha0 * @since v1-alpha0
*/ */
@SuppressWarnings({ "unused" }) @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. * Creates a new window.
* *
@ -63,59 +58,14 @@ public class Window extends de.staropensource.sosengine.graphics.classes.Window
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public void initializeWindow() throws WindowCreationFailureException, NotOnMainThreadException { public void initializeGlfwWindow() throws WindowCreationFailureException, NotOnMainThreadException {
// Ensure running on the main thread ownContext(getIdentifierAsLong()); // Own context
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
GL.createCapabilities(); // Create OpenGL capabilities GL.createCapabilities(); // Create OpenGL capabilities
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public void updateState() throws NotOnMainThreadException { public void updateGlfwState() 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();
}
/** {@inheritDoc} */ /** {@inheritDoc} */
@NotNull @NotNull
@ -130,30 +80,4 @@ public class Window extends de.staropensource.sosengine.graphics.classes.Window
public Vec2i getPositionWithDecorations() { public Vec2i getPositionWithDecorations() {
return getPosition(); 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);
}
} }

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
/**
* Contains the OpenGL subsystem.
*
* @since v1-alpha0
*/
package de.staropensource.sosengine.graphics.opengl;

View file

@ -14,16 +14,13 @@ module sosengine.graphics.opengl {
requires org.lwjgl; requires org.lwjgl;
requires org.lwjgl.glfw; requires org.lwjgl.glfw;
requires org.lwjgl.opengl; requires org.lwjgl.opengl;
requires sosengine.graphics.glfw.main;
// API access // API access
exports de.staropensource.sosengine.graphics.opengl; exports de.staropensource.sosengine.graphics.opengl;
exports de.staropensource.sosengine.graphics.opengl.classes; exports de.staropensource.sosengine.graphics.opengl.classes;
exports de.staropensource.sosengine.graphics.opengl.exceptions;
exports de.staropensource.sosengine.graphics.opengl.events;
// Reflection access // Reflection access
opens de.staropensource.sosengine.graphics.opengl; opens de.staropensource.sosengine.graphics.opengl;
opens de.staropensource.sosengine.graphics.opengl.classes; opens de.staropensource.sosengine.graphics.opengl.classes;
opens de.staropensource.sosengine.graphics.opengl.exceptions;
opens de.staropensource.sosengine.graphics.opengl.events;
} }

View file

@ -80,6 +80,7 @@ dependencies {
// -> Project <- // -> Project <-
implementation(project(":base")) implementation(project(":base"))
implementation(project(":graphics")) implementation(project(":graphics"))
implementation(project(":graphics:glfw"))
} }
// Fix delombok task // Fix delombok task

View file

@ -22,6 +22,7 @@ rootProject.name = "sosengine"
include "base" include "base"
include "slf4j-compat" include "slf4j-compat"
include "graphics" include "graphics"
include "graphics:glfw"
include "graphics:opengl" include "graphics:opengl"
include "graphics:vulkan" include "graphics:vulkan"
include "testapp" include "testapp"