121 lines
5.3 KiB
C#
121 lines
5.3 KiB
C#
using Mine2d.engine;
|
|
using Mine2d.game.core;
|
|
using Mine2d.game.core.world;
|
|
|
|
namespace Mine2d.game.frontend.renderer;
|
|
|
|
public class WorldRenderer : IRenderer
|
|
{
|
|
private readonly IntPtr light;
|
|
private IntPtr overlay;
|
|
private int overlayWidth, overlayHeight;
|
|
|
|
public WorldRenderer()
|
|
{
|
|
var rl = Context.Get().ResourceLoader;
|
|
var (ptr, size) = rl.LoadToIntPtr("assets.light2.png");
|
|
var sdlBuffer = SDL_RWFromMem(ptr, size);
|
|
var surface = IMG_Load_RW(sdlBuffer, 1);
|
|
this.light = Context.Get().Renderer.CreateTextureFromSurface(surface);
|
|
SDL_FreeSurface(surface);
|
|
var (w, h) = Context.Get().Window.GetSize();
|
|
this.overlay = SDL_CreateTexture(Context.Get().Renderer.GetRaw(), SDL_PIXELFORMAT_RGBA8888, (int)SDL_TextureAccess.SDL_TEXTUREACCESS_TARGET, w, h);
|
|
}
|
|
|
|
public void Render()
|
|
{
|
|
var ctx = Context.Get();
|
|
var world = ctx.GameState.World;
|
|
var tileRegistry = ctx.TileRegistry;
|
|
Renderer.ProcessStatus(SDL_SetRenderTarget(ctx.Renderer.GetRaw(), this.overlay));
|
|
var (ww, wh) = ctx.Window.GetSize();
|
|
if (wh != this.overlayHeight || ww != this.overlayWidth)
|
|
{
|
|
SDL_DestroyTexture(this.overlay);
|
|
this.overlay = SDL_CreateTexture(ctx.Renderer.GetRaw(), SDL_PIXELFORMAT_RGBA8888, (int)SDL_TextureAccess.SDL_TEXTUREACCESS_TARGET, ww, wh);
|
|
this.overlayWidth = ww;
|
|
this.overlayHeight = wh;
|
|
}
|
|
|
|
ClearTexture(this.overlay);
|
|
var renderer = Context.Get().Renderer;
|
|
var scale = ctx.FrontendGameState.Settings.GameScale;
|
|
var camera = Context.Get().FrontendGameState.Camera;
|
|
Renderer.ProcessStatus(SDL_SetTextureBlendMode(this.light, SDL_BlendMode.SDL_BLENDMODE_BLEND));
|
|
var player = PlayerEntity.GetSelf();
|
|
foreach (var (_, chunk) in world.Chunks)
|
|
{
|
|
if (player == null)
|
|
{
|
|
continue;
|
|
}
|
|
if ((player.Position - new Vector2(chunk.X * Constants.ChunkSize * Constants.TileSize, chunk.Y * Constants.ChunkSize * Constants.TileSize)).Length() > 1300)
|
|
{
|
|
continue;
|
|
}
|
|
for (var y = 0; y < Constants.ChunkSize; y++)
|
|
{
|
|
for (var x = 0; x < Constants.ChunkSize; x++)
|
|
{
|
|
var stile = chunk.GetTile(x, y);
|
|
var chunkOffsetX = chunk.X * Constants.TileSize * Constants.ChunkSize;
|
|
var chunkOffsetY = chunk.Y * Constants.TileSize * Constants.ChunkSize;
|
|
var drawX = x * 16 + chunkOffsetX;
|
|
var drawY = y * 16 + chunkOffsetY;
|
|
if (stile.Id == 0 || !tileRegistry.GetTile(stile.Id).IsSolid())
|
|
{
|
|
Renderer.ProcessStatus(SDL_SetRenderTarget(ctx.Renderer.GetRaw(), this.overlay));
|
|
renderer.DrawTexture(
|
|
this.light,
|
|
(drawX - (int)camera.Position.X - 40) * scale,
|
|
(drawY - (int)camera.Position.Y - 40) * scale,
|
|
96 * scale,
|
|
96 * scale
|
|
);
|
|
}
|
|
Renderer.ProcessStatus(SDL_SetRenderTarget(ctx.Renderer.GetRaw(), IntPtr.Zero));
|
|
if (stile.Id != 0)
|
|
{
|
|
var tile = tileRegistry.GetTile(stile.Id);
|
|
tile.Render(drawX, drawY, stile);
|
|
}
|
|
|
|
// Console.WriteLine(
|
|
// (chunk.Y * Constants.ChunkSize) + y + " "+
|
|
// (chunk.X * Constants.ChunkSize) + x
|
|
// );
|
|
if (ctx.FrontendGameState.DebugState.Overlay == "noise")
|
|
{
|
|
ctx.Renderer.DrawText("" + Math.Round(ChunkGenerator.Noise.coherentNoise(
|
|
(chunk.X * Constants.ChunkSize) + x,
|
|
(int)(((chunk.Y * Constants.ChunkSize) + y)*0.6),
|
|
0
|
|
), 4),
|
|
(drawX - (int)camera.Position.X) * scale,
|
|
(drawY - (int)camera.Position.Y) * scale);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Renderer.ProcessStatus(SDL_SetRenderTarget(ctx.Renderer.GetRaw(), IntPtr.Zero));
|
|
if (ctx.FrontendGameState.DebugState.NoFog)
|
|
{
|
|
return;
|
|
}
|
|
Renderer.ProcessStatus(SDL_SetTextureBlendMode(this.overlay, SDL_BlendMode.SDL_BLENDMODE_MUL));
|
|
Renderer.ProcessStatus(SDL_RenderCopy(ctx.Renderer.GetRaw(), this.overlay, IntPtr.Zero, IntPtr.Zero));
|
|
Renderer.ProcessStatus(SDL_SetRenderTarget(ctx.Renderer.GetRaw(), IntPtr.Zero));
|
|
}
|
|
|
|
public static void ClearTexture(IntPtr texture)
|
|
{
|
|
var ctx = Context.Get();
|
|
var renderer = ctx.Renderer;
|
|
var (w, h) = renderer.GetTextureSize(texture);
|
|
var clearRect = new SDL_Rect { x = 0, y = 0, w = w, h = h };
|
|
Renderer.ProcessStatus(SDL_SetRenderTarget(ctx.Renderer.GetRaw(), texture));
|
|
_ = SDL_SetRenderDrawColor(ctx.Renderer.GetRaw(), 0, 0, 0, 255);
|
|
Renderer.ProcessStatus(SDL_RenderFillRect(ctx.Renderer.GetRaw(), ref clearRect));
|
|
}
|
|
}
|