Procházet zdrojové kódy

added window view managers for handling different settings for scale,
font scale and size of the window

Kajetan Johannes Hammerle před 4 roky
rodič
revize
4c4b136e8b

+ 2 - 1
src/me/hammerle/snuviengine/Main.java

@@ -1,10 +1,11 @@
 package me.hammerle.snuviengine;
 
+import me.hammerle.snuviengine.api.ResizingWindowView;
 import me.hammerle.snuviengine.api.Window;
 
 public class Main {
     public static void main(String[] args) {
-        Window window = new Window(50_000_000);
+        Window window = new Window(50_000_000, new ResizingWindowView(400, 300));
         if(window.initialize("wusi", 1024, 620)) {
             TestGame game = new TestGame();
             window.open(game);

+ 1 - 1
src/me/hammerle/snuviengine/TestGame.java

@@ -42,7 +42,7 @@ public class TestGame implements Game {
         renderer.setTextureEnabled(true);
         y = renderer.getFontRenderer().drawString(10, y, true, String.format("FPS: #00FF00%.1f", stats.getFramesPerSecond()));
         y = renderer.getFontRenderer().drawString(10, y, true, String.format("TPS: %.1f", stats.getTicksPerSecond()));
-        for(Gamepad.GamepadButton binding : gamepad.bindings) {
+        for(Gamepad.Button binding : gamepad.bindings) {
             y = renderer.getFontRenderer().drawString(10, y, true, String.format("%s: %b, %d, %b", binding.getName(), binding.isDown(), binding.getTime(), binding.isReleased()));
         }
         renderer.setColorEnabled(true);

+ 48 - 0
src/me/hammerle/snuviengine/api/FixedWindowView.java

@@ -0,0 +1,48 @@
+package me.hammerle.snuviengine.api;
+
+public class FixedWindowView implements WindowView {
+    private final int width;
+    private final int height;
+    private final int fontScale;
+
+    public FixedWindowView(int width, int height, int fontScale) {
+        this.width = width;
+        this.height = height;
+        this.fontScale = fontScale;
+    }
+
+    @Override
+    public int getScale(int width, int height) {
+        return Math.max(width / this.width, 1);
+    }
+
+    @Override
+    public int getFontScale(int width, int height) {
+        return fontScale;
+    }
+
+    @Override
+    public int getWidth(int newWidth, int newHeight) {
+        return Math.max(getMaxScale(newWidth, newHeight) * width, width);
+    }
+
+    @Override
+    public int getHeight(int newWidth, int newHeight) {
+        return Math.max(getMaxScale(newWidth, newHeight) * height, height);
+    }
+
+    private int getMaxScale(int newWidth, int newHeight) {
+        return Math.max(getNearestScale(newWidth, width), getNearestScale(newHeight, height));
+    }
+
+    private int getNearestScale(int value, int multiple) {
+        float scale = (float) value / multiple;
+        int roundedScale = (int) scale;
+        if(scale == roundedScale) {
+            return roundedScale;
+        }
+        float diff = scale - roundedScale;
+        roundedScale += diff < 0.5f ? 1 : 0;
+        return roundedScale;
+    }
+}

+ 18 - 18
src/me/hammerle/snuviengine/api/Gamepad.java

@@ -5,7 +5,7 @@ import java.nio.FloatBuffer;
 import static org.lwjgl.glfw.GLFW.*;
 
 public final class Gamepad {
-    public static final class GamepadButton {
+    public static final class Button {
         private final String name;
         private final int mapping;
 
@@ -13,7 +13,7 @@ public final class Gamepad {
         private int time = 0;
         private boolean isReleased = false;
 
-        protected GamepadButton(String name, int mapping) {
+        protected Button(String name, int mapping) {
             this.name = name;
             this.mapping = mapping;
         }
@@ -58,24 +58,24 @@ public final class Gamepad {
         }
     }
 
-    public final GamepadButton a = new GamepadButton("A", 1);
-    public final GamepadButton b = new GamepadButton("B", 2);
-    public final GamepadButton x = new GamepadButton("X", 0);
-    public final GamepadButton y = new GamepadButton("Y", 3);
-    public final GamepadButton l = new GamepadButton("L", 4);
-    public final GamepadButton r = new GamepadButton("R", 5);
-    public final GamepadButton start = new GamepadButton("Start", 9);
-    public final GamepadButton select = new GamepadButton("Select", 8);
-    public final GamepadButton left = new GamepadButton("Left", 0);
-    public final GamepadButton right = new GamepadButton("Right", 0);
-    public final GamepadButton up = new GamepadButton("Up", 1);
-    public final GamepadButton down = new GamepadButton("Down", 1);
-
-    private final GamepadButton[] buttons = new GamepadButton[]{
+    public final Button a = new Button("A", 1);
+    public final Button b = new Button("B", 2);
+    public final Button x = new Button("X", 0);
+    public final Button y = new Button("Y", 3);
+    public final Button l = new Button("L", 4);
+    public final Button r = new Button("R", 5);
+    public final Button start = new Button("Start", 9);
+    public final Button select = new Button("Select", 8);
+    public final Button left = new Button("Left", 0);
+    public final Button right = new Button("Right", 0);
+    public final Button up = new Button("Up", 1);
+    public final Button down = new Button("Down", 1);
+
+    private final Button[] buttons = new Button[]{
         a, b, x, y, l, r, start, select
     };
 
-    public final GamepadButton[] bindings = new GamepadButton[]{
+    public final Button[] bindings = new Button[]{
         a, b, x, y, l, r, start, select, left, right, up, down
     };
 
@@ -98,7 +98,7 @@ public final class Gamepad {
         if(buttonBuffer == null) {
             return;
         }
-        for(GamepadButton binding : buttons) {
+        for(Button binding : buttons) {
             binding.tick(buttonBuffer.get(binding.getMapping()) != 0);
         }
     }

+ 21 - 0
src/me/hammerle/snuviengine/api/LazyWindowView.java

@@ -0,0 +1,21 @@
+package me.hammerle.snuviengine.api;
+
+public class LazyWindowView implements WindowView {
+    private final int scale;
+    private final int fontScale;
+
+    public LazyWindowView(int scale, int fontScale) {
+        this.scale = scale;
+        this.fontScale = fontScale;
+    }
+
+    @Override
+    public int getScale(int width, int height) {
+        return scale;
+    }
+
+    @Override
+    public int getFontScale(int width, int height) {
+        return fontScale;
+    }
+}

+ 5 - 10
src/me/hammerle/snuviengine/api/Renderer.java

@@ -29,11 +29,11 @@ public final class Renderer {
     private final int unifMixColorLoc;
     private final float[] unifMixColor = new float[]{0.0f, 0.0f, 0.0f, 0.0f};
 
-    protected Renderer(int program, int width, int height) {
+    protected Renderer(int program, int width, int height, WindowView windowView) {
         glUseProgram(program);
 
         unifViewMatrix = glGetUniformLocation(program, "viewMatrix");
-        setSize(width, height);
+        setSize(width, height, windowView);
 
         unifModelMatrix = glGetUniformLocation(program, "modelMatrix");
         updateMatrix();
@@ -57,8 +57,6 @@ public final class Renderer {
 
         unifMixColorLoc = glGetUniformLocation(program, "mixColor");
         setMixColor(0.0f, 0.0f, 0.0f, 0.0f);
-
-        setSize(width, height);
     }
 
     public FontRenderer getFontRenderer() {
@@ -90,12 +88,9 @@ public final class Renderer {
         buffer.put(d);
     }
 
-    protected void setSize(int width, int height) {
-        scale = 1;
-        while(width / (scale + 1) >= 400 && height / (scale + 1) >= 300) {
-            scale++;
-        }
-        fontRenderer.setScale(scale);
+    protected void setSize(int width, int height, WindowView windowView) {
+        scale = windowView.getScale(width, height);
+        fontRenderer.setScale(windowView.getFontScale(width, height));
         this.width = width / scale;
         this.height = height / scale;
         updateViewMatrix();

+ 25 - 0
src/me/hammerle/snuviengine/api/ResizingWindowView.java

@@ -0,0 +1,25 @@
+package me.hammerle.snuviengine.api;
+
+public class ResizingWindowView implements WindowView {
+    private final int minWidth;
+    private final int minHeight;
+
+    public ResizingWindowView(int minWidth, int minHeight) {
+        this.minWidth = minWidth;
+        this.minHeight = minHeight;
+    }
+
+    @Override
+    public int getScale(int width, int height) {
+        int scale = 1;
+        while(width / (scale + 1) >= minWidth && height / (scale + 1) >= minHeight) {
+            scale++;
+        }
+        return scale;
+    }
+
+    @Override
+    public int getFontScale(int width, int height) {
+        return getScale(width, height);
+    }
+}

+ 25 - 4
src/me/hammerle/snuviengine/api/Window.java

@@ -8,14 +8,18 @@ import static org.lwjgl.system.MemoryUtil.*;
 
 public final class Window {
     private final double secondsPerTick;
+    private final WindowView windowView;
     private long window = NULL;
     private Keys keys = null;
     private Gamepad gamepad = null;
     private Renderer renderer;
     private final Stats stats = new Stats();
+    private int newWidth = -1;
+    private int newHeight = -1;
 
-    public Window(long nanosPerTick) {
+    public Window(long nanosPerTick, WindowView windowView) {
         secondsPerTick = nanosPerTick / 1_000_000_000.0;
+        this.windowView = windowView;
     }
 
     public boolean initialize(String name, int width, int height) {
@@ -79,8 +83,8 @@ public final class Window {
 
     private void setResizeCallback() {
         glfwSetFramebufferSizeCallback(window, (eventWindow, width, height) -> {
-            glViewport(0, 0, width, height);
-            renderer.setSize(width, height);
+            newWidth = width;
+            newHeight = height;
         });
     }
 
@@ -98,7 +102,7 @@ public final class Window {
         if(shaderProgram == -1) {
             return true;
         }
-        renderer = new Renderer(shaderProgram, width, height);
+        renderer = new Renderer(shaderProgram, width, height, windowView);
         return false;
     }
 
@@ -134,6 +138,7 @@ public final class Window {
     }
 
     private void renderTick(Game game, float lag) {
+        updateWindowSize();
         stats.updateFramesPerSecond();
         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
         game.renderTick(renderer, lag);
@@ -141,6 +146,22 @@ public final class Window {
         glfwPollEvents();
     }
 
+    private void updateWindowSize() {
+        if(newWidth == -1 || newHeight == -1) {
+            return;
+        }
+        int width = windowView.getWidth(newWidth, newHeight);
+        int height = windowView.getHeight(newWidth, newHeight);
+        if(width != newWidth || height != newHeight) {
+            glfwSetWindowSize(window, width, height);
+        } else {
+            newWidth = -1;
+            newHeight = -1;
+        }
+        glViewport(0, 0, width, height);
+        renderer.setSize(width, height, windowView);
+    }
+
     private void destroyWindow() {
         glfwDestroyWindow(window);
     }

+ 15 - 0
src/me/hammerle/snuviengine/api/WindowView.java

@@ -0,0 +1,15 @@
+package me.hammerle.snuviengine.api;
+
+public interface WindowView {
+    public int getScale(int width, int height);
+
+    public int getFontScale(int width, int height);
+
+    public default int getWidth(int newWidth, int newHeight) {
+        return newWidth;
+    }
+
+    public default int getHeight(int newWidth, int newHeight) {
+        return newHeight;
+    }
+}

binární
tiles.png