diff --git a/src/main/java/ru/windcorp/optica/client/graphics/GUI.java b/src/main/java/ru/windcorp/optica/client/graphics/GUI.java index a476c08..75b6a2d 100644 --- a/src/main/java/ru/windcorp/optica/client/graphics/GUI.java +++ b/src/main/java/ru/windcorp/optica/client/graphics/GUI.java @@ -20,6 +20,10 @@ package ru.windcorp.optica.client.graphics; import java.util.ArrayList; import java.util.List; +import com.google.common.eventbus.Subscribe; + +import ru.windcorp.optica.client.graphics.input.FrameResizeEvent; + public class GUI { private static final List LAYERS = new ArrayList<>(); @@ -44,4 +48,19 @@ public class GUI { } } + public static void invalidateEverything() { + LAYERS.forEach(Layer::invalidate); + } + + public static Object getEventSubscriber() { + return new Object() { + + @Subscribe + public void onFrameResized(FrameResizeEvent event) { + GUI.invalidateEverything(); + } + + }; + } + } diff --git a/src/main/java/ru/windcorp/optica/client/graphics/Layer.java b/src/main/java/ru/windcorp/optica/client/graphics/Layer.java index 4b0a384..7d017e1 100644 --- a/src/main/java/ru/windcorp/optica/client/graphics/Layer.java +++ b/src/main/java/ru/windcorp/optica/client/graphics/Layer.java @@ -17,13 +17,18 @@ *******************************************************************************/ package ru.windcorp.optica.client.graphics; +import java.util.concurrent.atomic.AtomicBoolean; + import ru.windcorp.optica.client.graphics.backend.GraphicsInterface; public abstract class Layer { private final String name; + private boolean hasInitialized = false; + private final AtomicBoolean isValid = new AtomicBoolean(false); + public Layer(String name) { this.name = name; } @@ -33,7 +38,9 @@ public abstract class Layer { return "Layer " + name; } - public void render() { + void render() { + validate(); + if (!hasInitialized) { initialize(); hasInitialized = true; @@ -42,16 +49,28 @@ public abstract class Layer { doRender(); } + void validate() { + if (isValid.compareAndSet(false, true)) { + doValidate(); + } + } + + public void invalidate() { + isValid.set(false); + } + protected abstract void initialize(); + + protected abstract void doValidate(); protected abstract void doRender(); protected int getWidth() { - return GraphicsInterface.getFramebufferWidth(); + return GraphicsInterface.getFrameWidth(); } protected int getHeight() { - return GraphicsInterface.getFramebufferHeight(); + return GraphicsInterface.getFrameHeight(); } } diff --git a/src/main/java/ru/windcorp/optica/client/graphics/backend/GraphicsBackend.java b/src/main/java/ru/windcorp/optica/client/graphics/backend/GraphicsBackend.java index bd52e70..5aa8aab 100644 --- a/src/main/java/ru/windcorp/optica/client/graphics/backend/GraphicsBackend.java +++ b/src/main/java/ru/windcorp/optica/client/graphics/backend/GraphicsBackend.java @@ -18,6 +18,9 @@ package ru.windcorp.optica.client.graphics.backend; import static org.lwjgl.opengl.GL11.*; + +import glm.vec._2.i.Vec2i; + import static org.lwjgl.glfw.GLFW.*; public class GraphicsBackend { @@ -26,8 +29,7 @@ public class GraphicsBackend { private static long windowHandle; - private static int framebufferWidth; - private static int framebufferHeight; + private static final Vec2i FRAME_SIZE = new Vec2i(); private static double frameLength = 1.0 / 60; // TODO do something about it private static int framesRendered = 0; @@ -56,21 +58,25 @@ public class GraphicsBackend { return windowHandle; } - public static int getFramebufferWidth() { - return framebufferWidth; + public static int getFrameWidth() { + return FRAME_SIZE.x; } - public static int getFramebufferHeight() { - return framebufferHeight; + public static int getFrameHeight() { + return FRAME_SIZE.y; + } + + public static Vec2i getFrameSize() { + return FRAME_SIZE; } - static void onFramebufferResized(long window, int newWidth, int newHeight) { + static void onFrameResized(long window, int newWidth, int newHeight) { if (window != windowHandle) return; - framebufferWidth = newWidth; - framebufferHeight = newHeight; + InputHandler.handleFrameResize(newWidth, newHeight); + FRAME_SIZE.set(newWidth, newHeight); - glViewport(0, 0, framebufferWidth, framebufferHeight); + glViewport(0, 0, newWidth, newHeight); } static void startFrame() { diff --git a/src/main/java/ru/windcorp/optica/client/graphics/backend/GraphicsInterface.java b/src/main/java/ru/windcorp/optica/client/graphics/backend/GraphicsInterface.java index 42f6937..94a69f7 100644 --- a/src/main/java/ru/windcorp/optica/client/graphics/backend/GraphicsInterface.java +++ b/src/main/java/ru/windcorp/optica/client/graphics/backend/GraphicsInterface.java @@ -18,6 +18,7 @@ package ru.windcorp.optica.client.graphics.backend; import glm.vec._2.d.Vec2d; +import glm.vec._2.i.Vec2i; public class GraphicsInterface { @@ -31,16 +32,20 @@ public class GraphicsInterface { return Thread.currentThread() == getRenderThread(); } - public static int getFramebufferWidth() { - return GraphicsBackend.getFramebufferWidth(); + public static int getFrameWidth() { + return GraphicsBackend.getFrameWidth(); } - public static int getFramebufferHeight() { - return GraphicsBackend.getFramebufferHeight(); + public static int getFrameHeight() { + return GraphicsBackend.getFrameHeight(); + } + + public static Vec2i getFrameSize() { + return GraphicsBackend.getFrameSize(); } public static float getAspectRatio() { - return ((float) getFramebufferWidth()) / getFramebufferHeight(); + return ((float) getFrameWidth()) / getFrameHeight(); } public static double getTime() { diff --git a/src/main/java/ru/windcorp/optica/client/graphics/backend/InputHandler.java b/src/main/java/ru/windcorp/optica/client/graphics/backend/InputHandler.java index e040df3..87912a6 100644 --- a/src/main/java/ru/windcorp/optica/client/graphics/backend/InputHandler.java +++ b/src/main/java/ru/windcorp/optica/client/graphics/backend/InputHandler.java @@ -26,35 +26,16 @@ public class InputHandler { private static final EventBus INPUT_EVENT_BUS = new EventBus("Input"); - // ScrollEvent - - private static class ModifiableWheelScrollEvent extends WheelScrollEvent { - - public void initialize(double xoffset, double yoffset) { - this.xOffset = xoffset; - this.yOffset = yoffset; - } - - } - - private static final ModifiableWheelScrollEvent THE_SCROLL_EVENT = - new ModifiableWheelScrollEvent(); - - static void handleMouseWheel( - long window, - double xoffset, - double yoffset - ) { - if (GraphicsBackend.getWindowHandle() != window) return; - THE_SCROLL_EVENT.initialize(xoffset, yoffset); - dispatch(THE_SCROLL_EVENT); - } - // KeyEvent private static class ModifiableKeyEvent extends KeyEvent { + protected ModifiableKeyEvent() { + super(0, 0, 0, 0, Double.NaN); + } + public void initialize(int key, int scancode, int action, int mods) { + this.setTime(GraphicsInterface.getTime()); this.key = key; this.scancode = scancode; this.action = action; @@ -82,15 +63,18 @@ public class InputHandler { private static class ModifiableCursorMoveEvent extends CursorMoveEvent { + protected ModifiableCursorMoveEvent() { + super(0, 0, Double.NaN); + } + public void initialize(double x, double y) { - Vec2d newPos = getNewPosition(); - newPos.x = x; - newPos.y = y; + this.setTime(GraphicsInterface.getTime()); + getNewPosition().set(x, y); } } - private static final Vec2d CURSOR_POSITION = new Vec2d().set( + private static final Vec2d CURSOR_POSITION = new Vec2d( Double.NaN, Double.NaN ); @@ -113,8 +97,6 @@ public class InputHandler { CURSOR_POSITION.set(x, y); } - // Misc - public static double getCursorX() { return CURSOR_POSITION.x; } @@ -126,6 +108,65 @@ public class InputHandler { public static Vec2d getCursorPosition() { return CURSOR_POSITION; } + + // ScrollEvent + + private static class ModifiableWheelScrollEvent extends WheelScrollEvent { + + public ModifiableWheelScrollEvent() { + super(0, 0, Double.NaN); + } + + public void initialize(double xOffset, double yOffset) { + this.setTime(GraphicsInterface.getTime()); + this.getOffset().set(xOffset, yOffset); + } + + } + + private static final ModifiableWheelScrollEvent THE_WHEEL_SCROLL_EVENT = + new ModifiableWheelScrollEvent(); + + static void handleWheelScroll( + long window, + double xoffset, + double yoffset + ) { + if (GraphicsBackend.getWindowHandle() != window) return; + THE_WHEEL_SCROLL_EVENT.initialize(xoffset, yoffset); + dispatch(THE_WHEEL_SCROLL_EVENT); + } + + // FrameResizeEvent + + private static class ModifiableFrameResizeEvent extends FrameResizeEvent { + + public ModifiableFrameResizeEvent() { + super(0, 0, Double.NaN); + } + + public void initialize(int width, int height) { + this.setTime(GraphicsInterface.getTime()); + this.getNewSize().set(width, height); + } + + } + + private static final ModifiableFrameResizeEvent THE_FRAME_RESIZE_EVENT = + new ModifiableFrameResizeEvent(); + + /* + * NB: this is NOT a GLFW callback, the raw callback is in GraphicsBackend + */ + static void handleFrameResize( + int width, + int height + ) { + THE_FRAME_RESIZE_EVENT.initialize(width, height); + dispatch(THE_FRAME_RESIZE_EVENT); + } + + // Misc private static void dispatch(InputEvent event) { INPUT_EVENT_BUS.post(event); diff --git a/src/main/java/ru/windcorp/optica/client/graphics/backend/LWJGLInitializer.java b/src/main/java/ru/windcorp/optica/client/graphics/backend/LWJGLInitializer.java index 0d5edeb..8ecede8 100644 --- a/src/main/java/ru/windcorp/optica/client/graphics/backend/LWJGLInitializer.java +++ b/src/main/java/ru/windcorp/optica/client/graphics/backend/LWJGLInitializer.java @@ -23,6 +23,8 @@ import static org.lwjgl.system.MemoryUtil.*; import org.lwjgl.opengl.GL; +import ru.windcorp.optica.client.graphics.GUI; + class LWJGLInitializer { private LWJGLInitializer() {} @@ -88,12 +90,14 @@ class LWJGLInitializer { long handle = GraphicsBackend.getWindowHandle(); glfwSetFramebufferSizeCallback(handle, - GraphicsBackend::onFramebufferResized); + GraphicsBackend::onFrameResized); glfwSetKeyCallback(handle, InputHandler::handleKeyInput); glfwSetCursorPosCallback(handle, InputHandler::handleMouseMoveInput); - glfwSetScrollCallback(handle, InputHandler::handleMouseWheel); + glfwSetScrollCallback(handle, InputHandler::handleWheelScroll); + + GraphicsInterface.subscribeToInputEvents(GUI.getEventSubscriber()); } } diff --git a/src/main/java/ru/windcorp/optica/client/graphics/flat/AssembledFlatLayer.java b/src/main/java/ru/windcorp/optica/client/graphics/flat/AssembledFlatLayer.java index f246ee7..ad0a27f 100644 --- a/src/main/java/ru/windcorp/optica/client/graphics/flat/AssembledFlatLayer.java +++ b/src/main/java/ru/windcorp/optica/client/graphics/flat/AssembledFlatLayer.java @@ -26,7 +26,6 @@ public abstract class AssembledFlatLayer extends Layer { private final RenderTarget target = new RenderTarget(); - private boolean needsReassembly = true; private RenderTarget.Clip[] clips = null; public AssembledFlatLayer(String name) { @@ -39,24 +38,16 @@ public abstract class AssembledFlatLayer extends Layer { } - public void markForReassembly() { - needsReassembly = true; - } - - private void doReassemble() { + @Override + protected void doValidate() { assemble(target); clips = target.assemble(); - needsReassembly = false; } protected abstract void assemble(RenderTarget target); @Override protected void doRender() { - if (needsReassembly) { - doReassemble(); - } - for (RenderTarget.Clip clip : clips) { clip.render(helper); } diff --git a/src/main/java/ru/windcorp/optica/client/graphics/flat/FlatRenderHelper.java b/src/main/java/ru/windcorp/optica/client/graphics/flat/FlatRenderHelper.java index 45f9cc5..ec39961 100644 --- a/src/main/java/ru/windcorp/optica/client/graphics/flat/FlatRenderHelper.java +++ b/src/main/java/ru/windcorp/optica/client/graphics/flat/FlatRenderHelper.java @@ -33,8 +33,8 @@ public abstract class FlatRenderHelper extends ShapeRenderHelper { @Override public Mat4 getFinalTransform() { - float width = GraphicsInterface.getFramebufferWidth(); - float height = GraphicsInterface.getFramebufferHeight(); + float width = GraphicsInterface.getFrameWidth(); + float height = GraphicsInterface.getFrameHeight(); return finalTransform.identity().translate(-1, +1, 0) .scale(2 / width, -2 / height, 1 / MAX_DEPTH) diff --git a/src/main/java/ru/windcorp/optica/client/graphics/flat/LayerTestUI.java b/src/main/java/ru/windcorp/optica/client/graphics/flat/LayerTestUI.java index 16d73aa..cb08fab 100644 --- a/src/main/java/ru/windcorp/optica/client/graphics/flat/LayerTestUI.java +++ b/src/main/java/ru/windcorp/optica/client/graphics/flat/LayerTestUI.java @@ -133,7 +133,7 @@ public class LayerTestUI extends AssembledFlatLayer { } flag = event.isPress(); - markForReassembly(); + invalidate(); } /* diff --git a/src/main/java/ru/windcorp/optica/client/graphics/flat/TransformedMask.java b/src/main/java/ru/windcorp/optica/client/graphics/flat/TransformedMask.java index 829191b..eb5f492 100644 --- a/src/main/java/ru/windcorp/optica/client/graphics/flat/TransformedMask.java +++ b/src/main/java/ru/windcorp/optica/client/graphics/flat/TransformedMask.java @@ -106,7 +106,7 @@ public class TransformedMask { } private void flipY() { - float height = GraphicsInterface.getFramebufferHeight(); + float height = GraphicsInterface.getFrameHeight(); startXstartY.y = height - startXstartY.y; startXendY.y = height - startXendY.y; diff --git a/src/main/java/ru/windcorp/optica/client/graphics/input/CursorEvent.java b/src/main/java/ru/windcorp/optica/client/graphics/input/CursorEvent.java index 9483e28..62f058c 100644 --- a/src/main/java/ru/windcorp/optica/client/graphics/input/CursorEvent.java +++ b/src/main/java/ru/windcorp/optica/client/graphics/input/CursorEvent.java @@ -22,6 +22,10 @@ import ru.windcorp.optica.client.graphics.backend.GraphicsInterface; public abstract class CursorEvent extends InputEvent { + public CursorEvent(double time) { + super(time); + } + public double getCursorX() { return GraphicsInterface.getCursorX(); } diff --git a/src/main/java/ru/windcorp/optica/client/graphics/input/CursorMoveEvent.java b/src/main/java/ru/windcorp/optica/client/graphics/input/CursorMoveEvent.java index 6c04d2b..7f3a6b3 100644 --- a/src/main/java/ru/windcorp/optica/client/graphics/input/CursorMoveEvent.java +++ b/src/main/java/ru/windcorp/optica/client/graphics/input/CursorMoveEvent.java @@ -24,12 +24,13 @@ public class CursorMoveEvent extends CursorEvent { private final Vec2d newPosition = new Vec2d(); - protected CursorMoveEvent(double newX, double newY) { + protected CursorMoveEvent(double newX, double newY, double time) { + super(time); newPosition.set(newX, newY); } - protected CursorMoveEvent(Vec2d newPos) { - newPosition.set(newPos.x, newPos.y); + protected CursorMoveEvent(Vec2d newPos, double time) { + this(newPos.x, newPos.y, time); } @Override @@ -83,8 +84,6 @@ public class CursorMoveEvent extends CursorEvent { return result.set(getChangeX(), getChangeY()); } - protected CursorMoveEvent() {} - @Override public CursorMoveEvent snapshot() { return new StaticMouseMoveEvent( @@ -96,7 +95,6 @@ public class CursorMoveEvent extends CursorEvent { private class StaticMouseMoveEvent extends CursorMoveEvent { - private final double time; private final Vec2d previousPosition = new Vec2d(); public StaticMouseMoveEvent( @@ -104,25 +102,14 @@ public class CursorMoveEvent extends CursorEvent { Vec2d newPosition, double time ) { - super(newPosition); + super(newPosition, time); this.previousPosition.set(previousPosition.x, previousPosition.y); - this.time = time; } @Override public Vec2d getPreviousPosition() { return previousPosition; } - - @Override - public double getTime() { - return time; - } - - @Override - public CursorMoveEvent snapshot() { - return this; - } } diff --git a/src/main/java/ru/windcorp/optica/client/graphics/input/FrameResizeEvent.java b/src/main/java/ru/windcorp/optica/client/graphics/input/FrameResizeEvent.java new file mode 100644 index 0000000..549c2e9 --- /dev/null +++ b/src/main/java/ru/windcorp/optica/client/graphics/input/FrameResizeEvent.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Optica + * Copyright (C) 2020 Wind Corporation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *******************************************************************************/ +package ru.windcorp.optica.client.graphics.input; + +import glm.vec._2.i.Vec2i; +import ru.windcorp.optica.client.graphics.backend.GraphicsInterface; + +public class FrameResizeEvent extends InputEvent { + + private final Vec2i newSize = new Vec2i(); + + protected FrameResizeEvent(int newWidth, int newHeight, double time) { + super(time); + this.newSize.set(newWidth, newHeight); + } + + protected FrameResizeEvent(Vec2i newSize, double time) { + this(newSize.x, newSize.y, time); + } + + public int getNewWidth() { + return getNewSize().x; + } + + public int getNewHeight() { + return getNewSize().y; + } + + public Vec2i getNewSize() { + return newSize; + } + + public int getPreviousWidth() { + return getPreviousSize().x; + } + + public int getPreviousHeight() { + return getPreviousSize().y; + } + + public Vec2i getPreviousSize() { + return GraphicsInterface.getFrameSize(); + } + + @Override + public FrameResizeEvent snapshot() { + return new StaticFrameResizeEvent(getNewSize(), getPreviousSize(), getTime()); + } + + private static class StaticFrameResizeEvent extends FrameResizeEvent { + + private final Vec2i previousSize; + + public StaticFrameResizeEvent( + Vec2i newSize, + Vec2i previousSize, + double time + ) { + super(newSize, time); + this.previousSize = previousSize; + } + + @Override + public Vec2i getPreviousSize() { + return previousSize; + } + + } + +} diff --git a/src/main/java/ru/windcorp/optica/client/graphics/input/InputEvent.java b/src/main/java/ru/windcorp/optica/client/graphics/input/InputEvent.java index 8910bcf..cbf5fb4 100644 --- a/src/main/java/ru/windcorp/optica/client/graphics/input/InputEvent.java +++ b/src/main/java/ru/windcorp/optica/client/graphics/input/InputEvent.java @@ -17,12 +17,20 @@ *******************************************************************************/ package ru.windcorp.optica.client.graphics.input; -import ru.windcorp.optica.client.graphics.backend.GraphicsInterface; - public abstract class InputEvent { + private double time; + + public InputEvent(double time) { + this.time = time; + } + + protected void setTime(double time) { + this.time = time; + } + public double getTime() { - return GraphicsInterface.getTime(); + return time; } public abstract InputEvent snapshot(); diff --git a/src/main/java/ru/windcorp/optica/client/graphics/input/KeyEvent.java b/src/main/java/ru/windcorp/optica/client/graphics/input/KeyEvent.java index 4493f57..275e1f9 100644 --- a/src/main/java/ru/windcorp/optica/client/graphics/input/KeyEvent.java +++ b/src/main/java/ru/windcorp/optica/client/graphics/input/KeyEvent.java @@ -26,14 +26,15 @@ public class KeyEvent extends InputEvent { protected int action; protected int mods; - protected KeyEvent(int key, int scancode, int action, int mods) { + protected KeyEvent( + int key, int scancode, int action, int mods, double time + ) { + super(time); this.key = key; this.scancode = scancode; this.action = action; this.mods = mods; } - - protected KeyEvent() {} public int getKey() { return key; @@ -64,32 +65,8 @@ public class KeyEvent extends InputEvent { } @Override - public InputEvent snapshot() { - return new StaticKeyEvent(key, scancode, action, mods, getTime()); - } - - private class StaticKeyEvent extends KeyEvent { - - private final double time; - - public StaticKeyEvent( - int key, int scancode, int action, int mods, - double time - ) { - super(key, scancode, action, mods); - this.time = time; - } - - @Override - public double getTime() { - return time; - } - - @Override - public InputEvent snapshot() { - return this; - } - + public KeyEvent snapshot() { + return new KeyEvent(key, scancode, action, mods, getTime()); } } diff --git a/src/main/java/ru/windcorp/optica/client/graphics/input/WheelEvent.java b/src/main/java/ru/windcorp/optica/client/graphics/input/WheelEvent.java index 41c1aae..0e8f5af 100644 --- a/src/main/java/ru/windcorp/optica/client/graphics/input/WheelEvent.java +++ b/src/main/java/ru/windcorp/optica/client/graphics/input/WheelEvent.java @@ -19,7 +19,11 @@ package ru.windcorp.optica.client.graphics.input; public abstract class WheelEvent extends InputEvent { - @Override + public WheelEvent(double time) { + super(time); + } + + @Override public abstract WheelEvent snapshot(); } diff --git a/src/main/java/ru/windcorp/optica/client/graphics/input/WheelScrollEvent.java b/src/main/java/ru/windcorp/optica/client/graphics/input/WheelScrollEvent.java index 2b0f1b8..01706cf 100644 --- a/src/main/java/ru/windcorp/optica/client/graphics/input/WheelScrollEvent.java +++ b/src/main/java/ru/windcorp/optica/client/graphics/input/WheelScrollEvent.java @@ -17,75 +17,59 @@ *******************************************************************************/ package ru.windcorp.optica.client.graphics.input; +import glm.vec._2.d.Vec2d; + public class WheelScrollEvent extends WheelEvent { + + private final Vec2d offset = new Vec2d(); - protected double xOffset; - protected double yOffset; - - protected WheelScrollEvent(double xOffset, double yOffset) { - this.xOffset = xOffset; - this.yOffset = yOffset; + protected WheelScrollEvent(double xOffset, double yOffset, double time) { + super(time); + this.offset.set(xOffset, yOffset); + } + + protected WheelScrollEvent(Vec2d offset, double time) { + this(offset.x, offset.y, time); } - protected WheelScrollEvent() {} - public boolean isUp() { - return yOffset > 0; + return getY() > 0; } public boolean isDown() { - return yOffset < 0; + return getY() < 0; } public boolean isRight() { - return xOffset > 0; + return getX() > 0; } public boolean isLeft() { - return xOffset < 0; + return getX() < 0; } public boolean hasVerticalMovement() { - return yOffset != 0; + return getY() != 0; } public boolean hasHorizontalMovement() { - return xOffset != 0; + return getX() != 0; } public double getX() { - return xOffset; + return getOffset().x; } public double getY() { - return yOffset; + return getOffset().y; } + + public Vec2d getOffset() { + return offset; + } @Override public WheelEvent snapshot() { - return new StaticWheelScrollEvent(xOffset, yOffset, getTime()); - } - - private class StaticWheelScrollEvent extends WheelScrollEvent { - - private final double time; - - public StaticWheelScrollEvent( - double xOffset, double yOffset, double time - ) { - super(xOffset, yOffset); - this.time = time; - } - - @Override - public double getTime() { - return time; - } - - @Override - public WheelEvent snapshot() { - return this; - } - + return new WheelScrollEvent(getOffset(), getTime()); } } diff --git a/src/main/java/ru/windcorp/optica/client/graphics/world/LayerWorld.java b/src/main/java/ru/windcorp/optica/client/graphics/world/LayerWorld.java index 7e42272..79575f9 100644 --- a/src/main/java/ru/windcorp/optica/client/graphics/world/LayerWorld.java +++ b/src/main/java/ru/windcorp/optica/client/graphics/world/LayerWorld.java @@ -70,6 +70,11 @@ public class LayerWorld extends Layer { GraphicsInterface.subscribeToInputEvents(this); } + @Override + protected void doValidate() { + // Do nothing + } + @Override protected void doRender() { camera.apply(helper);