3

我在 Direct3D9 中渲染精灵和图元时遇到了问题。我正在尝试使用精灵制作一个简单的 2D 游戏,但是我发现我还需要原语来绘制简单的正方形、线条等。问题在于叠加。

如果我只使用 绘制图元Device.DrawUserPrimitives(),一切都很好,图元被正确渲染。如果我只使用 绘制精灵Sprite.Draw(),也可以。但是,如果我想同时绘制精灵和图元,所有精灵都会自动覆盖图元或使它们变黑。

我试过禁用 Z 缓冲区,在渲染精灵时禁用 Z 缓冲区中的写入等,但它总是一样的。我设法通过改变它们的z位置使图元覆盖精灵,但是所有图元都是黑色的...... :(

请注意,我已经尝试在绘制精灵之前和之后渲染图元。它没有帮助。

我将在这里发布一些绘图精灵和原语的片段(变量名称已更改,因此即使您对 C# 和 SlimDX 一无所知,您也可以理解我在绘制什么):

mSprite.Begin(SpriteFlags.ObjectSpace | SpriteFlags.DoNotModifyRenderState);
mSprite.Draw(texture, centerVector, positionVector, color); // positionVector = Vector3.Zero in my example
mSprite.Flush();

(...)

device.VertexDeclaration = vertexDecl;
device.DrawUserPrimitives(PrimitiveType.TriangleFan, m_fan1.Length - 2, m_fan1);

...其中m_fan1是一个包含Vector4 position和的结构,int colorvertexDecl声明了这些顶点元素。

m_fan1[0] = new TransformedColored(new Vector4(100.0f, 100.0f, 1.0f, 1.0f), Color.Green);
m_fan1[1] = new TransformedColored(new Vector4(0.0f, 0.0f, 1.0f, 1.0f), Color.Green);
m_fan1[2] = new TransformedColored(new Vector4(200.0f, 0.0f, 1.0f, 1.0f), Color.Green);
m_fan1[3] = new TransformedColored(new Vector4(200.0f, 200.0f, 1.0f, 1.0f), Color.Green);
m_fan1[4] = new TransformedColored(new Vector4(0.0f, 200.0f, 1.0f, 1.0f), Color.Yellow);
m_fan1[5] = new TransformedColored(new Vector4(0.0f, 0.0f, 1.0f, 1.0f), Color.Green);

顺便一提:

  1. 如果我将填充模式更改为线框,则可以正确绘制图元的线框。
  2. 如果图元覆盖精灵,图元几乎是黑色的,我绘制的精灵越多,图元越暗。也许它与阿尔法有关?
  3. 在我绘制 sprite 之前,所有图元都被正确渲染。但即使我停止绘制精灵,在我重置应用程序之前,图元将保持暗/黑色。

如果您需要我的源代码的其他片段,请写在这里,我会更新它。

4

3 回答 3

1

我解决了这个问题sprite.Transform();

sprite.Transform = Matrix.Scaling(1, 1, 1) * Matrix.Translation(x,y, 0); // works

相比

sprite.Transform = Matrix.Scaling(1, 1, 1) * Matrix.Translation(x,y, 1); // doesn't work

我希望这对遇到此问题的其他人有所帮助。

于 2012-08-21T09:53:29.243 回答
0

如果没有看到完整的代码,就不可能找到错误。我会检查精灵和我们的图元的 z 缓冲区值。如果那部分是正确的,那么您的原语就没有理由不应该过度绘制后缓冲区。您是否设置了每个渲染周期的图元所需的渲染状态?默认情况下,d3dx sprite 会设置自己的渲染状态,这可能会弄乱您的图元。并且,在绘制精灵时有一个标志 D3DXSPRITE_DONOTMODIFY_RENDERSTATE。

->当您更改 z 值时,当您的图元变暗时,我认为这是由您的光源(范围?)

于 2014-09-29T20:10:15.697 回答
0

我没有看到 sprite.End() 被调用。从此处的文档 (http://msdn.microsoft.com/en-us/library/ms881042.aspx) 中,Sprite.End() “将设备恢复到调用 Sprite.Begin 之前的状态。”

在绘制用户原语后,我也会做一个 device.EndScene() 。

希望有帮助!

于 2011-07-01T19:03:16.463 回答