0
我正在嘗試在XNA 4.0中創建的遊戲中創建一個粒子系統。 粒子在發射器初始化的世界呈現。 問題是我想更新Update()上的粒子位置,但它不起作用,粒子被渲染,但僅在位置0,0,0的世界中心。XNA更新VertexBuffer中頂點的位置更新
每個粒子由一組帶頂點的頂點組成。
任何人都可以幫我嗎? 下面是粒子發射器類:
public class ParticleEmitter : RenderableGameObject
{
VertexBuffer vertexBuffer;
VertexDeclaration vertexDeclaration;
Effect bbEffect;
VertexPositionTexture[] vertices;
Texture2D texture;
int noVertices = 0;
struct Particle
{
public Vector3 position;
}
Particle[] particles = new Particle[5];
public ParticleEmitter(Game1 game)
: base(game)
{
SetupParticles();
SetupVertices();
bbEffect = game.Content.Load<Effect>("Effects/Particle");
texture = game.Content.Load<Texture2D>("Textures/fire");
}
private void SetupVertices()
{
int vertexIndex = 0;
vertices = new VertexPositionTexture[particles.Length * 6];
for (int i = 0; i < particles.Length; ++i)
{
vertices[vertexIndex++] = new VertexPositionTexture(particles[i].position, new Vector2(0, 0));
vertices[vertexIndex++] = new VertexPositionTexture(particles[i].position, new Vector2(1, 0));
vertices[vertexIndex++] = new VertexPositionTexture(particles[i].position, new Vector2(1, 1));
vertices[vertexIndex++] = new VertexPositionTexture(particles[i].position, new Vector2(0, 0));
vertices[vertexIndex++] = new VertexPositionTexture(particles[i].position, new Vector2(1, 1));
vertices[vertexIndex++] = new VertexPositionTexture(particles[i].position, new Vector2(0, 1));
}
noVertices = vertexIndex;
vertexBuffer = new VertexBuffer(game.GraphicsDevice, typeof(VertexPositionTexture), vertices.Length, BufferUsage.WriteOnly);
vertexBuffer.SetData(vertices);
vertexDeclaration = new VertexDeclaration(VertexPositionTexture.VertexDeclaration.GetVertexElements());
}
private void SetupParticles()
{
for (int i = 0; i < particles.Length; ++i)
{
particles[i] = new Particle();
particles[i].position = Position * i;
}
}
private void UpdateVertices()
{
for (int i = 0; i < particles.Length; ++i)
{
vertices[i] = new VertexPositionTexture(particles[i].position, new Vector2(0, 0));
vertices[i] = new VertexPositionTexture(particles[i].position, new Vector2(1, 0));
vertices[i] = new VertexPositionTexture(particles[i].position, new Vector2(1, 1));
vertices[i] = new VertexPositionTexture(particles[i].position, new Vector2(0, 0));
vertices[i] = new VertexPositionTexture(particles[i].position, new Vector2(1, 1));
vertices[i] = new VertexPositionTexture(particles[i].position, new Vector2(0, 1));
}
game.GraphicsDevice.SetVertexBuffer(null);
vertexBuffer.SetData(vertices);
}
private void UpdateParticles()
{
for (int i = 0; i < particles.Length; ++i)
{
particles[i].position = Position;
}
}
public override void Update(GameTime gameTime)
{
UpdateParticles();
UpdateVertices();
base.Update(gameTime);
}
public override void Draw()
{
DrawParticles(game.camera.viewMatrix);
}
private void DrawParticles(Matrix currentViewMatrix)
{
bbEffect.CurrentTechnique = bbEffect.Techniques["CylBillboard"];
bbEffect.Parameters["xWorld"].SetValue(Matrix.Identity);
bbEffect.Parameters["xView"].SetValue(currentViewMatrix);
bbEffect.Parameters["xProjection"].SetValue(game.camera.projectionMatrix);
bbEffect.Parameters["xCamPos"].SetValue(game.camera.Position);
bbEffect.Parameters["xAllowedRotDir"].SetValue(new Vector3(0, 1, 0));
bbEffect.Parameters["xBillboardTexture"].SetValue(texture);
foreach (EffectPass pass in bbEffect.CurrentTechnique.Passes)
{
game.GraphicsDevice.BlendState = BlendState.AlphaBlend;
pass.Apply();
game.GraphicsDevice.SetVertexBuffer(vertexBuffer);
int noTriangles = noVertices/3;
game.GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, noTriangles);
}
}
}
從性能角度看,'DynamicVertexBuffer'會更好,如果你正在更新的頂點,每一幀。雖然我個人會主張一種不同的方法 - 固定頂點緩衝區和頂點着色器,它們以參數方式推進粒子位置。關於你的問題:你能否澄清你的意思是「它不會工作」? – 2013-04-10 06:11:40
感謝您的回覆,我更新了問題以澄清「它不起作用」。至於你提到的另一種方法。性能更好嗎?如果是這樣,你可以給如何做到這一點的資源? – pjongjang 2013-04-10 07:21:40
[這是我的一箇舊回答](http://stackoverflow.com/a/3138075/165500),給出了更詳細的概述。恐怕我沒有任何實施資源。 – 2013-04-10 09:36:41