From 197331ec4c998896ceae71add2f1880b80ddb7bc Mon Sep 17 00:00:00 2001 From: Pannoniae <25565223+Pannoniae@users.noreply.github.com> Date: Wed, 17 Jul 2024 18:01:51 +0100 Subject: [PATCH] fix up mipmapping with leaves --- shaders/shader.frag | 3 ++ shaders/simpleBlock.frag | 1 + src/render/Particle.cs | 30 +++++++++++++++---- src/render/ParticleManager.cs | 55 ++++++++++++++--------------------- src/render/TerrainParticle.cs | 9 ++++++ src/ui/menu/SettingsMenu.cs | 3 +- src/ui/screen/GameScreen.cs | 11 ++----- 7 files changed, 64 insertions(+), 48 deletions(-) create mode 100644 src/render/TerrainParticle.cs diff --git a/shaders/shader.frag b/shaders/shader.frag index f10222e..430322a 100644 --- a/shaders/shader.frag +++ b/shaders/shader.frag @@ -40,6 +40,9 @@ void main() { if (colour.a <= 0) { discard; } + // make it always opaque (for mipmapping) + colour.a = max(colour.a, 1); + // mix the fog colour between it and the sky vec4 mixedFogColour = mix(fogColour, skyColour, ratio); // mix fog diff --git a/shaders/simpleBlock.frag b/shaders/simpleBlock.frag index 7a8ee64..f20f4ed 100644 --- a/shaders/simpleBlock.frag +++ b/shaders/simpleBlock.frag @@ -21,4 +21,5 @@ void main() { if (color.a <= 0) { discard; } + color.a = max(color.a, 1); } \ No newline at end of file diff --git a/src/render/Particle.cs b/src/render/Particle.cs index 8511b5c..9cf0b1f 100644 --- a/src/render/Particle.cs +++ b/src/render/Particle.cs @@ -5,26 +5,44 @@ namespace BlockGame; public class Particle : Entity { - public Color4b tint; + + /// + /// The texture coordinates of the particle. + /// + public float u; + + /// + /// The texture coordinates of the particle. + /// + public float v; + + /// + /// The texture the particle uses. + /// + public string texture; + + /// + /// The size of the particle. (world coords) + /// public double size; /// /// The time-to-live of the particle in ticks. /// public int ttl; - public int maxLife; /// /// Is this particle valid? /// public bool active; - public Particle(Vector3D position, Color4b tint, double size, int ttl) { + public Particle(Vector3D position, string texture, float u, float v, double size, int ttl) { this.position = position; - this.tint = tint; + this.texture = texture; + this.u = u; + this.v = v; this.size = size; this.ttl = ttl; - maxLife = ttl; active = true; } @@ -36,7 +54,7 @@ public void update(double dt) { } } - public void render(double interp) { + public void render(double dt, double interp) { if (active) { //var pos = Vector3D.Lerp(prevPosition, position, (float)interp); //var col = new Vector4(tint, ttl / maxLife); diff --git a/src/render/ParticleManager.cs b/src/render/ParticleManager.cs index a512110..b9decef 100644 --- a/src/render/ParticleManager.cs +++ b/src/render/ParticleManager.cs @@ -1,51 +1,40 @@ -using Silk.NET.Maths; -using TrippyGL; +using Silk.NET.OpenGL; namespace BlockGame; public class ParticleManager { - private Particle[] particles; + private readonly List particles = []; - public ParticleManager(int maxParticles) { - particles = new Particle[maxParticles]; + public void add(Particle particle) { + particles.Add(particle); } public void update(double dt) { - for (int i = 0; i < particles.Length; i++) { - if (particles[i] != null) { - particles[i].update(dt); - if (particles[i].ttl <= 0) { - particles[i].active = false; - } + for (var i = 0; i < particles.Count; i++) { + var particle = particles[i]; + particle.update(dt); + + if (!particle.active) { + particles.RemoveAt(i); + // don't skip the next particle + i--; } } } - public void render(double interp) { - for (int i = 0; i < particles.Length; i++) { - if (particles[i].active) { - particles[i].render(interp); - } - } - } + public void render(double dt, double interp) { - // TODO implement pooling - public Particle newParticle(Vector3D position, Color4b color, double size, int ttl) { - return new Particle(position, color, size, ttl); - } + var currentTexture = "textures/blocks.png"; + Game.GL.ActiveTexture(TextureUnit.Texture0); + Game.GL.BindTexture(TextureTarget.Texture2D, Game.textureManager.blockTexture.handle); - public void addParticle(Particle particle) { - for (int i = 0; i < particles.Length; i++) { - if (!particles[i].active) { - particles[i] = particle; - return; + foreach (var particle in particles) { + if (particle.texture != currentTexture) { + Game.textureManager.load(particle.texture, particle.texture); + var tex = Game.textureManager.get(particle.texture); + Game.GL.BindTexture(TextureTarget.Texture2D, tex.Handle); } - } - } - - public void clear() { - for (int i = 0; i < particles.Length; i++) { - particles[i].reset(); + particle.render(dt, interp); } } } \ No newline at end of file diff --git a/src/render/TerrainParticle.cs b/src/render/TerrainParticle.cs new file mode 100644 index 0000000..b410821 --- /dev/null +++ b/src/render/TerrainParticle.cs @@ -0,0 +1,9 @@ +using Silk.NET.Maths; + +namespace BlockGame; + +public class TerrainParticle : Particle { + + public TerrainParticle(Vector3D position, string texture, float u, float v, double size, int ttl) : base(position, texture, u, v, size, ttl) { + } +} \ No newline at end of file diff --git a/src/ui/menu/SettingsMenu.cs b/src/ui/menu/SettingsMenu.cs index e671edb..c39d0cf 100644 --- a/src/ui/menu/SettingsMenu.cs +++ b/src/ui/menu/SettingsMenu.cs @@ -91,8 +91,9 @@ public SettingsMenu() { renderDistance.topCentre(); renderDistance.tooltip = "The maximum distance at which blocks are rendered.\nHigher values may reduce performance."; renderDistance.applied += () => { + var old = settings.renderDistance; settings.renderDistance = (int)renderDistance.value; - remeshIfRequired((int)renderDistance.value); + remeshIfRequired(old); }; renderDistance.getText = value => "Render Distance: " + value; settingElements.Add(renderDistance); diff --git a/src/ui/screen/GameScreen.cs b/src/ui/screen/GameScreen.cs index c9d6f7e..86e34c8 100644 --- a/src/ui/screen/GameScreen.cs +++ b/src/ui/screen/GameScreen.cs @@ -173,7 +173,7 @@ public override void onKeyDown(IKeyboard keyboard, Key key, int scancode) { if (!world.inMenu && !world.paused) { pause(); } - else { + else if (currentMenu != Menu.SETTINGS) { backToGame(); } } @@ -241,13 +241,8 @@ public void remeshWorld(int oldRenderDist) { foreach (var chunk in world.chunks.Values) { // don't set chunk if not loaded yet, else we will have broken chunkgen/lighting errors if (chunk.status >= ChunkStatus.MESHED) { - if (oldRenderDist < Settings.instance.renderDistance) { - // just unload everything - chunk.status = ChunkStatus.MESHED - 1; - } - else { - chunk.meshChunk(); - } + // just unload everything + chunk.status = ChunkStatus.MESHED - 1; } } world.player.loadChunksAroundThePlayer(Settings.instance.renderDistance);