更新VertexBuffer中顶点的位置
本文关键字:位置 顶点 VertexBuffer 更新 | 更新日期: 2023-09-27 18:08:23
我正尝试着在XNA 4.0中创造一个粒子系统。粒子在初始化发射器的世界中被渲染。问题是,我想在update()上更新粒子的位置,但它不起作用,粒子被渲染,但只在世界的中心位置0,0,0。
每个粒子由一组带有纹理的顶点组成。
有谁能帮我吗?下面是粒子发射器的类: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);
}
}
}
你实际上根本没有改变粒子的位置,在这个方法中:
private void UpdateParticles()
{
for (int i = 0; i < particles.Length; ++i)
{
particles[i].position = Position;
}
}
你把每个粒子都设置在相同的位置,假设是原点。
你可能想要做的是给每个粒子增加一个速度:
struct Particle
{
public Vector3 position;
public Vector3 velocity;
}
然后用随机速度初始化每个粒子:
// Pass a shared, per-thread instance of Random into this method
private void SetupParticles(Random random)
{
for (int i = 0; i < particles.Length; ++i)
{
particles[i] = new Particle() {
position = Vector.Zero,
velocity = new Vector3((float)(random.NextDouble() * 2 - 1),
(float)(random.NextDouble() * 2 - 1),
(float)(random.NextDouble() * 2 - 1))
};
}
}
然后根据一些物理模型(即:由于重力的速度和加速度,随着时间的推移)更新它们。
Vector3 gravity = new Vector3(0, -9.8f, 0);
private void UpdateParticles(float time)
{
for (int i = 0; i < particles.Length; ++i)
{
particles[i].velocity += gravity * time;
particles[i].position += particles[i].velocity * time;
}
}
(注意:本回答中的所有代码都是手工编写的,请注意语法错误等)