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
index ea633f7d..66a0266e 100644
--- 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
@@ -130,7 +130,6 @@ public class GlfwSubsystem implements SubsystemMainClass {
glfwSetErrorCallback(null).free();
}
-
/**
* Called when the engine shuts down.
*
diff --git a/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/classes/GlfwWindow.java b/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/classes/GlfwWindow.java
new file mode 100644
index 00000000..1e8672dc
--- /dev/null
+++ b/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/classes/GlfwWindow.java
@@ -0,0 +1,359 @@
+/*
+ * 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.Tristate;
+import de.staropensource.sosengine.base.types.vectors.Vec2i;
+import de.staropensource.sosengine.base.utility.Miscellaneous;
+import de.staropensource.sosengine.graphics.GraphicsSubsystemConfiguration;
+import de.staropensource.sosengine.graphics.classes.Window;
+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 lombok.Getter;
+import org.jetbrains.annotations.NotNull;
+import org.lwjgl.system.MemoryUtil;
+
+import static org.lwjgl.glfw.GLFW.*;
+
+/**
+ * A window on your screen.
+ *
+ * @since v1-alpha0
+ */
+@Getter
+@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
+public abstract class GlfwWindow extends Window {
+ /**
+ * Contains the {@link #identifier} as a long.
+ *
+ * @since v1-alpha2
+ *
+ * -- GETTER --
+ * Returns the window identifier as a long.
+ *
+ * @return window identifier as a long
+ * @since v1-alpha2
+ */
+ private long identifierLong;
+
+ /**
+ * Creates a new window.
+ *
+ * @param name name
+ * @param title title
+ * @param size size
+ * @param minimumSize minimum size
+ * @param maximumSize maximum 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()} and {@link #render()} methods of the implementing Graphics API
+ * @since v1-alpha2
+ */
+ public GlfwWindow(@NotNull String name, @NotNull String title, @NotNull Vec2i size, @NotNull Vec2i minimumSize, @NotNull Vec2i maximumSize, @NotNull Vec2i position, @NotNull WindowMode windowMode, @NotNull VsyncMode vsyncMode, boolean resizable, boolean borderless, boolean focusable, boolean onTop, boolean transparent, boolean rendering) throws UnexpectedThrowableException {
+ super(name, title, size, minimumSize, maximumSize, 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();
+
+ createGlfwWindow(); // Create the GLFW window
+ initializeGlfwWindow(); // Call GLFW window initialization method
+ }
+
+ /**
+ * Initializes the GLFW window.
+ *
+ * @throws Throwable throwable
+ * @since v1-alpha2
+ */
+ protected abstract void initializeGlfwWindow() throws Throwable;
+
+ /**
+ * Updates the window state.
+ *
+ * @since v1-alpha2
+ */
+ @Override
+ public void updateState() {
+ // Ensure running on the main thread
+ if (!Miscellaneous.onMainThread())
+ throw new NotOnMainThreadException();
+
+ // Own context
+ ownContext();
+
+ // Set swap interval based on isDisallowTearing setting
+ glfwSwapInterval(Miscellaneous.getIntegerizedBoolean(GraphicsSubsystemConfiguration.getInstance().isDisallowTearing()));
+
+ // Integer arrays, used for 'size' and 'position'
+ int[] width = new int[0];
+ int[] height = new int[0];
+
+ // Set window size
+ glfwGetWindowSize(identifierLong, width, height);
+ super.setSize(new Vec2i(width[0], height[0]));
+
+ // Set window position
+ glfwGetWindowPos(identifierLong, width, height);
+ super.setPosition(new Vec2i(width[0], height[0]));
+
+ // Set window mode
+ if (Miscellaneous.getBooleanizedInteger(glfwGetWindowAttrib(identifierLong, GLFW_ICONIFIED)))
+ super.setWindowMode(WindowMode.MINIMIZED);
+ else if (Miscellaneous.getBooleanizedInteger(glfwGetWindowAttrib(identifierLong, GLFW_MAXIMIZED)))
+ super.setWindowMode(WindowMode.MAXIMIZED);
+ else if (Miscellaneous.getBooleanizedInteger(glfwGetWindowAttrib(identifierLong, GLFW_VISIBLE)))
+ super.setWindowMode(WindowMode.WINDOWED);
+ else if (Miscellaneous.getBooleanizedInteger(glfwGetWindowAttrib(identifierLong, GLFW_VISIBLE)))
+ super.setWindowMode(WindowMode.HIDDEN);
+
+ // Set booleans
+ super.setResizable(Miscellaneous.getBooleanizedInteger(glfwGetWindowAttrib(identifierLong, GLFW_RESIZABLE)));
+ super.setOnTop(Miscellaneous.getBooleanizedInteger(glfwGetWindowAttrib(identifierLong, GLFW_FLOATING)));
+ super.setTransparent(Miscellaneous.getBooleanizedInteger(glfwGetWindowAttrib(identifierLong, GLFW_TRANSPARENT_FRAMEBUFFER)));
+
+ // Make Graphics API update it's state
+ updateGlfwState();
+ }
+
+ /**
+ * Updates the state of the GLFW window.
+ *
+ * @throws Throwable throwable
+ * @since v1-alpha2
+ */
+ protected abstract void updateGlfwState();
+
+ /** {@inheritDoc} */
+ @Override
+ public void render() throws NotOnMainThreadException {
+ // Ensure running on the main thread
+ if (!Miscellaneous.onMainThread())
+ throw new NotOnMainThreadException();
+
+ glfwSwapBuffers(identifierLong);
+ glfwPollEvents();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean isClosureRequested() {
+ return glfwWindowShouldClose(identifierLong);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean isFocused() {
+ return Tristate.toBoolean(Miscellaneous.getTristatedInteger(glfwGetWindowAttrib(identifierLong, GLFW_FOCUSED)));
+ }
+
+ /** {@inheritDoc} */
+ public void focus() {
+ glfwFocusWindow(identifierLong);
+ }
+
+ /** {@inheritDoc} */
+ public void requestAttention() {
+ glfwRequestWindowAttention(identifierLong);
+ }
+
+ /**
+ * Updates the OpenGL context.
+ *
+ * @since v1-alpha2
+ */
+ public void ownContext() {
+ glfwMakeContextCurrent(identifierLong);
+ }
+
+ /**
+ * (Re-)Creates the GLFW window.
+ *
+ * @since v1-alpha2
+ */
+ public void createGlfwWindow() throws WindowCreationFailureException {
+ // Get current focus
+ boolean focused = true;
+
+ // Destroy existing window
+ if (getIdentifier() != null) {
+ focused = isFocused();
+ glfwDestroyWindow(identifierLong);
+ }
+
+ // Set window hints
+ setWindowHints();
+ glfwWindowHint(GLFW_POSITION_X, getPosition().getX());
+ glfwWindowHint(GLFW_POSITION_Y, getPosition().getY());
+ glfwWindowHint(GLFW_CENTER_CURSOR, 0);
+ glfwWindowHint(GLFW_FOCUSED, Miscellaneous.getIntegerizedBoolean(focused));
+ glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, Miscellaneous.getIntegerizedBoolean(isTransparent()));
+ glfwWindowHint(GLFW_COCOA_GRAPHICS_SWITCHING, Miscellaneous.getIntegerizedBoolean(GraphicsSubsystemConfiguration.getInstance().isDisallowIntegratedGraphics()));
+ glfwWindowHintString(GLFW_WAYLAND_APP_ID, getName());
+ glfwWindowHintString(GLFW_X11_CLASS_NAME, getName());
+ glfwWindowHintString(GLFW_X11_INSTANCE_NAME, getName());
+
+ // 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
+ identifierLong = identifier;
+ setIdentifier(String.valueOf(identifier));
+
+ // Update the window state
+ setTitle(getTitle());
+ setSize(getSize());
+ setMinimumSize(getMinimumSize());
+ setMaximumSize(getMaximumSize());
+ setPosition(getPosition());
+ setWindowMode(getWindowMode());
+ }
+
+ /**
+ * Sets window hints.
+ *
+ * @since v1-alpha2
+ */
+ public abstract void setWindowHints();
+
+ /** {@inheritDoc} */
+ @Override
+ public void setName(@NotNull String name) {
+ super.setName(name);
+ createGlfwWindow();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setTitle(@NotNull String title) {
+ super.setTitle(title);
+ glfwSetWindowTitle(identifierLong, title);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setSize(@NotNull Vec2i size) {
+ super.setSize(size);
+ glfwSetWindowSize(identifierLong, size.getX(), size.getY());
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setMinimumSize(@NotNull Vec2i minimumSize) {
+ super.setMinimumSize(minimumSize);
+ glfwSetWindowSizeLimits(identifierLong, minimumSize.getX(), minimumSize.getY(), getMaximumSize().getX(), getMaximumSize().getY());
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setMaximumSize(@NotNull Vec2i maximumSize) {
+ super.setMaximumSize(maximumSize);
+ glfwSetWindowSizeLimits(identifierLong, getMinimumSize().getX(), getMinimumSize().getY(), maximumSize.getX(), maximumSize.getY());
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setPosition(@NotNull Vec2i position) {
+ super.setPosition(position);
+ glfwSetWindowSize(identifierLong, position.getX(), position.getY());
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setWindowMode(@NotNull WindowMode windowMode) {
+ super.setWindowMode(windowMode);
+ switch (windowMode) {
+ case HIDDEN -> glfwHideWindow(identifierLong);
+ case WINDOWED -> {
+ glfwShowWindow(identifierLong);
+ glfwRestoreWindow(identifierLong);
+ }
+ case MINIMIZED -> {
+ glfwShowWindow(identifierLong);
+ glfwIconifyWindow(identifierLong);
+ }
+ case MAXIMIZED -> {
+ glfwShowWindow(identifierLong);
+ glfwRestoreWindow(identifierLong);
+ glfwMaximizeWindow(identifierLong);
+ }
+ case BORDERLESS_FULLSCREEN -> {
+ glfwShowWindow(identifierLong);
+ glfwRestoreWindow(identifierLong);
+ // TODO
+ }
+ case EXCLUSIVE_FULLSCREEN -> {
+ glfwShowWindow(identifierLong);
+ glfwRestoreWindow(identifierLong);
+ // TODO
+ }
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setResizable(boolean resizable) {
+ super.setResizable(resizable);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setBorderless(boolean borderless) {
+ super.setBorderless(borderless);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setFocusable(boolean focusable) {
+ super.setFocusable(focusable);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setOnTop(boolean onTop) {
+ super.setOnTop(onTop);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setTransparent(boolean transparent) {
+ super.setTransparent(transparent);
+ createGlfwWindow();
+ }
+}
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
deleted file mode 100644
index cf52b94e..00000000
--- a/graphics/glfw/src/main/java/de/staropensource/sosengine/graphics/glfw/classes/Window.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * 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/OpenGlInternalApi.java b/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/OpenGlInternalApi.java
index 233d1285..a0dc4b6a 100644
--- a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/OpenGlInternalApi.java
+++ b/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/OpenGlInternalApi.java
@@ -21,6 +21,7 @@ package de.staropensource.sosengine.graphics.opengl;
import de.staropensource.sosengine.graphics.classes.ApiInternalClass;
import de.staropensource.sosengine.graphics.classes.Window;
+import de.staropensource.sosengine.graphics.opengl.classes.OpenGlWindow;
import org.jetbrains.annotations.NotNull;
public class OpenGlInternalApi implements ApiInternalClass {
@@ -28,6 +29,6 @@ public class OpenGlInternalApi implements ApiInternalClass {
@Override
@NotNull
public Class extends Window> getWindowClass() {
- return de.staropensource.sosengine.graphics.opengl.classes.Window.class;
+ return OpenGlWindow.class;
}
}
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/OpenGlWindow.java
similarity index 66%
rename from graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/classes/Window.java
rename to graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/classes/OpenGlWindow.java
index 27a7de5d..26d926c6 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/OpenGlWindow.java
@@ -21,6 +21,7 @@ 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.graphics.glfw.classes.GlfwWindow;
import de.staropensource.sosengine.graphics.glfw.exceptions.NotOnMainThreadException;
import de.staropensource.sosengine.graphics.glfw.exceptions.WindowCreationFailureException;
import de.staropensource.sosengine.graphics.types.VsyncMode;
@@ -28,18 +29,23 @@ import de.staropensource.sosengine.graphics.types.WindowMode;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.opengl.GL;
+import static org.lwjgl.glfw.GLFW.*;
+
/**
* A window on your screen.
*
* @since v1-alpha0
*/
@SuppressWarnings({ "unused" })
-public class Window extends de.staropensource.sosengine.graphics.glfw.classes.Window {
+public class OpenGlWindow extends GlfwWindow {
/**
* Creates a new window.
*
+ * @param name name
* @param title title
* @param size size
+ * @param minimumSize minimum size
+ * @param maximumSize maximum size
* @param position position
* @param windowMode window mode
* @param vsyncMode V-Sync mode
@@ -49,17 +55,17 @@ public class Window extends de.staropensource.sosengine.graphics.glfw.classes.Wi
* @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
+ * @throws UnexpectedThrowableException stuff thrown by the {@link #initializeWindow()} and {@link #render()} methods of the implementing 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);
+ public OpenGlWindow(@NotNull String name, @NotNull String title, @NotNull Vec2i size, @NotNull Vec2i minimumSize, @NotNull Vec2i maximumSize, @NotNull Vec2i position, @NotNull WindowMode windowMode, @NotNull VsyncMode vsyncMode, boolean resizable, boolean borderless, boolean focusable, boolean onTop, boolean transparent, boolean rendering) throws UnexpectedThrowableException {
+ super(name, title, size, minimumSize, maximumSize, position, windowMode, vsyncMode, resizable, borderless, focusable, onTop, transparent, rendering);
}
/** {@inheritDoc} */
@Override
public void initializeGlfwWindow() throws WindowCreationFailureException, NotOnMainThreadException {
- ownContext(getIdentifierAsLong()); // Own context
+ ownContext(); // Own the context
GL.createCapabilities(); // Create OpenGL capabilities
}
@@ -67,6 +73,16 @@ public class Window extends de.staropensource.sosengine.graphics.glfw.classes.Wi
@Override
public void updateGlfwState() throws NotOnMainThreadException {}
+ /** {@inheritDoc} */
+ @Override
+ public void setWindowHints() {
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
+ glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+ glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
+ glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API);
+ }
+
/** {@inheritDoc} */
@NotNull
@Override
diff --git a/graphics/src/main/java/de/staropensource/sosengine/graphics/GraphicsSubsystemConfiguration.java b/graphics/src/main/java/de/staropensource/sosengine/graphics/GraphicsSubsystemConfiguration.java
index 4b864a39..f1dc30b6 100644
--- a/graphics/src/main/java/de/staropensource/sosengine/graphics/GraphicsSubsystemConfiguration.java
+++ b/graphics/src/main/java/de/staropensource/sosengine/graphics/GraphicsSubsystemConfiguration.java
@@ -98,6 +98,36 @@ public final class GraphicsSubsystemConfiguration implements SubsystemConfigurat
*/
private boolean errorGraphicsError;
+ /**
+ * If enabled, will make the Graphics API try to prevent tearing from happening.
+ *
+ * @since v1-alph2
+ *
+ * -- GETTER --
+ * Gets the value for {@link #disallowTearing}.
+ *
+ * @return variable value
+ * @see GraphicsSubsystemConfiguration#disallowTearing
+ * @since v1-alpha2
+ */
+ private boolean disallowTearing;
+
+ /**
+ * If enabled, will make the Graphics API try to prevent using the integrated graphics card in your computer.
+ *
+ * Will have no effect if no integrated or discrete graphics card is installed in the system.
+ *
+ * @since v1-alph2
+ *
+ * -- GETTER --
+ * Gets the value for {@link #disallowIntegratedGraphics}.
+ *
+ * @return variable value
+ * @see GraphicsSubsystemConfiguration#disallowIntegratedGraphics
+ * @since v1-alpha2
+ */
+ private boolean disallowIntegratedGraphics;
+
/**
* Constructs this class.
*
@@ -132,6 +162,8 @@ public final class GraphicsSubsystemConfiguration implements SubsystemConfigurat
case "debug" -> debug = parser.getBoolean(group + property);
case "errorGraphicsError" -> errorGraphicsError = parser.getBoolean(group + property);
+
+ case "disallowTearing" -> disallowTearing = parser.getBoolean(group + property);
}
} catch (NullPointerException ignored) {}
}
@@ -150,6 +182,8 @@ public final class GraphicsSubsystemConfiguration implements SubsystemConfigurat
debug = false;
errorGraphicsError = true;
+
+ disallowTearing = false;
}
/** {@inheritDoc} */
@@ -162,6 +196,9 @@ public final class GraphicsSubsystemConfiguration implements SubsystemConfigurat
case "errorGraphicsError" -> {
return errorGraphicsError;
}
+ case "disallowTearing" -> {
+ return disallowTearing;
+ }
default -> {
return null;
}
diff --git a/graphics/src/main/java/de/staropensource/sosengine/graphics/classes/Window.java b/graphics/src/main/java/de/staropensource/sosengine/graphics/classes/Window.java
index 0903a68f..5db986d6 100644
--- a/graphics/src/main/java/de/staropensource/sosengine/graphics/classes/Window.java
+++ b/graphics/src/main/java/de/staropensource/sosengine/graphics/classes/Window.java
@@ -48,6 +48,7 @@ import java.util.Set;
*
* @since v1-alpha0
*/
+// TODO monitors
@Getter
@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
public abstract class Window {
@@ -97,6 +98,69 @@ public abstract class Window {
@Setter(AccessLevel.PROTECTED)
private String identifier = null;
+ /**
+ * Determines the name of this window.
+ *
+ * Window names should:
+ *
+ * - be lowercase,
+ * - be simple,
+ * - be not very long,
+ * - only contain letters, numbers, hyphens and dots, and
+ * - represent the name of your application and window purpose (if your application supports multiple windows)
+ *
+ *
+ * On some platforms this may be used for window identification.
+ * A prime example of this is X11 and Wayland, where window
+ * managers and compositors can use this information to identify
+ * windows and customize them.
+ *
+ * @since v1-alpha1
+ *
+ * -- GETTER --
+ * Returns the name of this window.
+ *
+ * Window names should:
+ *
+ * - be lowercase,
+ * - be simple,
+ * - be not very long,
+ * - only contain letters, numbers, hyphens and dots, and
+ * - represent the name of your application and window purpose (if your application supports multiple windows)
+ *
+ *
+ * On some platforms this may be used for window identification.
+ * A prime example of this is X11 and Wayland, where window
+ * managers and compositors can use this information to identify
+ * windows and customize them.
+ *
+ * @return window title
+ * @since v1-alpha2
+ *
+ * -- SETTER --
+ * Sets the name of this window.
+ *
+ * Window names should:
+ *
+ * - be lowercase,
+ * - be simple,
+ * - be not very long,
+ * - only contain letters, numbers, hyphens and dots, and
+ * - represent the name of your application and window purpose (if your application supports multiple windows)
+ *
+ *
+ * On some platforms this may be used for window identification.
+ * A prime example of this is X11 and Wayland, where window
+ * managers and compositors can use this information to identify
+ * windows and customize them.
+ *
+ * @param name new window name
+ * @since v1-alpha2
+ */
+ @NotNull
+ @Setter
+ private String name;
+
/**
* Determines the title of this window.
*
@@ -139,6 +203,48 @@ public abstract class Window {
@Setter
private Vec2i size;
+ /**
+ * Determines the minimum size of this window.
+ *
+ * @since v1-alpha1
+ *
+ * -- GETTER --
+ * Returns the minimum window size.
+ *
+ * @return minimum window size
+ * @since v1-alpha2
+ *
+ * -- SETTER --
+ * Sets the minimum window size.
+ *
+ * @param size new minimum window size
+ * @since v1-alpha2
+ */
+ @NotNull
+ @Setter
+ private Vec2i minimumSize;
+
+ /**
+ * Determines the maximum size of this window.
+ *
+ * @since v1-alpha1
+ *
+ * -- GETTER --
+ * Returns the maximum window size.
+ *
+ * @return maximum window size
+ * @since v1-alpha2
+ *
+ * -- SETTER --
+ * Sets the maximum window size.
+ *
+ * @param size new maximum window size
+ * @since v1-alpha2
+ */
+ @NotNull
+ @Setter
+ private Vec2i maximumSize;
+
/**
* Determines the position of this window.
*
@@ -202,6 +308,26 @@ public abstract class Window {
@Setter
private VsyncMode vsyncMode;
+ /**
+ * Determines how fast the window may update it's contents.
+ *
+ * @since v1-alpha1
+ *
+ * -- GETTER --
+ * Returns how fast the window may update it's contents.
+ *
+ * @return new window frame limit
+ * @since v1-alpha2
+ *
+ * -- SETTER --
+ * Sets how fast the window may update it's contents.
+ *
+ * @param framerate new window frame limit
+ * @since v1-alpha2
+ */
+ @Setter
+ private int framerate;
+
/**
* Determines if this window can be resized by the user.
*
@@ -343,8 +469,11 @@ public abstract class Window {
/**
* Creates a new window.
*
+ * @param name name
* @param title title
* @param size size
+ * @param minimumSize minimum size
+ * @param maximumSize maximum size
* @param position position
* @param windowMode window mode
* @param vsyncMode V-Sync mode
@@ -354,15 +483,18 @@ public abstract class Window {
* @param onTop on top flag
* @param transparent transparency flag
* @param rendering rendering flag
- * @throws UnexpectedThrowableException stuff thrown by the {@link #initializeWindow()}, {@link #updateState()} and {@link #render()} methods of the implementing Graphics API
+ * @throws UnexpectedThrowableException stuff thrown by the {@link #initializeWindow()} and {@link #render()} methods of the implementing 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 {
+ public Window(@NotNull String name, @NotNull String title, @NotNull Vec2i size, @NotNull Vec2i minimumSize, @NotNull Vec2i maximumSize, @NotNull Vec2i position, @NotNull WindowMode windowMode, @NotNull VsyncMode vsyncMode, boolean resizable, boolean borderless, boolean focusable, boolean onTop, boolean transparent, boolean rendering) throws UnexpectedThrowableException {
logger.diag("Creating new window with properties: title=\"" + title + "\" size=" + size + " position=" + position + " windowMode=" + windowMode + " vsyncMode=" + vsyncMode + " resizable=" + resizable + " borderless=" + borderless + " focusable=" + focusable + " onTop=" + onTop + " transparent=" + transparent + " rendering=" + rendering);
// Initialize variables
+ this.name = name;
this.title = title;
this.size = size;
+ this.minimumSize = minimumSize;
+ this.maximumSize = maximumSize;
this.position = position;
this.windowMode = windowMode;
this.vsyncMode = vsyncMode;
@@ -442,6 +574,34 @@ public abstract class Window {
*/
public abstract boolean isClosureRequested();
+ /**
+ * Returns if the window is currently focused.
+ *
+ * @return {@code true} if focused, {@code false} otherwise
+ * @since v1-alpha2
+ */
+ public abstract boolean isFocused();
+
+ /**
+ * Will cause the window to be focused immediately, even
+ * without any user input.
+ *
+ * @since v1-alpha2
+ */
+ public abstract void focus();
+
+ /**
+ * Will request user attention.
+ *
+ * What the window manager or compositor does
+ * with this request is uncertain. It may be
+ * ignored, or will cause the icon in some bar
+ * or dock flash or blink.
+ *
+ * @since v1-alpha2
+ */
+ public abstract void requestAttention();
+
/**
* Provides an API for building {@link Window} classes more easily.
*
@@ -450,6 +610,22 @@ public abstract class Window {
@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
@Getter
public static class Builder {
+ /**
+ * Contains the window name.
+ *
+ * @see Window#name
+ * @since v1-alpha2
+ *
+ * -- GETTER --
+ * Returns the window name.
+ *
+ * @return window name
+ * @see Window#name
+ * @since v1-alpha2
+ */
+ @Nullable
+ private String name = null;
+
/**
* Contains the window title.
*
@@ -482,6 +658,38 @@ public abstract class Window {
@Nullable
private Vec2i size = null;
+ /**
+ * Contains the minimum window size.
+ *
+ * @see Window#minimumSize
+ * @since v1-alpha2
+ *
+ * -- GETTER --
+ * Returns the minimum window size.
+ *
+ * @return minimum window size
+ * @see Window#minimumSize
+ * @since v1-alpha2
+ */
+ @Nullable
+ private Vec2i minimumSize = null;
+
+ /**
+ * Contains the maximum window size.
+ *
+ * @see Window#maximumSize
+ * @since v1-alpha2
+ *
+ * -- GETTER --
+ * Returns the maximum window size.
+ *
+ * @return maximum window size
+ * @see Window#maximumSize
+ * @since v1-alpha2
+ */
+ @Nullable
+ private Vec2i maximumSize = null;
+
/**
* Contains the window position.
*
@@ -650,14 +858,20 @@ public abstract class Window {
boolean renderingBoolean = true;
// Check for required fields
- if (title == null)
+ if (name == null)
throw new IllegalStateException("The window name is unset");
+ if (title == null)
+ throw new IllegalStateException("The window title is unset");
if (size == null)
throw new IllegalStateException("The window size is unset");
if (position == null)
throw new IllegalStateException("The window position is unset");
- // Set default
+ // Set defaults
+ if (minimumSize == null)
+ minimumSize = new Vec2i(0, 0);
+ if (maximumSize == null)
+ maximumSize = new Vec2i(0, 0);
if (windowMode == null)
windowMode = WindowMode.WINDOWED;
if (vsyncMode == null)
@@ -680,13 +894,26 @@ public abstract class Window {
// Create new Window instance
try {
return GraphicsSubsystem.getInstance().getApi().getInternalApi().getWindowClass()
- .getDeclaredConstructor(String.class, Vec2i.class, Vec2i.class, WindowMode.class, VsyncMode.class, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE)
- .newInstance(title, size, position, windowMode, vsyncMode, resizableBoolean, borderlessBoolean, focusableBoolean, onTopBoolean, transparentBoolean, renderingBoolean);
+ .getDeclaredConstructor(String.class, String.class, Vec2i.class, Vec2i.class, Vec2i.class, Vec2i.class, WindowMode.class, VsyncMode.class, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE)
+ .newInstance(name, title, size, minimumSize, maximumSize, position, windowMode, vsyncMode, resizableBoolean, borderlessBoolean, focusableBoolean, onTopBoolean, transparentBoolean, renderingBoolean);
} catch (Throwable throwable) {
throw new UnexpectedThrowableException(throwable, "Window.Builder was unable to create new Window instance");
}
}
+ /**
+ * Sets the window name.
+ *
+ * @param name new window name
+ * @return builder instance
+ * @since v1-alpha2
+ */
+ @NotNull
+ public synchronized Builder setName(@Nullable String name) {
+ this.name = name;
+ return this;
+ }
+
/**
* Sets the window title.
*
@@ -713,6 +940,32 @@ public abstract class Window {
return this;
}
+ /**
+ * Sets the minimum window size.
+ *
+ * @param minimumSize new minimum window size
+ * @return builder instance
+ * @since v1-alpha2
+ */
+ @NotNull
+ public synchronized Builder setMinimumSize(@Nullable Vec2i minimumSize) {
+ this.minimumSize = minimumSize;
+ return this;
+ }
+
+ /**
+ * Sets the maximum window size.
+ *
+ * @param maximumSize new maximum window size
+ * @return builder instance
+ * @since v1-alpha2
+ */
+ @NotNull
+ public synchronized Builder setMaximumSize(@Nullable Vec2i maximumSize) {
+ this.maximumSize = maximumSize;
+ return this;
+ }
+
/**
* Sets the window position.
*
diff --git a/graphics/src/main/java/de/staropensource/sosengine/graphics/types/WindowMode.java b/graphics/src/main/java/de/staropensource/sosengine/graphics/types/WindowMode.java
index 08c6af1c..267a4363 100644
--- a/graphics/src/main/java/de/staropensource/sosengine/graphics/types/WindowMode.java
+++ b/graphics/src/main/java/de/staropensource/sosengine/graphics/types/WindowMode.java
@@ -27,22 +27,40 @@ package de.staropensource.sosengine.graphics.types;
@SuppressWarnings({ "unused" })
public enum WindowMode {
/**
- * Makes the window invisible and unable to be interacted with.
+ * Marks the window as {@code hidden}, making the window invisible and unable to be interacted with.
*
* @since v1-alpha2
*/
HIDDEN,
/**
- * Makes the window able to be dragged around.
+ * Marks the window as {@code windowed}, which
+ * will allow the user to drag around the window freely.
*
* @since v1-alpha1
*/
WINDOWED,
/**
- * Same as {@code WINDOWED} mode, but the window will have
- * the same size as the monitor it is currently on.
+ * Same as {@link #HIDDEN} mode, but the window can
+ * be summoned back into {@link #WINDOWED} mode by the user.
+ *
+ * @since v1-alpha2
+ */
+ MINIMIZED,
+
+ /**
+ * Same as {@link #WINDOWED}, but will make the window occupy
+ * most of the screen space, except for window manager/compositor
+ * windows/bars/docks.
+ *
+ * @since v1-alpha2
+ */
+ MAXIMIZED,
+
+ /**
+ * Makes the window will have the same
+ * size as the monitor it is currently on.
*
* @since v1-alpha1
*/
@@ -51,6 +69,10 @@ public enum WindowMode {
/**
* Makes the window occupy the entire monitor it is currently on
* without allowing other windows to occupy the same space.
+ *
+ * This will increase rendering throughput as the window manager
+ * or compositor does not need to care about other windows occupying
+ * the same monitor.
*
* @since v1-alpha1
*/
diff --git a/testapp/src/main/java/de/staropensource/sosengine/testapp/Main.java b/testapp/src/main/java/de/staropensource/sosengine/testapp/Main.java
index a01f09f6..11f79574 100644
--- a/testapp/src/main/java/de/staropensource/sosengine/testapp/Main.java
+++ b/testapp/src/main/java/de/staropensource/sosengine/testapp/Main.java
@@ -114,6 +114,7 @@ public class Main {
// Create window
try {
Window window = new Window.Builder()
+ .setName("sosengine-testapp")
.setTitle("test application window")
.setSize(new Vec2i(960, 540))
.setPosition(new Vec2i(10, 10))