diff --git a/src/projectzombie/display/DisplayRender.java b/src/projectzombie/display/DisplayRender.java index cf1adc1..f3ba990 100755 --- a/src/projectzombie/display/DisplayRender.java +++ b/src/projectzombie/display/DisplayRender.java @@ -25,6 +25,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); + GL33.glUniform3f(Main.window.glsl_src_high, 1, 1, 1); + if(Main.menu.doGameRender) { if(ChunkEventHandler.loaded) diff --git a/src/projectzombie/display/DisplayWindow.java b/src/projectzombie/display/DisplayWindow.java index deae0e3..ae19816 100755 --- a/src/projectzombie/display/DisplayWindow.java +++ b/src/projectzombie/display/DisplayWindow.java @@ -1,5 +1,9 @@ package projectzombie.display; +import static org.lwjgl.opengl.GL11.GL_RGBA; +import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE; + +import java.nio.ByteBuffer; import java.nio.IntBuffer; import org.lwjgl.BufferUtils; @@ -9,6 +13,7 @@ import org.lwjgl.opengl.GL33; import gl_engine.graphics.GraphicsHelpers; import gl_engine.graphics.GraphicsShader; import mainloop.task.IMainloopTask; +import projectzombie.display.lighting.TileLighting; import projectzombie.init.Resources; import projectzombie.input.CursorEnterCallback; import projectzombie.input.CursorPosCallback; @@ -41,6 +46,11 @@ public class DisplayWindow implements IMainloopTask public int glsl_camera; public int glsl_time; + public int glsl_day_low; + public int glsl_day_high; + public int glsl_src_low; + public int glsl_src_high; + public int getWidth() { return this.width; } @@ -76,7 +86,7 @@ public class DisplayWindow implements IMainloopTask width = w.get()*4; height = h.get()*4; - GLFW.glfwWindowHint(GLFW.GLFW_DOUBLEBUFFER, GLFW.GLFW_FALSE); + //GLFW.glfwWindowHint(GLFW.GLFW_DOUBLEBUFFER, GLFW.GLFW_FALSE); // Create the window window = GraphicsHelpers.initWindow("Project Zombie", width, height, monitor); @@ -109,6 +119,17 @@ public class DisplayWindow implements IMainloopTask glsl_time = GL33.glGetUniformLocation(environmentRenderer.program, "time"); glsl_tex_cut = GL33.glGetUniformLocation(environmentRenderer.program, "tex_cut"); glsl_color = GL33.glGetUniformLocation(environmentRenderer.program, "color"); + + glsl_day_low = GL33.glGetUniformLocation(environmentRenderer.program, "lighting_day_low"); + glsl_day_high = GL33.glGetUniformLocation(environmentRenderer.program, "lighting_day_high"); + glsl_src_low = GL33.glGetUniformLocation(environmentRenderer.program, "lighting_src_low"); + glsl_src_high = GL33.glGetUniformLocation(environmentRenderer.program, "lighting_src_high"); + + int glsl_atlas = GL33.glGetUniformLocation(environmentRenderer.program, "atlas"); + int glsl_lightmap = GL33.glGetUniformLocation(environmentRenderer.program, "lightmap"); + + GL33.glUniform1ui(glsl_atlas, 1); + GL33.glUniform1ui(glsl_lightmap, 0); } public void render() @@ -120,9 +141,14 @@ public class DisplayWindow implements IMainloopTask width = w[0]; height = h[0]; - // Bind the texture atlas + // Bind the texture atlas + GL33.glActiveTexture(GL33.GL_TEXTURE1); Resources.ATLAS.bind(); + // Bind the lightmap + GL33.glActiveTexture(GL33.GL_TEXTURE0); + GL33.glBindTexture(GL33.GL_TEXTURE_2D, TileLighting.lightmap); + // Render everything DisplayRender.render(w[0], h[0]); diff --git a/src/projectzombie/display/lighting/TileLighting.java b/src/projectzombie/display/lighting/TileLighting.java index 8c933c9..825754d 100755 --- a/src/projectzombie/display/lighting/TileLighting.java +++ b/src/projectzombie/display/lighting/TileLighting.java @@ -1,5 +1,13 @@ package projectzombie.display.lighting; +import static org.lwjgl.opengl.GL11.GL_RGBA; +import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE; + +import java.nio.ByteBuffer; +import java.util.Arrays; + +import org.lwjgl.opengl.GL33; + import gl_engine.MathHelpers; import gl_engine.range.Range4i; import gl_engine.vec.Vec2i; @@ -17,6 +25,11 @@ import projectzombie.world.layer.Layer; public class TileLighting implements IMainloopTask { public static boolean lighting_dirty = false; + public static int lightmap; + + public TileLighting() { + lightmap = GL33.glGenTextures(); + } public static void update() { @@ -87,7 +100,11 @@ public class TileLighting implements IMainloopTask } }, - () -> { + () -> + { + int size = chunks.RENDER_DISTANCE * 32 + 16; + ByteBuffer tex_data = ByteBuffer.allocateDirect(size * size * 4); + for(int cx=-chunks.RENDER_DISTANCE;cx<=chunks.RENDER_DISTANCE;cx++) { for(int cy=-chunks.RENDER_DISTANCE;cy<=chunks.RENDER_DISTANCE;cy++) { @@ -104,12 +121,22 @@ public class TileLighting implements IMainloopTask Vec2i tpos = new Vec2i(cpos.x * 16 + x, cpos.y * 16 + y); int tid = tpos.getId(Chunk.CHUNK_SIZE); + int id = (((cx + chunks.RENDER_DISTANCE) * 16 + x) + + ((cy + chunks.RENDER_DISTANCE) * 16 + y) * size) * 4; + chunk.setDaylightLevel(chunk_t.getDaylightLevel(tid), tid); chunk.setLightLevel(chunk_t.getLightLevel(tid), tid); + + tex_data.put(id+0, (byte)(chunk_t.getDaylightLevel(tid) * 255)); + tex_data.put(id+1, (byte)(chunk_t.getLightLevel(tid) * 255)); } } } } + + GL33.glBindTexture(GL33.GL_TEXTURE_2D, lightmap); + GL33.glTexImage2D(GL33.GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data); + GL33.glGenerateMipmap(GL33.GL_TEXTURE_2D); }); } diff --git a/src/projectzombie/world/chunk/Chunk.java b/src/projectzombie/world/chunk/Chunk.java index 3af16ef..81f0ac4 100755 --- a/src/projectzombie/world/chunk/Chunk.java +++ b/src/projectzombie/world/chunk/Chunk.java @@ -262,11 +262,7 @@ 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 5171b6b..bb688c6 100644 --- a/src/resources/shader/environmentRenderer.vsh +++ b/src/resources/shader/environmentRenderer.vsh @@ -3,22 +3,39 @@ layout (location = 0) in vec3 aPos; layout (location = 1) in vec3 aTex; layout (location = 2) in vec2 aTexY; -layout (location = 3) in vec3 aTranslate; +layout (location = 3) in vec3 aChunkOffset; layout (location = 4) in vec3 aFlags; +out vec3 pLighting; out vec3 pTexture; out vec3 pPos; +uniform sampler2D lightmap; uniform mat4 projection; uniform mat4 model; uniform mat4 camera; uniform mat4 rotated; uniform int time; +uniform vec3 lighting_day_low; +uniform vec3 lighting_day_high; +uniform vec3 lighting_src_low; +uniform vec3 lighting_src_high; + 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; } +vec3 mapVec(float x, float in_min, float in_max, vec3 out_min, vec3 out_max) { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +vec3 biggest(vec3 a, vec3 b) { + return vec3(a.x > b.x ? a.x : b.x, + a.y > b.y ? a.y : b.y, + a.z > b.z ? a.z : b.z); +} + mat4 translate(vec3 vec) { mat4 result = mat4(1); @@ -50,12 +67,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(aTranslate) * model * camera * projection; + translate(vec3(chunk_offset.x, 0, chunk_offset.y)) * model * camera * projection; pTexture = vec3(aTex.x, getTexY(), aTex.z); pPos = aPos; + + vec4 light = texture(lightmap, vec2(0.5, 0.5)); + 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); + + pLighting = biggest(light_day, light_src); } \ No newline at end of file