Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b23c779d3 | ||
|
|
f5684a50dc | ||
|
|
579ce9f944 | ||
|
|
7aa88089b8 | ||
|
|
be983f8407 | ||
|
|
249b930602 | ||
|
|
6472f378b7 | ||
|
|
8672f0571c | ||
|
|
e7a990c1bd | ||
|
|
6727fa8e8f | ||
|
|
66d8c489b5 | ||
|
|
1931c4713a | ||
|
|
f19f172e7c | ||
|
|
092fa76124 |
14
CHANGELOG.md
14
CHANGELOG.md
@@ -1,5 +1,19 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
## v0.16.7
|
||||||
|
|
||||||
|
- 修复空帧导致的包围盒计算错误
|
||||||
|
- 修复重复启动程序无法唤出界面的问题
|
||||||
|
|
||||||
|
## v0.16.6
|
||||||
|
|
||||||
|
- 修复控件尺寸为0时导致的画面缩放错误
|
||||||
|
|
||||||
|
## v0.16.5
|
||||||
|
|
||||||
|
- 修复对于无 size 行的旧 atlas 格式读取错误
|
||||||
|
- 修复托盘化之后无法联动显示窗口的问题
|
||||||
|
|
||||||
## v0.16.4
|
## v0.16.4
|
||||||
|
|
||||||
- 增加 apng 导出格式
|
- 增加 apng 导出格式
|
||||||
|
|||||||
@@ -240,8 +240,8 @@ namespace SFMLRenderer
|
|||||||
if (RenderWindow is null) return;
|
if (RenderWindow is null) return;
|
||||||
float parentW = (float)sizeInfo.NewSize.Width;
|
float parentW = (float)sizeInfo.NewSize.Width;
|
||||||
float parentH = (float)sizeInfo.NewSize.Height;
|
float parentH = (float)sizeInfo.NewSize.Height;
|
||||||
float renderW = (float)_hwndHost.ActualWidth;
|
float renderW = _resolution.X;
|
||||||
float renderH = (float)_hwndHost.ActualHeight;
|
float renderH = _resolution.Y;
|
||||||
float scale = Math.Min(parentW / renderW, parentH / renderH); // 两方向取较小值, 保证 parent 覆盖 render
|
float scale = Math.Min(parentW / renderW, parentH / renderH); // 两方向取较小值, 保证 parent 覆盖 render
|
||||||
renderW *= scale;
|
renderW *= scale;
|
||||||
renderH *= scale;
|
renderH *= scale;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<TargetFramework>net8.0-windows</TargetFramework>
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||||
<Version>0.16.0</Version>
|
<Version>0.16.6</Version>
|
||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -112,6 +112,14 @@ namespace Spine.Implementations
|
|||||||
if (ForceMipmap) texture.GenerateMipmap();
|
if (ForceMipmap) texture.GenerateMipmap();
|
||||||
|
|
||||||
page.rendererObject = texture;
|
page.rendererObject = texture;
|
||||||
|
|
||||||
|
// 有些旧的 atlas 会省略 size 行, 这时需要在读取纹理时赋值
|
||||||
|
if (page.width <= 0 || page.height <= 0)
|
||||||
|
{
|
||||||
|
var texSize = texture.Size;
|
||||||
|
page.width = (int)texSize.X;
|
||||||
|
page.height = (int)texSize.Y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Load(SpineRuntime34.AtlasPage page, string path)
|
public virtual void Load(SpineRuntime34.AtlasPage page, string path)
|
||||||
@@ -147,6 +155,14 @@ namespace Spine.Implementations
|
|||||||
if (ForceMipmap) texture.GenerateMipmap();
|
if (ForceMipmap) texture.GenerateMipmap();
|
||||||
|
|
||||||
page.rendererObject = texture;
|
page.rendererObject = texture;
|
||||||
|
|
||||||
|
// 有些旧的 atlas 会省略 size 行, 这时需要在读取纹理时赋值
|
||||||
|
if (page.width <= 0 || page.height <= 0)
|
||||||
|
{
|
||||||
|
var texSize = texture.Size;
|
||||||
|
page.width = (int)texSize.X;
|
||||||
|
page.height = (int)texSize.Y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Load(SpineRuntime35.AtlasPage page, string path)
|
public virtual void Load(SpineRuntime35.AtlasPage page, string path)
|
||||||
@@ -182,6 +198,14 @@ namespace Spine.Implementations
|
|||||||
if (ForceMipmap) texture.GenerateMipmap();
|
if (ForceMipmap) texture.GenerateMipmap();
|
||||||
|
|
||||||
page.rendererObject = texture;
|
page.rendererObject = texture;
|
||||||
|
|
||||||
|
// 有些旧的 atlas 会省略 size 行, 这时需要在读取纹理时赋值
|
||||||
|
if (page.width <= 0 || page.height <= 0)
|
||||||
|
{
|
||||||
|
var texSize = texture.Size;
|
||||||
|
page.width = (int)texSize.X;
|
||||||
|
page.height = (int)texSize.Y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Load(SpineRuntime36.AtlasPage page, string path)
|
public virtual void Load(SpineRuntime36.AtlasPage page, string path)
|
||||||
@@ -217,6 +241,14 @@ namespace Spine.Implementations
|
|||||||
if (ForceMipmap) texture.GenerateMipmap();
|
if (ForceMipmap) texture.GenerateMipmap();
|
||||||
|
|
||||||
page.rendererObject = texture;
|
page.rendererObject = texture;
|
||||||
|
|
||||||
|
// 有些旧的 atlas 会省略 size 行, 这时需要在读取纹理时赋值
|
||||||
|
if (page.width <= 0 || page.height <= 0)
|
||||||
|
{
|
||||||
|
var texSize = texture.Size;
|
||||||
|
page.width = (int)texSize.X;
|
||||||
|
page.height = (int)texSize.Y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Load(SpineRuntime37.AtlasPage page, string path)
|
public virtual void Load(SpineRuntime37.AtlasPage page, string path)
|
||||||
@@ -252,6 +284,14 @@ namespace Spine.Implementations
|
|||||||
if (ForceMipmap) texture.GenerateMipmap();
|
if (ForceMipmap) texture.GenerateMipmap();
|
||||||
|
|
||||||
page.rendererObject = texture;
|
page.rendererObject = texture;
|
||||||
|
|
||||||
|
// 有些旧的 atlas 会省略 size 行, 这时需要在读取纹理时赋值
|
||||||
|
if (page.width <= 0 || page.height <= 0)
|
||||||
|
{
|
||||||
|
var texSize = texture.Size;
|
||||||
|
page.width = (int)texSize.X;
|
||||||
|
page.height = (int)texSize.Y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Load(SpineRuntime38.AtlasPage page, string path)
|
public virtual void Load(SpineRuntime38.AtlasPage page, string path)
|
||||||
@@ -288,9 +328,13 @@ namespace Spine.Implementations
|
|||||||
|
|
||||||
page.rendererObject = texture;
|
page.rendererObject = texture;
|
||||||
|
|
||||||
// 似乎是不需要设置的, 因为存在某些 png 和 atlas 大小不同的情况, 一般是有一些缩放, 如果设置了反而渲染异常
|
// 有些旧的 atlas 会省略 size 行, 这时需要在读取纹理时赋值
|
||||||
// page.width = (int)texture.Size.X;
|
if (page.width <= 0 || page.height <= 0)
|
||||||
// page.height = (int)texture.Size.Y;
|
{
|
||||||
|
var texSize = texture.Size;
|
||||||
|
page.width = (int)texSize.X;
|
||||||
|
page.height = (int)texSize.Y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Load(SpineRuntime40.AtlasPage page, string path)
|
public virtual void Load(SpineRuntime40.AtlasPage page, string path)
|
||||||
@@ -326,6 +370,14 @@ namespace Spine.Implementations
|
|||||||
if (ForceMipmap) texture.GenerateMipmap();
|
if (ForceMipmap) texture.GenerateMipmap();
|
||||||
|
|
||||||
page.rendererObject = texture;
|
page.rendererObject = texture;
|
||||||
|
|
||||||
|
// 有些旧的 atlas 会省略 size 行, 这时需要在读取纹理时赋值
|
||||||
|
if (page.width <= 0 || page.height <= 0)
|
||||||
|
{
|
||||||
|
var texSize = texture.Size;
|
||||||
|
page.width = (int)texSize.X;
|
||||||
|
page.height = (int)texSize.Y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Load(SpineRuntime41.AtlasPage page, string path)
|
public virtual void Load(SpineRuntime41.AtlasPage page, string path)
|
||||||
@@ -361,6 +413,14 @@ namespace Spine.Implementations
|
|||||||
if (ForceMipmap) texture.GenerateMipmap();
|
if (ForceMipmap) texture.GenerateMipmap();
|
||||||
|
|
||||||
page.rendererObject = texture;
|
page.rendererObject = texture;
|
||||||
|
|
||||||
|
// 有些旧的 atlas 会省略 size 行, 这时需要在读取纹理时赋值
|
||||||
|
if (page.width <= 0 || page.height <= 0)
|
||||||
|
{
|
||||||
|
var texSize = texture.Size;
|
||||||
|
page.width = (int)texSize.X;
|
||||||
|
page.height = (int)texSize.Y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Load(SpineRuntime42.AtlasPage page, string path)
|
public virtual void Load(SpineRuntime42.AtlasPage page, string path)
|
||||||
@@ -396,6 +456,14 @@ namespace Spine.Implementations
|
|||||||
if (ForceMipmap) texture.GenerateMipmap();
|
if (ForceMipmap) texture.GenerateMipmap();
|
||||||
|
|
||||||
page.rendererObject = texture;
|
page.rendererObject = texture;
|
||||||
|
|
||||||
|
// 有些旧的 atlas 会省略 size 行, 这时需要在读取纹理时赋值
|
||||||
|
if (page.width <= 0 || page.height <= 0)
|
||||||
|
{
|
||||||
|
var texSize = texture.Size;
|
||||||
|
page.width = (int)texSize.X;
|
||||||
|
page.height = (int)texSize.Y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Unload(object texture)
|
public virtual void Unload(object texture)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<TargetFramework>net8.0-windows</TargetFramework>
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||||
<Version>0.16.4</Version>
|
<Version>0.16.7</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|||||||
@@ -110,20 +110,42 @@ namespace Spine
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int ii = 0; ii + 1 < verticesLength; ii += 2)
|
if (verticesLength > 0)
|
||||||
{
|
{
|
||||||
float vx = vertices[ii];
|
for (int ii = 0; ii + 1 < verticesLength; ii += 2)
|
||||||
float vy = vertices[ii + 1];
|
{
|
||||||
minX = Math.Min(minX, vx);
|
float vx = vertices[ii];
|
||||||
minY = Math.Min(minY, vy);
|
float vy = vertices[ii + 1];
|
||||||
maxX = Math.Max(maxX, vx);
|
minX = Math.Min(minX, vx);
|
||||||
maxY = Math.Max(maxY, vy);
|
minY = Math.Min(minY, vy);
|
||||||
|
maxX = Math.Max(maxX, vx);
|
||||||
|
maxY = Math.Max(maxY, vy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var boneX = slot.Bone.WorldX;
|
||||||
|
var boneY = slot.Bone.WorldY;
|
||||||
|
minX = Math.Min(minX, boneX);
|
||||||
|
minY = Math.Min(minY, boneY);
|
||||||
|
maxX = Math.Max(maxX, boneX);
|
||||||
|
maxY = Math.Max(maxY, boneY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
x = minX;
|
if (minX >= int.MaxValue || minY >= int.MaxValue || maxX <= int.MinValue || maxY <= int.MinValue)
|
||||||
y = minY;
|
{
|
||||||
w = maxX - minX;
|
x = self.X;
|
||||||
h = maxY - minY;
|
y = self.Y;
|
||||||
|
w = 0;
|
||||||
|
h = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x = minX;
|
||||||
|
y = minY;
|
||||||
|
w = maxX - minX;
|
||||||
|
h = maxY - minY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -69,8 +69,7 @@ namespace SpineViewer
|
|||||||
_instanceMutex = new Mutex(true, MutexName, out var createdNew);
|
_instanceMutex = new Mutex(true, MutexName, out var createdNew);
|
||||||
if (!createdNew)
|
if (!createdNew)
|
||||||
{
|
{
|
||||||
ShowExistedInstance();
|
ConnectAndSendArgs();
|
||||||
SendCommandLineArgs();
|
|
||||||
Environment.Exit(0); // 不再启动新实例
|
Environment.Exit(0); // 不再启动新实例
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -100,55 +99,27 @@ namespace SpineViewer
|
|||||||
LogManager.Configuration = config;
|
LogManager.Configuration = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ShowExistedInstance()
|
private static void ConnectAndSendArgs()
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
// 遍历同名进程
|
|
||||||
var processes = Process.GetProcessesByName(ProcessName);
|
|
||||||
foreach (var p in processes)
|
|
||||||
{
|
|
||||||
// 跳过当前进程
|
|
||||||
if (p.Id == Process.GetCurrentProcess().Id)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
IntPtr hWnd = p.MainWindowHandle;
|
|
||||||
if (hWnd != IntPtr.Zero)
|
|
||||||
{
|
|
||||||
// 3. 显示并置顶窗口
|
|
||||||
if (User32.IsIconic(hWnd))
|
|
||||||
{
|
|
||||||
User32.ShowWindow(hWnd, User32.SW_RESTORE);
|
|
||||||
}
|
|
||||||
User32.SetForegroundWindow(hWnd);
|
|
||||||
break; // 找到一个就可以退出
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// 忽略异常,不影响当前进程退出
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void SendCommandLineArgs()
|
|
||||||
{
|
|
||||||
var args = Environment.GetCommandLineArgs().Skip(1).ToArray();
|
|
||||||
if (args.Length <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_logger.Info("Send command line args to existed instance, \"{0}\"", string.Join(", ", args));
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 已有实例在运行,把参数通过命名管道发过去
|
// 已有实例在运行,把参数通过命名管道发过去
|
||||||
using (var client = new NamedPipeClientStream(".", PipeName, PipeDirection.Out))
|
using (var client = new NamedPipeClientStream(".", PipeName, PipeDirection.Out))
|
||||||
{
|
{
|
||||||
client.Connect(10000); // 10 秒超时
|
// 只要启动了实例就要进行连接, 10 秒超时
|
||||||
using (var writer = new StreamWriter(client))
|
client.Connect(10000);
|
||||||
|
|
||||||
|
// 但是只有有参数的时候才发送参数
|
||||||
|
var args = Environment.GetCommandLineArgs().Skip(1).ToArray();
|
||||||
|
if (args.Length > 0)
|
||||||
{
|
{
|
||||||
foreach (var v in args)
|
_logger.Info("Send command line args to existed instance, \"{0}\"", string.Join(", ", args));
|
||||||
|
using (var writer = new StreamWriter(client))
|
||||||
{
|
{
|
||||||
writer.WriteLine(v);
|
foreach (var v in args)
|
||||||
|
{
|
||||||
|
writer.WriteLine(v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,6 +135,7 @@ namespace SpineViewer
|
|||||||
{
|
{
|
||||||
var t = new Task(() =>
|
var t = new Task(() =>
|
||||||
{
|
{
|
||||||
|
// 防止实例和窗口还没创建好
|
||||||
while (Current is null) Thread.Sleep(10);
|
while (Current is null) Thread.Sleep(10);
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
@@ -176,26 +148,48 @@ namespace SpineViewer
|
|||||||
}
|
}
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
using (var server = new NamedPipeServerStream(PipeName, PipeDirection.In))
|
try
|
||||||
{
|
{
|
||||||
server.WaitForConnection();
|
using (var server = new NamedPipeServerStream(PipeName, PipeDirection.In))
|
||||||
using (var reader = new StreamReader(server))
|
|
||||||
{
|
{
|
||||||
var args = new List<string>();
|
server.WaitForConnection();
|
||||||
string? line;
|
|
||||||
while ((line = reader.ReadLine()) != null)
|
|
||||||
args.Add(line);
|
|
||||||
|
|
||||||
if (args.Count > 0)
|
// 只要收到连接就可以显示窗口了
|
||||||
|
Current.Dispatcher.Invoke(() =>
|
||||||
{
|
{
|
||||||
Current.Dispatcher.Invoke(() =>
|
var window = (MainWindow)Current.MainWindow;
|
||||||
|
window.Show();
|
||||||
|
if (window.WindowState == WindowState.Minimized)
|
||||||
{
|
{
|
||||||
var vm = (MainWindowViewModel)((MainWindow)Current.MainWindow).DataContext;
|
window.WindowState = WindowState.Normal;
|
||||||
vm.SpineObjectListViewModel.AddSpineObjectFromFileList(args);
|
}
|
||||||
});
|
window.Activate();
|
||||||
|
});
|
||||||
|
using (var reader = new StreamReader(server))
|
||||||
|
{
|
||||||
|
var args = new List<string>();
|
||||||
|
string? line;
|
||||||
|
while ((line = reader.ReadLine()) != null)
|
||||||
|
args.Add(line);
|
||||||
|
|
||||||
|
if (args.Count > 0)
|
||||||
|
{
|
||||||
|
Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
// 尝试加载参数内容
|
||||||
|
var window = (MainWindow)Current.MainWindow;
|
||||||
|
var vm = (MainWindowViewModel)window.DataContext;
|
||||||
|
vm.SpineObjectListViewModel.AddSpineObjectFromFileList(args);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Trace(ex.ToString());
|
||||||
|
_logger.Error("Failed to process arguments, {0}", ex.Message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, default, TaskCreationOptions.LongRunning);
|
}, default, TaskCreationOptions.LongRunning);
|
||||||
t.Start();
|
t.Start();
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<TargetFramework>net8.0-windows</TargetFramework>
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||||
<Version>0.16.4</Version>
|
<Version>0.16.7</Version>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user