- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是我在 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,但由于某种原因它被拉伸(stretch)到 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 channel )?当我的原始纹理是 150x150 时,为什么 SurfaceDescription 报告为 256x256?
最佳答案
回答我自己的问题有点尴尬,但经过更多的挖掘和简单的试验和错误,我找到了解决方案。
首先,我必须改变加载纹理的方式。为了防止它在内部调整为二次幂大小,我必须使用以下方法:
Texture texture = Texture.FromFile(_graphicsDevice, [filePath], D3DX.DefaultNonPowerOf2, D3DX.DefaultNonPowerOf2, 1, Usage.None, Format.Unknown, Pool.Managed, Filter.None, Filter.None, 0);
请注意我如何具体指定大小为非二的幂。
接下来,我的新纹理定义中有一个错误。我必须指定 1 个级别,而不是指定 0 个级别(并使其自动生成 MipMap),如下所示:
Texture texture2 = new Texture(_graphicsDevice, [sourceWidth], [sourceHeight], 1, surface.Usage, surface.Format, surface.Pool);
完成此操作后,我在实际问题中的 for 循环工作正常:
DataRectangle dataRectangle = texture.LockRectangle(0, LockFlags.None);
SurfaceDescription surface = texture.GetLevelDescription(0);
DataRectangle dataRectangle2 = texture2.LockRectangle(0, LockFlags.None);
for (int y = [sourceX]; y < [sourceHeight]; k++)
{
for (int x = [sourceY]; x < [sourceWidth]; l++)
{
byte[] buffer = new byte[4];
dataRectangle.Data.Seek((y * dataRectangle.Pitch) + (x * 4), SeekOrigin.Begin);
dataRectangle.Data.Read(buffer, 0, 4);
dataRectangle2.Data.Seek(((y - [sourceY]) * dataRectangle2.Pitch) + ((x - [sourceX]) * 4), SeekOrigin.Begin);
dataRectangle2.Data.Write(buffer, 0, 4);
}
}
texture.UnlockRectangle(0);
texture2.UnlockRectangle(0);
_graphicsDevice.SetTexture(0, texture2);
括号中的所有内容都被视为此代码段外部的变量。我想 _graphicsDevice 已经足够清楚了。我知道 .Seek 可以简化,但我认为它对于示例目的来说效果很好。请注意,我不建议每帧都执行此类操作,因为如果使用错误,它会很快耗尽 FPS。
我花了很长时间才弄清楚,但结果令人满意。我要感谢所有看到这个问题并试图帮助我的人。
伦纳德·方泰因
关于directx - SlimDX/DirectX9/C# - 如何访问纹理中的像素数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7033801/
我有一个未定义数量的显示上下文,每个都将显示一个纹理。当我调用 glGenTextures 时,我会在所有显示上下文中返回相同的名称。这会起作用吗?即使它们具有相同的名称,它们仍会存储和显示不同的纹理
我在 SVG 中看到过:文本填充是图像而不是颜色;我一直想知道使用 CSS3 是否可以实现这样的事情。 我浏览了整个网络,到目前为止只找到了基本上将图像覆盖在文本上的解决方法(请参阅 this ,这对
我是 WebGL 的新手。 :)我知道顶点数据和纹理不应该经常更新,但是当它们确实发生变化时,首选哪个:- 通过调用 gl.deleteBuffer 销毁先前的缓冲区 (static_draw) 并创
我需要将 GL_RGBA32F 作为内部格式,但我在 OpenGL ES 实现中没有得到它。相反,我只得到 GL_FLOAT 作为纹理数据类型。 OES_texture_float 规范没有说明里面的
当我执行某些几何体的渲染时,我可以在控制台中看到此警告: THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter sho
我正在尝试使用阴影贴图实现阴影,因此我需要将场景渲染到单独的帧缓冲区(纹理)。我无法让它正常工作,因此在剥离我的代码库后,我留下了一组相对简单的指令,这些指令应该将场景渲染到纹理,然后简单地渲染纹理。
我在 XNA 中使用带有自定义着色器的标准 .fbx 导入器。当我使用 BasicEffect 时,.fbx 模型被 UV 正确包裹并且纹理正确。但是,当我使用我的自定义效果时,我必须将纹理作为参数加
如果我创建一个 .PNG 1024 x 1024 的纹理并在中间画一个 124 x 124 的圆,它周围是空的,它使用的 RAM 量是否与我画一个 124 x 的圆一样124 x 124 空间上的 1
我试图在 Android 中绘制一个地球仪,为此我使用了 OpenGL。然而,为了让它更容易理解,我将从制作一个简单的 3D 立方体开始。我使用 Blender 创建我的 3D 对象(立方体),并在我
文本本身的背景图像层是否有任何 JS/CSS 解决方案? 示例 最佳答案 检查这个http://lea.verou.me/2012/05/text-masking-the-standards-way/
非功能代码: if sprite.texture == "texture" { (code) } 当 Sprite 具有特定纹理时,我正在尝试访问 Sprite 的纹理以运行代码。目前纹理仅在我的
我正在尝试学习适用于 iOS 的 SceneKit 并超越基本形状。我对纹理的工作原理有点困惑。在示例项目中,平面是一个网格,并对其应用了平面 png 纹理。你如何“告诉”纹理如何包裹到物体上?在 3
基本上, 这有效: var expl1 = new THREE.ImageUtils.loadTexture( 'images/explodes/expl1.png' ); this.material
我正在尝试将各种场景渲染为一组纹理,每个场景都有自己的纹理到应该绘制的位置...... 问题: 创建 512 个 FBO,每个 FBO 绑定(bind)了 512 个纹理,这有多糟糕。只使用一个 FB
我正在使用文本 protobuf 文件进行系统配置。 我遇到的一个问题是序列化的 protobuf 格式不支持注释。 有没有办法解决? 我说的是文本序列化数据格式,而不是方案定义。 这个问题是有人在某
我想将我的 3D 纹理的初始化从 CPU 移到 GPU。作为测试,我编写了一个着色器将所有体素设置为一个常数值,但纹理根本没有修改。我如何使它工作? 计算着色器: #version 430 layou
我可以像这样用 JavFX 制作一个矩形: Rectangle node2 = RectangleBuilder.create() .x(-100) .
我在 iPhone 上遇到了 openGL 问题,我确信一定有一个简单的解决方案! 当我加载纹理并显示它时,我得到了很多我认为所谓的“色带”,其中颜色,特别是渐变上的颜色,似乎会自动“优化”。 只是为
假设我有一个域类 class Profile{ String name byte[] logo } 和一个 Controller : class ImageController {
我正在开发一款使用 SDL 的 2D 游戏。由于某些系统的 CPU 较弱而 GPU 较强,因此除了普通的 SDL/软件之外,我还有一个使用 OpenGL 的渲染器后端。 渲染器界面的简化版本如下所示:
我是一名优秀的程序员,十分优秀!