Compare commits

...

3 Commits

Author SHA1 Message Date
6ca5d1294f better light 2025-04-26 19:24:52 +02:00
b62dcffcb1 refactor 2025-04-26 18:18:27 +02:00
65c904478f enable face culling 2025-04-26 17:26:27 +02:00
7 changed files with 133 additions and 127 deletions

View File

@@ -68,8 +68,8 @@ public class BoardModelLoader {
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 + 1] = i * 4 + 2;
indices[i * 6 + 2] = i * 4 + 1;
indices[i * 6 + 3] = i * 4 + 1;
indices[i * 6 + 4] = i * 4 + 2;
indices[i * 6 + 5] = i * 4 + 3;

View File

@@ -8,16 +8,21 @@ public class Camera {
public static final float zNear = 0.01f;
public static final float zFar = 1000.0f;
private static final Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
private static final Vector3f center = new Vector3f(0.0f, 0.0f, 0.0f);
private final float distance = 1.5f;
private final float camHeight = 1.5f;
private float aspectRatio;
private float angle;
private Vector3f pos;
private float yaw = 0.0f;
private float pitch = 0.0f;
public Camera() {
this.pos = new Vector3f(1.5f, 1.5f, 0);
setRotation(0.0f, -3.14150f / 2.0f);
this.pos = new Vector3f(0.0f, camHeight, 0.0f);
this.angle = 0.0f;
}
public void move(float x, float y) {
@@ -25,23 +30,25 @@ public class Camera {
this.pos.y += y;
}
public void rotate(float yaw, float pitch) {
this.yaw += yaw;
this.pitch += pitch;
public void setRotateAngle(float angle) {
this.angle = angle;
updatePostion();
}
private void updatePostion() {
final float finalX = (float) Math.sin(angle);
final float finalZ = (float) -Math.cos(angle);
this.pos.set(distance * finalX, this.pos.get(1), distance * finalZ);
}
public float getRotateAngle() {
return angle;
}
public Vector3f getPos() {
return pos;
}
public float getYaw() {
return yaw;
}
public float getPitch() {
return pitch;
}
public float getFov() {
return fov;
}
@@ -58,70 +65,19 @@ public class Camera {
this.pos.z = z;
}
public void setYaw(float yaw) {
this.yaw = yaw;
}
public void setPitch(float pitch) {
this.pitch = pitch;
}
public void reset() {
resetPosition();
resetRotation();
}
public void resetPosition() {
pos = new Vector3f(0.0f, 0.0f, 0.0f);
}
public void resetRotation() {
yaw = 0.0f;
pitch = 0.0f;
}
public void moveForward(float distance) {
pos.x += distance * (float) Math.cos(yaw);
pos.y += distance * (float) Math.sin(yaw);
}
public void moveRight(float distance) {
pos.x += distance * (float) Math.cos(yaw);
pos.y += distance * (float) Math.sin(yaw);
}
public void moveUp(float distance) {
pos.z += distance;
}
public void moveDown(float distance) {
pos.z -= distance;
}
public void addYaw(float angle) {
yaw += angle;
}
public void addPitch(float angle) {
pitch += angle;
}
public void setPosition(Vector3f pos) {
this.pos = pos;
}
public void setRotation(float yaw, float pitch) {
this.yaw = yaw;
this.pitch = pitch;
}
public void setAspectRatio(float aspectRatio) {
this.aspectRatio = aspectRatio;
}
public Matrix4f getMatrix() {
return new Matrix4f()
.perspective((float) (Math.toRadians(fov)), aspectRatio, zNear, zFar)
.lookAt(pos, new Vector3f(0.0f, 0, 0), new Vector3f(0.0f, 1.0f, 0.0f));
public Matrix4f getPerspectiveMatrix() {
return new Matrix4f().perspective((float) (Math.toRadians(fov)), aspectRatio, zNear, zFar);
}
public Matrix4f getViewMatrix() {
return new Matrix4f().lookAt(pos, center, up);
}
}

View File

@@ -22,8 +22,8 @@ public class Renderer {
private VertexArray boardVao;
private final PieceModel models;
private static final Vector3f BLACK = new Vector3f(0.1f, 0.1f, 0.1f);
private static final Vector3f WHITE = new Vector3f(0.7f, 0.7f, 0.7f);
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();
@@ -49,9 +49,9 @@ public class Renderer {
public void Render(Camera cam) {
this.boardShader.Start();
this.boardShader.SetCamMatrix(cam.getMatrix());
this.boardShader.SetCamMatrix(cam);
this.pieceShader.Start();
this.pieceShader.SetCamMatrix(cam.getMatrix());
this.pieceShader.SetCamMatrix(cam);
RenderVao(this.boardShader, this.boardVao);
}

View File

@@ -1,6 +1,5 @@
package chess.view.DDDrender;
import org.joml.Vector3f;
import org.lwjgl.*;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
@@ -11,7 +10,6 @@ import chess.controller.commands.GetPieceAtCommand;
import chess.model.Coordinate;
import chess.model.Piece;
import java.io.IOException;
import java.nio.*;
import static org.lwjgl.glfw.Callbacks.*;
@@ -96,16 +94,11 @@ public class Window {
glfwShowWindow(window);
}
private void render() {
final float angle = 0.01f;
float x = cam.getPos().x();
float y = cam.getPos().z();
cam.setPosition(new Vector3f(x * (float) Math.cos(angle) - y * (float) Math.sin(angle), 1.0f,
x * (float) Math.sin(angle) + y * (float) Math.cos(angle)));
int width[] = new int[1];
int height[] = new int[1];
glfwGetWindowSize(window, width, height);
cam.setAspectRatio((float) width[0] / (float) height[0]);
private void render(float delta, float aspectRatio) {
final float angle = 1f;
cam.setRotateAngle(cam.getRotateAngle() + angle * delta);
cam.setAspectRatio(aspectRatio);
renderer.Render(cam);
renderPieces();
}
@@ -143,14 +136,26 @@ public class Window {
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glFrontFace(GL_CW);
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
double lastTime = glfwGetTime();
int width[] = new int[1];
int height[] = new int[1];
glfwGetWindowSize(window, width, height);
// Run the rendering loop until the user has attempted to close
// the window or has pressed the ESCAPE key.
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
render();
double currentTime = glfwGetTime();
render((float) (currentTime - lastTime), (float) width[0] / (float) height[0]);
lastTime = glfwGetTime();
glfwSwapBuffers(window); // swap the color buffers
@@ -158,15 +163,9 @@ public class Window {
// invoked during this call.
glfwPollEvents();
try (MemoryStack stack = stackPush()) {
IntBuffer pWidth = stack.mallocInt(1); // int*
IntBuffer pHeight = stack.mallocInt(1); // int*
glfwGetWindowSize(window, width, height);
glViewport(0, 0, width[0], height[0]);
// Get the window size passed to glfwCreateWindow
glfwGetWindowSize(window, pWidth, pHeight);
glViewport(0, 0, pWidth.get(), pHeight.get());
} // the stack frame is popped automatically
}
}

View File

@@ -1,6 +1,6 @@
package chess.view.DDDrender.shader;
import org.joml.Matrix4f;
import chess.view.DDDrender.Camera;
public class BoardShader extends ShaderProgram {
@@ -10,17 +10,28 @@ public class BoardShader extends ShaderProgram {
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 color;
uniform mat4 camMatrix;
uniform vec3 lightPosition;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform vec3 lightPosition = vec3(0, 10, 0);
flat out vec3 pass_color;
out vec3 toLightVector;
out vec3 toCameraVector;
out vec3 surfaceNormal;
void main(void){
gl_Position = camMatrix * vec4(position, 1.0);
const vec4 normal = vec4(0.0, 1.0, 0.0, 1.0);
gl_Position = projectionMatrix * viewMatrix * vec4(position, 1.0);
vec3 camPos = (inverse(viewMatrix) * vec4(0.0, 0.0, 0.0, 1.0)).xyz;
toLightVector = lightPosition - position;
toCameraVector = camPos - position;
surfaceNormal = (normal).xyz;
pass_color = color;
}
@@ -32,6 +43,8 @@ public class BoardShader extends ShaderProgram {
flat in vec3 pass_color;
in vec3 toLightVector;
in vec3 toCameraVector;
in vec3 surfaceNormal;
out vec4 out_color;
@@ -41,18 +54,22 @@ public class BoardShader extends ShaderProgram {
float lightDistance = length(toLightVector);
const vec3 attenuation = vec3(0.3, 0.03, 0);
const vec3 attenuation = vec3(0.2, 0.1, 0.0);
float attenuationFactor = attenuation.x + attenuation.y * lightDistance + attenuation.z * lightDistance * lightDistance;
vec3 unitNormal = vec3(0, 1, 0);
vec3 unitNormal = normalize(surfaceNormal);
vec3 unitLightVector = normalize(toLightVector);
vec3 unitCamVector = normalize(toCameraVector);
vec3 lightDirection = -unitLightVector;
vec3 reflectedLightDirection = reflect(lightDirection, unitNormal);
float diffuse = max(0.2, dot(unitNormal, unitLightVector));
float brightness = diffuse / attenuationFactor;
float specularFactor = max(0.0, dot(reflectedLightDirection, unitCamVector));
float specular = pow(specularFactor, shineDamper) * reflectivity;
float brightness = (diffuse + specular) / attenuationFactor;
out_color = brightness * vec4(pass_color, 1.0);
out_color.w = 1.0;
@@ -61,7 +78,8 @@ public class BoardShader extends ShaderProgram {
""";
private int location_CamMatrix = 0;
private int location_ProjectionMatrix = 0;
private int location_ViewMatrix = 0;
public BoardShader() {
@@ -73,10 +91,12 @@ public class BoardShader extends ShaderProgram {
@Override
protected void GetAllUniformLocation() {
location_CamMatrix = GetUniformLocation("camMatrix");
location_ProjectionMatrix = GetUniformLocation("projectionMatrix");
location_ViewMatrix = GetUniformLocation("viewMatrix");
}
public void SetCamMatrix(Matrix4f mat) {
LoadMat4(location_CamMatrix, mat);
public void SetCamMatrix(Camera camera) {
LoadMat4(location_ProjectionMatrix, camera.getPerspectiveMatrix());
LoadMat4(location_ViewMatrix, camera.getViewMatrix());
}
}

View File

@@ -3,6 +3,8 @@ package chess.view.DDDrender.shader;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import chess.view.DDDrender.Camera;
public class PieceShader extends ShaderProgram {
private static String vertexShader = """
@@ -12,48 +14,75 @@ public class PieceShader extends ShaderProgram {
layout(location = 1) in vec2 uv;
layout(location = 2) in vec3 normal;
uniform mat4 camMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelTransform;
uniform vec3 lightPosition = vec3(0, 1, 0);
uniform vec3 lightPosition = vec3(0, 10, 0);
out vec3 toLightVector;
out vec3 toCameraVector;
out vec3 surfaceNormal;
void main(void){
vec4 worldPos = modelTransform * vec4(position, 1.0);
toLightVector = lightPosition - worldPos.xyz;
surfaceNormal = (modelTransform * vec4(normal, 0.0)).xyz;
vec4 modelPos = modelTransform * vec4(position, 1.0);
vec4 globalNormal = modelTransform * vec4(normal, 1.0);
gl_Position = camMatrix * worldPos;
gl_Position = projectionMatrix * viewMatrix * modelPos;
vec3 camPos = (inverse(viewMatrix) * vec4(0.0, 0.0, 0.0, 1.0)).xyz;
toLightVector = lightPosition - modelPos.xyz;
toCameraVector = camPos - position;
surfaceNormal = normalize(globalNormal.xyz);
}
""";
private static String fragmentShader = """
#version 330
in vec3 toLightVector;
in vec3 toCameraVector;
in vec3 surfaceNormal;
uniform vec3 modelColor = vec3(1, 1, 1);
uniform vec3 modelColor;
out vec4 out_color;
void main(void){
const float shineDamper = 10.0;
const float reflectivity = 1.0;
float lightDistance = length(toLightVector);
const vec3 attenuation = vec3(0.2, 0.1, 0.0);
float attenuationFactor = attenuation.x + attenuation.y * lightDistance + attenuation.z * lightDistance * lightDistance;
vec3 unitNormal = normalize(surfaceNormal);
vec3 unitLightVector = normalize(toLightVector);
vec3 unitCamVector = normalize(toCameraVector);
float diffuse = max(0.5, dot(unitNormal, unitLightVector));
vec3 lightDirection = -unitLightVector;
vec3 reflectedLightDirection = reflect(lightDirection, unitNormal);
float brightness = diffuse;
float diffuse = max(0.2, dot(unitNormal, unitLightVector));
out_color = vec4(modelColor, 1.0) * brightness;
float specularFactor = max(0.0, dot(reflectedLightDirection, unitCamVector));
float specular = pow(specularFactor, shineDamper) * reflectivity;
float brightness = (diffuse + specular) / attenuationFactor;
out_color = brightness * vec4(modelColor, 1.0);
out_color.w = 1.0;
}
""";
private int location_CamMatrix = 0;
private int location_ProjectionMatrix = 0;
private int location_ViewMatrix = 0;
private int location_ModelTransform = 0;
private int location_ModelColor = 0;
@@ -67,13 +96,15 @@ public class PieceShader extends ShaderProgram {
@Override
protected void GetAllUniformLocation() {
location_CamMatrix = GetUniformLocation("camMatrix");
location_ProjectionMatrix = GetUniformLocation("projectionMatrix");
location_ViewMatrix = GetUniformLocation("viewMatrix");
location_ModelTransform = GetUniformLocation("modelTransform");
location_ModelColor = GetUniformLocation("modelColor");
}
public void SetCamMatrix(Matrix4f mat) {
LoadMat4(location_CamMatrix, mat);
public void SetCamMatrix(Camera camera) {
LoadMat4(location_ProjectionMatrix, camera.getPerspectiveMatrix());
LoadMat4(location_ViewMatrix, camera.getViewMatrix());
}
public void setModelTransform(Matrix4f mat) {

View File

@@ -56,8 +56,8 @@ public abstract class ShaderProgram {
if (compileSuccesful.get() != 1) {
System.out.println("Shader did not compile !");
System.err.println(GL30.glGetShaderInfoLog(shaderId));
return -1;
}
return shaderId;
@@ -68,7 +68,7 @@ public abstract class ShaderProgram {
protected int GetUniformLocation(String uniformName) {
int location = GL30.glGetUniformLocation(programId, uniformName);
if (location == -1) {
System.out.println("Uniform value not found !");
System.out.println("Uniform value \"" + uniformName + "\" not found !");
}
return location;
}