Update Window classes
This commit is contained in:
parent
260464d727
commit
42d0feb574
9 changed files with 705 additions and 171 deletions
|
@ -130,7 +130,6 @@ public class GlfwSubsystem implements SubsystemMainClass {
|
|||
glfwSetErrorCallback(null).free();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called when the engine shuts down.
|
||||
*
|
||||
|
|
|
@ -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 <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.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();
|
||||
}
|
||||
}
|
|
@ -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 <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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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.
|
||||
* <p>
|
||||
* 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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
* <p>
|
||||
* Window names should:
|
||||
* <ul>
|
||||
* <li>be lowercase,</li>
|
||||
* <li>be simple,</li>
|
||||
* <li>be not very long,</li>
|
||||
* <li>only contain letters, numbers, hyphens and dots, and</li>
|
||||
* <li>represent the name of your application and window purpose (if your application supports multiple windows)</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* Window names should:
|
||||
* <ul>
|
||||
* <li>be lowercase,</li>
|
||||
* <li>be simple,</li>
|
||||
* <li>be not very long,</li>
|
||||
* <li>only contain letters, numbers, hyphens and dots, and</li>
|
||||
* <li>represent the name of your application and window purpose (if your application supports multiple windows)</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* Window names should:
|
||||
* <ul>
|
||||
* <li>be lowercase,</li>
|
||||
* <li>be simple,</li>
|
||||
* <li>be not very long,</li>
|
||||
* <li>only contain letters, numbers, hyphens and dots, and</li>
|
||||
* <li>represent the name of your application and window purpose (if your application supports multiple windows)</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
*
|
||||
|
|
|
@ -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.
|
||||
* <p>
|
||||
* 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
|
||||
*/
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in a new issue