Support mixed indexed/BGRA terrain tiles.
This commit is contained in:
@@ -36,22 +36,13 @@ namespace OpenRA.Mods.Common.Terrain
|
||||
public sealed class DefaultTileCache : IDisposable
|
||||
{
|
||||
readonly Dictionary<ushort, TheaterTemplate> templates = new Dictionary<ushort, TheaterTemplate>();
|
||||
SheetBuilder sheetBuilder;
|
||||
readonly Cache<SheetType, SheetBuilder> sheetBuilders;
|
||||
readonly Sprite missingTile;
|
||||
readonly MersenneTwister random;
|
||||
|
||||
public DefaultTileCache(DefaultTerrain terrainInfo, Action<uint, string> onMissingImage = null)
|
||||
{
|
||||
var allocated = false;
|
||||
|
||||
Func<Sheet> allocate = () =>
|
||||
{
|
||||
if (allocated)
|
||||
throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
|
||||
allocated = true;
|
||||
|
||||
return new Sheet(SheetType.Indexed, new Size(terrainInfo.SheetSize, terrainInfo.SheetSize));
|
||||
};
|
||||
sheetBuilders = new Cache<SheetType, SheetBuilder>(t => new SheetBuilder(t, terrainInfo.SheetSize));
|
||||
|
||||
random = new MersenneTwister();
|
||||
|
||||
@@ -99,25 +90,16 @@ namespace OpenRA.Mods.Common.Terrain
|
||||
var offset = new float3(f.Offset, zOffset);
|
||||
var type = SheetBuilder.FrameTypeToSheetType(f.Type);
|
||||
|
||||
// Defer SheetBuilder creation until we know what type of frames we are loading!
|
||||
// TODO: Support mixed indexed and BGRA frames
|
||||
if (sheetBuilder == null)
|
||||
sheetBuilder = new SheetBuilder(SheetBuilder.FrameTypeToSheetType(f.Type), allocate);
|
||||
else if (type != sheetBuilder.Type)
|
||||
throw new YamlException("Sprite type mismatch. Terrain sprites must all be either Indexed or RGBA.");
|
||||
|
||||
var s = sheetBuilder.Allocate(f.Size, zRamp, offset);
|
||||
var s = sheetBuilders[type].Allocate(f.Size, zRamp, offset);
|
||||
OpenRA.Graphics.Util.FastCopyIntoChannel(s, f.Data, f.Type);
|
||||
|
||||
if (terrainInfo.EnableDepth)
|
||||
{
|
||||
var depthFrame = allFrames[j + frameCount];
|
||||
var ss = sheetBuilder.Allocate(f.Size, zRamp, offset);
|
||||
var depthType = SheetBuilder.FrameTypeToSheetType(depthFrame.Type);
|
||||
var ss = sheetBuilders[depthType].Allocate(depthFrame.Size, zRamp, offset);
|
||||
OpenRA.Graphics.Util.FastCopyIntoChannel(ss, depthFrame.Data, depthFrame.Type);
|
||||
|
||||
// s and ss are guaranteed to use the same sheet
|
||||
// because of the custom terrain sheet allocation
|
||||
s = new SpriteWithSecondaryData(s, s.Sheet, ss.Bounds, ss.Channel);
|
||||
s = new SpriteWithSecondaryData(s, ss.Sheet, ss.Bounds, ss.Channel);
|
||||
}
|
||||
|
||||
return s;
|
||||
@@ -137,12 +119,22 @@ namespace OpenRA.Mods.Common.Terrain
|
||||
}
|
||||
|
||||
// 1x1px transparent tile
|
||||
if (sheetBuilder.Type == SheetType.BGRA)
|
||||
missingTile = sheetBuilder.Add(new byte[4], SpriteFrameType.Bgra32, new Size(1, 1));
|
||||
else
|
||||
missingTile = sheetBuilder.Add(new byte[1], SpriteFrameType.Indexed8, new Size(1, 1));
|
||||
var missingDataLength = 1;
|
||||
var missingFrameType = SpriteFrameType.Indexed8;
|
||||
var missingSheetType = SheetType.Indexed;
|
||||
|
||||
Sheet.ReleaseBuffer();
|
||||
// Avoid creating an indexed sheet if all tiles are BGRA
|
||||
var missing = sheetBuilders.FirstOrDefault();
|
||||
if (missing.Value != null && missing.Key == SheetType.BGRA)
|
||||
{
|
||||
missingDataLength = 4;
|
||||
missingFrameType = SpriteFrameType.Bgra32;
|
||||
missingSheetType = SheetType.BGRA;
|
||||
}
|
||||
|
||||
missingTile = sheetBuilders[missingSheetType].Add(new byte[missingDataLength], missingFrameType, new Size(1, 1));
|
||||
foreach (var sb in sheetBuilders.Values)
|
||||
sb.Current.ReleaseBuffer();
|
||||
}
|
||||
|
||||
public bool HasTileSprite(TerrainTile r, int? variant = null)
|
||||
@@ -162,11 +154,12 @@ namespace OpenRA.Mods.Common.Terrain
|
||||
return template.Sprites[start * template.Stride + r.Index];
|
||||
}
|
||||
|
||||
public Sheet Sheet { get { return sheetBuilder.Current; } }
|
||||
public Sprite MissingTile { get { return missingTile; } }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
sheetBuilder.Dispose();
|
||||
foreach (var sb in sheetBuilders.Values)
|
||||
sb.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,9 +80,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
void IWorldLoaded.WorldLoaded(World world, WorldRenderer wr)
|
||||
{
|
||||
worldRenderer = wr;
|
||||
var emptySprite = new Sprite(tileCache.Sheet, Rectangle.Empty, TextureChannel.Alpha);
|
||||
spriteLayer = new TerrainSpriteLayer(world, wr, emptySprite, BlendMode.Alpha, world.Type != WorldType.Editor);
|
||||
|
||||
spriteLayer = new TerrainSpriteLayer(world, wr, tileCache.MissingTile, BlendMode.Alpha, world.Type != WorldType.Editor);
|
||||
foreach (var cell in map.AllCells)
|
||||
UpdateCell(cell);
|
||||
|
||||
@@ -124,7 +122,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
Sheet ITiledTerrainRenderer.Sheet { get { return tileCache.Sheet; } }
|
||||
Sprite ITiledTerrainRenderer.MissingTile { get { return tileCache.MissingTile; } }
|
||||
|
||||
Sprite ITiledTerrainRenderer.TileSprite(TerrainTile r, int? variant)
|
||||
{
|
||||
|
||||
@@ -654,7 +654,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[RequireExplicitImplementation]
|
||||
public interface ITiledTerrainRenderer
|
||||
{
|
||||
Sheet Sheet { get; }
|
||||
Sprite MissingTile { get; }
|
||||
Sprite TileSprite(TerrainTile r, int? variant = null);
|
||||
Rectangle TemplateBounds(TerrainTemplateInfo template);
|
||||
IEnumerable<IRenderable> RenderUIPreview(WorldRenderer wr, TerrainTemplateInfo template, int2 origin, float scale);
|
||||
|
||||
@@ -13,7 +13,6 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.D2k.Traits
|
||||
@@ -52,8 +51,7 @@ namespace OpenRA.Mods.D2k.Traits
|
||||
|
||||
void IWorldLoaded.WorldLoaded(World w, WorldRenderer wr)
|
||||
{
|
||||
var emptySprite = new Sprite(terrainRenderer.Sheet, Rectangle.Empty, TextureChannel.Alpha);
|
||||
render = new TerrainSpriteLayer(w, wr, emptySprite, BlendMode.Alpha, wr.World.Type != WorldType.Editor);
|
||||
render = new TerrainSpriteLayer(w, wr, terrainRenderer.MissingTile, BlendMode.Alpha, wr.World.Type != WorldType.Editor);
|
||||
paletteReference = wr.Palette(info.Palette);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user