C# 托管DirectX:指定包含纹理和文本的精灵的深度(Z顺序)

C# 托管DirectX:指定包含纹理和文本的精灵的深度(Z顺序),c#,directx,sprite,managed-directx,C#,Directx,Sprite,Managed Directx,我正在使用托管DirectX尝试使用精灵在屏幕上绘制纹理和文本。不幸的是,如果我将文本和纹理放置在同一个精灵中,则无论我执行绘制命令的顺序如何,纹理都会覆盖(覆盖?)文本 因为我最终会想要散布纹理和文本,所以如何为这些精灵指定Z顺序。每一层都必须在一个单独的精灵中吗 以下是当前代码: m_device.BeginScene(); m_device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0); m_sprite.Begin(SpriteFlags.

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

因为我最终会想要散布纹理和文本,所以如何为这些精灵指定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中的示例。


非常感谢

如果要更改渲染的Z顺序,则必须在“绘制”命令中设置Z值。如果将all设置为0,则会出现各种奇怪的情况。你更大的问题是DrawText不允许你设置一个Z深度,这是各种各样的垃圾

因此,您唯一的机会就是使用ID3DXSprite::SetTransform。您只需要将Z坐标移回相应的Z排序位置。因此,您可以按如下方式设置变换(假设您使用的是标识世界矩阵)(C++示例)

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

希望能有所帮助。

以下是我(海报)的答案:

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();

Draw方法是否有接受layerDepth参数的重载?XNA的SpriteBatch有,所以我希望managed DirectX的sprite也有。谢谢你的评论。Sprite.Draw和Font.DrawText都没有层深度参数。Sprite.Draw中的第二个矢量3确实指定了3d位置,但使Z为负数会导致纹理根本不出现,而使其为正数不会改变透支行为。谢谢。这足够近,可以为纹理和文本设置精灵深度。我将很快添加一个答案,提供一个代码示例。次要点-对于变换矩阵,需要平移z阶,而不是缩放z阶。我是用Matrix t=Microsoft.DirectX.Matrix.Identity做的;t、 翻译(0,0,zOrder)@汤姆·韦斯特:对不起,你完全正确。。那是我的一个愚蠢的错误。我将编辑我的答案:)
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();