aboutsummaryrefslogtreecommitdiff
path: root/source/game/systems/LightingSystem.cs
diff options
context:
space:
mode:
authorhazel <hazel@hazelthats.me>2026-01-26 22:04:39 +0100
committerhazel <hazel@hazelthats.me>2026-01-26 22:04:39 +0100
commit567c422f8cd42eba2437f9a8c2522716a1649be7 (patch)
tree93c5b296f3b7c14b626d0aadf5cad37764c41c74 /source/game/systems/LightingSystem.cs
downloadcelesteia-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.cs100
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