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

时间:2011-09-12 12:09:46

标签: c# directx sprite managed-directx

我正在使用托管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中的示例。

非常感谢提前!

2 个答案:

答案 0 :(得分:2)

如果要更改渲染的Z顺序,则必须在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排序深度。

希望有所帮助。

答案 1 :(得分: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();