Skip to content

Commit

Permalink
Render minimap to render target instead of drawing static objects eac…
Browse files Browse the repository at this point in the history
…h draw loop. Improves rendering performance and eliminates frame drops when minimap is enabled
  • Loading branch information
ethanmoffat committed May 2, 2023
1 parent 0a48caf commit abd8f85
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 124 deletions.
9 changes: 7 additions & 2 deletions EOLib/Domain/Character/Character.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Amadevus.RecordGenerator;
using EOLib.Domain.Extensions;
using EOLib.Domain.Spells;

namespace EOLib.Domain.Character
Expand All @@ -18,9 +19,13 @@ public sealed partial class Character : ISpellTargetable

public int Index => ID;

public int X => RenderProperties.MapX;
public int X => RenderProperties.IsActing(CharacterActionState.Walking)
? RenderProperties.GetDestinationX()
: RenderProperties.MapX;

public int Y => RenderProperties.MapY;
public int Y => RenderProperties.IsActing(CharacterActionState.Walking)
? RenderProperties.GetDestinationY()
: RenderProperties.MapY;

public string Name { get; }

Expand Down
64 changes: 35 additions & 29 deletions EndlessClient/Rendering/GridDrawCoordinateCalculator.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using AutomaticTypeMapper;
using EOLib.Domain.Character;
using EOLib.Domain.Extensions;
using EOLib.Domain.Map;
using Microsoft.Xna.Framework;
using System;
Expand All @@ -11,9 +12,6 @@ namespace EndlessClient.Rendering
[AutoMappedType]
public class GridDrawCoordinateCalculator : IGridDrawCoordinateCalculator
{
private const int GridSpaceWidth = 64;
private const int GridSpaceHeight = 32;

private readonly ICharacterProvider _characterProvider;
private readonly ICurrentMapProvider _currentMapProvider;
private readonly IRenderOffsetCalculator _renderOffsetCalculator;
Expand All @@ -30,15 +28,23 @@ public GridDrawCoordinateCalculator(ICharacterProvider characterProvider,
_clientWindowSizeProvider = clientWindowSizeProvider;
}

public Vector2 CalculateRawRenderCoordinatesFromGridUnits(int gridX, int gridY, int tileWidth = 64, int tileHeight = 32)
{
var widthFactor = tileWidth / 2;
var heightFactor = tileHeight / 2;

return new Vector2((gridX * widthFactor) - (gridY * widthFactor),
(gridY * heightFactor) + (gridX * heightFactor));
}

public Vector2 CalculateDrawCoordinatesFromGridUnits(int gridX, int gridY)
{
var widthFactor = _clientWindowSizeProvider.Width / 2; // 640 * (1/2) - 1
var heightFactor = _clientWindowSizeProvider.Resizable
? _clientWindowSizeProvider.Height / 2
: _clientWindowSizeProvider.Height * 3 / 10 - 2; // 480 * (3/10) - 2

return new Vector2(widthFactor + (gridX * 32) - (gridY * 32),
heightFactor + (gridY * 16) + (gridX * 16)) - GetMainCharacterOffsets();
return new Vector2(widthFactor, heightFactor) + CalculateRawRenderCoordinatesFromGridUnits(gridX, gridY) - GetMainCharacterOffsets();
}

public Vector2 CalculateDrawCoordinatesFromGridUnits(MapCoordinate mapCoordinate)
Expand All @@ -48,34 +54,36 @@ public Vector2 CalculateDrawCoordinatesFromGridUnits(MapCoordinate mapCoordinate

public Vector2 CalculateBaseLayerDrawCoordinatesFromGridUnits(int gridX, int gridY)
{
var widthFactor = (_clientWindowSizeProvider.Width - GridSpaceWidth) / 2; // 288 = (640 - 64) / 2
var heightFactor = _clientWindowSizeProvider.Resizable
? _clientWindowSizeProvider.Height / 2
: _clientWindowSizeProvider.Height * 3 / 10 - 2; // 144 = 480 * (3/10)

return new Vector2(widthFactor + (gridX * 32) - (gridY * 32),
heightFactor + (gridY * 16) + (gridX * 16)) - GetMainCharacterOffsets();
return CalculateDrawCoordinatesFromGridUnits(gridX, gridY) -
new Vector2(IGridDrawCoordinateCalculator.DefaultGridWidth / 2, 0);
}

public Vector2 CalculateBaseLayerDrawCoordinatesFromGridUnits(MapCoordinate mapCoordinate)
{
return CalculateBaseLayerDrawCoordinatesFromGridUnits(mapCoordinate.X, mapCoordinate.Y);
}

public Vector2 CalculateGroundLayerDrawCoordinatesFromGridUnits()
public Vector2 CalculateGroundLayerRenderTargetDrawCoordinates(bool isMiniMap = false, int tileWidth = 64, int tileHeight = 32)
{
var ViewportWidthFactor = _clientWindowSizeProvider.Width / 2 - 1; // 640 * (1/2) - 1
var ViewportHeightFactor = _clientWindowSizeProvider.Resizable
? _clientWindowSizeProvider.Height / 2
: _clientWindowSizeProvider.Height * 3 / 10 - 2; // 480 * (3/10) - 2

var props = _characterProvider.MainCharacter.RenderProperties;
var rp = _characterProvider.MainCharacter.RenderProperties;
var cx = isMiniMap ? _characterProvider.MainCharacter.X : rp.MapX;
var cy = isMiniMap ? _characterProvider.MainCharacter.Y : rp.MapY;

var mapHeightPlusOne = _currentMapProvider.CurrentMap.Properties.Height + 1;

var tileWidthFactor = tileWidth / 2;
var tileHeightFactor = tileHeight / 2;

var walkAdjustOffsets = isMiniMap ? Vector2.Zero : GetMainCharacterWalkAdjustOffsets();

// opposite of the algorithm for rendering the base layers
return new Vector2(ViewportWidthFactor - (mapHeightPlusOne * 32) + (props.MapY * 32) - (props.MapX * 32),
ViewportHeightFactor - (props.MapY * 16) - (props.MapX * 16)) - GetMainCharacterWalkAdjustOffsets();
return new Vector2(ViewportWidthFactor - (mapHeightPlusOne * tileWidthFactor) + (cy * tileWidthFactor) - (cx * tileWidthFactor),
ViewportHeightFactor - (cy * tileHeightFactor) - (cx * tileHeightFactor)) - walkAdjustOffsets;
}

public Vector2 CalculateDrawCoordinates(DomainNPC npc)
Expand Down Expand Up @@ -109,14 +117,10 @@ public MapCoordinate CalculateGridCoordinatesFromDrawLocation(Vector2 drawLocati
if (_clientWindowSizeProvider.Resizable)
{
var msX = drawLocation.X;
var msY = drawLocation.Y - GridSpaceHeight / 2;
var msY = drawLocation.Y - IGridDrawCoordinateCalculator.DefaultGridHeight / 2;

var widthFactor = _clientWindowSizeProvider.Resizable
? _clientWindowSizeProvider.Width / 2 // 288 = 640 * .45, viewport width factor
: _clientWindowSizeProvider.Width * 9 / 10; // 288 = 640 * .45, 576 = 640 * .9
var heightFactor = _clientWindowSizeProvider.Resizable
? _clientWindowSizeProvider.Height / 2 // 144 = 480 * .45, viewport height factor
: _clientWindowSizeProvider.Height * 3 / 10;
var widthFactor = _clientWindowSizeProvider.Width / 2;
var heightFactor = _clientWindowSizeProvider.Height / 2;

var offsetX = _renderOffsetCalculator.CalculateOffsetX(_characterProvider.MainCharacter.RenderProperties);
var offsetY = _renderOffsetCalculator.CalculateOffsetY(_characterProvider.MainCharacter.RenderProperties);
Expand All @@ -131,11 +135,8 @@ public MapCoordinate CalculateGridCoordinatesFromDrawLocation(Vector2 drawLocati
const int ViewportWidthFactor = 288; // 640 * (1/2) - 32
const int ViewportHeightFactor = 142; // 480 * (3/10) - 2

var msX = drawLocation.X - GridSpaceWidth / 2;
var msY = drawLocation.Y - GridSpaceHeight / 2;

var widthFactor = _clientWindowSizeProvider.Width * 9 / 10; // 288 = 640 * .45, 576 = 640 * .9
var heightFactor = _clientWindowSizeProvider.Height * 3 / 10;
var msX = drawLocation.X - IGridDrawCoordinateCalculator.DefaultGridWidth / 2;
var msY = drawLocation.Y - IGridDrawCoordinateCalculator.DefaultGridHeight / 2;

var offsetX = _renderOffsetCalculator.CalculateOffsetX(_characterProvider.MainCharacter.RenderProperties);
var offsetY = _renderOffsetCalculator.CalculateOffsetY(_characterProvider.MainCharacter.RenderProperties);
Expand Down Expand Up @@ -164,6 +165,11 @@ private Vector2 GetMainCharacterWalkAdjustOffsets()

public interface IGridDrawCoordinateCalculator
{
const int DefaultGridWidth = 64;
const int DefaultGridHeight = 32;

Vector2 CalculateRawRenderCoordinatesFromGridUnits(int gridX, int gridY, int tileWidth = DefaultGridWidth, int tileHeight = DefaultGridHeight);

Vector2 CalculateDrawCoordinatesFromGridUnits(int gridX, int gridY);

Vector2 CalculateDrawCoordinatesFromGridUnits(MapCoordinate mapCoordinate);
Expand All @@ -172,7 +178,7 @@ public interface IGridDrawCoordinateCalculator

Vector2 CalculateBaseLayerDrawCoordinatesFromGridUnits(MapCoordinate mapCoordinate);

Vector2 CalculateGroundLayerDrawCoordinatesFromGridUnits();
Vector2 CalculateGroundLayerRenderTargetDrawCoordinates(bool isMiniMap = false, int tileWidth = DefaultGridWidth, int tileHeight = DefaultGridHeight);

Vector2 CalculateDrawCoordinates(DomainNPC npc);

Expand Down
12 changes: 6 additions & 6 deletions EndlessClient/Rendering/Map/MapRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ private void DrawToSpriteBatch(SpriteBatch spriteBatch, GameTime gameTime)
{
spriteBatch.Begin();

var drawLoc = _gridDrawCoordinateCalculator.CalculateGroundLayerDrawCoordinatesFromGridUnits();
var drawLoc = _gridDrawCoordinateCalculator.CalculateGroundLayerRenderTargetDrawCoordinates();
var offset = _quakeState.Map(qs => qs.Offset).Match(some: o => o, none: () => 0);

lock (_rt_locker_)
Expand All @@ -370,11 +370,11 @@ private void DrawToSpriteBatch(SpriteBatch spriteBatch, GameTime gameTime)

spriteBatch.Draw(_mapObjectTarget, new Vector2(offset, 0), Color.White);

foreach (var target in _mapGridEffectRenderers.Values)
{
target.DrawBehindTarget(spriteBatch);
target.DrawInFrontOfTarget(spriteBatch);
}
foreach (var target in _mapGridEffectRenderers.Values)
{
target.DrawBehindTarget(spriteBatch);
target.DrawInFrontOfTarget(spriteBatch);
}

spriteBatch.End();
}
Expand Down
Loading

0 comments on commit abd8f85

Please sign in to comment.