From 9bc09cf8121817302c1b82be6797b96a5324a968 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Sun, 27 Apr 2025 11:00:14 +0200 Subject: [PATCH] add world interface --- .../java/chess/view/DDDrender/DDDView.java | 66 ++++++++++++++-- .../java/chess/view/DDDrender/Renderer.java | 32 ++------ .../java/chess/view/DDDrender/Window.java | 79 ++++++++++++------- .../{ => loader}/BoardModelLoader.java | 2 +- .../DDDrender/{ => loader}/ModelLoader.java | 20 ++--- .../DDDrender/{ => loader}/Piece3DModel.java | 3 +- .../chess/view/DDDrender/world/Entity.java | 9 +++ .../view/DDDrender/world/PieceEntity.java | 55 +++++++++++++ .../chess/view/DDDrender/world/World.java | 40 ++++++++++ 9 files changed, 235 insertions(+), 71 deletions(-) rename app/src/main/java/chess/view/DDDrender/{ => loader}/BoardModelLoader.java (98%) rename app/src/main/java/chess/view/DDDrender/{ => loader}/ModelLoader.java (89%) rename app/src/main/java/chess/view/DDDrender/{ => loader}/Piece3DModel.java (95%) create mode 100644 app/src/main/java/chess/view/DDDrender/world/Entity.java create mode 100644 app/src/main/java/chess/view/DDDrender/world/PieceEntity.java create mode 100644 app/src/main/java/chess/view/DDDrender/world/World.java diff --git a/app/src/main/java/chess/view/DDDrender/DDDView.java b/app/src/main/java/chess/view/DDDrender/DDDView.java index cbbd8ef..b7b657f 100644 --- a/app/src/main/java/chess/view/DDDrender/DDDView.java +++ b/app/src/main/java/chess/view/DDDrender/DDDView.java @@ -1,22 +1,78 @@ package chess.view.DDDrender; -import chess.controller.CommandExecutor; -import chess.controller.event.GameAdaptator; +import org.joml.Vector2f; +import org.joml.Vector3f; -public class DDDView extends GameAdaptator{ +import chess.controller.CommandExecutor; +import chess.controller.commands.GetPieceAtCommand; +import chess.controller.event.GameAdaptator; +import chess.model.Color; +import chess.model.Coordinate; +import chess.model.Piece; +import chess.view.DDDrender.world.PieceEntity; +import chess.view.DDDrender.world.World; + +public class DDDView extends GameAdaptator { + + private static final Vector3f BLACK = new Vector3f(0.3f, 0.3f, 0.3f); + private static final Vector3f WHITE = new Vector3f(1.0f, 1.0f, 1.0f); private final CommandExecutor commandExecutor; private final Window window; private final Renderer renderer; + private final World world; public DDDView(CommandExecutor commandExecutor) { this.commandExecutor = commandExecutor; this.renderer = new Renderer(); - this.window = new Window(commandExecutor, this.renderer); + this.world = new World(new Camera()); + this.window = new Window(this.renderer, this.world); + this.window.OnCellClick.connect(this::onCellClick); + } + + // Invoked when a cell is clicked + private void onCellClick(Coordinate coordinate) { + + } + + private Piece pieceAt(Coordinate pos) { + GetPieceAtCommand cmd = new GetPieceAtCommand(pos); + this.commandExecutor.executeCommand(cmd); + return cmd.getPiece(); + } + + @Override + public void onGameStart() { + this.window.scheduleTask(() -> { + initBoard(); + }); + } + + private void initBoard() { + for (int i = 0; i < Coordinate.VALUE_MAX; i++) { + for (int j = 0; j < Coordinate.VALUE_MAX; j++) { + Coordinate pos = new Coordinate(i, j); + Piece piece = pieceAt(pos); + if (piece == null) + continue; + + Vector2f pieceBoardPos = DDDPlacement.coordinates_to_vector(pos); + Vector3f pieceWorldPos = new Vector3f(pieceBoardPos.x(), 0, pieceBoardPos.y()); + + this.world.addEntity(new PieceEntity(piece, pieceWorldPos, + piece.getColor() == Color.White ? WHITE : BLACK, + piece.getColor() == Color.White ? 0.0f : (float) Math.PI)); + } + } } public void run() { + this.window.addRegularTask((delta) -> { + final float angle = 1f; + final Camera cam = this.world.getCamera(); + cam.setRotateAngle(cam.getRotateAngle() + angle * delta); + }); this.window.run(); } - + } diff --git a/app/src/main/java/chess/view/DDDrender/Renderer.java b/app/src/main/java/chess/view/DDDrender/Renderer.java index 758f921..20e402e 100644 --- a/app/src/main/java/chess/view/DDDrender/Renderer.java +++ b/app/src/main/java/chess/view/DDDrender/Renderer.java @@ -2,16 +2,11 @@ package chess.view.DDDrender; import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT; -import java.io.IOException; - import org.joml.Matrix4f; -import org.joml.Vector2f; import org.joml.Vector3f; import org.lwjgl.opengl.GL30; -import chess.model.Color; -import chess.model.Coordinate; -import chess.model.Piece; +import chess.view.DDDrender.loader.BoardModelLoader; import chess.view.DDDrender.opengl.VertexArray; import chess.view.DDDrender.shader.BoardShader; import chess.view.DDDrender.shader.PieceShader; @@ -21,15 +16,10 @@ public class Renderer { private BoardShader boardShader; private PieceShader pieceShader; private VertexArray boardVao; - private final Piece3DModel models; - - private static final Vector3f BLACK = new Vector3f(0.3f, 0.3f, 0.3f); - private static final Vector3f WHITE = new Vector3f(1.0f, 1.0f, 1.0f); public Renderer() { this.boardShader = new BoardShader(); this.pieceShader = new PieceShader(); - this.models = new Piece3DModel(); } public void Init() { @@ -38,29 +28,21 @@ public class Renderer { this.boardVao = BoardModelLoader.GetBoardModel(); } - public void RenderPiece(Piece piece, Coordinate pos) { - try { - DDDModel pieceModel = this.models.getModel(piece); - Render(pieceModel, piece.getColor() == Color.White ? WHITE : BLACK, DDDPlacement.coordinates_to_vector(pos), - piece.getColor() == Color.White ? 0.0f : 3.14f); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public void Render(Camera cam) { + public void Update(Camera cam) { this.boardShader.Start(); this.boardShader.SetCamMatrix(cam); this.pieceShader.Start(); this.pieceShader.SetCamMatrix(cam); + } + + public void RenderBoard() { RenderVao(this.boardShader, this.boardVao); } - public void Render(DDDModel model, Vector3f color, Vector2f position, float rotation) { - Vector3f realPos = new Vector3f(position.x(), 0, position.y()); + public void Render(DDDModel model, Vector3f color, Vector3f position, float rotation) { this.pieceShader.Start(); this.pieceShader.setModelColor(color); - this.pieceShader.setModelTransform(new Matrix4f().translate(realPos).rotate(rotation, new Vector3f(0, 1, 0))); + this.pieceShader.setModelTransform(new Matrix4f().translate(position).rotate(rotation, new Vector3f(0, 1, 0))); Render(model); } diff --git a/app/src/main/java/chess/view/DDDrender/Window.java b/app/src/main/java/chess/view/DDDrender/Window.java index 62b04ce..8841569 100644 --- a/app/src/main/java/chess/view/DDDrender/Window.java +++ b/app/src/main/java/chess/view/DDDrender/Window.java @@ -5,12 +5,17 @@ import org.lwjgl.glfw.*; import org.lwjgl.opengl.*; import org.lwjgl.system.*; -import chess.controller.CommandExecutor; -import chess.controller.commands.GetPieceAtCommand; import chess.model.Coordinate; -import chess.model.Piece; +import chess.view.DDDrender.world.Entity; +import chess.view.DDDrender.world.World; +import common.Signal1; import java.nio.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.function.Consumer; import static org.lwjgl.glfw.Callbacks.*; import static org.lwjgl.glfw.GLFW.*; @@ -24,13 +29,32 @@ public class Window { private long window; private Renderer renderer; - private Camera cam; - private final CommandExecutor commandExecutor; + private final Camera cam; + private final World world; - public Window(CommandExecutor commandExecutor, Renderer renderer) { + private final Queue tasks; + private final List> regularTasks; + + public final Signal1 OnCellClick = new Signal1<>(); + + public Window(Renderer renderer, World world) { this.renderer = new Renderer(); - this.cam = new Camera(); - this.commandExecutor = commandExecutor; + this.cam = world.getCamera(); + this.tasks = new ConcurrentLinkedDeque<>(); + this.world = world; + this.regularTasks = new ArrayList<>(); + } + + public void addRegularTask(Consumer task) { + this.regularTasks.add(task); + } + + public synchronized void scheduleTask(Runnable runnable) { + this.tasks.add(runnable); + } + + public synchronized Runnable getNextTask() { + return this.tasks.poll(); } public void run() { @@ -95,29 +119,27 @@ public class Window { } private void render(float delta, float aspectRatio) { - final float angle = 1f; - cam.setRotateAngle(cam.getRotateAngle() + angle * delta); - cam.setAspectRatio(aspectRatio); - renderer.Render(cam); - renderPieces(); + renderer.Update(cam); + renderer.RenderBoard(); + renderWorld(); + // renderPieces(); } - private Piece pieceAt(Coordinate pos) { - GetPieceAtCommand cmd = new GetPieceAtCommand(pos); - this.commandExecutor.executeCommand(cmd); - return cmd.getPiece(); + private void renderWorld() { + for (Entity entity : this.world.getEntites()) { + entity.render(this.renderer); + } } - private void renderPieces() { - for (int i = 0; i < Coordinate.VALUE_MAX; i++) { - for (int j = 0; j < Coordinate.VALUE_MAX; j++) { - Coordinate pos = new Coordinate(i, j); - Piece piece = pieceAt(pos); - if (piece == null) - continue; - this.renderer.RenderPiece(pieceAt(pos), pos); - } + private void executeTasks(float delta) { + Runnable task = getNextTask(); + while (task != null) { + task.run(); + task = getNextTask(); + } + for (Consumer consumer : regularTasks) { + consumer.accept(delta); } } @@ -154,7 +176,8 @@ public class Window { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer double currentTime = glfwGetTime(); - render((float) (currentTime - lastTime), (float) width[0] / (float) height[0]); + float deltaTime = (float) (currentTime - lastTime); + render(deltaTime, (float) width[0] / (float) height[0]); lastTime = glfwGetTime(); glfwSwapBuffers(window); // swap the color buffers @@ -163,6 +186,8 @@ public class Window { // invoked during this call. glfwPollEvents(); + executeTasks(deltaTime); + glfwGetWindowSize(window, width, height); glViewport(0, 0, width[0], height[0]); diff --git a/app/src/main/java/chess/view/DDDrender/BoardModelLoader.java b/app/src/main/java/chess/view/DDDrender/loader/BoardModelLoader.java similarity index 98% rename from app/src/main/java/chess/view/DDDrender/BoardModelLoader.java rename to app/src/main/java/chess/view/DDDrender/loader/BoardModelLoader.java index 24144e1..0ae12fe 100644 --- a/app/src/main/java/chess/view/DDDrender/BoardModelLoader.java +++ b/app/src/main/java/chess/view/DDDrender/loader/BoardModelLoader.java @@ -1,4 +1,4 @@ -package chess.view.DDDrender; +package chess.view.DDDrender.loader; import org.joml.Vector3f; diff --git a/app/src/main/java/chess/view/DDDrender/ModelLoader.java b/app/src/main/java/chess/view/DDDrender/loader/ModelLoader.java similarity index 89% rename from app/src/main/java/chess/view/DDDrender/ModelLoader.java rename to app/src/main/java/chess/view/DDDrender/loader/ModelLoader.java index de2beb5..3499cb3 100644 --- a/app/src/main/java/chess/view/DDDrender/ModelLoader.java +++ b/app/src/main/java/chess/view/DDDrender/loader/ModelLoader.java @@ -1,4 +1,4 @@ -package chess.view.DDDrender; +package chess.view.DDDrender.loader; import java.io.IOException; import java.io.InputStream; @@ -6,9 +6,7 @@ import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.util.ArrayList; import java.util.List; -import java.util.stream.IntStream; -import org.lwjgl.PointerBuffer; import org.lwjgl.assimp.AIFace.Buffer; import org.lwjgl.assimp.AIMesh; import org.lwjgl.assimp.AINode; @@ -18,6 +16,7 @@ import org.lwjgl.assimp.Assimp; import org.lwjgl.system.MemoryUtil; import chess.view.AssetManager; +import chess.view.DDDrender.DDDModel; import chess.view.DDDrender.opengl.ElementBuffer; import chess.view.DDDrender.opengl.VertexArray; import chess.view.DDDrender.opengl.VertexBuffer; @@ -57,10 +56,7 @@ public class ModelLoader { int faceNumber = mesh.mNumFaces(); for (int i = 0; i < faceNumber; i++) { - int offset = indicies.size(); - int numIndices = faces.get(i).mNumIndices(); IntBuffer faceIndicies = faces.get(i).mIndices(); - // IntStream.of(faceIndicies.array()).forEach(indicies::add); for (int j = 0; j < faceIndicies.capacity(); j++) { indicies.add(faceIndicies.get(j)); } @@ -83,12 +79,12 @@ public class ModelLoader { normals.add(normal.z()); } - PointerBuffer vertexTexture = mesh.mTextureCoords(); - for (int i = 0; i < vertNumber; i++) { - // PointerBuffer buff = mesh.mTextureCoords(); - // textureCoords.add(buff.get(i).x()); - // textureCoords.add(buff.get(i).y()); - } + // PointerBuffer vertexTexture = mesh.mTextureCoords(); + // for (int i = 0; i < vertNumber; i++) { + // PointerBuffer buff = mesh.mTextureCoords(); + // textureCoords.add(buff.get(i).x()); + // textureCoords.add(buff.get(i).y()); + // } VertexBuffer positionVBO = new VertexBuffer(toFloatArray(positions), VERTEX_SIZE); positionVBO.AddVertexAttribPointer(VERTEX_POSITION_INDEX, VERTEX_SIZE, 0); diff --git a/app/src/main/java/chess/view/DDDrender/Piece3DModel.java b/app/src/main/java/chess/view/DDDrender/loader/Piece3DModel.java similarity index 95% rename from app/src/main/java/chess/view/DDDrender/Piece3DModel.java rename to app/src/main/java/chess/view/DDDrender/loader/Piece3DModel.java index 2081d84..7b9c21f 100644 --- a/app/src/main/java/chess/view/DDDrender/Piece3DModel.java +++ b/app/src/main/java/chess/view/DDDrender/loader/Piece3DModel.java @@ -1,4 +1,4 @@ -package chess.view.DDDrender; +package chess.view.DDDrender.loader; import java.io.IOException; import java.util.HashMap; @@ -13,6 +13,7 @@ import chess.model.pieces.Knight; import chess.model.pieces.Pawn; import chess.model.pieces.Queen; import chess.model.pieces.Rook; +import chess.view.DDDrender.DDDModel; public class Piece3DModel implements PieceVisitor { diff --git a/app/src/main/java/chess/view/DDDrender/world/Entity.java b/app/src/main/java/chess/view/DDDrender/world/Entity.java new file mode 100644 index 0000000..47f0b69 --- /dev/null +++ b/app/src/main/java/chess/view/DDDrender/world/Entity.java @@ -0,0 +1,9 @@ +package chess.view.DDDrender.world; + +import chess.view.DDDrender.Renderer; + +public abstract class Entity { + + public abstract void render(Renderer renderer); + +} diff --git a/app/src/main/java/chess/view/DDDrender/world/PieceEntity.java b/app/src/main/java/chess/view/DDDrender/world/PieceEntity.java new file mode 100644 index 0000000..4f8d880 --- /dev/null +++ b/app/src/main/java/chess/view/DDDrender/world/PieceEntity.java @@ -0,0 +1,55 @@ +package chess.view.DDDrender.world; + +import java.io.IOException; + +import org.joml.Vector3f; + +import chess.model.Piece; +import chess.view.DDDrender.DDDModel; +import chess.view.DDDrender.Renderer; +import chess.view.DDDrender.loader.Piece3DModel; + +public class PieceEntity extends Entity { + + private static final Piece3DModel modelLoader = new Piece3DModel(); + + private final Piece piece; + private Vector3f position; + private Vector3f color; + private float rotation; + private DDDModel model; + + public PieceEntity(Piece piece, Vector3f position, Vector3f color, float rotation) { + this.piece = piece; + this.position = position; + this.color = color; + this.rotation = rotation; + try { + this.model = modelLoader.getModel(piece); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public Piece getPiece() { + return piece; + } + + @Override + public void render(Renderer renderer) { + renderer.Render(model, color, position, rotation); + } + + public void setPosition(Vector3f position) { + this.position = position; + } + + public void setColor(Vector3f color) { + this.color = color; + } + + public void setRotation(float rotation) { + this.rotation = rotation; + } + +} diff --git a/app/src/main/java/chess/view/DDDrender/world/World.java b/app/src/main/java/chess/view/DDDrender/world/World.java new file mode 100644 index 0000000..0d30f44 --- /dev/null +++ b/app/src/main/java/chess/view/DDDrender/world/World.java @@ -0,0 +1,40 @@ +package chess.view.DDDrender.world; + +import java.util.ArrayList; +import java.util.List; + +import chess.model.Piece; +import chess.view.DDDrender.Camera; + +public class World { + private final Camera camera; + private final List entites; + + public World(Camera camera) { + this.camera = camera; + this.entites = new ArrayList<>(); + } + + public PieceEntity getEntity(Piece piece) { + for (Entity entity : entites) { + if (entity instanceof PieceEntity p) { + if (p.getPiece() == piece) + return p; + } + } + return null; + } + + public void addEntity(Entity entity) { + this.entites.add(entity); + } + + public Camera getCamera() { + return camera; + } + + public List getEntites() { + return entites; + } + +}