diff --git a/src/projectzombie/display/Camera.java b/src/projectzombie/display/Camera.java index dba326d..b1ea098 100755 --- a/src/projectzombie/display/Camera.java +++ b/src/projectzombie/display/Camera.java @@ -3,7 +3,9 @@ package projectzombie.display; import gl_engine.matrix.Matrix4; import gl_engine.vec.Vec3d; import projectzombie.Main; +import projectzombie.time.GameTimer; import projectzombie.world.chunk.Chunk; +import projectzombie.world.layer.Layer; public class Camera { @@ -12,26 +14,32 @@ public class Camera public Matrix4 matrix; public Matrix4 projection; - public Matrix4 projection_matrix; + public Matrix4 projection_sun; public static Camera camera; public Camera(int w, int h) { - Matrix4 identity = Matrix4.identity(); + matrix = Matrix4.identity(); Vec3d pos = Main.player.getPos(); angle = Main.player.angle; x = pos.x - 0.5; y = pos.z - 0.5; - identity = Matrix4.multiply(identity, Matrix4.rotate(angle + 180, 0, 1, 0)); - identity = Matrix4.multiply(identity, Matrix4.rotate(-45, 1, 0, 0)); - identity = Matrix4.multiply(identity, Matrix4.translate(0, 0, -16)); + matrix = Matrix4.multiply(matrix, Matrix4.rotate(angle + 180, 0, 1, 0)); + matrix = Matrix4.multiply(matrix, Matrix4.rotate(-45, 1, 0, 0)); + matrix = Matrix4.multiply(matrix, Matrix4.translate(0, 0, -16)); - projection_matrix = Matrix4.projection((double)w / (double)h, 45, 0.1, Chunk.RENDER_DISTANCE*16+32); - projection = Matrix4.multiply(identity, projection_matrix); + projection = Matrix4.projection((double)w / (double)h, 45, 0.1, Chunk.RENDER_DISTANCE*16+32); + projection = Matrix4.multiply(matrix, projection); - matrix = identity; + double time = Main.world.getLayer().layergen.getSunPosition(); + + projection_sun = Matrix4.identity(); + projection_sun = Matrix4.multiply(projection_sun, Matrix4.rotate(20, 0, 0, 1)); + projection_sun = Matrix4.multiply(projection_sun, Matrix4.rotate(-time, 1, 0, 0)); + projection_sun = Matrix4.multiply(projection_sun, Matrix4.translate(0, 0, -16)); + projection_sun = Matrix4.multiply(projection_sun, Matrix4.scale(new Vec3d(1/32.0, 1/32.0, -1/32.0))); } } diff --git a/src/projectzombie/display/DisplayRender.java b/src/projectzombie/display/DisplayRender.java index c21146b..4be7804 100755 --- a/src/projectzombie/display/DisplayRender.java +++ b/src/projectzombie/display/DisplayRender.java @@ -9,6 +9,7 @@ import java.nio.ByteBuffer; import org.lwjgl.opengl.GL33; +import gl_engine.MathHelpers; import gl_engine.matrix.Matrix4; import gl_engine.vec.Vec3d; import projectzombie.Main; @@ -17,11 +18,14 @@ import projectzombie.model.Model; import projectzombie.util.math.ColorRange; import projectzombie.world.chunk.Chunk; import projectzombie.world.chunk.ChunkEventHandler; +import projectzombie.world.layer.layergen.LayerGen; public class DisplayRender { - private static int shadow_fbo; - private static int shadow_depth; + public static int shadow_fbo; + public static int shadow_depth; + + private static final int SHADOW_SIZE = 4096; private static int generateDepthTexture(int width, int height) { @@ -59,14 +63,12 @@ public class DisplayRender public static void init() { - //int size = 1024; + shadow_fbo = GL33.glGenFramebuffers(); + GL33.glBindFramebuffer(GL33.GL_FRAMEBUFFER, shadow_fbo); + GL33.glDrawBuffer(GL33.GL_NONE); + GL33.glReadBuffer(GL33.GL_NONE); - //shadow_fbo = GL33.glGenFramebuffers(); - //GL33.glBindFramebuffer(GL33.GL_FRAMEBUFFER, shadow_fbo); - //GL33.glDrawBuffer(GL33.GL_DEPTH_ATTACHMENT); - //GL33.glBindFramebuffer(GL33.GL_FRAMEBUFFER, 0); - - //shadow_depth = generateDepthTexture(size, size); + shadow_depth = generateDepthTexture(SHADOW_SIZE, SHADOW_SIZE); } public static void render(int w, int h) @@ -97,12 +99,30 @@ public class DisplayRender Main.window.environmentRenderer.use(); GL33.glUniformMatrix4fv(Main.window.glsl_billboard, true, billboard.getArray()); - GL33.glUniformMatrix4fv(Main.window.glsl_projection, true, Camera.camera.projection.getArray()); GL33.glUniformMatrix4fv(Main.window.glsl_rotated, true, rotated.getArray()); + GL33.glUniformMatrix4fv(Main.window.glsl_projection_sun, true, Camera.camera.projection_sun.getArray()); GL33.glUniform1i(Main.window.glsl_time, (int)((System.currentTimeMillis() / 10) % 1000)); Main.world.markPoolDirty(); + // Render from the sun/moons perspective + GL33.glBindFramebuffer(GL33.GL_FRAMEBUFFER, shadow_fbo); + glClear(GL_DEPTH_BUFFER_BIT); + glViewport(0, 0, SHADOW_SIZE, SHADOW_SIZE); + + GL33.glUniformMatrix4fv(Main.window.glsl_projection, true, Camera.camera.projection_sun.getArray()); + LayerGen layergen = Main.world.getLayer().layergen; + double sunPosition = MathHelpers.mod(layergen.getSunPosition(), 360); + + if(layergen.hasSun() && sunPosition > 0 && sunPosition < 180) { + Main.world.render(camera); + } + + // Render from the player perspective + GL33.glBindFramebuffer(GL33.GL_FRAMEBUFFER, 0); + glViewport(0, 0, w, h); + + GL33.glUniformMatrix4fv(Main.window.glsl_projection, true, Camera.camera.projection.getArray()); Main.world.render(camera); player.chunk = Main.world.getLayer().getChunk(player.getPos().xz()); diff --git a/src/projectzombie/display/DisplayWindow.java b/src/projectzombie/display/DisplayWindow.java index 69f0cf7..43b9b29 100755 --- a/src/projectzombie/display/DisplayWindow.java +++ b/src/projectzombie/display/DisplayWindow.java @@ -45,6 +45,7 @@ public class DisplayWindow implements IMainloopTask public int glsl_tex_cut; public int glsl_model; public int glsl_projection; + public int glsl_projection_sun; public int glsl_rotated; public int glsl_billboard; public int glsl_time; @@ -124,6 +125,7 @@ public class DisplayWindow implements IMainloopTask glsl_model = GL33.glGetUniformLocation(environmentRenderer.program, "model"); glsl_rotated = GL33.glGetUniformLocation(environmentRenderer.program, "rotated"); glsl_projection = GL33.glGetUniformLocation(environmentRenderer.program, "projection"); + glsl_projection_sun = GL33.glGetUniformLocation(environmentRenderer.program, "projection_sun"); glsl_time = GL33.glGetUniformLocation(environmentRenderer.program, "time"); glsl_tex_cut = GL33.glGetUniformLocation(environmentRenderer.program, "tex_cut"); glsl_color = GL33.glGetUniformLocation(environmentRenderer.program, "color"); @@ -138,9 +140,11 @@ public class DisplayWindow implements IMainloopTask int glsl_atlas = GL33.glGetUniformLocation(environmentRenderer.program, "atlas"); int glsl_lightmap = GL33.glGetUniformLocation(environmentRenderer.program, "lightmap"); + int glsl_depthmap = GL33.glGetUniformLocation(environmentRenderer.program, "depthmap"); GL33.glUniform1i(glsl_atlas, 0); GL33.glUniform1i(glsl_lightmap, 1); + GL33.glUniform1i(glsl_depthmap, 2); effectRenderer = new GraphicsShader("/resources/shader/effectRenderer"); effectRenderer.use(); @@ -152,6 +156,8 @@ public class DisplayWindow implements IMainloopTask glsl_effect_red_freq = GL33.glGetUniformLocation(effectRenderer.program, "red_freq"); glsl_effect_chill = GL33.glGetUniformLocation(effectRenderer.program, "chill"); + //GL33.glUniform1i(GL33.glGetUniformLocation(effectRenderer.program, "shadowMap"), 2); + effect_vao = GL33.glGenVertexArrays(); GL33.glBindVertexArray(effect_vao); @@ -199,12 +205,20 @@ public class DisplayWindow implements IMainloopTask GL33.glActiveTexture(GL33.GL_TEXTURE1); GL33.glBindTexture(GL33.GL_TEXTURE_2D, DisplayLighting.lightmap); + // Bind the shadow depth map + GL33.glActiveTexture(GL33.GL_TEXTURE2); + GL33.glBindTexture(GL33.GL_TEXTURE_2D, DisplayRender.shadow_depth); + // Render everything DisplayRender.render(w[0], h[0]); // Use the effect shader effectRenderer.use(); + // Bind the shadow depth map + GL33.glActiveTexture(GL33.GL_TEXTURE0); + GL33.glBindTexture(GL33.GL_TEXTURE_2D, DisplayRender.shadow_depth); + // Send extra data to the shader if(!Main.player.dead && Main.menu.doGameloop) { GL33.glUniform1i(glsl_effect_time, (int)System.currentTimeMillis()); diff --git a/src/projectzombie/init/Models.java b/src/projectzombie/init/Models.java index 66216e6..da3eb04 100755 --- a/src/projectzombie/init/Models.java +++ b/src/projectzombie/init/Models.java @@ -58,7 +58,7 @@ public class Models public static final Model TILE_SAND = new ModelTile(Resources.ATLAS.get("/tile/sand.png")); public static final Model TILE_STONE = new ModelTile(Resources.ATLAS.get("/tile/stone.png")); public static final Model TILE_DIRT = new ModelTile(Resources.ATLAS.get("/tile/dirt.png")); - public static final Model TILE_ROCK = new ModelPlayerHead();//new ModelRock(Resources.ATLAS.get("/tile/rock.png")); + public static final Model TILE_ROCK = new ModelRock(Resources.ATLAS.get("/tile/rock.png")); public static final Model TILE_ROCK_ICE = new ModelRock(Resources.ATLAS.get("/tile/rock_ice.png")); public static final Model TILE_ROCK_SANDSTONE = new ModelRock(Resources.ATLAS.get("/tile/rock_sandstone.png")); public static final Model TILE_LADDER = new ModelVertical(Resources.ATLAS.get("/tile/ladder.png")); diff --git a/src/projectzombie/init/Resources.java b/src/projectzombie/init/Resources.java index ec27f55..22614f7 100755 --- a/src/projectzombie/init/Resources.java +++ b/src/projectzombie/init/Resources.java @@ -28,7 +28,13 @@ public class Resources HIT_OGG_1.load(); HIT_OGG_2.load(); + WALK_STONE_0.load(); + WALK_STONE_1.load(); + WALK_STONE_2.load(); + WALK_STONE_3.load(); + EXPLOSION_OGG.load(); + FUSE_OGG.load(); } public static TextureAtlas3D ATLAS; @@ -49,5 +55,11 @@ public class Resources public static final Resource HIT_OGG_1 = new Resource("/sound/hit1.ogg"); public static final Resource HIT_OGG_2 = new Resource("/sound/hit2.ogg"); + public static final Resource WALK_STONE_0 = new Resource("/sound/walk_stone_0.ogg"); + public static final Resource WALK_STONE_1 = new Resource("/sound/walk_stone_1.ogg"); + public static final Resource WALK_STONE_2 = new Resource("/sound/walk_stone_2.ogg"); + public static final Resource WALK_STONE_3 = new Resource("/sound/walk_stone_3.ogg"); + public static final Resource EXPLOSION_OGG = new Resource("/sound/explosion.ogg"); + public static final Resource FUSE_OGG = new Resource("/sound/fuse.ogg"); } diff --git a/src/projectzombie/world/World.java b/src/projectzombie/world/World.java index 58bc850..ae80d88 100755 --- a/src/projectzombie/world/World.java +++ b/src/projectzombie/world/World.java @@ -59,7 +59,7 @@ public class World implements IBdfClassManager // Re-generate the particle pool if the pool has changed if(pool_dirty) { - pool_particle_count = loaded.getParticlePoolSize() + 1; + pool_particle_count = loaded.getParticlePoolSize(); boolean changed = false; if(pool_particle_count > pool_size) diff --git a/src/projectzombie/world/layer/layergen/LayerGen.java b/src/projectzombie/world/layer/layergen/LayerGen.java index 98ca1b5..8086dd9 100755 --- a/src/projectzombie/world/layer/layergen/LayerGen.java +++ b/src/projectzombie/world/layer/layergen/LayerGen.java @@ -39,4 +39,12 @@ public abstract class LayerGen implements IMap2D public void tickLayer(Layer layer, Chunk chunk) { } + + public boolean hasSun() { + return false; + } + + public double getSunPosition() { + return 0; + } } diff --git a/src/projectzombie/world/layer/layergen/LayerGenEarth.java b/src/projectzombie/world/layer/layergen/LayerGenEarth.java index 0e985f5..d7a0c71 100755 --- a/src/projectzombie/world/layer/layergen/LayerGenEarth.java +++ b/src/projectzombie/world/layer/layergen/LayerGenEarth.java @@ -202,7 +202,17 @@ public class LayerGenEarth extends LayerGen } private double getEarthLight() { - return MathHelpers.sin(GameTimer.getTime() / 14400.0); + return MathHelpers.sin(((MathHelpers.TWO_PI * (GameTimer.getTime() % 720000)) / 72000.0) + MathHelpers.PI/4); + } + + @Override + public boolean hasSun() { + return true; + } + + @Override + public double getSunPosition() { + return (GameTimer.getTime() % 720000) / 200.0 + 45; } @Override @@ -211,9 +221,10 @@ public class LayerGenEarth extends LayerGen double light = getEarthLight(); ColorRange daylightRange = new ColorRange( - new Vec3d(60/255.0, 74/255.0, 68/255.0), + new Vec3d(31/255.0, 15/255.0, 0), new Vec3d(205/255.0, 191/255.0, 162/255.0)); - return new ColorRange(new Vec3d(0, 0, 0), daylightRange.getColor(light)); + Vec3d daylight = daylightRange.getColor(light); + return new ColorRange(daylight.multiply(7/8.0), daylight); } } diff --git a/src/resources/shader/environmentRenderer.fsh b/src/resources/shader/environmentRenderer.fsh index ded2fcb..bd2feb4 100644 --- a/src/resources/shader/environmentRenderer.fsh +++ b/src/resources/shader/environmentRenderer.fsh @@ -3,7 +3,7 @@ in vec3 pPos; in vec3 pTexture; in vec3 pLightMapPos; -in vec4 pGLPosition; +in vec3 pSunDepth; flat in int pFlags; flat in float pFade; @@ -13,6 +13,7 @@ out vec4 FragColor; uniform sampler3D atlas; uniform sampler2D lightmap; +uniform sampler2D depthmap; uniform vec3 lighting_day_low; uniform vec3 lighting_day_high; @@ -30,6 +31,8 @@ vec3 color_grass_hot_dry = vec3(1, 0.6, 0); vec3 color_grass_cold_wet = vec3(0.075, 0.533, 0.047); vec3 color_grass_cold_dry = vec3(0.812, 0.761, 0); +float depth_c = 0.001; + float map(float x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } @@ -45,7 +48,7 @@ vec3 biggest(vec3 a, vec3 b) { } float scaleLight(float level) { - return pow(level, 1.5); + return level * level; } float smoothStep(float a) { @@ -66,7 +69,18 @@ void main() map(pLightMapPos.x, lightmap_offset.x, lightmap_offset.x + lightmap_size.x, 0, 1), map(pLightMapPos.z, lightmap_offset.y, lightmap_offset.y + lightmap_size.y, 0, 1))); - vec3 light_day = mapVec(max(0, scaleLight(light.r)), 0, 1, lighting_day_low, lighting_day_high); + + vec2 sunDepthTexPos = pSunDepth.xy * 0.5 + 0.5; + float shadowAmount = 0; + + //shadowAmount += pSunDepth.z < (texture(depthmap, sunDepthTexPos + vec2( 0.5, 0.5) / 2048.0).r * 2 - 1 + depth_c) ? 1 : 0; + //shadowAmount += pSunDepth.z < (texture(depthmap, sunDepthTexPos + vec2( 0.5, -0.5) / 2048.0).r * 2 - 1 + depth_c) ? 1 : 0; + //shadowAmount += pSunDepth.z < (texture(depthmap, sunDepthTexPos + vec2(-0.5, 0.5) / 2048.0).r * 2 - 1 + depth_c) ? 1 : 0; + //shadowAmount += pSunDepth.z < (texture(depthmap, sunDepthTexPos + vec2(-0.5, -0.5) / 2048.0).r * 2 - 1 + depth_c) ? 1 : 0; + + shadowAmount += pSunDepth.z < (texture(depthmap, sunDepthTexPos).r * 2 - 1 + depth_c) ? 1 : 0; + + vec3 light_day = mapVec(shadowAmount, 0, 1, lighting_day_low, lighting_day_high); vec3 light_src = vec3(1, 1, 1) * (scaleLight(max(0, light.g)) - abs(pLightMapPos.y) * 0.1); vec4 rgb = vec4((pRGB % 64) / 64.0, ((pRGB >> 6) % 64) / 64.0, ((pRGB >> 12) % 64) / 64.0, 1); @@ -74,15 +88,16 @@ void main() smoothStep(light.b), smoothStep(light.a), color_grass_cold_dry, color_grass_hot_dry, color_grass_cold_wet, color_grass_hot_wet), 1); - - FragColor = texture(atlas, pTexture) * (mod(int(pFlags / 4), 2) == 1 ? color_grass : vec4(1,1,1,1)) * - color * vec4(biggest(light_day, light_src), pFade) * (mod(int(pFlags / 2), 2) == 1 ? rgb : vec4(1, 1, 1, 1)); float saturation = contrast * 1.6 + 1; - - FragColor.x = min(1, FragColor.x * saturation + contrast); - FragColor.y = min(1, FragColor.y * saturation + contrast); - FragColor.z = min(1, FragColor.z * saturation + contrast); + + FragColor = texture(atlas, pTexture) * (mod(int(pFlags / 4), 2) == 1 ? color_grass : vec4(1,1,1,1)) + * color * vec4(biggest(light_day, light_src), pFade) * (mod(int(pFlags / 2), 2) == 1 ? rgb : vec4(1, 1, 1, 1)) + * saturation + contrast; + + FragColor.r = min(1, FragColor.r); + FragColor.g = min(1, FragColor.g); + FragColor.b = min(1, FragColor.b); discard(FragColor.a == 0 || (pPos.x > tex_cut.y && tex_cut.x > 0.5)); } \ No newline at end of file diff --git a/src/resources/shader/environmentRenderer.vsh b/src/resources/shader/environmentRenderer.vsh index a996591..820ca78 100644 --- a/src/resources/shader/environmentRenderer.vsh +++ b/src/resources/shader/environmentRenderer.vsh @@ -7,15 +7,16 @@ layout (location = 3) in vec3 aOffset; layout (location = 4) in vec2 aAnimate; layout (location = 5) in vec3 aFlags; +out vec3 pSunDepth; out vec3 pLightMapPos; out vec3 pTexture; out vec3 pPos; -out vec4 pGLPosition; flat out int pFlags; flat out float pFade; flat out int pRGB; +uniform mat4 projection_sun; uniform mat4 billboard; uniform mat4 projection; uniform mat4 model; @@ -62,8 +63,8 @@ void main() vec4 pos = vec4(aPos, 1) * (mod(type >> 3, 2) == 1 ? billboard : (mod(type, 2) == 1 ? rotated : mat4(1))) * translate(aOffset) * model; - pGLPosition = pos * projection; gl_Position = pos * projection; + pSunDepth = (pos * projection_sun).xyz; pLightMapPos = pos.xyz; pTexture = vec3(aTex.x, getTexY(), aTex.z); diff --git a/src/resources/sound/fuse.ogg b/src/resources/sound/fuse.ogg new file mode 100644 index 0000000..4977722 Binary files /dev/null and b/src/resources/sound/fuse.ogg differ diff --git a/src/resources/sound/walk_stone_0.ogg b/src/resources/sound/walk_stone_0.ogg new file mode 100644 index 0000000..5787d93 Binary files /dev/null and b/src/resources/sound/walk_stone_0.ogg differ diff --git a/src/resources/sound/walk_stone_1.ogg b/src/resources/sound/walk_stone_1.ogg new file mode 100644 index 0000000..48d70f8 Binary files /dev/null and b/src/resources/sound/walk_stone_1.ogg differ diff --git a/src/resources/sound/walk_stone_2.ogg b/src/resources/sound/walk_stone_2.ogg new file mode 100644 index 0000000..2563498 Binary files /dev/null and b/src/resources/sound/walk_stone_2.ogg differ diff --git a/src/resources/sound/walk_stone_3.ogg b/src/resources/sound/walk_stone_3.ogg new file mode 100644 index 0000000..d69e016 Binary files /dev/null and b/src/resources/sound/walk_stone_3.ogg differ