Skip to content

Commit a0db610

Browse files
Connected spot light functionality to the rest of the engine.
1 parent e84a7de commit a0db610

File tree

9 files changed

+100
-22
lines changed

9 files changed

+100
-22
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,5 @@ hs_err_pid*
1414
# shader files in target
1515
/target/classes/shaders/*.frag
1616
/target/classes/shaders/*.vert
17+
/target/
18+
/bin/

src/main/java/me/oskarmendel/mass/Mass.java

-12
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,6 @@
2525
package me.oskarmendel.mass;
2626

2727
import me.oskarmendel.mass.core.Game;
28-
import org.lwjgl.glfw.GLFWErrorCallback;
29-
import org.lwjgl.glfw.GLFWVidMode;
30-
import org.lwjgl.opengl.GL;
31-
import org.lwjgl.system.MemoryStack;
32-
33-
import java.nio.IntBuffer;
34-
35-
import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks;
36-
import static org.lwjgl.glfw.GLFW.*;
37-
import static org.lwjgl.opengl.GL11.*;
38-
import static org.lwjgl.system.MemoryStack.stackPush;
39-
import static org.lwjgl.system.MemoryUtil.NULL;
4028

4129
/**
4230
* Starting point of the application.

src/main/java/me/oskarmendel/mass/core/Game.java

+31-4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import me.oskarmendel.mass.gfx.*;
3131
import me.oskarmendel.mass.gfx.light.DirectionalLight;
3232
import me.oskarmendel.mass.gfx.light.PointLight;
33+
import me.oskarmendel.mass.gfx.light.SpotLight;
3334
import me.oskarmendel.mass.util.OBJLoader;
3435
import org.joml.Vector3f;
3536
import org.lwjgl.glfw.GLFWErrorCallback;
@@ -90,6 +91,10 @@ public class Game {
9091
private PointLight pointLight;
9192
private DirectionalLight directionalLight;
9293
private float lightAngle;
94+
95+
private SpotLight spotLight;
96+
private float spotAngle = 0;
97+
private float spotInc = 1;
9398

9499
/**
95100
* Default constructor for the game.
@@ -166,6 +171,15 @@ public void init() {
166171
pointLight = new PointLight(lightColour, lightPosition, lightIntensity);
167172
PointLight.Attenuation att = new PointLight.Attenuation(0.0f, 0.0f, 1.0f);
168173
pointLight.setAttenuation(att);
174+
175+
// Spot light example.
176+
lightPosition = new Vector3f(0.0f, 0.0f, 10f);
177+
pointLight = new PointLight(lightColour, lightPosition, lightIntensity);
178+
att = new PointLight.Attenuation(0.0f, 0.0f, 0.02f);
179+
pointLight.setAttenuation(att);
180+
Vector3f coneDir = new Vector3f(0, 0, -1);
181+
float cutOff = (float) Math.cos(Math.toRadians(140));
182+
spotLight = new SpotLight(pointLight, coneDir, cutOff);
169183

170184
// Directional light example.
171185
lightPosition = new Vector3f(-1, 0,0 );
@@ -238,11 +252,11 @@ private void input() {
238252
cameraInc.y = 1;
239253
}
240254

241-
float lightPos = pointLight.getPosition().z;
255+
float lightPos = spotLight.getPointLight().getPosition().z;
242256
if (screen.isKeyPressed(GLFW_KEY_N)) {
243-
this.pointLight.getPosition().z = lightPos + 0.1f;
257+
this.spotLight.getPointLight().getPosition().z = lightPos + 0.1f;
244258
} else if (screen.isKeyPressed(GLFW_KEY_M)) {
245-
this.pointLight.getPosition().z = lightPos - 0.1f;
259+
this.spotLight.getPointLight().getPosition().z = lightPos - 0.1f;
246260
}
247261
}
248262

@@ -260,6 +274,18 @@ public void update() {
260274
// Do something for every loaded entity.
261275
entity.getRotation().y += 1.0f;
262276
}
277+
278+
// Update spot light direction.
279+
spotAngle += spotInc * 0.05f;
280+
if (spotAngle > 2) {
281+
spotInc = -1;
282+
} else if (spotAngle < -2) {
283+
spotInc = 1;
284+
}
285+
286+
double spotAngleRad = Math.toRadians(spotAngle);
287+
Vector3f coneDir = spotLight.getConeDirection();
288+
coneDir.y = (float) Math.sin(spotAngleRad);
263289

264290
// Update directional light direction.
265291
lightAngle += 1.1f;
@@ -289,6 +315,7 @@ public void update() {
289315
* Renders the game.
290316
*/
291317
public void render() {
292-
renderer.render(this.camera, this.entities, ambientLight, pointLight, directionalLight);
318+
renderer.render(this.camera, this.entities, ambientLight,
319+
pointLight, spotLight, directionalLight);
293320
}
294321
}

