diff options
| author | hazel <hazel@hazelthats.me> | 2026-01-26 22:04:39 +0100 |
|---|---|---|
| committer | hazel <hazel@hazelthats.me> | 2026-01-26 22:04:39 +0100 |
| commit | 567c422f8cd42eba2437f9a8c2522716a1649be7 (patch) | |
| tree | 93c5b296f3b7c14b626d0aadf5cad37764c41c74 /source/game/systems/LightingSystem.cs | |
| download | celesteia-567c422f8cd42eba2437f9a8c2522716a1649be7.tar.gz celesteia-567c422f8cd42eba2437f9a8c2522716a1649be7.tar.bz2 celesteia-567c422f8cd42eba2437f9a8c2522716a1649be7.zip | |
celesteia archive, last updated april 9th 2024
Signed-off-by: hazel <hazel@hazelthats.me>
Diffstat (limited to 'source/game/systems/LightingSystem.cs')
| -rw-r--r-- | source/game/systems/LightingSystem.cs | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/source/game/systems/LightingSystem.cs b/source/game/systems/LightingSystem.cs new file mode 100644 index 0000000..73c6cf8 --- /dev/null +++ b/source/game/systems/LightingSystem.cs @@ -0,0 +1,100 @@ +using Celesteia.Graphics; +using Celesteia.Graphics.Lighting; +using Celesteia.Resources; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using MonoGame.Extended.Entities.Systems; +using Celesteia.Resources.Types; +using Celesteia.Game.Planets; +using System.Threading.Tasks; +using System.Collections.Generic; + +namespace Celesteia.Game.Systems { + public class LightingSystem : IUpdateSystem, IDrawSystem + { + private readonly Camera2D _camera; + private readonly SpriteBatch _spriteBatch; + private readonly ChunkMap _chunkMap; + + public LightingSystem(Camera2D camera, SpriteBatch spriteBatch, ChunkMap chunkMap) { + _camera = camera; + _spriteBatch = spriteBatch; + _chunkMap = chunkMap; + } + public void Dispose() { } + + private int _lightRenderDistance = 5; + + private Dictionary<byte, BlockLightProperties> lightingDictionary; + public void Initialize(MonoGame.Extended.Entities.World world) { + int _size = 2 * _lightRenderDistance * Chunk.CHUNK_SIZE; + + _lightMap = new LightMap(_size, _size); + _texture = new Texture2D(_spriteBatch.GraphicsDevice, _size, _size); + + lightingDictionary = new Dictionary<byte, BlockLightProperties>(); + } + + private LightMap _lightMap; + private Texture2D _texture; + + private bool drawTexture = false; + private Task _lightUpdate; + public void Update(GameTime gameTime) + { + if (_lightUpdate == null || (_lightUpdate != null && _lightUpdate.IsCompleted)) + _lightUpdate = Task.Factory.StartNew(() => UpdateLight()); + + if (drawTexture) UpdateTexture(); + } + + private Point _position; + private void UpdatePosition() { + _position = ChunkVector.FromVector2(_camera.Center).Resolve() - new Point(_lightRenderDistance * Chunk.CHUNK_SIZE); + } + + private void UpdateTexture() { + _drawPosition = _position.ToVector2(); + _texture.SetData<Color>(_lightMap.GetColors(), 0, _lightMap.GetColorCount()); + drawTexture = false; + } + + private void UpdateLight() { + UpdatePosition(); + + UpdateEmission(); + _lightMap.Propagate(); + _lightMap.CreateColorMap(); + + drawTexture = true; + } + + private BlockState _block; + private void UpdateEmission() { + for (int i = 0; i < _lightMap.Width; i++) { + for (int j = 0; j < _lightMap.Height; j++) { + if (!(_block = _chunkMap.GetForeground(i + _position.X, j + _position.Y)).Empty && _lightMap.AddForeground(i, j, _block.Type.Light)) continue; + if (!(_block = _chunkMap.GetBackground(i + _position.X, j + _position.Y)).Empty && _lightMap.AddBackground(i, j, _block.Type.Light)) continue; + + _lightMap.AddLight(i, j, true, LightColor.ambient, 4); + } + } + } + + private BlendState multiply = new BlendState() { + ColorBlendFunction = BlendFunction.Add, + ColorSourceBlend = Blend.DestinationColor, + ColorDestinationBlend = Blend.Zero, + }; + + private Vector2 _drawPosition; + public void Draw(GameTime gameTime) + { + _spriteBatch.Begin(SpriteSortMode.Immediate, multiply, SamplerState.LinearClamp, null, null, null, _camera.GetViewMatrix()); + + _spriteBatch.Draw(_texture, _drawPosition, Color.White); + + _spriteBatch.End(); + } + } +}
\ No newline at end of file |
