diff --git a/client/src/main/java/client/Client.java b/client/src/main/java/client/Client.java index 21feaf5b..f542f48a 100755 --- a/client/src/main/java/client/Client.java +++ b/client/src/main/java/client/Client.java @@ -62,7 +62,7 @@ import client.network.DummyConnection; import client.renderer.Drawing; import client.renderer.EffectRenderer; import client.renderer.Renderer; -import client.renderer.Shader; +import client.renderer.ShaderContext; import client.renderer.GlState; import client.renderer.ItemRenderer; import client.renderer.blockmodel.ModelManager; @@ -850,7 +850,7 @@ public class Client implements IThreadListener { Font.loadFonts(); Font.select(this.font); if(this.shaders) - Shader.loadShaders(); + ShaderContext.loadShaders(); this.textureManager.onReload(); this.modelManager.onReload(); this.renderItem.onReload(); @@ -2391,7 +2391,7 @@ public class Client implements IThreadListener { GlState.blendFunc(GL15.GL_SRC_ALPHA, GL15.GL_ONE_MINUS_SRC_ALPHA); this.initConsole(); if(this.shaders) - Shader.loadShaders(); + ShaderContext.loadShaders(); this.startSound(true); this.vidMode = Window.getDisplayMode(); if(this.vidMode != null && (this.vidMode.width() < MIN_WIDTH || this.vidMode.height() < MIN_HEIGHT)) @@ -2462,7 +2462,7 @@ public class Client implements IThreadListener { this.save(); Font.unloadFonts(); if(this.shaders) - Shader.unloadShaders(); + ShaderContext.unloadShaders(); Window.destroyWindow(); Log.SYSTEM.info("Beendet."); } diff --git a/client/src/main/java/client/renderer/Renderer.java b/client/src/main/java/client/renderer/Renderer.java index 847663f9..f5a325e8 100755 --- a/client/src/main/java/client/renderer/Renderer.java +++ b/client/src/main/java/client/renderer/Renderer.java @@ -20,7 +20,6 @@ import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL20; import client.Client; -import client.renderer.Shader.ShaderContext; import client.renderer.blockmodel.BakedQuad; import client.renderer.blockmodel.FaceBakery; import client.renderer.blockmodel.IBakedModel; @@ -46,6 +45,7 @@ import common.collect.Lists; import common.collect.Maps; import common.collect.Sets; import common.dimension.DimType; +import common.dimension.Shader; import common.effect.Effect; import common.entity.Entity; import common.entity.npc.EntityCameraHolder; @@ -70,6 +70,7 @@ import common.util.Pair; import common.util.HitPosition.ObjectType; import common.vars.Vars; import common.util.ParticleType; +import common.util.Util; import common.util.Vec3; import common.util.Vec3i; import common.util.Vector3f; @@ -2559,7 +2560,7 @@ public class Renderer { } } - if(this.gm.shaders && this.gm.useShader && this.gm.dimensionName.equals("cyberspace")) { + if(this.gm.shaders && this.gm.useShader && this.gm.world.dimension.getShader() != null) { GlState.setActiveTexture(GL15.GL_TEXTURE1); GL15.glMatrixMode(GL15.GL_TEXTURE); GL15.glLoadIdentity(); @@ -2575,7 +2576,11 @@ public class Renderer { if (this.initialized) { - ShaderContext context = Shader.GRID.use(); + ShaderContext context = ShaderContext.use(this.gm.world.dimension.getShader()); + context.matrix("view", MatrixState.getModelView()); + context.matrix("projection", MatrixState.getProjection()); + context.vec("time", (float)Util.ftime()); + context.vec("tex_mul", (float)this.gm.getTextureMapBlocks().getWidth() / 16.0f, (float)this.gm.getTextureMapBlocks().getHeight() / 16.0f); for (RenderChunk renderchunk : this.renderChunks) { VertexBuffer vertexbuffer = renderchunk.getVertexBuffer(); @@ -2595,7 +2600,7 @@ public class Renderer { GL20.glEnableVertexAttribArray(1); GL20.glVertexAttribPointer(2, 2, GL15.GL_FLOAT, false, 28, 16L); GL20.glEnableVertexAttribArray(2); - GL20.glVertexAttribPointer(3, 4, GL15.GL_UNSIGNED_BYTE, true, 28, 24L); + GL20.glVertexAttribPointer(3, 2, GL15.GL_SHORT, true, 28, 24L); GL20.glEnableVertexAttribArray(3); vertexbuffer.drawArrays(GL15.GL_QUADS); diff --git a/client/src/main/java/client/renderer/Shader.java b/client/src/main/java/client/renderer/Shader.java deleted file mode 100644 index c6495ec2..00000000 --- a/client/src/main/java/client/renderer/Shader.java +++ /dev/null @@ -1,278 +0,0 @@ -package client.renderer; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; -import java.util.Map; -import java.util.Map.Entry; -import java.util.function.Consumer; -import java.util.function.Supplier; - -import org.lwjgl.opengl.GL20; - -import client.Client; -import client.util.FileUtils; -import common.collect.Maps; -import common.log.Log; -import common.util.Matrix4f; -import common.util.Util; -import common.util.Vec3; -import common.util.Vector3f; -import common.util.Vector4f; - -public enum Shader { - GRID("grid", "grid", context -> {context.integer("tex", 0);}, context -> { - context.matrix("view", MatrixState.getModelView()); - context.matrix("projection", MatrixState.getProjection()); - context.vec("time", (float)Util.ftime()); - context.vec("tex_mul", (float)Client.CLIENT.getTextureMapBlocks().getWidth() / 16.0f, (float)Client.CLIENT.getTextureMapBlocks().getHeight() / 16.0f); - }), - - VIS("vis", "vis", null, context -> { - context.matrix("view", MatrixState.getModelView()); - context.matrix("projection", MatrixState.getProjection()); - }); - - public class ShaderContext { - private final int program; - - private ShaderContext(int program) { - this.program = program; - } - - public int getProgram() { - return this.program; - } - - public ShaderContext bool(String name, boolean x) { - GL20.glUniform1i(GL20.glGetUniformLocation(this.program, name), x ? 1 : 0); - return this; - } - - public ShaderContext integer(String name, int x) { - GL20.glUniform1i(GL20.glGetUniformLocation(this.program, name), x); - return this; - } - - public ShaderContext vec(String name, float x) { - GL20.glUniform1f(GL20.glGetUniformLocation(this.program, name), x); - return this; - } - - public ShaderContext vec(String name, float x, float y) { - GL20.glUniform2f(GL20.glGetUniformLocation(this.program, name), x, y); - return this; - } - - public ShaderContext vec(String name, float x, float y, float z) { - GL20.glUniform3f(GL20.glGetUniformLocation(this.program, name), x, y, z); - return this; - } - - public ShaderContext vec(String name, float x, float y, float z, float w) { - GL20.glUniform4f(GL20.glGetUniformLocation(this.program, name), x, y, z, w); - return this; - } - - public ShaderContext vec(String name, Vec3 vec) { - GL20.glUniform3f(GL20.glGetUniformLocation(this.program, name), (float)vec.xCoord, (float)vec.yCoord, (float)vec.zCoord); - return this; - } - - public ShaderContext vec(String name, Vector3f vec) { - GL20.glUniform3f(GL20.glGetUniformLocation(this.program, name), vec.x, vec.y, vec.z); - return this; - } - - public ShaderContext vec(String name, Vector4f vec) { - GL20.glUniform4f(GL20.glGetUniformLocation(this.program, name), vec.x, vec.y, vec.z, vec.w); - return this; - } - - public ShaderContext matrix(String name, FloatBuffer mat) { - GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(this.program, name), false, mat); - return this; - } - - public ShaderContext matrix(String name, Matrix4f mat) { - mat.store(BUFFER); - GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(this.program, name), false, BUFFER); - return this; - } - - public ShaderContext color(String name, int color) { - GL20.glUniform4f(GL20.glGetUniformLocation(this.program, name), - (float)((int)((color >> 16) & 0xff)) / 255.0f, (float)((int)((color >> 8) & 0xff)) / 255.0f, - (float)((int)(color & 0xff)) / 255.0f, (float)((int)((color >> 24) & 0xff)) / 255.0f - ); - return this; - } - - public ShaderContext color3(String name, int color) { - GL20.glUniform3f(GL20.glGetUniformLocation(this.program, name), - (float)((int)((color >> 16) & 0xff)) / 255.0f, (float)((int)((color >> 8) & 0xff)) / 255.0f, - (float)((int)(color & 0xff)) / 255.0f - ); - return this; - } - - public void finish() { - if(context != this) - throw new IllegalStateException("Der Shader-Kontext wird nicht mehr verwendet"); - GL20.glUseProgram(0); - context = null; - } - } - - private static final FloatBuffer BUFFER = ByteBuffer.allocateDirect(16 << 2).order(ByteOrder.nativeOrder()).asFloatBuffer(); - - private static ShaderContext context; - - private final String vertex; - private final String fragment; - private final Consumer init; - private final Consumer draw; - private final Map> variables; - - private int program; - - public static void loadShaders() { - for(Shader shader : values()) { - if(!shader.load()) { - if(shader.program == 0) - throw new IllegalStateException("Konnte erforderliches Shader-Programm '" + shader.name() + "' nicht erstellen"); - else - Log.RENDER.error("Konnte Shader-Programm '%s' nicht neu laden", shader.name()); - } - } - } - - public static void unloadShaders() { - for(Shader shader : values()) { - shader.unload(); - } - } - - private Shader(String vertex, String fragment, Consumer init, Consumer draw, Object ... vars) { - this.vertex = vertex; - this.fragment = fragment; - this.init = init; - this.draw = draw; - if(vars.length % 2 == 1) - throw new IllegalArgumentException("Es muss eine gerade Zahl an Argmumenten angegeben werden"); - this.variables = vars.length == 0 ? null : Maps.newLinkedHashMap(); - for(int z = 0; z < vars.length / 2; z++) { - this.variables.put((String)vars[z / 2], (Supplier)vars[z / 2 + 1]); - } - } - - private String buildInclude() { - if(this.variables == null) - return ""; - StringBuilder sb = new StringBuilder(); - for(Entry> entry : this.variables.entrySet()) { - sb.append("#define ").append(entry.getKey()).append(' ').append(entry.getValue().get()).append('\n'); - } - return sb.toString(); - } - - private boolean compile(String vcode, String fcode) { - String include = this.buildInclude(); - int vs = GL20.glCreateShader(GL20.GL_VERTEX_SHADER); - GL20.glShaderSource(vs, "#version 460 compatibility\n" + include + vcode); - GL20.glCompileShader(vs); - int ok = GL20.glGetShaderi(vs, GL20.GL_COMPILE_STATUS); - if(ok == 0) { - Log.RENDER.error(GL20.glGetShaderInfoLog(vs)); - Log.RENDER.error("Fehler beim Kompilieren des Vertex-Shaders '%s'", this.vertex); - GL20.glDeleteShader(vs); - return false; - } - int fs = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER); - GL20.glShaderSource(fs, "#version 460 compatibility\n" + include + fcode); - GL20.glCompileShader(fs); - ok = GL20.glGetShaderi(fs, GL20.GL_COMPILE_STATUS); - if(ok == 0) { - Log.RENDER.error(GL20.glGetShaderInfoLog(fs)); - Log.RENDER.error("Fehler beim Kompilieren des Fragment-Shaders '%s'", this.fragment); - GL20.glDeleteShader(vs); - GL20.glDeleteShader(fs); - return false; - } - int pr = GL20.glCreateProgram(); - GL20.glAttachShader(pr, vs); - GL20.glAttachShader(pr, fs); - GL20.glLinkProgram(pr); - ok = GL20.glGetProgrami(pr, GL20.GL_LINK_STATUS); - if(ok == 0) { - Log.RENDER.error(GL20.glGetProgramInfoLog(pr)); - Log.RENDER.error("Fehler beim Verbinden des Shader-Programms '%s' / '%s'", this.vertex, this.fragment); - GL20.glDeleteShader(vs); - GL20.glDeleteShader(fs); - GL20.glDeleteProgram(pr); - return false; - } - GL20.glDeleteShader(vs); - GL20.glDeleteShader(fs); - if(this.program != 0) { - GL20.glDeleteProgram(this.program); - Log.RENDER.debug("Shader '%s' / '%s' / ID #%d wurde mit ID #%d neu geladen", this.vertex, this.fragment, this.program, pr); - } - else { - Log.RENDER.debug("Shader '%s' / '%s' wurde mit ID #%d geladen", this.vertex, this.fragment, pr); - } - this.program = pr; - if(this.init != null) { - GL20.glUseProgram(this.program); - context = new ShaderContext(this.program); - this.init.accept(context); - context.finish(); - } - return true; - } - - private boolean load() { - String vcode; - try { - vcode = FileUtils.read("shaders/" + this.vertex + ".vsh"); - } - catch(IOException e) { - Log.RENDER.error(e, "Fehler beim Laden des Vertex-Shaders '%s'", this.vertex); - return false; - } - String fcode; - try { - fcode = FileUtils.read("shaders/" + this.fragment + ".fsh"); - } - catch(IOException e) { - Log.RENDER.error(e, "Fehler beim Laden des Fragment-Shaders '%s'", this.fragment); - return false; - } - return this.compile(vcode, fcode); - } - - private boolean unload() { - if(this.program == 0) - return false; - GL20.glDeleteProgram(this.program); - Log.RENDER.debug("Shader '%s' / '%s' / ID #%d wurde gelöscht", this.vertex, this.fragment, this.program); - this.program = 0; - return true; - } - - public ShaderContext use() { - if(context != null) - throw new IllegalStateException("Ein Shader wird bereits verwendet"); - GL20.glUseProgram(this.program); - context = new ShaderContext(this.program); - if(this.draw != null) - this.draw.accept(context); - return context; - } - - public void update() { - if(this.program != 0 && !this.load()) - Log.RENDER.error("Konnte Shader-Programm '%s' nicht neu laden", this.name()); - } -} diff --git a/client/src/main/java/client/renderer/ShaderContext.java b/client/src/main/java/client/renderer/ShaderContext.java new file mode 100644 index 00000000..0eee17d1 --- /dev/null +++ b/client/src/main/java/client/renderer/ShaderContext.java @@ -0,0 +1,253 @@ +package client.renderer; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; + +import org.lwjgl.opengl.GL20; + +import client.util.FileUtils; +import common.dimension.Shader; +import common.log.Log; +import common.util.Matrix4f; +import common.util.Vec3; +import common.util.Vector3f; +import common.util.Vector4f; + +public class ShaderContext { + private static final FloatBuffer BUFFER = ByteBuffer.allocateDirect(16 << 2).order(ByteOrder.nativeOrder()).asFloatBuffer(); + private static final String VERTEX = """ + #version 110 + + in vec3 pos; + in vec4 color; + in vec2 coord; + in vec2 light; + + varying vec3 vertex; + varying vec2 tex_coord; + + uniform mat4 model; + uniform mat4 view; + uniform mat4 projection; + uniform vec3 offset; + uniform int chunk_x; + uniform int chunk_y; + uniform int chunk_z; + + void main() { + vec3 nvertex = vec3(model * vec4(pos, 1.0)); + vertex = vec3(float(chunk_x) + pos.x, float(chunk_y) + pos.y, float(chunk_z) + pos.z); + tex_coord = coord; + gl_Position = projection * view * vec4(offset + nvertex, 1.0); + } + """; + private static final String FRAG_HEADER = """ + #version 110 + + varying vec3 vertex; + varying vec2 tex_coord; + + uniform vec2 tex_mul; + uniform float time; + uniform sampler2D tex; + uniform sampler2D lightmap; + """; + private static final int[] PROGRAMS = new int[Shader.values().length]; + + private static ShaderContext context; + + private final int program; + + public static void loadShaders() { + for(Shader shader : Shader.values()) { + int prog = load(PROGRAMS[shader.ordinal()], shader.toString()); + if(prog == 0) + throw new IllegalStateException("Konnte erforderliches Shader-Programm '" + shader + "' nicht erstellen"); + else if(prog == PROGRAMS[shader.ordinal()]) + Log.RENDER.error("Konnte Shader-Programm '%s' nicht neu laden", shader); + else + PROGRAMS[shader.ordinal()] = prog; + } + } + + public static void unloadShaders() { + for(Shader shader : Shader.values()) { + unload(PROGRAMS[shader.ordinal()], shader.toString()); + PROGRAMS[shader.ordinal()] = 0; + } + } + + private static int compile(int old, String fragment, String fcode) { + int vs = GL20.glCreateShader(GL20.GL_VERTEX_SHADER); + GL20.glShaderSource(vs, VERTEX); + GL20.glCompileShader(vs); + int ok = GL20.glGetShaderi(vs, GL20.GL_COMPILE_STATUS); + if(ok == 0) { + Log.RENDER.error(GL20.glGetShaderInfoLog(vs)); + Log.RENDER.error("Fehler beim Kompilieren des Vertex-Shaders"); + GL20.glDeleteShader(vs); + return old; + } + int fs = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER); + GL20.glShaderSource(fs, FRAG_HEADER + fcode); + GL20.glCompileShader(fs); + ok = GL20.glGetShaderi(fs, GL20.GL_COMPILE_STATUS); + if(ok == 0) { + Log.RENDER.error(GL20.glGetShaderInfoLog(fs)); + Log.RENDER.error("Fehler beim Kompilieren des Fragment-Shaders '%s'", fragment); + GL20.glDeleteShader(vs); + GL20.glDeleteShader(fs); + return old; + } + int pr = GL20.glCreateProgram(); + GL20.glAttachShader(pr, vs); + GL20.glAttachShader(pr, fs); + + GL20.glBindAttribLocation(pr, 0, "pos"); + GL20.glBindAttribLocation(pr, 1, "color"); + GL20.glBindAttribLocation(pr, 2, "coord"); + GL20.glBindAttribLocation(pr, 3, "light"); + + GL20.glLinkProgram(pr); + ok = GL20.glGetProgrami(pr, GL20.GL_LINK_STATUS); + if(ok == 0) { + Log.RENDER.error(GL20.glGetProgramInfoLog(pr)); + Log.RENDER.error("Fehler beim Verbinden des Shader-Programms '%s'", fragment); + GL20.glDeleteShader(vs); + GL20.glDeleteShader(fs); + GL20.glDeleteProgram(pr); + return old; + } + GL20.glDeleteShader(vs); + GL20.glDeleteShader(fs); + if(old != 0) { + GL20.glDeleteProgram(old); + Log.RENDER.debug("Shader '%s' / ID #%d wurde mit ID #%d neu geladen", fragment, old, pr); + } + else { + Log.RENDER.debug("Shader '%s' wurde mit ID #%d geladen", fragment, pr); + } + GL20.glUseProgram(pr); + context = new ShaderContext(pr); + context.integer("tex", 0); + context.integer("lightmap", 1); + context.finish(); + return pr; + } + + private static int load(int old, String fragment) { + String fcode; + try { + fcode = FileUtils.read("shaders/" + fragment + ".fsh"); + } + catch(IOException e) { + Log.RENDER.error(e, "Fehler beim Laden des Fragment-Shaders '%s'", fragment); + return old; + } + return compile(old, fragment, fcode); + } + + private static boolean unload(int old, String fragment) { + if(old == 0) + return false; + GL20.glDeleteProgram(old); + Log.RENDER.debug("Shader '%s' / ID #%d wurde gelöscht", fragment, old); + return true; + } + + public static ShaderContext use(Shader shader) { + if(context != null) + throw new IllegalStateException("Ein Shader wird bereits verwendet"); + GL20.glUseProgram(PROGRAMS[shader.ordinal()]); + return context = new ShaderContext(PROGRAMS[shader.ordinal()]); + } + + private ShaderContext(int program) { + this.program = program; + } + + public int getProgram() { + return this.program; + } + + public ShaderContext bool(String name, boolean x) { + GL20.glUniform1i(GL20.glGetUniformLocation(this.program, name), x ? 1 : 0); + return this; + } + + public ShaderContext integer(String name, int x) { + GL20.glUniform1i(GL20.glGetUniformLocation(this.program, name), x); + return this; + } + + public ShaderContext vec(String name, float x) { + GL20.glUniform1f(GL20.glGetUniformLocation(this.program, name), x); + return this; + } + + public ShaderContext vec(String name, float x, float y) { + GL20.glUniform2f(GL20.glGetUniformLocation(this.program, name), x, y); + return this; + } + + public ShaderContext vec(String name, float x, float y, float z) { + GL20.glUniform3f(GL20.glGetUniformLocation(this.program, name), x, y, z); + return this; + } + + public ShaderContext vec(String name, float x, float y, float z, float w) { + GL20.glUniform4f(GL20.glGetUniformLocation(this.program, name), x, y, z, w); + return this; + } + + public ShaderContext vec(String name, Vec3 vec) { + GL20.glUniform3f(GL20.glGetUniformLocation(this.program, name), (float)vec.xCoord, (float)vec.yCoord, (float)vec.zCoord); + return this; + } + + public ShaderContext vec(String name, Vector3f vec) { + GL20.glUniform3f(GL20.glGetUniformLocation(this.program, name), vec.x, vec.y, vec.z); + return this; + } + + public ShaderContext vec(String name, Vector4f vec) { + GL20.glUniform4f(GL20.glGetUniformLocation(this.program, name), vec.x, vec.y, vec.z, vec.w); + return this; + } + + public ShaderContext matrix(String name, FloatBuffer mat) { + GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(this.program, name), false, mat); + return this; + } + + public ShaderContext matrix(String name, Matrix4f mat) { + mat.store(BUFFER); + GL20.glUniformMatrix4fv(GL20.glGetUniformLocation(this.program, name), false, BUFFER); + return this; + } + + public ShaderContext color(String name, int color) { + GL20.glUniform4f(GL20.glGetUniformLocation(this.program, name), + (float)((int)((color >> 16) & 0xff)) / 255.0f, (float)((int)((color >> 8) & 0xff)) / 255.0f, + (float)((int)(color & 0xff)) / 255.0f, (float)((int)((color >> 24) & 0xff)) / 255.0f + ); + return this; + } + + public ShaderContext color3(String name, int color) { + GL20.glUniform3f(GL20.glGetUniformLocation(this.program, name), + (float)((int)((color >> 16) & 0xff)) / 255.0f, (float)((int)((color >> 8) & 0xff)) / 255.0f, + (float)((int)(color & 0xff)) / 255.0f + ); + return this; + } + + public void finish() { + if(context != this) + throw new IllegalStateException("Der Shader-Kontext wird nicht mehr verwendet"); + GL20.glUseProgram(0); + context = null; + } +} diff --git a/client/src/main/resources/shaders/blit.fsh b/client/src/main/resources/shaders/blit.fsh deleted file mode 100644 index c52248e5..00000000 --- a/client/src/main/resources/shaders/blit.fsh +++ /dev/null @@ -1,9 +0,0 @@ -out vec4 FragColor; - -in vec2 tex_coord; - -uniform sampler2D tex; - -void main() { - FragColor = texture(tex, tex_coord); -} diff --git a/client/src/main/resources/shaders/blit.vsh b/client/src/main/resources/shaders/blit.vsh deleted file mode 100644 index 68849298..00000000 --- a/client/src/main/resources/shaders/blit.vsh +++ /dev/null @@ -1,8 +0,0 @@ -layout (location = 0) in vec2 coords; - -out vec2 tex_coord; - -void main() { - tex_coord = coords; - gl_Position = vec4(coords * 2.0 - 1.0, 0.0, 1.0); -} diff --git a/client/src/main/resources/shaders/grid.fsh b/client/src/main/resources/shaders/grid.fsh index 7ebf58a7..868029fd 100644 --- a/client/src/main/resources/shaders/grid.fsh +++ b/client/src/main/resources/shaders/grid.fsh @@ -2,14 +2,6 @@ #define GLM_SQRT2 1.41421356237309504880168872420969808 #define vis_div 24.0 -out vec4 FragColor; - -in vec3 vertex; -in vec2 tex_coord; - -uniform vec2 tex_mul; -uniform float time; - float v2rand(vec2 uv) { return fract(sin(dot(uv, vec2(12.9898,78.233))) * 43758.5453123); } @@ -36,5 +28,5 @@ void main() { vec2 shift = vec2(v2rand(coord + fract(time)) * 2.0 - 1.0, v2rand(coord + 0.5 + fract(time)) * 2.0 - 1.0); shift = vec2(dgauss(shift.x, 0.0, 1.0), dgauss(shift.y, 0.0, 1.0)) * 0.015; vec3 cl = vec3(inside(coord / vis_div, shift, 0.0, 1.0, 64.0, 1.0, 3.0, 1.0, 3.0), inside(coord / vis_div, shift, 0.0, 1.0, 64.0, 63.0, 1.0, 63.0, 1.0), inside(coord / vis_div, shift, 0.0, 1.0, 64.0, 61.0, 63.0, 61.0, 63.0)); - FragColor = vec4(mix(vec3(0.0, 0.0, clamp(0.1 + 0.2 * (vertex.y + 64.0) / 128.0, 0.0, 1.0)), cl, clamp(cl.x + cl.y + cl.z, 0.0, 1.0)), 1.0); + gl_FragColor = vec4(mix(vec3(0.0, 0.0, clamp(0.1 + 0.2 * (vertex.y + 64.0) / 128.0, 0.0, 1.0)), cl, clamp(cl.x + cl.y + cl.z, 0.0, 1.0)), 1.0); } diff --git a/client/src/main/resources/shaders/grid.vsh b/client/src/main/resources/shaders/grid.vsh deleted file mode 100644 index a6c592d7..00000000 --- a/client/src/main/resources/shaders/grid.vsh +++ /dev/null @@ -1,22 +0,0 @@ -layout (location = 0) in vec3 pos; -layout (location = 1) in vec4 color; -layout (location = 2) in vec2 coord; -layout (location = 3) in vec4 light; - -out vec3 vertex; -out vec2 tex_coord; - -uniform mat4 model; -uniform mat4 view; -uniform mat4 projection; -uniform vec3 offset; -uniform int chunk_x; -uniform int chunk_y; -uniform int chunk_z; - -void main() { - vec3 nvertex = vec3(model * vec4(pos, 1.0)); - vertex = vec3(float(chunk_x) + pos.x, float(chunk_y) + pos.y, float(chunk_z) + pos.z); - tex_coord = coord; - gl_Position = projection * view * vec4(offset + nvertex, 1.0); -} diff --git a/client/src/main/resources/shaders/vis.fsh b/client/src/main/resources/shaders/vis.fsh index 1d2fb5bb..28f3e9a9 100644 --- a/client/src/main/resources/shaders/vis.fsh +++ b/client/src/main/resources/shaders/vis.fsh @@ -1,7 +1,3 @@ -out vec4 FragColor; - -in float ypos; - void main() { - FragColor = vec4(clamp(-0.3 + 1.8 * (ypos + 64.0) / 128.0, 0.0, 1.0), clamp(-0.7 + 2.2 * (ypos + 64.0) / 128.0, 0.0, 1.0), clamp(0.1 + 2.0 * (ypos + 64.0) / 128.0, 0.0, 1.0), 1.0); + gl_FragColor = vec4(clamp(-0.3 + 1.8 * (vertex.y + 64.0) / 128.0, 0.0, 1.0), clamp(-0.7 + 2.2 * (vertex.y + 64.0) / 128.0, 0.0, 1.0), clamp(0.1 + 2.0 * (vertex.y + 64.0) / 128.0, 0.0, 1.0), 1.0); } diff --git a/client/src/main/resources/shaders/vis.vsh b/client/src/main/resources/shaders/vis.vsh deleted file mode 100644 index 08c78a02..00000000 --- a/client/src/main/resources/shaders/vis.vsh +++ /dev/null @@ -1,17 +0,0 @@ -layout (location = 0) in vec3 pos; -layout (location = 1) in vec4 color; -layout (location = 2) in vec2 coord; -layout (location = 3) in vec2 light; - -out float ypos; - -uniform mat4 model; -uniform mat4 view; -uniform mat4 projection; -uniform vec3 offset; - -void main() { - vec3 vertex = offset + vec3(model * vec4(pos, 1.0)); - ypos = vertex.y; - gl_Position = projection * view * vec4(vertex, 1.0); -} diff --git a/common/src/main/java/common/dimension/Dimension.java b/common/src/main/java/common/dimension/Dimension.java index b150b818..18411cdd 100755 --- a/common/src/main/java/common/dimension/Dimension.java +++ b/common/src/main/java/common/dimension/Dimension.java @@ -57,6 +57,7 @@ public abstract class Dimension extends Section { // client private boolean denseFog = false; + private Shader shader = null; private float cloudHeight = 192.0f; private int skyColor = 0x000000; private int fogColor = 0x000000; @@ -206,6 +207,11 @@ public abstract class Dimension extends Section { return this; } + public final Dimension setShader(Shader shader) { + this.shader = shader; + return this; + } + public final Dimension setDefaultWeather(Weather value) { this.defaultWeather = this.weather = value; return this; @@ -339,6 +345,10 @@ public abstract class Dimension extends Section { public final int getLightColor() { return this.lightColor; } + + public final Shader getShader() { + return this.shader; + } public final String getCloudTexture() { return "textures/world/" + this.cloudTexture.getTexture() + ".png"; @@ -513,6 +523,7 @@ public abstract class Dimension extends Section { this.fogColor = tag.getInt("FogColor"); this.cloudColor = tag.getInt("CloudColor"); this.lightColor = tag.getInt("LightColor"); + this.shader = tag.hasString("Shader") ? Shader.getByName(tag.getString("Shader")) : null; this.gravity = tag.getFloat("Gravity"); this.size = tag.getInt("Size"); this.temperature = tag.getFloat("Temperature"); @@ -560,6 +571,8 @@ public abstract class Dimension extends Section { tag.setInt("FogColor", this.fogColor); tag.setInt("CloudColor", this.cloudColor); tag.setInt("LightColor", this.lightColor); + if(this.shader != null) + tag.setString("Shader", this.shader.toString()); tag.setFloat("Gravity", this.gravity); tag.setInt("Size", this.size); tag.setFloat("Temperature", this.temperature); diff --git a/common/src/main/java/common/dimension/Shader.java b/common/src/main/java/common/dimension/Shader.java new file mode 100644 index 00000000..be4fd30d --- /dev/null +++ b/common/src/main/java/common/dimension/Shader.java @@ -0,0 +1,32 @@ +package common.dimension; + +import java.util.Map; + +import common.collect.Maps; + +public enum Shader { + GRID("grid"), + VIS("vis"); + + private static final Map LOOKUP = Maps.newHashMap(); + + private final String fragment; + + private Shader(String fragment) { + this.fragment = fragment; + } + + public String toString() { + return this.fragment; + } + + public static Shader getByName(String name) { + return LOOKUP.get(name.toLowerCase()); + } + + static { + for(Shader type : values()) { + LOOKUP.put(type.fragment, type); + } + } +} diff --git a/server/src/main/java/server/init/UniverseRegistry.java b/server/src/main/java/server/init/UniverseRegistry.java index 1eb556a6..2b446583 100755 --- a/server/src/main/java/server/init/UniverseRegistry.java +++ b/server/src/main/java/server/init/UniverseRegistry.java @@ -15,6 +15,7 @@ import common.dimension.Moon; import common.dimension.Section; import common.dimension.Planet; import common.dimension.Semi; +import common.dimension.Shader; import common.dimension.Space; import common.dimension.Star; import common.entity.Entity; @@ -755,7 +756,7 @@ public abstract class UniverseRegistry extends DimensionRegistry { registerDomain("Digital", () -> { GeneratorSettings settings = new GeneratorSettings(); settings.stretchY = 48.0f; - registerArea("Cyberspace", new Area(0x000000, 16777216, 293.15f, 15, Blocks.cyber.getState(), Blocks.spring_water.getState(), 63).setLightColor(0x00003f), + registerArea("Cyberspace", new Area(0x000000, 16777216, 293.15f, 15, Blocks.cyber.getState(), Blocks.spring_water.getState(), 63).setLightColor(0x00003f).setShader(Shader.GRID), new GeneratorData().setGenerator(new GeneratorPerlin(false, settings, 0.1f, 3.5f))); }); registerDomain("hell", "Hölle", () -> {