src/main/java/me/oskarmendel/mass/gfx/Renderer.java

+17-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import me.oskarmendel.mass.entity.Entity;
2929
import me.oskarmendel.mass.gfx.light.DirectionalLight;
3030
import me.oskarmendel.mass.gfx.light.PointLight;
31+
import me.oskarmendel.mass.gfx.light.SpotLight;
3132
import me.oskarmendel.mass.gfx.shader.Shader;
3233
import me.oskarmendel.mass.gfx.shader.ShaderProgram;
3334
import org.joml.Matrix4f;
@@ -86,7 +87,7 @@ public void init() {
8687
}
8788

8889
public void render(Camera camera, Entity[] entities, Vector3f ambientLight,
89-
PointLight pointLight, DirectionalLight directionalLight) {
90+
PointLight pointLight, SpotLight spotLight, DirectionalLight directionalLight) {
9091
clear();
9192

9293
shaderProgram.use();
@@ -108,10 +109,24 @@ public void render(Camera camera, Entity[] entities, Vector3f ambientLight,
108109
lightPos.y = aux.y;
109110
lightPos.z = aux.z;
110111
shaderProgram.setUniform("pointLight", currPointLight);
112+
113+
// Update the spot light relative to the view matrix.
114+
SpotLight currSpotLight = new SpotLight(spotLight);
115+
Vector4f dir = new Vector4f(currSpotLight.getConeDirection(), 0);
116+
dir.mul(viewMatrix);
117+
currSpotLight.setConeDirection(new Vector3f(dir.x, dir.y, dir.z));
118+
119+
Vector3f spotLightPos = currSpotLight.getPointLight().getPosition();
120+
Vector4f auxSpot = new Vector4f(spotLightPos, 1);
121+
auxSpot.mul(viewMatrix);
122+
spotLightPos.x = auxSpot.x;
123+
spotLightPos.y = auxSpot.y;
124+
spotLightPos.z = auxSpot.z;
125+
shaderProgram.setUniform("spotLight", currSpotLight);
111126

112127
// Update the directional light relative to the viewMatrix of the camera.
113128
DirectionalLight currDirLight = new DirectionalLight(directionalLight);
114-
Vector4f dir = new Vector4f(currDirLight.getDirection(), 0);
129+
dir = new Vector4f(currDirLight.getDirection(), 0);
115130
dir.mul(viewMatrix);
116131
currDirLight.setDirection(new Vector3f(dir.x, dir.y, dir.z));
117132
shaderProgram.setUniform("directionalLight", currDirLight);

src/main/java/me/oskarmendel/mass/gfx/Screen.java

+9
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,13 @@ public void destroy() {
153153
public boolean isClosing() {
154154
return glfwWindowShouldClose(id);
155155
}
156+
157+
/**
158+
* Returns the vsync value for this screen.
159+
*
160+
* @return - The vsync value set for this screen.
161+
*/
162+
public boolean getVsync() {
163+
return this.vsync;
164+
}
156165
}

src/main/java/me/oskarmendel/mass/gfx/Transformation.java

-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424

2525
package me.oskarmendel.mass.gfx;
2626

27-
import com.sun.deploy.config.VerboseDefaultConfig;
2827
import me.oskarmendel.mass.entity.Entity;
2928
import org.joml.Matrix4f;
3029
import org.joml.Vector3f;

src/main/java/me/oskarmendel/mass/gfx/shader/ShaderProgram.java

+14
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import me.oskarmendel.mass.gfx.Material;
2828
import me.oskarmendel.mass.gfx.light.DirectionalLight;
2929
import me.oskarmendel.mass.gfx.light.PointLight;
30+
import me.oskarmendel.mass.gfx.light.SpotLight;
31+
3032
import org.joml.Matrix4f;
3133
import org.joml.Vector3f;
3234
import org.joml.Vector4f;
@@ -162,6 +164,18 @@ public void setUniform(String location, PointLight pointLight) {
162164
setUniform(getUniformLocation(location + ".att.linear"), pointLight.getAttenuation().getLinear());
163165
setUniform(getUniformLocation(location + ".att.exponent"), pointLight.getAttenuation().getExponent());
164166
}
167+
168+
/**
169+
* Sets the SpotLight uniform variable with the specified location name.
170+
*
171+
* @param location - Location name.
172+
* @param spotLight - SpotLight object to get values from.
173+
*/
174+
public void setUniform(String location, SpotLight spotLight) {
175+
setUniform((location + ".pl"), spotLight.getPointLight());
176+
setUniform(getUniformLocation(location + ".coneDirection"), spotLight.getConeDirection());
177+
setUniform(getUniformLocation(location + ".cutOff"), spotLight.getCutOff());
178+
}
165179

166180
/**
167181
* Sets the DirectionalLight uniform variable with the specified location name.

src/main/resources/shaders/default.frag

+24
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ struct PointLight {
2020
Attenuation att;
2121
};
2222

23+
struct SpotLight {
24+
PointLight pl;
25+
vec3 coneDirection;
26+
float cutOff;
27+
};
28+
2329
struct DirectionalLight {
2430
vec3 color;
2531
vec3 direction;
@@ -39,6 +45,7 @@ uniform vec3 ambientLight;
3945
uniform float specularPower;
4046
uniform Material material;
4147
uniform PointLight pointLight;
48+
uniform SpotLight spotLight;
4249
uniform DirectionalLight directionalLight;
4350

4451
vec4 ambientC;
@@ -95,6 +102,22 @@ vec4 calcPointLight(PointLight light, vec3 position, vec3 normal) {
95102
return lightColor / attenuationInv;
96103
}
97104

105+
vec4 calcSpotLight(SpotLight light, vec3 position, vec3 normal) {
106+
vec3 lightDirection = light.pl.position - position;
107+
vec3 toLightDir = normalize(lightDirection);
108+
vec3 fromLightDir = -toLightDir;
109+
float spotAlfa = dot(fromLightDir, normalize(light.coneDirection));
110+
111+
vec4 color = vec4(0, 0, 0, 0);
112+
113+
if (spotAlfa > light.cutOff) {
114+
color = calcPointLight(light.pl, position, normal);
115+
color *= (1.0 - (1.0 - spotAlfa) / (1.0 - light.cutOff));
116+
}
117+
118+
return color;
119+
}
120+
98121
vec4 calcDirectionalLight(DirectionalLight light, vec3 position, vec3 normal) {
99122
return calcLightColor(light.color, light.intensity, position, normalize(light.direction), normal);
100123
}
@@ -104,6 +127,7 @@ void main() {
104127

105128
vec4 diffuseSpecularComp = calcDirectionalLight(directionalLight, vertexPos, vertexNormal);
106129
diffuseSpecularComp += calcPointLight(pointLight, vertexPos, vertexNormal);
130+
diffuseSpecularComp += calcSpotLight(spotLight, vertexPos, vertexNormal);
107131

108132
fragColor = ambientC * vec4(ambientLight, 1) + diffuseSpecularComp;
109133
}

src/main/resources/shaders/default.vert

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ uniform mat4 modelViewMatrix;
1212
uniform mat4 projectionMatrix;
1313

1414
void main() {
15-
vec4 mvPos = modelViewMatrix * vec4(position, 1.0);
16-
gl_Position = projectionMatrix * mvPos;
15+
vec4 pos = modelViewMatrix * vec4(position, 1.0);
16+
gl_Position = projectionMatrix * pos;
1717
outTexCoord = texCoord;
1818
vertexNormal = normalize(modelViewMatrix * vec4(normals, 0.0)).xyz;
19-
vertexPos = mvPos.xyz;
19+
vertexPos = pos.xyz;
2020
}

0 commit comments

Comments
 (0)