using System.Collections.Generic;
using System.Drawing;
using Amphora;
using Azimuth;
using Blacklight.Core;
using Blacklight.Core.Cameras;
using Blacklight.Core.Drawables;
using Konis.Blacklight;
namespace Konis.Testbed
{
///
/// A particle world and what it takes to draw it with Blacklight.
///
public class ParticleDemo
{
private const SpriteBatch.Varying WrittenColumns =
SpriteBatch.Varying.TintColor | SpriteBatch.Varying.Transform;
private readonly WindowHandle window;
private readonly Camera camera;
private readonly Scene scene = new Scene();
private readonly Cel cel = new Cel();
private readonly SpriteSheet sheet;
private readonly SpriteSource source;
// One set for each emitter, since a batch reads its set in place until the cel is next cleared.
private readonly List entrySets = new List();
///
/// Makes a demo that draws into , which must already be bound.
///
public ParticleDemo(WindowHandle window, Camera camera, Rand random)
{
this.window = window;
this.camera = camera;
World = new ParticleWorld(random);
scene.Cels.Add(cel);
sheet = SpriteSheet.Create(
window, SoftDisc.Build(), spriteSize: new Size(SoftDisc.Side, SoftDisc.Side), borderSize: 0);
source = sheet.Frame(new Point(0, 0));
}
///
/// Gets the world the demo runs.
///
public ParticleWorld World { get; }
///
/// Gets or sets which of a spawn makes.
///
public int EffectIndex { get; set; }
///
/// Gets or sets how the world's three dimensions land on the screen.
///
public ViewProjection Projection { get; set; } = ViewProjection.Dimetric2To1;
///
/// Starts the chosen effect at .
///
public Emitter Spawn(Vector3 position, float preWarmSeconds)
{
return World.Spawn(Effects.All[EffectIndex].Def, position, preWarmSeconds);
}
///
/// Draws one complete frame.
///
public void Draw()
{
// Only FrameReset empties the batch pools, so the reset/queue/submit triple has to stay together.
window.FrameReset();
cel.Clear();
for (int i = 0; i < World.Count; i++)
{
var emitter = (StandardEmitter)World[i];
if (i == entrySets.Count)
{
entrySets.Add(new SpriteBatch.EntrySet());
}
int count = ParticleSpriteWriter.Write(emitter, Projection, source, entrySets[i]);
if (count == 0)
{
continue;
}
SpriteBatch batch = cel.NewSpriteBatchView(entrySets[i], count, WrittenColumns);
batch.Texture = sheet.Texture;
if (Effects.IsAdditive(emitter.Def))
{
batch.Additiveness = 1;
}
cel.AddEntity(batch, AffineMatrix.Identity);
}
window.DrawScene(scene, camera);
window.SubmitDrawCalls();
}
}
}