internal SheetBuilder(TextureChannel ch) { current = null; rowHeight = 0; channel = null; initialChannel = ch; }
public override void Initialize(WidgetArgs args) { base.Initialize(args); var width = world.Map.Bounds.Width; var height = world.Map.Bounds.Height; var size = Math.Max(width, height); var rb = RenderBounds; previewScale = Math.Min(rb.Width * 1f / width, rb.Height * 1f / height); previewOrigin = new int2((int)(previewScale * (size - width) / 2), (int)(previewScale * (size - height) / 2)); mapRect = new Rectangle(previewOrigin.X, previewOrigin.Y, (int)(previewScale * width), (int)(previewScale * height)); // Only needs to be done once using (var terrainBitmap = Minimap.TerrainBitmap(world.Map.Rules.TileSets[world.Map.Tileset], world.Map)) { var r = new Rectangle(0, 0, width, height); var s = new Size(terrainBitmap.Width, terrainBitmap.Height); var terrainSheet = new Sheet(s, false); terrainSheet.Texture.SetData(terrainBitmap); terrainSprite = new Sprite(terrainSheet, r, TextureChannel.Alpha); // Data is set in Tick() customTerrainSprite = new Sprite(new Sheet(s, false), r, TextureChannel.Alpha); actorSprite = new Sprite(new Sheet(s, false), r, TextureChannel.Alpha); shroudSprite = new Sprite(new Sheet(s, false), r, TextureChannel.Alpha); } }
public void Init(Manifest m, Dictionary<string, string> info) { var sheet = new Sheet(SheetType.BGRA, info["Image"]); var res = Game.Renderer.Resolution; bounds = new Rectangle(0, 0, res.Width, res.Height); sprite = new Sprite(sheet, new Rectangle(0, 0, 1024, 480), TextureChannel.Alpha); }
public override void Init(Manifest m, Dictionary<string, string> info) { loadInfo = info; // Avoid standard loading mechanisms so we // can display loadscreen as early as possible r = Game.Renderer; if (r == null) return; sheet = new Sheet(SheetType.BGRA, Platform.ResolvePath(loadInfo["Image"])); var res = r.Resolution; bounds = new Rectangle(0, 0, res.Width, res.Height); borderTop = new Sprite(sheet, new Rectangle(161, 128, 62, 33), TextureChannel.Alpha); borderBottom = new Sprite(sheet, new Rectangle(161, 223, 62, 33), TextureChannel.Alpha); borderLeft = new Sprite(sheet, new Rectangle(128, 161, 33, 62), TextureChannel.Alpha); borderRight = new Sprite(sheet, new Rectangle(223, 161, 33, 62), TextureChannel.Alpha); cornerTopLeft = new Sprite(sheet, new Rectangle(128, 128, 33, 33), TextureChannel.Alpha); cornerTopRight = new Sprite(sheet, new Rectangle(223, 128, 33, 33), TextureChannel.Alpha); cornerBottomLeft = new Sprite(sheet, new Rectangle(128, 223, 33, 33), TextureChannel.Alpha); cornerBottomRight = new Sprite(sheet, new Rectangle(223, 223, 33, 33), TextureChannel.Alpha); nodLogo = new Sprite(sheet, new Rectangle(0, 256, 256, 256), TextureChannel.Alpha); gdiLogo = new Sprite(sheet, new Rectangle(256, 256, 256, 256), TextureChannel.Alpha); evaLogo = new Sprite(sheet, new Rectangle(256, 64, 128, 64), TextureChannel.Alpha); nodPos = new float2(bounds.Width / 2 - 384, bounds.Height / 2 - 128); gdiPos = new float2(bounds.Width / 2 + 128, bounds.Height / 2 - 128); evaPos = new float2(bounds.Width - 43 - 128, 43); brightBlock = new Sprite(sheet, new Rectangle(320, 0, 16, 35), TextureChannel.Alpha); dimBlock = new Sprite(sheet, new Rectangle(336, 0, 16, 35), TextureChannel.Alpha); versionText = m.Mod.Version; }
public void DrawVertexBuffer(IVertexBuffer<Vertex> buffer, int start, int length, PrimitiveType type, Sheet sheet) { shader.SetTexture("DiffuseTexture", sheet.Texture); renderer.Device.SetBlendMode(BlendMode.Alpha); shader.Render(() => renderer.DrawBatch(buffer, start, length, type)); renderer.Device.SetBlendMode(BlendMode.None); }
public void Init(Manifest m, Dictionary<string, string> info) { var sheet = new Sheet("mods/modchooser/chrome.png"); var res = Game.Renderer.Resolution; bounds = new Rectangle(0, 0, res.Width, res.Height); sprite = new Sprite(sheet, new Rectangle(0,0,1024,480), TextureChannel.Alpha); }
public SheetBuilder(SheetType t, Func<Sheet> allocateSheet) { channel = TextureChannel.Red; type = t; current = allocateSheet(); this.allocateSheet = allocateSheet; }
public TerrainRenderer(World world, WorldRenderer wr) { this.world = world; this.map = world.Map; var tileSize = new Size( Game.CellSize, Game.CellSize ); var tileMapping = new Cache<TileReference<ushort,byte>, Sprite>( x => Game.modData.SheetBuilder.Add(world.TileSet.GetBytes(x), tileSize)); var vertices = new Vertex[4 * map.Bounds.Height * map.Bounds.Width]; terrainSheet = tileMapping[map.MapTiles.Value[map.Bounds.Left, map.Bounds.Top]].sheet; int nv = 0; var terrainPalette = wr.Palette("terrain").Index; for( int j = map.Bounds.Top; j < map.Bounds.Bottom; j++ ) for( int i = map.Bounds.Left; i < map.Bounds.Right; i++ ) { var tile = tileMapping[map.MapTiles.Value[i, j]]; // TODO: move GetPaletteIndex out of the inner loop. Util.FastCreateQuad(vertices, Game.CellSize * new float2(i, j), tile, terrainPalette, nv, tile.size); nv += 4; if (tileMapping[map.MapTiles.Value[i, j]].sheet != terrainSheet) throw new InvalidOperationException("Terrain sprites span multiple sheets"); } vertexBuffer = Game.Renderer.Device.CreateVertexBuffer( vertices.Length ); vertexBuffer.SetData( vertices, nv ); }
public TerrainSpriteLayer(World world, WorldRenderer wr, Sheet sheet, BlendMode blendMode, PaletteReference palette, bool restrictToBounds) { worldRenderer = wr; this.restrictToBounds = restrictToBounds; Sheet = sheet; BlendMode = blendMode; paletteIndex = palette.TextureIndex; map = world.Map; rowStride = 4 * map.MapSize.X; vertices = new Vertex[rowStride * map.MapSize.Y]; vertexBuffer = Game.Renderer.Device.CreateVertexBuffer(vertices.Length); emptySprite = new Sprite(sheet, Rectangle.Empty, TextureChannel.Alpha); wr.PaletteInvalidated += () => { paletteIndex = palette.TextureIndex; // Everything in the layer uses the same palette, // so we can fix the indices in one pass for (var i = 0; i < vertices.Length; i++) { var v = vertices[i]; vertices[i] = new Vertex(v.X, v.Y, v.Z, v.U, v.V, paletteIndex, v.C); } for (var row = 0; row < map.MapSize.Y; row++) dirtyRows.Add(row); }; }
public static Sprite GetImage(Renderer renderer, string collection, string image) { // Cached sprite if (cachedSprites.ContainsKey(collection) && cachedSprites[collection].ContainsKey(image)) return cachedSprites[collection][image]; MappedImage mi; try { mi = collections[collection][image]; } catch (KeyNotFoundException) { throw new InvalidOperationException( "Collection `{0}` does not have an image `{1}`".F(collection, image)); } // Cached sheet Sheet sheet; if (cachedSheets.ContainsKey(mi.Src)) sheet = cachedSheets[mi.Src]; else { sheet = new Sheet(renderer, mi.Src); cachedSheets.Add(mi.Src, sheet); } // Cache the sprite if (!cachedSprites.ContainsKey(collection)) cachedSprites.Add(collection, new Dictionary<string, Sprite>()); cachedSprites[collection].Add(image, mi.GetImage(renderer, sheet)); return cachedSprites[collection][image]; }
public SheetBuilder(Renderer r, TextureChannel ch) { renderer = r; current = null; rowHeight = 0; channel = null; initialChannel = ch; }
void SetRenderStateForSprite(Sprite s) { renderer.CurrentBatchRenderer = this; if (s.BlendMode != currentBlend || s.Sheet != currentSheet || nv + 4 > renderer.TempBufferSize) Flush(); currentBlend = s.BlendMode; currentSheet = s.Sheet; }
public void DrawSprite(Sprite s, float2 location, string palette, float2 size) { if (s.sheet != currentSheet) Flush(); currentSheet = s.sheet; Util.FastCreateQuad(vertices, indices, location.ToInt2(), s, Game.world.WorldRenderer.GetPaletteIndex(palette), nv, ni, size); nv += 4; ni += 6; if (++sprites >= spritesPerBatch) Flush(); }
public void Init(ModData modData, Dictionary<string, string> info) { var res = Game.Renderer.Resolution; bounds = new Rectangle(0, 0, res.Width, res.Height); using (var stream = modData.DefaultFileSystem.Open(info["Image"])) { var sheet = new Sheet(SheetType.BGRA, stream); sprite = new Sprite(sheet, new Rectangle(0, 0, 1024, 480), TextureChannel.Alpha); } }
public void Init(Dictionary<string, string> info) { Info = info; // Avoid standard loading mechanisms so we // can display loadscreen as early as possible r = Game.Renderer; if (r == null) return; var s = new Sheet("mods/d2k/uibits/loadscreen.png"); Logo = new Sprite(s, new Rectangle(0,0,256,256), TextureChannel.Alpha); Stripe = new Sprite(s, new Rectangle(256,0,256,256), TextureChannel.Alpha); StripeRect = new Rectangle(0, Renderer.Resolution.Height/2 - 128, Renderer.Resolution.Width, 256); LogoPos = new float2(Renderer.Resolution.Width/2 - 128, Renderer.Resolution.Height/2 - 128); }
public override void Initialize(WidgetArgs args) { base.Initialize(args); // Bitmap data is generated in a background thread and then flipped front = new byte[4*256*256]; back = new byte[4*256*256]; var rect = new Rectangle((int)(255*SRange[0]), (int)(255*(1 - VRange[1])), (int)(255*(SRange[1] - SRange[0]))+1, (int)(255*(VRange[1] - VRange[0])) + 1); var mixerSheet = new Sheet(new Size(256, 256), false); mixerSheet.Texture.SetData(front, 256, 256); mixerSprite = new Sprite(mixerSheet, rect, TextureChannel.Alpha); }
public void Flush() { if (nv > 0) { shader.SetTexture("DiffuseTexture", currentSheet.GetTexture()); renderer.Device.SetBlendMode(currentBlend); shader.Render(renderAction); renderer.Device.SetBlendMode(BlendMode.None); nv = 0; currentSheet = null; } }
public void DrawSprite(Sprite s, float2 location, int paletteIndex, float2 size) { Renderer.CurrentBatchRenderer = this; if (s.sheet != currentSheet) Flush(); if( nv + 4 > Renderer.TempBufferSize ) Flush(); currentSheet = s.sheet; Util.FastCreateQuad(vertices, location.ToInt2(), s, paletteIndex, nv, size); nv += 4; }
public void Init() { // Avoid standard loading mechanisms so we // can display loadscreen as early as possible r = Game.Renderer; if (r == null) return; Font = r.BoldFont; var s = new Sheet("mods/ra/loadscreen.png"); Logo = new Sprite(s, new Rectangle(0,0,256,256), TextureChannel.Alpha); Stripe = new Sprite(s, new Rectangle(256,0,256,256), TextureChannel.Alpha); StripeRect = new Rectangle(0, Renderer.Resolution.Height/2 - 128, Renderer.Resolution.Width, 256); LogoPos = new float2(Renderer.Resolution.Width/2 - 128, Renderer.Resolution.Height/2 - 128); }
public void Init(Manifest m, Dictionary<string, string> info) { // Avoid standard loading mechanisms so we // can display the loadscreen as early as possible r = Game.Renderer; if (r == null) return; messages = info["Text"].Split(','); var s = new Sheet(info["Image"]); logo = new Sprite(s, new Rectangle(0, 0, 256, 256), TextureChannel.Alpha); stripe = new Sprite(s, new Rectangle(256, 0, 256, 256), TextureChannel.Alpha); stripeRect = new Rectangle(0, r.Resolution.Height / 2 - 128, r.Resolution.Width, 256); logoPos = new float2(r.Resolution.Width / 2 - 128, r.Resolution.Height / 2 - 128); }
public Sprite(Sheet sheet, Rectangle bounds, float2 offset, TextureChannel channel, BlendMode blendMode = BlendMode.Alpha) { Sheet = sheet; Bounds = bounds; Offset = offset; Channel = channel; Size = new float2(bounds.Size); BlendMode = blendMode; FractionalOffset = offset / Size; Left = (float)Math.Min(bounds.Left, bounds.Right) / sheet.Size.Width; Top = (float)Math.Min(bounds.Top, bounds.Bottom) / sheet.Size.Height; Right = (float)Math.Max(bounds.Left, bounds.Right) / sheet.Size.Width; Bottom = (float)Math.Max(bounds.Top, bounds.Bottom) / sheet.Size.Height; }
public override void Draw() { var map = Map(); if( map == null ) return; if (lastMap != map) { lastMap = map; // Update image data var preview = PreviewCache[map]; if( mapChooserSheet == null || mapChooserSheet.Size.Width != preview.Width || mapChooserSheet.Size.Height != preview.Height ) mapChooserSheet = new Sheet(new Size( preview.Width, preview.Height ) ); mapChooserSheet.Texture.SetData( preview ); mapChooserSprite = new Sprite( mapChooserSheet, new Rectangle( 0, 0, map.Bounds.Width, map.Bounds.Height ), TextureChannel.Alpha ); } // Update map rect PreviewScale = Math.Min(RenderBounds.Width * 1.0f / map.Bounds.Width, RenderBounds.Height * 1.0f / map.Bounds.Height); var size = Math.Max(map.Bounds.Width, map.Bounds.Height); var dw = (int)(PreviewScale * (size - map.Bounds.Width)) / 2; var dh = (int)(PreviewScale * (size - map.Bounds.Height)) / 2; MapRect = new Rectangle(RenderBounds.X + dw, RenderBounds.Y + dh, (int)(map.Bounds.Width * PreviewScale), (int)(map.Bounds.Height * PreviewScale)); Game.Renderer.RgbaSpriteRenderer.DrawSprite( mapChooserSprite, new float2(MapRect.Location), new float2( MapRect.Size ) ); if (ShowSpawnPoints) { var colors = SpawnColors(); foreach (var p in map.GetSpawnPoints()) { var owned = colors.ContainsKey(p); var pos = ConvertToPreview(p); var sprite = ChromeProvider.GetImage("spawnpoints", owned ? "owned" : "unowned"); var offset = new int2(-sprite.bounds.Width/2, -sprite.bounds.Height/2); if (owned) WidgetUtils.FillRectWithColor(new Rectangle(pos.X + offset.X + 2, pos.Y + offset.Y + 2, 12, 12), colors[p]); Game.Renderer.RgbaSpriteRenderer.DrawSprite(sprite, pos + offset); } } }
public void Open(VqaReader video) { this.video = video; stopped = true; paused = true; Game.Sound.StopVideo(); onComplete = () => { }; invLength = video.Framerate * 1f / video.Frames; var size = Math.Max(video.Width, video.Height); var textureSize = Exts.NextPowerOf2(size); var videoSheet = new Sheet(SheetType.BGRA, new Size(textureSize, textureSize)); videoSheet.GetTexture().ScaleFilter = TextureScaleFilter.Linear; videoSheet.GetTexture().SetData(video.FrameData); videoSprite = new Sprite(videoSheet, new Rectangle( 0, 0, video.Width, video.Height), TextureChannel.Alpha); var scale = Math.Min((float)RenderBounds.Width / video.Width, (float)RenderBounds.Height / video.Height * AspectRatio); videoOrigin = new float2( RenderBounds.X + (RenderBounds.Width - scale * video.Width) / 2, RenderBounds.Y + (RenderBounds.Height - scale * video.Height * AspectRatio) / 2); // Round size to integer pixels. Round up to be consistent with the scale calcuation. videoSize = new float2((int)Math.Ceiling(video.Width * scale), (int)Math.Ceiling(video.Height * AspectRatio * scale)); if (!DrawOverlay) return; var scaledHeight = (int)videoSize.Y; overlay = new uint[Exts.NextPowerOf2(scaledHeight), 1]; var black = (uint)255 << 24; for (var y = 0; y < scaledHeight; y += 2) overlay[y, 0] = black; var overlaySheet = new Sheet(SheetType.BGRA, new Size(1, Exts.NextPowerOf2(scaledHeight))); overlaySheet.GetTexture().SetData(overlay); overlaySprite = new Sprite(overlaySheet, new Rectangle(0, 0, 1, scaledHeight), TextureChannel.Alpha); }
public static Sprite GetImage(string collectionName, string imageName) { if (string.IsNullOrEmpty(collectionName)) return null; // Cached sprite Dictionary<string, Sprite> cachedCollection; Sprite sprite; if (cachedSprites.TryGetValue(collectionName, out cachedCollection) && cachedCollection.TryGetValue(imageName, out sprite)) return sprite; Collection collection; if (!collections.TryGetValue(collectionName, out collection)) { Log.Write("debug", "Could not find collection '{0}'", collectionName); return null; } MappedImage mi; if (!collection.Regions.TryGetValue(imageName, out mi)) return null; // Cached sheet Sheet sheet; if (cachedSheets.ContainsKey(mi.Src)) sheet = cachedSheets[mi.Src]; else { using (var stream = fileSystem.Open(mi.Src)) sheet = new Sheet(SheetType.BGRA, stream); cachedSheets.Add(mi.Src, sheet); } // Cache the sprite if (cachedCollection == null) { cachedCollection = new Dictionary<string, Sprite>(); cachedSprites.Add(collectionName, cachedCollection); } var image = mi.GetImage(sheet); cachedCollection.Add(imageName, image); return image; }
public TerrainSpriteLayer(World world, WorldRenderer wr, Sheet sheet, BlendMode blendMode, PaletteReference palette, bool restrictToBounds) { worldRenderer = wr; this.restrictToBounds = restrictToBounds; Sheet = sheet; BlendMode = blendMode; this.palette = palette; map = world.Map; rowStride = 6 * map.MapSize.X; vertices = new Vertex[rowStride * map.MapSize.Y]; vertexBuffer = Game.Renderer.Device.CreateVertexBuffer(vertices.Length); emptySprite = new Sprite(sheet, Rectangle.Empty, TextureChannel.Alpha); wr.PaletteInvalidated += UpdatePaletteIndices; }
public Sheet AllocateSheet() { // Reuse cached fbo if (unmappedBuffers.Count > 0) { var kv = unmappedBuffers.Pop(); mappedBuffers.Add(kv.Key, kv.Value); return kv.Key; } var size = new Size(renderer.SheetSize, renderer.SheetSize); var framebuffer = renderer.Device.CreateFrameBuffer(size); var sheet = new Sheet(SheetType.BGRA, framebuffer.Texture); mappedBuffers.Add(sheet, framebuffer); return sheet; }
public Sprite(Sheet sheet, Rectangle bounds, float zRamp, float3 offset, TextureChannel channel, BlendMode blendMode = BlendMode.Alpha) { Sheet = sheet; Bounds = bounds; Offset = offset; ZRamp = zRamp; Channel = channel; Size = new float3(bounds.Size.Width, bounds.Size.Height, bounds.Size.Height * zRamp); BlendMode = blendMode; FractionalOffset = Size.Z != 0 ? offset / Size : new float3(offset.X / Size.X, offset.Y / Size.Y, 0); Left = (float)Math.Min(bounds.Left, bounds.Right) / sheet.Size.Width; Top = (float)Math.Min(bounds.Top, bounds.Bottom) / sheet.Size.Height; Right = (float)Math.Max(bounds.Left, bounds.Right) / sheet.Size.Width; Bottom = (float)Math.Max(bounds.Top, bounds.Bottom) / sheet.Size.Height; }
public void DrawSprite(Sprite s, float2 a, float2 b, float2 c, float2 d) { Renderer.CurrentBatchRenderer = this; if (s.sheet != currentSheet) Flush(); if (s.blendMode != currentBlend) Flush(); if (nv + 4 > Renderer.TempBufferSize) Flush(); currentSheet = s.sheet; currentBlend = s.blendMode; Util.FastCreateQuad(vertices, a, b, c, d, s, 0, nv); nv += 4; }
public override void Initialize(WidgetArgs args) { base.Initialize(args); // The four layers are stored in a 2x2 grid within a single texture radarSheet = new Sheet(SheetType.BGRA, new Size(2 * previewWidth, 2 * previewHeight).NextPowerOf2()); radarSheet.CreateBuffer(); radarData = radarSheet.GetData(); MapBoundsChanged(); // Set initial terrain data foreach (var cell in world.Map.AllCells) UpdateTerrainCell(cell); world.Map.MapTiles.Value.CellEntryChanged += UpdateTerrainCell; world.Map.CustomTerrain.CellEntryChanged += UpdateTerrainCell; }
void DrawSprite(Sprite s, float2 location, int paletteIndex, float2 size) { Renderer.CurrentBatchRenderer = this; if (s.sheet != currentSheet) Flush(); if (s.blendMode != currentBlend) Flush(); if (nv + 4 > Renderer.TempBufferSize) Flush(); currentBlend = s.blendMode; currentSheet = s.sheet; Util.FastCreateQuad(vertices, location + s.offset, s, paletteIndex, nv, size); nv += 4; }
public void DrawVertexBuffer(IVertexBuffer <Vertex> buffer, int start, int length, PrimitiveType type, Sheet sheet) { shader.SetTexture("DiffuseTexture", sheet.GetTexture()); renderer.Device.SetBlendMode(BlendMode.Alpha); shader.Render(() => renderer.DrawBatch(buffer, start, length, type)); renderer.Device.SetBlendMode(BlendMode.None); }
public Sprite(Sheet sheet, Rectangle bounds, TextureChannel channel, BlendMode blendMode) : this(sheet, bounds, float2.Zero, channel, blendMode) { }
public Sprite GetImage(Sheet s) { return(new Sprite(s, rect, TextureChannel.Alpha)); }
public Sprite(Sheet sheet, Rectangle bounds, TextureChannel channel) : this(sheet, bounds, float2.Zero, channel) { }
public ModelRenderData(int start, int count, Sheet sheet) { Start = start; Count = count; Sheet = sheet; }
public Theater(TileSet tileset) { this.tileset = tileset; 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(tileset.SheetSize, tileset.SheetSize))); }; random = new MersenneTwister(); var frameCache = new FrameCache(Game.ModData.DefaultFileSystem, Game.ModData.SpriteLoaders); foreach (var t in tileset.Templates) { var variants = new List <Sprite[]>(); foreach (var i in t.Value.Images) { var allFrames = frameCache[i]; var frameCount = tileset.EnableDepth ? allFrames.Length / 2 : allFrames.Length; var indices = t.Value.Frames != null ? t.Value.Frames : Enumerable.Range(0, frameCount); variants.Add(indices.Select(j => { var f = allFrames[j]; var tile = t.Value.Contains(j) ? t.Value[j] : null; // The internal z axis is inverted from expectation (negative is closer) var zOffset = tile != null ? -tile.ZOffset : 0; var zRamp = tile != null ? tile.ZRamp : 1f; 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 InvalidDataException("Sprite type mismatch. Terrain sprites must all be either Indexed or RGBA."); } var s = sheetBuilder.Allocate(f.Size, zRamp, offset); Util.FastCopyIntoChannel(s, f.Data); if (tileset.EnableDepth) { var ss = sheetBuilder.Allocate(f.Size, zRamp, offset); Util.FastCopyIntoChannel(ss, allFrames[j + frameCount].Data); // 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); } return(s); }).ToArray()); } var allSprites = variants.SelectMany(s => s); // Ignore the offsets baked into R8 sprites if (tileset.IgnoreTileSpriteOffsets) { allSprites = allSprites.Select(s => new Sprite(s.Sheet, s.Bounds, s.ZRamp, new float3(float2.Zero, s.Offset.Z), s.Channel, s.BlendMode)); } templates.Add(t.Value.Id, new TheaterTemplate(allSprites.ToArray(), variants.First().Count(), t.Value.Images.Length)); } // 1x1px transparent tile missingTile = sheetBuilder.Add(new byte[sheetBuilder.Type == SheetType.BGRA ? 4 : 1], new Size(1, 1)); Sheet.ReleaseBuffer(); }
public Theater(TileSet tileset, Action <uint, string> onMissingImage = null) { this.tileset = tileset; 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(tileset.SheetSize, tileset.SheetSize))); }; random = new MersenneTwister(); var frameCache = new FrameCache(Game.ModData.DefaultFileSystem, Game.ModData.SpriteLoaders); foreach (var t in tileset.Templates) { var variants = new List <Sprite[]>(); foreach (var i in t.Value.Images) { ISpriteFrame[] allFrames; if (onMissingImage != null) { try { allFrames = frameCache[i]; } catch (FileNotFoundException) { onMissingImage(t.Key, i); continue; } } else { allFrames = frameCache[i]; } var frameCount = tileset.EnableDepth ? allFrames.Length / 2 : allFrames.Length; var indices = t.Value.Frames != null ? t.Value.Frames : Exts.MakeArray(t.Value.TilesCount, j => j); var start = indices.Min(); var end = indices.Max(); if (start < 0 || end >= frameCount) { throw new YamlException("Template `{0}` uses frames [{1}..{2}] of {3}, but only [0..{4}] actually exist" .F(t.Key, start, end, i, frameCount - 1)); } variants.Add(indices.Select(j => { var f = allFrames[j]; var tile = t.Value.Contains(j) ? t.Value[j] : null; // The internal z axis is inverted from expectation (negative is closer) var zOffset = tile != null ? -tile.ZOffset : 0; var zRamp = tile != null ? tile.ZRamp : 1f; 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); Util.FastCopyIntoChannel(s, f.Data, f.Type); if (tileset.EnableDepth) { var ss = sheetBuilder.Allocate(f.Size, zRamp, offset); var depthFrame = allFrames[j + frameCount]; 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); } return(s); }).ToArray()); } var allSprites = variants.SelectMany(s => s); // Ignore the offsets baked into R8 sprites if (tileset.IgnoreTileSpriteOffsets) { allSprites = allSprites.Select(s => new Sprite(s.Sheet, s.Bounds, s.ZRamp, new float3(float2.Zero, s.Offset.Z), s.Channel, s.BlendMode)); } if (onMissingImage != null && !variants.Any()) { continue; } templates.Add(t.Value.Id, new TheaterTemplate(allSprites.ToArray(), variants.First().Count(), t.Value.Images.Length)); } // 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)); } Sheet.ReleaseBuffer(); }
public void DrawVertexBuffer(IVertexBuffer <Vertex> buffer, int start, int length, PrimitiveType type, Sheet sheet, BlendMode blendMode) { shader.SetTexture("Texture0", sheet.GetTexture()); renderer.Context.SetBlendMode(blendMode); shader.PrepareRender(); renderer.DrawBatch(buffer, start, length, type); renderer.Context.SetBlendMode(BlendMode.None); }
public static Sprite GetImageOld(string collectionName, string imageName) { if (imageName == "harktitle") { } if (string.IsNullOrEmpty(collectionName)) { return(null); } // Cached sprite Dictionary <string, Sprite> cachedCollection; Sprite sprite; if (cachedSprites.TryGetValue(collectionName, out cachedCollection) && cachedCollection.TryGetValue(imageName, out sprite)) { return(sprite); } Collection collection; if (!collections.TryGetValue(collectionName, out collection)) { Log.Write("debug", "Could not find collection '{0}'", collectionName); return(null); } MappedImage mi; if (!collection.Regions.TryGetValue(imageName, out mi)) { return(null); } SequenceProvider seqprov; seqprov = World.Map.Rules.Sequences; // по идее, можно написать в chrome.yaml разные ресурсы игры cps и т.п. , они будут загружаться , только при обращении в этот метод. // при обращении за cps , переменная wolrd уже будет заполнена. bool switch2Seq = false; if (seqprov != null) { if (seqprov.HasSequence(mi.Src)) { switch2Seq = true; } } Sprite image = null, image2 = null; Sheet sheet; if (switch2Seq) { if (cachedSheets.ContainsKey(mi.Src)) //mi.Src это имя png файла. { sheet = cachedSheets[mi.Src]; } else { sheet = seqprov.GetSequence(mi.Src, "idle").GetSprite(0).Sheet; cachedSheets.Add(mi.Src, sheet); } image2 = seqprov.GetSequence(mi.Src, "idle").GetSprite(0); int2 offset = new int2(image2.Bounds.Location.X, image2.Bounds.Location.Y); //основная часть текстуры image = new Sprite(sheet, new Rectangle(mi.rect.X + offset.X, mi.rect.Y + offset.Y, mi.rect.Width, mi.rect.Height), TextureChannel.Red); //смещение в основной части текстуры if (mi.Rotate > 0) { // передаем данные о повороте, если больше 0 image.Rotate = mi.Rotate; } if (mi.Stretched) { image.Stretched = true; } image.SpriteType = 3; // для Utils.FastCreateQuad для алгоритма Fill rect with if (cachedCollection == null) { cachedCollection = new Dictionary <string, Sprite>(); cachedSprites.Add(collectionName, cachedCollection); } cachedCollection.Add(imageName, image); return(image); } if (!switch2Seq) { // Cached sheet if (cachedSheets.ContainsKey(mi.Src)) //mi.Src это имя png файла. То есть Sheet создается под каждый файл png. { sheet = cachedSheets[mi.Src]; } else { using (var stream = fileSystem.Open(mi.Src)) sheet = new Sheet(SheetType.BGRA, stream); cachedSheets.Add(mi.Src, sheet); } // Cache the sprite if (cachedCollection == null) { cachedCollection = new Dictionary <string, Sprite>(); cachedSprites.Add(collectionName, cachedCollection); } image = mi.GetImage(sheet); cachedCollection.Add(imageName, image); } return(image); }
public Sprite(Sheet sheet, Rectangle bounds, TextureChannel channel, float scale = 1) : this(sheet, bounds, 0, float2.Zero, channel, BlendMode.Alpha, scale) { }