add world interface

This commit is contained in:
2025-04-27 11:00:14 +02:00
parent c488f3b4e0
commit 9bc09cf812
9 changed files with 235 additions and 71 deletions

View File

@@ -1,22 +1,78 @@
package chess.view.DDDrender; package chess.view.DDDrender;
import chess.controller.CommandExecutor; import org.joml.Vector2f;
import chess.controller.event.GameAdaptator; 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 CommandExecutor commandExecutor;
private final Window window; private final Window window;
private final Renderer renderer; private final Renderer renderer;
private final World world;
public DDDView(CommandExecutor commandExecutor) { public DDDView(CommandExecutor commandExecutor) {
this.commandExecutor = commandExecutor; this.commandExecutor = commandExecutor;
this.renderer = new Renderer(); 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() { 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(); this.window.run();
} }
} }

View File

@@ -2,16 +2,11 @@ package chess.view.DDDrender;
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT; import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT;
import java.io.IOException;
import org.joml.Matrix4f; import org.joml.Matrix4f;
import org.joml.Vector2f;
import org.joml.Vector3f; import org.joml.Vector3f;
import org.lwjgl.opengl.GL30; import org.lwjgl.opengl.GL30;
import chess.model.Color; import chess.view.DDDrender.loader.BoardModelLoader;
import chess.model.Coordinate;
import chess.model.Piece;
import chess.view.DDDrender.opengl.VertexArray; import chess.view.DDDrender.opengl.VertexArray;
import chess.view.DDDrender.shader.BoardShader; import chess.view.DDDrender.shader.BoardShader;
import chess.view.DDDrender.shader.PieceShader; import chess.view.DDDrender.shader.PieceShader;
@@ -21,15 +16,10 @@ public class Renderer {
private BoardShader boardShader; private BoardShader boardShader;
private PieceShader pieceShader; private PieceShader pieceShader;
private VertexArray boardVao; 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() { public Renderer() {
this.boardShader = new BoardShader(); this.boardShader = new BoardShader();
this.pieceShader = new PieceShader(); this.pieceShader = new PieceShader();
this.models = new Piece3DModel();
} }
public void Init() { public void Init() {
@@ -38,29 +28,21 @@ public class Renderer {
this.boardVao = BoardModelLoader.GetBoardModel(); this.boardVao = BoardModelLoader.GetBoardModel();
} }
public void RenderPiece(Piece piece, Coordinate pos) { public void Update(Camera cam) {
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) {
this.boardShader.Start(); this.boardShader.Start();
this.boardShader.SetCamMatrix(cam); this.boardShader.SetCamMatrix(cam);
this.pieceShader.Start(); this.pieceShader.Start();
this.pieceShader.SetCamMatrix(cam); this.pieceShader.SetCamMatrix(cam);
}
public void RenderBoard() {
RenderVao(this.boardShader, this.boardVao); RenderVao(this.boardShader, this.boardVao);
} }
public void Render(DDDModel model, Vector3f color, Vector2f position, float rotation) { public void Render(DDDModel model, Vector3f color, Vector3f position, float rotation) {
Vector3f realPos = new Vector3f(position.x(), 0, position.y());
this.pieceShader.Start(); this.pieceShader.Start();
this.pieceShader.setModelColor(color); 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); Render(model);
} }

View File

@@ -5,12 +5,17 @@ import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*; import org.lwjgl.opengl.*;
import org.lwjgl.system.*; import org.lwjgl.system.*;
import chess.controller.CommandExecutor;
import chess.controller.commands.GetPieceAtCommand;
import chess.model.Coordinate; 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.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.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*; import static org.lwjgl.glfw.GLFW.*;
@@ -24,13 +29,32 @@ public class Window {
private long window; private long window;
private Renderer renderer; private Renderer renderer;
private Camera cam; private final Camera cam;
private final CommandExecutor commandExecutor; private final World world;
public Window(CommandExecutor commandExecutor, Renderer renderer) { private final Queue<Runnable> tasks;
private final List<Consumer<Float>> regularTasks;
public final Signal1<Coordinate> OnCellClick = new Signal1<>();
public Window(Renderer renderer, World world) {
this.renderer = new Renderer(); this.renderer = new Renderer();
this.cam = new Camera(); this.cam = world.getCamera();
this.commandExecutor = commandExecutor; this.tasks = new ConcurrentLinkedDeque<>();
this.world = world;
this.regularTasks = new ArrayList<>();
}
public void addRegularTask(Consumer<Float> 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() { public void run() {
@@ -95,29 +119,27 @@ public class Window {
} }
private void render(float delta, float aspectRatio) { private void render(float delta, float aspectRatio) {
final float angle = 1f;
cam.setRotateAngle(cam.getRotateAngle() + angle * delta);
cam.setAspectRatio(aspectRatio); cam.setAspectRatio(aspectRatio);
renderer.Render(cam); renderer.Update(cam);
renderPieces(); renderer.RenderBoard();
renderWorld();
// renderPieces();
} }
private Piece pieceAt(Coordinate pos) { private void renderWorld() {
GetPieceAtCommand cmd = new GetPieceAtCommand(pos); for (Entity entity : this.world.getEntites()) {
this.commandExecutor.executeCommand(cmd); entity.render(this.renderer);
return cmd.getPiece(); }
} }
private void renderPieces() { private void executeTasks(float delta) {
for (int i = 0; i < Coordinate.VALUE_MAX; i++) { Runnable task = getNextTask();
for (int j = 0; j < Coordinate.VALUE_MAX; j++) { while (task != null) {
Coordinate pos = new Coordinate(i, j); task.run();
Piece piece = pieceAt(pos); task = getNextTask();
if (piece == null) }
continue; for (Consumer<Float> consumer : regularTasks) {
this.renderer.RenderPiece(pieceAt(pos), pos); consumer.accept(delta);
}
} }
} }
@@ -154,7 +176,8 @@ public class Window {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
double currentTime = glfwGetTime(); 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(); lastTime = glfwGetTime();
glfwSwapBuffers(window); // swap the color buffers glfwSwapBuffers(window); // swap the color buffers
@@ -163,6 +186,8 @@ public class Window {
// invoked during this call. // invoked during this call.
glfwPollEvents(); glfwPollEvents();
executeTasks(deltaTime);
glfwGetWindowSize(window, width, height); glfwGetWindowSize(window, width, height);
glViewport(0, 0, width[0], height[0]); glViewport(0, 0, width[0], height[0]);

View File

@@ -1,4 +1,4 @@
package chess.view.DDDrender; package chess.view.DDDrender.loader;
import org.joml.Vector3f; import org.joml.Vector3f;

View File

@@ -1,4 +1,4 @@
package chess.view.DDDrender; package chess.view.DDDrender.loader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -6,9 +6,7 @@ import java.nio.ByteBuffer;
import java.nio.IntBuffer; import java.nio.IntBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.IntStream;
import org.lwjgl.PointerBuffer;
import org.lwjgl.assimp.AIFace.Buffer; import org.lwjgl.assimp.AIFace.Buffer;
import org.lwjgl.assimp.AIMesh; import org.lwjgl.assimp.AIMesh;
import org.lwjgl.assimp.AINode; import org.lwjgl.assimp.AINode;
@@ -18,6 +16,7 @@ import org.lwjgl.assimp.Assimp;
import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.MemoryUtil;
import chess.view.AssetManager; import chess.view.AssetManager;
import chess.view.DDDrender.DDDModel;
import chess.view.DDDrender.opengl.ElementBuffer; import chess.view.DDDrender.opengl.ElementBuffer;
import chess.view.DDDrender.opengl.VertexArray; import chess.view.DDDrender.opengl.VertexArray;
import chess.view.DDDrender.opengl.VertexBuffer; import chess.view.DDDrender.opengl.VertexBuffer;
@@ -57,10 +56,7 @@ public class ModelLoader {
int faceNumber = mesh.mNumFaces(); int faceNumber = mesh.mNumFaces();
for (int i = 0; i < faceNumber; i++) { for (int i = 0; i < faceNumber; i++) {
int offset = indicies.size();
int numIndices = faces.get(i).mNumIndices();
IntBuffer faceIndicies = faces.get(i).mIndices(); IntBuffer faceIndicies = faces.get(i).mIndices();
// IntStream.of(faceIndicies.array()).forEach(indicies::add);
for (int j = 0; j < faceIndicies.capacity(); j++) { for (int j = 0; j < faceIndicies.capacity(); j++) {
indicies.add(faceIndicies.get(j)); indicies.add(faceIndicies.get(j));
} }
@@ -83,12 +79,12 @@ public class ModelLoader {
normals.add(normal.z()); normals.add(normal.z());
} }
PointerBuffer vertexTexture = mesh.mTextureCoords(); // PointerBuffer vertexTexture = mesh.mTextureCoords();
for (int i = 0; i < vertNumber; i++) { // for (int i = 0; i < vertNumber; i++) {
// PointerBuffer buff = mesh.mTextureCoords(); // PointerBuffer buff = mesh.mTextureCoords();
// textureCoords.add(buff.get(i).x()); // textureCoords.add(buff.get(i).x());
// textureCoords.add(buff.get(i).y()); // textureCoords.add(buff.get(i).y());
} // }
VertexBuffer positionVBO = new VertexBuffer(toFloatArray(positions), VERTEX_SIZE); VertexBuffer positionVBO = new VertexBuffer(toFloatArray(positions), VERTEX_SIZE);
positionVBO.AddVertexAttribPointer(VERTEX_POSITION_INDEX, VERTEX_SIZE, 0); positionVBO.AddVertexAttribPointer(VERTEX_POSITION_INDEX, VERTEX_SIZE, 0);

View File

@@ -1,4 +1,4 @@
package chess.view.DDDrender; package chess.view.DDDrender.loader;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
@@ -13,6 +13,7 @@ import chess.model.pieces.Knight;
import chess.model.pieces.Pawn; import chess.model.pieces.Pawn;
import chess.model.pieces.Queen; import chess.model.pieces.Queen;
import chess.model.pieces.Rook; import chess.model.pieces.Rook;
import chess.view.DDDrender.DDDModel;
public class Piece3DModel implements PieceVisitor<String> { public class Piece3DModel implements PieceVisitor<String> {

View File

@@ -0,0 +1,9 @@
package chess.view.DDDrender.world;
import chess.view.DDDrender.Renderer;
public abstract class Entity {
public abstract void render(Renderer renderer);
}

View File

@@ -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;
}
}

View File

@@ -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<Entity> 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<Entity> getEntites() {
return entites;
}
}