0

我正在使用托管 DirectX 尝试使用 Sprite 在屏幕上绘制纹理和一段文本。不幸的是,如果我将文本和纹理放在同一个精灵中,无论我执行绘制命令的顺序如何,纹理都会覆盖(过度绘制?)文本。

由于我最终会想要散布纹理和文本,我如何为这些精灵指定 Z 顺序。每一层都必须在一个单独的精灵中吗?

这是当前代码:

m_device.BeginScene();
m_device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);
m_sprite.Begin(SpriteFlags.SortTexture | SpriteFlags.AlphaBlend);

// Switching the order of following two statements doesn't change the Z-Order!
m_sprite.Draw(m_texture, Vector3.Empty, new Vector3(0, 0, 0), 
              Color.White.ToArgb());
m_d3dFont.DrawText(m_sprite, m_text, x, y, color);

m_sprite.End();
m_device.EndScene();
m_device.Present();

注意:使用 SpriteFlags.SortDepthBackToFront 或 SpriteFlags.SortDepthBackToFront 不会改变行为。

这可能是我的概念上的误解,但如果代码有用,我将不胜感激地接受使用 C++ 或任何语言的非托管 DirectX 中的示例。

提前谢谢了!

4

2 回答 2

2

如果要更改渲染的 Z-Order,则必须在 Draw 命令中设置 Z 值。如果你将 all 设置为 0,你会得到各种奇怪的东西。您更大的问题是 DrawText 不允许您设置 Z-Depth 这是各种垃圾。

因此,您唯一的机会是使用 ID3DXSprite::SetTransform。对于相关的 z 排序位置,您只需要将 Z 坐标向后移动。因此,您可以按如下方式设置转换(假设您使用的是恒等世界矩阵)(C++ 示例)

D3DXMATRIX mat( 1.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 1.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 1.0f, 0.0f,
                0.0f, 0.0f, zOrder, 1.0f );
m_Sprite->SetTransform( &mat );

然后,您继续传递 (0, 0, 0) 的位置进行渲染,文本也将获得正确的 z 排序深度。

希望有帮助。

于 2011-09-12T17:18:53.240 回答
0

这是我(海报)的答案:

Goz 提供了解决问题所需的大部分信息。本质上,对于纹理,您可以使用第二个 Verctor3 的第三个参数指定 z 顺序。实验表明 (1) z 顺序从 0.0 到 1.0,其中 0.0 最接近,1.0 最远。超出该范围的任何内容都不会出现。

对于文本,因为没有机会在调用中指定 z,您需要使用 Goz 建议的变换矩阵。

最后,这是我使用的大致代码。

m_device.BeginScene();
m_device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);
m_sprite.Begin(SpriteFlags.SortDepthFrontToBack | SpriteFlags.SortTexture | SpriteFlags.AlphaBlend);

// The "1.0f" is the z-order of texture1.  This places it at the very back.
m_sprite.Draw(m_texture1, Vector3.Empty, new Vector3(0, 0, 1.0f), 
             Color.White.ToArgb());

// The text1 is placed at z-order 0.8f, in order to place it in front of texture1
Microsoft.DirectX.Matrix t = Microsoft.DirectX.Matrix.Identity;
t.Translate(new Vector3(0, 0, 0.8f));
m_sprite.Transform = t;
m_d3dFont.DrawText(m_sprite, m_text1, 200, 200, color1);
m_sprite.Transform = Microsoft.DirectX.Matrix.Identity;


// The "0.6f" is the z-order of texture2.  This places it at the very back.
m_sprite.Draw(m_texture2, Vector3.Empty, new Vector3(220, 220, 0.6f), 
              Color.White.ToArgb());

// The text2 is placed at z-order 0.4f, in order to place it in front of texture2
t = Microsoft.DirectX.Matrix.Identity;
t.Translate(new Vector3(0, 0, 0.4f));
m_sprite.Transform = t;
m_d3dFont.DrawText(m_sprite, m_text2, 240, 240, color2);
m_sprite.Transform = Microsoft.DirectX.Matrix.Identity;

m_sprite.End();
m_device.EndScene();
m_device.Present();
于 2011-09-13T01:16:54.090 回答