using NLog;
using SFML.Graphics;
using SFML.System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Spine.Exporters
{
///
/// 导出类基类, 提供基本的帧渲染功能
///
public abstract class BaseExporter : IDisposable
{
///
/// 日志器
///
protected static readonly Logger _logger = LogManager.GetCurrentClassLogger();
///
/// 用于渲染的画布
///
protected RenderTexture _renderTexture;
///
/// 初始化导出器
///
/// 画布宽像素值
/// 画布高像素值
public BaseExporter(uint width , uint height)
{
if (width <= 0 || height <= 0)
throw new ArgumentException($"Invalid resolution: {width}, {height}");
_renderTexture = new(width, height);
_renderTexture.SetActive(false);
}
///
/// 初始化导出器
///
public BaseExporter(Vector2u resolution)
{
if (resolution.X <= 0 || resolution.Y <= 0)
throw new ArgumentException($"Invalid resolution: {resolution}");
_renderTexture = new(resolution.X, resolution.Y);
_renderTexture.SetActive(false);
}
///
/// 可选的进度回调函数
///
/// - total: 任务总量
/// - done: 已完成量
/// - progressText: 需要设置的进度提示文本
///
///
public Action? ProgressReporter { get => _progressReporter; set => _progressReporter = value; }
protected Action? _progressReporter;
///
/// 背景颜色
///
public Color BackgroundColor
{
get => _backgroundColor;
set
{
_backgroundColor = value;
var bcPma = value;
var a = bcPma.A / 255f;
bcPma.R = (byte)(bcPma.R * a);
bcPma.G = (byte)(bcPma.G * a);
bcPma.B = (byte)(bcPma.B * a);
_backgroundColorPma = bcPma;
}
}
protected Color _backgroundColor = Color.Transparent;
///
/// 预乘后的背景颜色
///
protected Color _backgroundColorPma = Color.Transparent;
///
/// 画面分辨率
///
///
public Vector2u Resolution
{
get => _renderTexture.Size;
set
{
if (value.X <= 0 || value.Y <= 0)
{
_logger.Warn("Omit invalid exporter resolution: {0}", value);
return;
}
if (_renderTexture.Size != value)
{
using var old = _renderTexture;
using var view = old.GetView();
var renderTexture = new RenderTexture(value.X, value.Y);
renderTexture.SetActive(false);
renderTexture.SetView(view);
_renderTexture = renderTexture;
}
}
}
///
///
///
public FloatRect Viewport
{
get { using var view = _renderTexture.GetView(); return view.Viewport; }
set { using var view = _renderTexture.GetView(); view.Viewport = value; _renderTexture.SetView(view); }
}
///
///
///
public Vector2f Center
{
get { using var view = _renderTexture.GetView(); return view.Center; }
set { using var view = _renderTexture.GetView(); view.Center = value; _renderTexture.SetView(view); }
}
///
///
///
public Vector2f Size
{
get { using var view = _renderTexture.GetView(); return view.Size; }
set { using var view = _renderTexture.GetView(); view.Size = value; _renderTexture.SetView(view); }
}
///
///
///
public float Rotation
{
get { using var view = _renderTexture.GetView(); return view.Rotation; }
set { using var view = _renderTexture.GetView(); view.Rotation = value; _renderTexture.SetView(view); }
}
///
/// 获取的一帧, 结果是预乘的
///
protected virtual SFMLImageVideoFrame GetFrame(SpineObject[] spines)
{
_renderTexture.SetActive(true);
_renderTexture.Clear(_backgroundColorPma);
foreach (var sp in spines.Reverse()) _renderTexture.Draw(sp);
_renderTexture.Display();
_renderTexture.SetActive(false);
return new(_renderTexture.Texture.CopyToImage());
}
///
/// 导出给定的模型, 从前往后对应从上往下的渲染顺序
///
/// 输出路径, 一般而言都是文件路径, 少数情况指定的是文件夹
/// 要导出的模型, 从前往后对应从上往下的渲染顺序
public abstract void Export(string output, params SpineObject[] spines);
#region IDisposable 接口实现
private bool _disposed = false;
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
if (disposing)
{
_renderTexture.Dispose();
}
_disposed = true;
}
~BaseExporter()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
if (_disposed)
{
GC.SuppressFinalize(this);
}
}
#endregion
}
}