From 4f9cb191c429b2ce58eb4b5df01852a7581cb494 Mon Sep 17 00:00:00 2001 From: josua Date: Mon, 22 Jun 2020 12:22:11 +1000 Subject: [PATCH] Added smooth lighting --- src/projectzombie/Main.java | 5 +- src/projectzombie/display/DisplayRender.java | 10 +- .../display/DisplayRenderUI.java | 8 +- .../display/DisplayStatsEventHandler.java | 2 + src/projectzombie/display/DisplayWindow.java | 16 ++-- .../display/lighting/TileLighting.java | 89 +++++++++++++----- src/projectzombie/entity/EntityContainer.java | 3 +- src/projectzombie/entity/EntityTnt.java | 1 - .../entity/particle/ParticleBlood.java | 2 - .../entity/particle/ParticleSpark.java | 1 - .../entity/particle/ParticleWater.java | 1 - .../entity/player/EntityPlayer.java | 13 ++- src/projectzombie/input/KeyCallback.java | 28 +++++- src/projectzombie/items/ItemAmmo.java | 5 - src/projectzombie/menu/gui/Button.java | 2 - src/projectzombie/menu/gui/Label.java | 2 - src/projectzombie/menu/gui/Overlay.java | 1 - src/projectzombie/text/Text.java | 3 - src/projectzombie/util/gl/GlHelpers.java | 19 ---- src/projectzombie/util/math/ColorRange.java | 12 +-- src/projectzombie/worker/Worker.java | 36 ++++++- src/projectzombie/world/World.java | 6 +- src/projectzombie/world/chunk/Chunk.java | 38 +++++--- src/resources/shader/environmentRenderer.fsh | 2 +- src/resources/shader/environmentRenderer.vsh | 17 ++-- worker.jar | Bin 64154 -> 64420 bytes 26 files changed, 207 insertions(+), 115 deletions(-) diff --git a/src/projectzombie/Main.java b/src/projectzombie/Main.java index b2bd1fa..09bb4e6 100755 --- a/src/projectzombie/Main.java +++ b/src/projectzombie/Main.java @@ -76,7 +76,7 @@ public class Main LayerGenerators.init(); // Create the display - window = new DisplayWindow("Project Zombie"); + window = new DisplayWindow(); window.init(); // Load the resources @@ -109,5 +109,8 @@ public class Main // Start the mainloop menu = new MenuMain(); mainloop.start(); + + // Kill the worker thread + worker.kill(); } } diff --git a/src/projectzombie/display/DisplayRender.java b/src/projectzombie/display/DisplayRender.java index f3ba990..2a0a8ee 100755 --- a/src/projectzombie/display/DisplayRender.java +++ b/src/projectzombie/display/DisplayRender.java @@ -10,7 +10,9 @@ import org.lwjgl.opengl.GL33; import gl_engine.matrix.Matrix4; import projectzombie.Main; import projectzombie.entity.player.EntityPlayer; +import projectzombie.init.Layers; import projectzombie.model.Model; +import projectzombie.util.math.ColorRange; import projectzombie.world.chunk.ChunkEventHandler; public class DisplayRender @@ -25,9 +27,11 @@ public class DisplayRender GL33.glUniform4f(Main.window.glsl_color, 1, 1, 1, 1); GL33.glUniform2f(Main.window.glsl_tex_cut, 0, 0); - GL33.glUniform3f(Main.window.glsl_day_low, 0.1f, 0, 0); - GL33.glUniform3f(Main.window.glsl_day_high, 1, 1, 1); - GL33.glUniform3f(Main.window.glsl_src_low, 0, 0.1f, 0); + ColorRange range = Main.world.getLayer().layergen.getLightLevel(); + + GL33.glUniform3f(Main.window.glsl_day_low, (float)range.min.x, (float)range.min.y, (float)range.min.z); + GL33.glUniform3f(Main.window.glsl_day_high, (float)range.max.x, (float)range.max.y, (float)range.max.z); + GL33.glUniform3f(Main.window.glsl_src_low, 0, 0, 0); GL33.glUniform3f(Main.window.glsl_src_high, 1, 1, 1); if(Main.menu.doGameRender) diff --git a/src/projectzombie/display/DisplayRenderUI.java b/src/projectzombie/display/DisplayRenderUI.java index 933a823..df35041 100755 --- a/src/projectzombie/display/DisplayRenderUI.java +++ b/src/projectzombie/display/DisplayRenderUI.java @@ -90,13 +90,17 @@ public class DisplayRenderUI camera = Matrix4.identity(); projection = Matrix4.scale(new Vec3d(0.1/GlHelpers.getAspectRatio(), 0.1, 1)); + GL33.glUniform3f(Main.window.glsl_day_low, 1, 1, 1); + GL33.glUniform3f(Main.window.glsl_day_high, 1, 1, 1); + GL33.glUniform3f(Main.window.glsl_src_low, 1, 1, 1); + GL33.glUniform3f(Main.window.glsl_src_high, 1, 1, 1); + GL33.glUniformMatrix4fv(Main.window.glsl_projection, true, projection.getArray()); GL33.glUniformMatrix4fv(Main.window.glsl_camera, true, camera.getArray()); GL33.glDisable(GL33.GL_DEPTH_TEST); - if(Main.menu.doGameRender && Main.menu.showIngameGUI) - { + if(Main.menu.doGameRender && Main.menu.showIngameGUI) { renderGameGui(); } diff --git a/src/projectzombie/display/DisplayStatsEventHandler.java b/src/projectzombie/display/DisplayStatsEventHandler.java index b3d3e48..ec6af02 100755 --- a/src/projectzombie/display/DisplayStatsEventHandler.java +++ b/src/projectzombie/display/DisplayStatsEventHandler.java @@ -27,6 +27,8 @@ public class DisplayStatsEventHandler implements IMainloopTask fps = DisplayWindow.fps; DisplayWindow.fps = 0; + + Main.worker.updateTime(); } diff --git a/src/projectzombie/display/DisplayWindow.java b/src/projectzombie/display/DisplayWindow.java index 19100fc..2ff9ac9 100755 --- a/src/projectzombie/display/DisplayWindow.java +++ b/src/projectzombie/display/DisplayWindow.java @@ -1,12 +1,9 @@ package projectzombie.display; import static org.lwjgl.opengl.GL11.GL_FLOAT; -import static org.lwjgl.opengl.GL11.GL_RGBA; -import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE; import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray; import static org.lwjgl.opengl.GL20.glVertexAttribPointer; -import java.nio.ByteBuffer; import java.nio.IntBuffer; import org.lwjgl.BufferUtils; @@ -15,7 +12,6 @@ import org.lwjgl.opengl.GL33; import gl_engine.graphics.GraphicsHelpers; import gl_engine.graphics.GraphicsShader; -import gl_engine.texture.TextureRef3D; import mainloop.task.IMainloopTask; import projectzombie.display.lighting.TileLighting; import projectzombie.init.Resources; @@ -27,11 +23,9 @@ import projectzombie.input.KeyCharCallback; import projectzombie.input.MouseButtonCallback; import projectzombie.input.ScrollWheelCallback; import projectzombie.mainloop.MainloopEventHandler; -import projectzombie.model.Model; public class DisplayWindow implements IMainloopTask { - private String name; private long window; private long monitor; private int width; @@ -58,6 +52,9 @@ public class DisplayWindow implements IMainloopTask public int glsl_src_low; public int glsl_src_high; + public int glsl_lightmap_offset; + public int glsl_lightmap_size; + public int getWidth() { return this.width; } @@ -74,10 +71,6 @@ public class DisplayWindow implements IMainloopTask height = h; } - public DisplayWindow(String name) { - this.name = name; - } - public void init() { // Initialize GLFW @@ -132,6 +125,9 @@ public class DisplayWindow implements IMainloopTask glsl_src_low = GL33.glGetUniformLocation(environmentRenderer.program, "lighting_src_low"); glsl_src_high = GL33.glGetUniformLocation(environmentRenderer.program, "lighting_src_high"); + glsl_lightmap_offset = GL33.glGetUniformLocation(environmentRenderer.program, "lightmap_offset"); + glsl_lightmap_size = GL33.glGetUniformLocation(environmentRenderer.program, "lightmap_size"); + int glsl_atlas = GL33.glGetUniformLocation(environmentRenderer.program, "atlas"); int glsl_lightmap = GL33.glGetUniformLocation(environmentRenderer.program, "lightmap"); diff --git a/src/projectzombie/display/lighting/TileLighting.java b/src/projectzombie/display/lighting/TileLighting.java index 45d1c00..323a856 100755 --- a/src/projectzombie/display/lighting/TileLighting.java +++ b/src/projectzombie/display/lighting/TileLighting.java @@ -1,10 +1,5 @@ package projectzombie.display.lighting; -import static org.lwjgl.opengl.GL11.GL_RGBA; -import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE; -import static org.lwjgl.opengl.GL12.GL_TEXTURE_3D; -import static org.lwjgl.opengl.GL12.glTexImage3D; - import java.nio.ByteBuffer; import java.util.Arrays; @@ -13,14 +8,10 @@ import org.lwjgl.opengl.GL33; import bdf.types.BdfNamedList; import bdf.types.BdfObject; import gl_engine.MathHelpers; -import gl_engine.range.Range4i; import gl_engine.vec.Vec2i; -import gl_engine.vec.Vec4i; -import mainloop.task.IMainloopTask; import projectzombie.Main; import projectzombie.display.Camera; import projectzombie.entity.player.EntityPlayer; -import projectzombie.mainloop.MainloopHelpers; import projectzombie.util.math.TileState; import projectzombie.world.chunk.Chunk; import projectzombie.world.chunk.ChunkEventHandler; @@ -28,30 +19,71 @@ import projectzombie.world.layer.Layer; public class TileLighting { - public static boolean lighting_dirty = false; + private static class LightingTask { + float[] b; + int w, h; + int x, y; + } + + private static boolean lighting_dirty = false; public static int lightmap; + private static LightingTask task; + + public static void setDirty() { + lighting_dirty = true; + } + + public synchronized static LightingTask getTask() { + LightingTask t = task; + task = null; + return t; + } + + public synchronized static void setTask(LightingTask task) { + TileLighting.task = task; + } + public TileLighting() { lightmap = GL33.glGenTextures(); } public static void update() { + { + LightingTask task = getTask(); + + if(task != null) + { + GL33.glBindTexture(GL33.GL_TEXTURE_2D, lightmap); + GL33.glTexImage2D(GL33.GL_TEXTURE_2D, 0, GL33.GL_RGB, task.w, task.h, 0, GL33.GL_RGB, GL33.GL_FLOAT, task.b); + GL33.glGenerateMipmap(GL33.GL_TEXTURE_2D); + + Main.window.environmentRenderer.use(); + GL33.glUniform2f(Main.window.glsl_lightmap_offset, task.x * 16 - 1, task.y * 16 - 1); + GL33.glUniform2f(Main.window.glsl_lightmap_size, task.w, task.h); + } + } + if(Camera.camera == null) return; if(!ChunkEventHandler.loaded) return; Layer layer = Main.world.getLayer(); EntityPlayer player = Main.player; - boolean dirty = false; - for(int cx=-Chunk.RENDER_DISTANCE;cx<=Chunk.RENDER_DISTANCE;cx++) { - for(int cy=-Chunk.RENDER_DISTANCE;cy<=Chunk.RENDER_DISTANCE;cy++) { - Vec2i cpos = new Vec2i( - cx + MathHelpers.floor(player.pos.x / 16), - cy + MathHelpers.floor(player.pos.y / 16)); - Chunk chunk = layer.chunks.get(cpos); - if(chunk.isLightDirty()) { - chunk.resetLightDirty(); - dirty = true; + boolean dirty = lighting_dirty; + + if(!dirty) + { + for(int cx=-Chunk.RENDER_DISTANCE;cx<=Chunk.RENDER_DISTANCE;cx++) { + for(int cy=-Chunk.RENDER_DISTANCE;cy<=Chunk.RENDER_DISTANCE;cy++) { + Vec2i cpos = new Vec2i( + cx + MathHelpers.floor(player.pos.x / 16), + cy + MathHelpers.floor(player.pos.y / 16)); + Chunk chunk = layer.chunks.get(cpos); + if(chunk.isLightDirty()) { + chunk.resetLightDirty(); + dirty = true; + } } } } @@ -60,6 +92,7 @@ public class TileLighting return; } + lighting_dirty = false; int size = (Chunk.RENDER_DISTANCE * 2 + 1) * 16; float[] lights = new float[size * size * 3]; @@ -102,7 +135,9 @@ public class TileLighting } } - Main.worker.processLighting(lights, size, size); + Main.worker.processLighting(lights, size, size, + MathHelpers.floor(player.pos.x / 16) - Chunk.RENDER_DISTANCE, + MathHelpers.floor(player.pos.y / 16) - Chunk.RENDER_DISTANCE); } public static void updateLighting(BdfObject bdf) @@ -111,6 +146,8 @@ public class TileLighting float[] light = nl.get("light").getFloatArray(); int width = nl.get("w").getInteger(); int height = nl.get("h").getInteger(); + int x = nl.get("x").getInteger(); + int y = nl.get("y").getInteger(); float[] pixels = new float[width*height*3]; @@ -119,7 +156,13 @@ public class TileLighting pixels[i*3+1] = light[i*2+1]; } - GL33.glBindTexture(GL33.GL_TEXTURE_2D, lightmap); - GL33.glTexImage2D(GL33.GL_TEXTURE_2D, 0, GL33.GL_RGB, width, height, 0, GL33.GL_RGB, GL33.GL_FLOAT, light); + LightingTask task = new LightingTask(); + task.w = width; + task.h = height; + task.b = pixels; + task.x = x; + task.y = y; + + setTask(task); } } diff --git a/src/projectzombie/entity/EntityContainer.java b/src/projectzombie/entity/EntityContainer.java index ea28103..98b3d3f 100644 --- a/src/projectzombie/entity/EntityContainer.java +++ b/src/projectzombie/entity/EntityContainer.java @@ -1,6 +1,5 @@ package projectzombie.entity; -import bdf.classes.IBdfClassManager; import bdf.types.BdfArray; import bdf.types.BdfNamedList; import bdf.types.BdfObject; @@ -86,7 +85,7 @@ public class EntityContainer extends Entity implements EntityHoldsEntities { Entity e = entities[i]; - if(e.getID() == -1) { + if(e == null || e.getID() == -1) { continue; } diff --git a/src/projectzombie/entity/EntityTnt.java b/src/projectzombie/entity/EntityTnt.java index b0f7673..31014d1 100755 --- a/src/projectzombie/entity/EntityTnt.java +++ b/src/projectzombie/entity/EntityTnt.java @@ -5,7 +5,6 @@ import bdf.types.BdfObject; import gl_engine.MathHelpers; import gl_engine.vec.Vec2d; import gl_engine.vec.Vec3d; -import projectzombie.entity.particle.ParticleSmoke; import projectzombie.entity.particle.ParticleSpark; import projectzombie.init.Models; import projectzombie.model.Model; diff --git a/src/projectzombie/entity/particle/ParticleBlood.java b/src/projectzombie/entity/particle/ParticleBlood.java index 469ff60..5840781 100755 --- a/src/projectzombie/entity/particle/ParticleBlood.java +++ b/src/projectzombie/entity/particle/ParticleBlood.java @@ -1,7 +1,5 @@ package projectzombie.entity.particle; -import java.util.Random; - import gl_engine.MathHelpers; import gl_engine.vec.Vec2d; import gl_engine.vec.Vec3d; diff --git a/src/projectzombie/entity/particle/ParticleSpark.java b/src/projectzombie/entity/particle/ParticleSpark.java index d002e99..17cb310 100755 --- a/src/projectzombie/entity/particle/ParticleSpark.java +++ b/src/projectzombie/entity/particle/ParticleSpark.java @@ -2,7 +2,6 @@ package projectzombie.entity.particle; import java.util.Random; -import gl_engine.vec.Vec2d; import gl_engine.vec.Vec3d; import projectzombie.entity.EntityHeight; import projectzombie.entity.EntityParticle; diff --git a/src/projectzombie/entity/particle/ParticleWater.java b/src/projectzombie/entity/particle/ParticleWater.java index 7eff816..a41974f 100755 --- a/src/projectzombie/entity/particle/ParticleWater.java +++ b/src/projectzombie/entity/particle/ParticleWater.java @@ -9,7 +9,6 @@ import projectzombie.entity.EntityHeight; import projectzombie.entity.EntityParticle; import projectzombie.init.Models; import projectzombie.model.Model; -import projectzombie.util.math.random.RandomHelpers; import projectzombie.world.chunk.Chunk; import projectzombie.world.layer.Layer; diff --git a/src/projectzombie/entity/player/EntityPlayer.java b/src/projectzombie/entity/player/EntityPlayer.java index 2efcc71..c0aec59 100755 --- a/src/projectzombie/entity/player/EntityPlayer.java +++ b/src/projectzombie/entity/player/EntityPlayer.java @@ -4,8 +4,10 @@ import bdf.types.BdfNamedList; import bdf.types.BdfObject; import gl_engine.MathHelpers; import gl_engine.vec.Vec2d; +import gl_engine.vec.Vec2i; import mainloop.task.IMainloopTask; import projectzombie.Main; +import projectzombie.display.lighting.TileLighting; import projectzombie.entity.Entity; import projectzombie.entity.EntityAlive; import projectzombie.entity.EntityBullet; @@ -16,7 +18,6 @@ import projectzombie.entity.particle.ParticleBreak; import projectzombie.init.Items; import projectzombie.init.Models; import projectzombie.inventory.Inventory; -import projectzombie.items.spawner.ItemSpawnZombie; import projectzombie.menu.MenuDeath; import projectzombie.model.Model; import projectzombie.settings.Cheats; @@ -53,6 +54,8 @@ public class EntityPlayer extends Entity implements EntityAlive, EntityInventory public double angle; public double speed; + private Vec2i last_chunk; + public EntityPlayer(BdfObject bdf) { super(bdf); } @@ -106,7 +109,8 @@ public class EntityPlayer extends Entity implements EntityAlive, EntityInventory inventory = new Inventory(10); inventory.addItem(new ItemStack(Items.SPAWN_ZOMBIE, 99, (short)0)); - inventory.addItem(new ItemStack(Items.AMMO, 999, (short)0)); + inventory.addItem(new ItemStack(Items.AMMO, 99, (short)0)); + inventory.addItem(new ItemStack(Items.LANTERN, 99, (short)0)); } @Override @@ -132,6 +136,11 @@ public class EntityPlayer extends Entity implements EntityAlive, EntityInventory { chunk = layer.getChunk(pos); + if(chunk != null && (last_chunk == null || !chunk.c_pos.equal(last_chunk))) { + last_chunk = chunk.c_pos; + TileLighting.setDirty(); + } + if(dead) return; // Handle player deaths diff --git a/src/projectzombie/input/KeyCallback.java b/src/projectzombie/input/KeyCallback.java index 5dea276..94caf20 100755 --- a/src/projectzombie/input/KeyCallback.java +++ b/src/projectzombie/input/KeyCallback.java @@ -1,7 +1,31 @@ package projectzombie.input; -import static org.lwjgl.glfw.GLFW.*; -import static projectzombie.input.GameInput.*; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_0; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_1; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_2; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_3; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_4; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_5; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_6; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_7; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_8; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_9; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_A; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_D; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_E; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_ESCAPE; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_F11; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_Q; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_S; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_W; +import static org.lwjgl.glfw.GLFW.GLFW_RELEASE; +import static projectzombie.input.GameInput.backButton_last; +import static projectzombie.input.GameInput.fireGun; +import static projectzombie.input.GameInput.moveDown; +import static projectzombie.input.GameInput.moveLeft; +import static projectzombie.input.GameInput.moveRight; +import static projectzombie.input.GameInput.moveUp; +import static projectzombie.input.GameInput.move_last; import org.lwjgl.glfw.GLFWKeyCallbackI; diff --git a/src/projectzombie/items/ItemAmmo.java b/src/projectzombie/items/ItemAmmo.java index 7a3ca2e..c3297e9 100755 --- a/src/projectzombie/items/ItemAmmo.java +++ b/src/projectzombie/items/ItemAmmo.java @@ -1,12 +1,7 @@ package projectzombie.items; -import projectzombie.entity.Entity; -import projectzombie.entity.player.EntityPlayer; import projectzombie.init.Models; import projectzombie.model.ModelItem; -import projectzombie.util.math.ItemStack; -import projectzombie.world.chunk.Chunk; -import projectzombie.world.layer.Layer; public class ItemAmmo extends Item { diff --git a/src/projectzombie/menu/gui/Button.java b/src/projectzombie/menu/gui/Button.java index 96d9857..0aa6315 100755 --- a/src/projectzombie/menu/gui/Button.java +++ b/src/projectzombie/menu/gui/Button.java @@ -4,10 +4,8 @@ import gl_engine.matrix.Matrix4; import gl_engine.vec.Vec2d; import gl_engine.vec.Vec3d; import projectzombie.Main; -import projectzombie.display.DisplayRenderUI; import projectzombie.init.Models; import projectzombie.input.InputMode; -import projectzombie.model.Model; import projectzombie.model.ModelGui; import projectzombie.text.Text; import projectzombie.util.gl.GlHelpers; diff --git a/src/projectzombie/menu/gui/Label.java b/src/projectzombie/menu/gui/Label.java index c207dda..532bfc0 100755 --- a/src/projectzombie/menu/gui/Label.java +++ b/src/projectzombie/menu/gui/Label.java @@ -2,8 +2,6 @@ package projectzombie.menu.gui; import gl_engine.vec.Vec2d; import gl_engine.vec.Vec3d; -import projectzombie.text.Text; -import projectzombie.util.gl.GlHelpers; public class Label implements GUIComponent { diff --git a/src/projectzombie/menu/gui/Overlay.java b/src/projectzombie/menu/gui/Overlay.java index 7dd31a9..f060412 100755 --- a/src/projectzombie/menu/gui/Overlay.java +++ b/src/projectzombie/menu/gui/Overlay.java @@ -3,7 +3,6 @@ package projectzombie.menu.gui; import gl_engine.vec.Vec2d; import gl_engine.vec.Vec3d; import gl_engine.vec.Vec4d; -import projectzombie.util.gl.GlHelpers; public class Overlay implements GUIComponent { diff --git a/src/projectzombie/text/Text.java b/src/projectzombie/text/Text.java index efb999e..c03580d 100755 --- a/src/projectzombie/text/Text.java +++ b/src/projectzombie/text/Text.java @@ -1,12 +1,9 @@ package projectzombie.text; import gl_engine.matrix.Matrix4; -import gl_engine.vec.Vec2d; -import projectzombie.Main; import projectzombie.init.Resources; import projectzombie.model.Model; import projectzombie.model.ModelGui; -import projectzombie.util.gl.GlHelpers; public class Text { diff --git a/src/projectzombie/util/gl/GlHelpers.java b/src/projectzombie/util/gl/GlHelpers.java index ef96467..c54ee93 100755 --- a/src/projectzombie/util/gl/GlHelpers.java +++ b/src/projectzombie/util/gl/GlHelpers.java @@ -1,24 +1,5 @@ package projectzombie.util.gl; -import static org.lwjgl.opengl.GL11.GL_ALPHA; -import static org.lwjgl.opengl.GL11.GL_BLEND; -import static org.lwjgl.opengl.GL11.GL_CULL_FACE; -import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST; -import static org.lwjgl.opengl.GL11.GL_QUADS; -import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D; -import static org.lwjgl.opengl.GL11.glBegin; -import static org.lwjgl.opengl.GL11.glColor3d; -import static org.lwjgl.opengl.GL11.glColor4d; -import static org.lwjgl.opengl.GL11.glDisable; -import static org.lwjgl.opengl.GL11.glEnable; -import static org.lwjgl.opengl.GL11.glEnd; -import static org.lwjgl.opengl.GL11.glPopMatrix; -import static org.lwjgl.opengl.GL11.glPushMatrix; -import static org.lwjgl.opengl.GL11.glRotated; -import static org.lwjgl.opengl.GL11.glTranslated; -import static org.lwjgl.opengl.GL11.glVertex2d; -import static org.lwjgl.opengl.GL11.glVertex3d; - import projectzombie.Main; import projectzombie.display.DisplayRenderUI; diff --git a/src/projectzombie/util/math/ColorRange.java b/src/projectzombie/util/math/ColorRange.java index 08ea94c..34def8b 100755 --- a/src/projectzombie/util/math/ColorRange.java +++ b/src/projectzombie/util/math/ColorRange.java @@ -5,17 +5,17 @@ import gl_engine.vec.Vec3d; public class ColorRange { - Vec3d colorMin, colorMax; + public Vec3d min, max; public ColorRange(Vec3d colorMin, Vec3d colorMax) { - this.colorMin = colorMin; - this.colorMax = colorMax; + this.min = colorMin; + this.max = colorMax; } public Vec3d getColor(double v) { return new Vec3d( - MathHelpers.map(v, 0, 1, colorMin.x, colorMax.x), - MathHelpers.map(v, 0, 1, colorMin.y, colorMax.y), - MathHelpers.map(v, 0, 1, colorMin.z, colorMax.z)); + MathHelpers.map(v, 0, 1, min.x, max.x), + MathHelpers.map(v, 0, 1, min.y, max.y), + MathHelpers.map(v, 0, 1, min.z, max.z)); } } diff --git a/src/projectzombie/worker/Worker.java b/src/projectzombie/worker/Worker.java index 9f51f14..0d3fdc1 100644 --- a/src/projectzombie/worker/Worker.java +++ b/src/projectzombie/worker/Worker.java @@ -2,13 +2,11 @@ package projectzombie.worker; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.io.OutputStream; import java.lang.ProcessBuilder.Redirect; import java.nio.ByteBuffer; import bdf.data.BdfDatabase; -import bdf.types.BdfIndent; import bdf.types.BdfNamedList; import bdf.types.BdfObject; import projectzombie.display.lighting.TileLighting; @@ -21,6 +19,8 @@ public class Worker extends Thread InputStream in; OutputStream out; + boolean running = true; + public Worker() throws IOException { pb = new ProcessBuilder("java", "-jar", "worker.jar"); @@ -36,7 +36,7 @@ public class Worker extends Thread - public void processLighting(float[] lights, int width, int height) + public void processLighting(float[] lights, int width, int height, int x, int y) { BdfObject bdf = new BdfObject(); BdfNamedList nl = bdf.getNamedList(); @@ -44,7 +44,24 @@ public class Worker extends Thread nl.set("light", BdfObject.withFloatArray(lights)); nl.set("w", BdfObject.withInteger(width)); nl.set("h", BdfObject.withInteger(height)); + nl.set("x", BdfObject.withInteger(x)); + nl.set("y", BdfObject.withInteger(y)); + sendData(bdf); + } + + public void updateTime() + { + BdfObject bdf = new BdfObject(); + BdfNamedList nl = bdf.getNamedList(); + nl.set("task", BdfObject.withString("time")); + nl.set("millis", BdfObject.withLong(System.currentTimeMillis())); + + sendData(bdf); + } + + private void sendData(BdfObject bdf) + { byte[] data = bdf.serialize().getBytes(); ByteBuffer size_buff = ByteBuffer.allocate(4); @@ -88,15 +105,24 @@ public class Worker extends Thread case "light": TileLighting.updateLighting(bdf); break; + default: + Thread.sleep(10); } - System.out.println("Hello"); + if(!running) { + return; + } } } - catch(IOException e) + catch(IOException | InterruptedException e) { } } + + public void kill() { + process.destroy(); + running = false; + } } diff --git a/src/projectzombie/world/World.java b/src/projectzombie/world/World.java index 956fd80..ff20f31 100755 --- a/src/projectzombie/world/World.java +++ b/src/projectzombie/world/World.java @@ -8,6 +8,7 @@ import bdf.types.BdfNamedList; import bdf.types.BdfObject; import projectzombie.Main; import projectzombie.display.Camera; +import projectzombie.display.lighting.TileLighting; import projectzombie.entity.player.EntityPlayer; import projectzombie.time.GameTimer; import projectzombie.world.chunk.ChunkEventHandler; @@ -30,8 +31,11 @@ public class World implements IBdfClassManager loaded.spawnRandomEntities(); } - public void setLayer(int id) { + public void setLayer(int id) + { ChunkEventHandler.loaded = false; + TileLighting.setDirty(); + this.loaded = layers.get(id); } diff --git a/src/projectzombie/world/chunk/Chunk.java b/src/projectzombie/world/chunk/Chunk.java index 81f0ac4..1d4627b 100755 --- a/src/projectzombie/world/chunk/Chunk.java +++ b/src/projectzombie/world/chunk/Chunk.java @@ -1,11 +1,8 @@ package projectzombie.world.chunk; import java.util.ArrayList; -import java.util.Iterator; import java.util.Random; -import org.lwjgl.opengl.GL33; - import bdf.classes.IBdfClassManager; import bdf.types.BdfArray; import bdf.types.BdfNamedList; @@ -17,7 +14,6 @@ import gl_engine.texture.TextureRef3D; import gl_engine.vec.Vec2d; import gl_engine.vec.Vec2i; import gl_engine.vec.Vec3d; -import projectzombie.Main; import projectzombie.display.Camera; import projectzombie.entity.Entity; import projectzombie.entity.EntityAlive; @@ -261,12 +257,19 @@ public class Chunk implements IBdfClassManager { for(int i2=0;i2 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 bb688c6..e30aad2 100644 --- a/src/resources/shader/environmentRenderer.vsh +++ b/src/resources/shader/environmentRenderer.vsh @@ -22,6 +22,9 @@ uniform vec3 lighting_day_high; uniform vec3 lighting_src_low; uniform vec3 lighting_src_high; +uniform vec2 lightmap_offset; +uniform vec2 lightmap_size; + 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; } @@ -67,19 +70,21 @@ void main() { int type = int(aFlags.z); - int chunk_offset_id = int(aChunkOffset.x); - vec2 chunk_offset = vec2(mod(chunk_offset_id, 16), chunk_offset_id / 16); - mat4 do_rotation = rotated; mat4 no_rotation = mat4(1); - gl_Position = vec4(aPos, 1) * (mod(type, 2) == 1 ? do_rotation : no_rotation) * - translate(vec3(chunk_offset.x, 0, chunk_offset.y)) * model * camera * projection; + vec4 pos = vec4(aPos, 1) * (mod(type, 2) == 1 ? do_rotation : no_rotation) * + translate(aChunkOffset) * model; + + gl_Position = pos * camera * projection; pTexture = vec3(aTex.x, getTexY(), aTex.z); pPos = aPos; - vec4 light = texture(lightmap, vec2(0.5, 0.5)); + vec4 light = texture(lightmap, vec2( + map(floor(pos.x), lightmap_offset.x, lightmap_offset.x + lightmap_size.x, 0, 1), + map(floor(pos.z), lightmap_offset.y, lightmap_offset.y + lightmap_size.y, 0, 1))); + vec3 light_day = mapVec(light.r, 0, 1, lighting_day_low, lighting_day_high); vec3 light_src = mapVec(light.g, 0, 1, lighting_src_low, lighting_src_high); diff --git a/worker.jar b/worker.jar index b0af808288b1512149c64e1ef67ed396456a656f..74efdd46cc4fa9fbcf7842b20c350d2598dcb215 100644 GIT binary patch delta 7553 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 SGc`P(ocT+eZSzY|-~s@rP0ITK delta 7322 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 M{T5(b`2yrl03VZPtN;K2