如何使基元在DirectX(2D)中正确叠加精灵

时间:2011-07-01 16:43:22

标签: c# graphics directx slimdx

我在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 positionint color的结构, vertexDecl 声明这些顶点元素。

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. 如果基元叠加精灵,基元几乎黑色,我绘制的精灵越多,基色越暗。也许它与alpha有关?
  3. 正确渲染所有基元,直到我绘制精灵。但即使我停止绘制精灵,基元也将保持黑/黑,直到我重置应用程序。
  4. 如果你需要我的源代码的其他一些片段,请在这里写一下,我会更新。

3 个答案:

答案 0 :(得分: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

我希望这可以帮助遇到此问题的其他人。

答案 1 :(得分:0)

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

在绘制用户基元之后,我也会做一个device.EndScene()。

希望有所帮助!

答案 2 :(得分:0)

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

- &gt;当您更改z值时基元变暗,我认为这是由光源引起的(范围?)