【问题标题】:Why is this happening? (SharpFont / Monogame Error)为什么会这样? (SharpFont / Monogame 错误)
【发布时间】:2015-03-08 01:36:33
【问题描述】:

我正在尝试从 FreeType (SharpFont) 位图中获取 MonoGame 纹理。

如果我使用Bitmap.ToGdipBitmap,它可以正常工作,但这似乎非常低效和hacky。当我尝试自己转换它时,我得到一个System.ArgumentException(源数组不够长)。

Bitmap.ToGdipBitmap 的代码如下所示:

for (int i = 0; i < rec.rows; i++)
    PInvokeHelper.Copy(Buffer, i * rec.pitch, locked.Scan0, i * locked.Stride, rec.width);

我的代码如下所示:

byte[] data = fontFace.Glyph.Bitmap.BufferData;
for (int y = 0; y < (int)glyphTexture.Height; y++)
{
    byte[] row = new byte[(int)glyphTexture.Width];
    Array.Copy(data, y * fontFace.Glyph.Bitmap.Pitch, row, 0, row.Length);
    ...
}

主要关注这两个:

i * rec.pitch

y * fontFace.Glyph.Bitmap.Pitch

难道他们都不会做基本相同的事情吗?

【问题讨论】:

  • “似乎非常低效和hacky”并不是一个客观的衡量标准。需要它的效率如何?您真的对执行操作需要多长时间有真正的问题吗?必须测量什么?不太清楚你在问什么。
  • 更多的是我想知道为什么它会发生,即使我正在做与 Bitmap.ToGdipBitmap 相同的事情。

标签: c# arrays monogame freetype


【解决方案1】:

披露我是 SharpFont 的作者。

FTBitmap.ToGdipBitmap 的编写考虑了性能。 PInvokeHelper.Copy 对指针进行按字节复制,这在性能上应该只比 Buffer.BlockCopy 好,但是当两者当前都只是指向非托管内存的指针时,这需要源和目标都是数组。 C# 中的其他复制方法,如Marshal.Copy,仍然需要一侧是数组。

您的实现涉及至少两倍的内存复制(Bitmap.BufferData 执行 Marshal.Copy)并且还通过分配大量小数组来强调 GC。

您关注的那部分看起来不错,我会说它是您的 glyphTexture 的宽度小于 FTBitmap 的 pitch,但那部分代码没有发布所以我不能在没有更多信息的情况下完全确定。

【讨论】:

  • 这个错误实际上是Bitmap.BufferData中的一个错误,rec.rows * rec.width应该是rec.rows * rec.pitch,但我看到它现在已经修复了。
  • 嗯...猜猜这就是我在查看当前代码时试图回答一个老问题的结果:P
猜你喜欢
  • 2020-01-19
  • 2017-01-01
  • 2021-04-14
  • 1970-01-01
  • 1970-01-01
  • 2018-10-15
  • 1970-01-01
  • 2011-06-03
相关资源
最近更新 更多