package chess.view.DDDrender; import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST; import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT; import static org.lwjgl.opengl.GL11.glEnable; import java.io.IOException; import org.joml.Matrix4f; import org.joml.Vector2f; import org.joml.Vector3f; import org.lwjgl.opengl.GL30; import chess.model.Coordinate; import chess.model.Piece; import chess.view.DDDrender.shader.BoardShader; import chess.view.DDDrender.shader.PieceShader; import chess.view.DDDrender.shader.ShaderProgram; public class Renderer { private BoardShader boardShader; private PieceShader pieceShader; private VertexArray vao; private final PieceModel models; private static int BOARD_WIDTH = 8; private static int BOARD_HEIGHT = 8; private static int BOARD_SIZE = BOARD_WIDTH * BOARD_HEIGHT; private static int SQUARE_VERTEX_COUNT = 4; public Renderer() { this.boardShader = new BoardShader(); this.pieceShader = new PieceShader(); this.models = new PieceModel(); } public void Init() { boardShader.LoadShader(); pieceShader.LoadShader(); glEnable(GL_DEPTH_TEST); InitBoard(); } private float[] GetBoardPositions() { float[] positions = new float[BOARD_SIZE * SQUARE_VERTEX_COUNT * 3]; for (int i = 0; i < BOARD_WIDTH; i++) { for (int j = 0; j < BOARD_HEIGHT; j++) { float x = i / (float) BOARD_WIDTH; float dx = (i + 1) / (float) BOARD_WIDTH; float z = j / (float) BOARD_HEIGHT; float dz = (j + 1) / (float) BOARD_HEIGHT; float trueX = 2 * x - 1; float trueZ = 2 * z - 1; float trueDX = 2 * dx - 1; float trueDZ = 2 * dz - 1; positions[(BOARD_WIDTH * i + j) * SQUARE_VERTEX_COUNT * 3] = trueX; positions[(BOARD_WIDTH * i + j) * SQUARE_VERTEX_COUNT * 3 + 1] = 0.0f; positions[(BOARD_WIDTH * i + j) * SQUARE_VERTEX_COUNT * 3 + 2] = trueZ; positions[(BOARD_WIDTH * i + j) * SQUARE_VERTEX_COUNT * 3 + 3] = trueDX; positions[(BOARD_WIDTH * i + j) * SQUARE_VERTEX_COUNT * 3 + 4] = 0.0f; positions[(BOARD_WIDTH * i + j) * SQUARE_VERTEX_COUNT * 3 + 5] = trueZ; positions[(BOARD_WIDTH * i + j) * SQUARE_VERTEX_COUNT * 3 + 6] = trueX; positions[(BOARD_WIDTH * i + j) * SQUARE_VERTEX_COUNT * 3 + 7] = 0.0f; positions[(BOARD_WIDTH * i + j) * SQUARE_VERTEX_COUNT * 3 + 8] = trueDZ; positions[(BOARD_WIDTH * i + j) * SQUARE_VERTEX_COUNT * 3 + 9] = trueDX; positions[(BOARD_WIDTH * i + j) * SQUARE_VERTEX_COUNT * 3 + 10] = 0.0f; positions[(BOARD_WIDTH * i + j) * SQUARE_VERTEX_COUNT * 3 + 11] = trueDZ; } } return positions; } private float[] GetBoardColors() { float[] colors = new float[BOARD_SIZE * SQUARE_VERTEX_COUNT * 3]; for (int i = 0; i < BOARD_WIDTH; i++) { for (int j = 0; j < BOARD_HEIGHT; j++) { Vector3f color; if ((i + j) % 2 == 0) { color = new Vector3f(1.0f, 1.0f, 1.0f); } else { color = new Vector3f(0.0f, 0.0f, 0.0f); } int squareIndex = i * BOARD_WIDTH + j; for (int k = 0; k < SQUARE_VERTEX_COUNT; k++) { colors[squareIndex * SQUARE_VERTEX_COUNT * 3 + k * 3] = color.x; colors[squareIndex * SQUARE_VERTEX_COUNT * 3 + k * 3 + 1] = color.y; colors[squareIndex * SQUARE_VERTEX_COUNT * 3 + k * 3 + 2] = color.z; } } } return colors; } private int[] GetBoardIndicies() { int[] indices = new int[BOARD_SIZE * 6]; for (int i = 0; i < BOARD_SIZE; i++) { indices[i * 6] = i * 4; indices[i * 6 + 1] = i * 4 + 1; indices[i * 6 + 2] = i * 4 + 2; indices[i * 6 + 3] = i * 4 + 1; indices[i * 6 + 4] = i * 4 + 2; indices[i * 6 + 5] = i * 4 + 3; } return indices; } private void InitBoard() { ElementBuffer eBuffer = new ElementBuffer(GetBoardIndicies()); this.vao = new VertexArray(eBuffer); VertexBuffer positionBuffer = new VertexBuffer(GetBoardPositions(), 3); positionBuffer.AddVertexAttribPointer(0, 3, 0); VertexBuffer colorBuffer = new VertexBuffer(GetBoardColors(), 3); colorBuffer.AddVertexAttribPointer(1, 3, 0); this.vao.Bind(); this.vao.BindVertexBuffer(positionBuffer); this.vao.BindVertexBuffer(colorBuffer); this.vao.Unbind(); } public void RenderPiece(Piece piece, Coordinate pos) { try { DDDModel pieceModel = this.models.getModel(piece); Render(pieceModel, DDDPlacement.coordinates_to_vector(pos)); } catch (IOException e) { e.printStackTrace(); } } public void Render(Camera cam) { GL30.glClear(GL30.GL_DEPTH_BUFFER_BIT); this.boardShader.Start(); this.boardShader.SetCamMatrix(cam.getMatrix()); this.pieceShader.Start(); this.pieceShader.SetCamMatrix(cam.getMatrix()); RenderVao(this.boardShader, vao); } public void Render(DDDModel model, Vector2f position) { Vector3f realPos = new Vector3f(position.x(), 0, position.y()); this.pieceShader.Start(); this.pieceShader.setModelTransform(new Matrix4f().translate(realPos)); Render(model); } public void Render(DDDModel model) { for (int i = 0; i < model.getVaos().size(); i++) { VertexArray vao = model.getVaos().get(i); RenderVao(this.pieceShader, vao); } } public void RenderVao(ShaderProgram shader, VertexArray vertexArray) { shader.Start(); vertexArray.Bind(); GL30.glDrawElements(GL30.GL_TRIANGLES, vertexArray.GetVertexCount(), GL_UNSIGNED_INT, 0); vertexArray.Unbind(); } }