这是我在 StackOverflow 上遇到的第一个问题,万岁!我可以诚实地说,我每天都使用 StackOverflow 来处理我的工作和个人编程谜题。 99.9% 的情况下,我实际上也在这里找到了我需要的答案,这太棒了!
我当前的问题实际上让我有点困惑,因为我似乎找不到任何真正有效的东西。我已经阅读了 GameDev.net 上的几篇文章,并在网上找到了其他资源,但无法整理出来。
我正在将我为 XNA 编写的小型 2D 引擎移植到 SlimDX(目前只是 DirectX9),这是一个很好的举措,因为我在短短几天内就比我在几天内了解了更多有关 DirectX 内部工作原理的信息。与 XNA 合作六个月。我完成了大部分基本渲染功能,并且实际上成功地重新创建了具有大量附加功能的 XNA SpriteBatch(我在 XNA 中真的很怀念)。
我试图开始工作的最后一件事是从给定纹理中提取源矩形并将其用于平铺。原因:不平铺时,您可以随意使用 UV 来获取想要显示的源(例如:0.3;0.3 到 0.5;0.5),但是平铺时,您需要 UV 来平铺(0;0 到 2;2)意味着平铺图像两次),因此需要剪切纹理。
长话短说,我尝试使用以下内容:
DataRectangle dataRectangle = sprite.Texture.LockRectangle(0, LockFlags.None);
Format format = sprite.Texture.GetLevelDescription(0).Format;
byte[] buffer = new byte[4];
dataRectangle.Data.Read(buffer, ([y] * dataRectangle.Pitch) + ([x] * 4), buffer.Length);
texture.UnlockRectangle(0);
我尝试了不同的像素,但似乎都给出了虚假数据。例如,我实际上尝试使用当前的头像来查看从 DataRectangle 获取的缓冲区是否与图像中的实际像素匹配,但没有运气(甚至检查了格式是否正确,确实如此)。
我究竟做错了什么?有更好的方法吗?或者我的紫外线故事是错误的吗?可以解决吗?
比平铺之前切掉源矩形要简单得多吗?
感谢您的时间,
伦纳德·方泰因
更新#1
实际上,我设法使用以下字节数组转换将像素数据导出到位图:
int pixel = (buffer[0] & 0xFF) | ((buffer[1] & 0xFF) << 8) | ((buffer[2] & 0xFF) << 16) | ((255 - buffer[3] & 0xFF) << 24);
所以数据看起来并不像我想象的那么假。然而,我的下一个问题是抓取源矩形中指定的像素并将它们复制到新纹理。我试图剪切的图像是 150x150,但由于某种原因它被拉伸到 256x256 图像(2 的幂),但当实际尝试访问超过 150x150 的像素时,它会抛出 OutOfBounds 异常。另外,当我实际尝试创建第二个尺寸为 256x256 的空白纹理时,无论我放入什么,它都会变成全黑的。
这是我当前的代码:
//Texture texture = 150x150
DataRectangle dataRectangle = texture.LockRectangle(0, LockFlags.None);
SurfaceDescription surface = texture.GetLevelDescription(0);
Texture texture2 = new Texture(_graphicsDevice, surface.Width, surface.Height, 0, surface.Usage, surface.Format, surface.Pool);
DataRectangle dataRectangle2 = texture2.LockRectangle(0, LockFlags.None);
for (int k = sourceX; k < sourceHeight; k++)
{
for (int l = sourceY; l < sourceWidth; l++)
{
byte[] buffer = new byte[4];
dataRectangle.Data.Seek((k * dataRectangle.Pitch) + (l* 4), SeekOrigin.Begin);
dataRectangle.Data.Read(buffer, 0, 4);
dataRectangle2.Data.Seek(((k - sourceY) * dataRectangle2.Pitch) + ((l - sourceX) * 4), SeekOrigin.Begin);
dataRectangle2.Data.Write(buffer, 0, 4);
}
}
sprite.Texture.UnlockRectangle(0);
texture2.UnlockRectangle(0);
_graphicsDevice.SetTexture(0, texture2);
所以我的新(附加)问题是:如何将像素从一个纹理移动到另一个较小的纹理(包括 Alpha 通道)?当我的原始纹理是 150x150 时,为什么 SurfaceDescription 报告为 256x256?