Skip to content

Commit 6838728

Browse files
author
Cheng Xie
committed
Did cloud, horizontal billboard, scaled billboard, extended particle system
1 parent f5afc9b commit 6838728

19 files changed

+342
-75
lines changed

src/TornadoParticleSystem.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ void TornadoParticleSystem::update(float dt)
7373
// If we are past the threshold, it's time to bring a new pixel online,
7474
float threshold = m_tornado->getHeight() / (m_cycleSpeed * m_numParticles);
7575
if(m_lastActivation >= threshold){
76-
std::cout<<"PING"<<endl;
76+
//std::cout<<"PING"<<endl;
7777
m_lastActivation -= threshold;
7878
particle.active = true;
7979
m_active_count++;

src/camera.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Camera::Camera()
1010
heightAngle_ = 60;
1111

1212
updateProjection();
13-
lookAt({-100, 20, 100}, {0, 0, 0}, {0, 1, 0});
13+
lookAt({0, 10, 10}, {0, 0, 0}, {0, 1, 0});
1414
}
1515

1616
void Camera::apply(DrawContext &context)

src/cloud.cpp

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#include "cloud.h"
2+
#include "texture.h"
3+
#include "texturecache.h"
4+
#include "particlematerial.h"
5+
6+
Cloud::Cloud(float radius)
7+
{
8+
radius_ = radius;
9+
10+
Texture* texture = TextureCache::getInstance()->acquire("cloud2", TextureType::Texture2D);
11+
setParticleTexture(texture);
12+
13+
setEmissionRate(10);
14+
15+
setMaxParticleCount(1000);
16+
17+
ParticleMaterial* material = static_cast<ParticleMaterial *>(material_);
18+
material->setHorizontal(true);
19+
}
20+
21+
void Cloud::spawnParticle(Particle *particle)
22+
{
23+
float speed = randf(5, 15);
24+
vec3 velocity = {0, 0, 1};
25+
velocity *= speed;
26+
27+
particle->velocity = velocity;
28+
29+
float phi = randf(0, M_PI * 2);
30+
float r = radius_ * randf();
31+
32+
// float x = randf(-radius_, radius_);
33+
// float z = randf(-radius_, radius_);
34+
35+
float x = cosf(phi) * r;
36+
float y = randf() * 10;
37+
float z = sinf(phi) * r;
38+
39+
particle->position = {x, y, z};
40+
41+
particle->rotation = randf(180, 360);
42+
43+
particle->maxLife = 20;
44+
45+
particle->size = randf(50, 150);
46+
47+
float scale = randf(0.6, 0.7f);
48+
particle->color = {scale, scale, scale};
49+
50+
particle->opacity = 0;
51+
}
52+
53+
void Cloud::updateParticle(Particle &particle, float dt)
54+
{
55+
particle.position += particle.velocity * dt;
56+
57+
float x = particle.life / particle.maxLife;
58+
59+
if (x < 0.5) {
60+
particle.opacity = x;
61+
}
62+
else {
63+
particle.opacity = 1 - x;
64+
}
65+
66+
67+
}
68+

src/cloud.h

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef CLOUD_H
2+
#define CLOUD_H
3+
4+
#include "particlesystem.h"
5+
6+
class Cloud : public ParticleSystem
7+
{
8+
public:
9+
Cloud(float radius);
10+
11+
virtual void spawnParticle(Particle *particle) override;
12+
13+
virtual void updateParticle(Particle &particle, float dt) override;
14+
15+
private:
16+
float radius_;
17+
};
18+
19+
#endif // CLOUD_H

src/common.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,15 @@ class Texture;
4343
class MeshRenderer;
4444
class Mesh;
4545

46+
47+
// random number between 0 and 1
4648
inline float randf() {
47-
return (float)rand() / RAND_MAX * 2 - 1;
49+
return (float)rand() / RAND_MAX;
50+
}
51+
52+
// random number between a and b
53+
inline float randf(float a, float b) {
54+
return randf() * (b - a) + a;
4855
}
4956

5057
#endif // COMMON_H

src/final.pro

+4-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ SOURCES += main.cpp \
4747
TornadoParticleSystem.cpp \
4848
DustcloudParticleSystem.cpp \
4949
terrainmaterial.cpp \
50-
material.cpp
50+
material.cpp \
51+
cloud.cpp
5152

5253
HEADERS += mainwindow.h \
5354
view.h \
@@ -83,6 +84,7 @@ HEADERS += mainwindow.h \
8384
Tornado.h \
8485
TornadoParticleSystem.h \
8586
DustcloudParticleSystem.h \
86-
terrainmaterial.h
87+
terrainmaterial.h \
88+
cloud.h
8789

8890
FORMS += mainwindow.ui

src/particlematerial.cpp

+44
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ void ParticleMaterial::apply(DrawContext &context)
1515

1616
Material::apply(context);
1717

18+
shader_->setUniformValue("lengthScale", lengthScale_);
19+
shader_->setUniformValue("horizontal", horizontal_);
20+
21+
mat4 slopeMatrix;
22+
slopeMatrix.rotate(slope_, {1, 0, 0});
23+
24+
shader_->setUniformValue("slope", slopeMatrix);
25+
1826
texture_->apply(context, "map", 0);
1927

2028
//glDisable(GL_DEPTH_TEST);
@@ -32,3 +40,39 @@ void ParticleMaterial::setTexture(Texture *texture)
3240
texture_ = texture;
3341
}
3442

43+
float ParticleMaterial::lengthScale() const
44+
{
45+
return lengthScale_;
46+
}
47+
48+
void ParticleMaterial::setLengthScale(float lengthScale)
49+
{
50+
lengthScale_ = lengthScale;
51+
}
52+
53+
float ParticleMaterial::slope() const
54+
{
55+
return slope_;
56+
}
57+
58+
void ParticleMaterial::setSlope(float slope)
59+
{
60+
slope_ = slope;
61+
}
62+
bool ParticleMaterial::horizontal() const
63+
{
64+
return horizontal_;
65+
}
66+
67+
void ParticleMaterial::setHorizontal(bool horizontal)
68+
{
69+
horizontal_ = horizontal;
70+
}
71+
72+
73+
74+
75+
76+
77+
78+

src/particlematerial.h

+13
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,21 @@ class ParticleMaterial : public Material
1313

1414
void setTexture(Texture *texture);
1515

16+
float lengthScale() const;
17+
void setLengthScale(float lengthScale);
18+
19+
float slope() const;
20+
void setSlope(float slope);
21+
22+
bool horizontal() const;
23+
void setHorizontal(bool horizontal);
24+
1625
protected:
1726
Texture* texture_;
27+
28+
bool horizontal_ = false;
29+
float lengthScale_ = 1;
30+
float slope_ = 0;
1831
};
1932

2033
#endif // PARTICLEMATERIAL_H

src/particlesystem.cpp

+70-7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
ParticleSystem::ParticleSystem()
99
{
10+
ParticleMaterial* material = new ParticleMaterial;
11+
setMaterial(material);
1012
mesh_ = new Mesh;
1113
}
1214

@@ -20,10 +22,14 @@ void ParticleSystem::renderGeometry(DrawContext &context)
2022
{
2123
update(context.deltaTime);
2224

25+
if (particles_.size() < 1) {
26+
return;
27+
}
28+
2329
VertexBufferDesc desc;
2430
desc.bufferData = particles_.data();
2531
desc.bufferSize = particles_.size() * sizeof(Particle);
26-
desc.vertexElementSizes = {3, 1, 1};
32+
desc.vertexElementSizes = {3, 1, 1, 3, 1};
2733
desc.stride = sizeof(Particle);
2834

2935
mesh_->setVertexBuffer(desc, PrimitiveType::Points);
@@ -33,16 +39,73 @@ void ParticleSystem::renderGeometry(DrawContext &context)
3339

3440
void ParticleSystem::setParticleTexture(Texture *texture)
3541
{
36-
ParticleMaterial* material = new ParticleMaterial;
42+
ParticleMaterial* material = static_cast<ParticleMaterial *>(material_);
3743
material->setTexture(texture);
38-
setMaterial(material);
3944
}
4045

4146
void ParticleSystem::update(float dt)
4247
{
43-
for (Particle& particle : particles_) {
44-
particle.position += {randf() * 10 * dt, randf() * 10 * dt, randf() * 10 * dt};
45-
particle.size += 0.5 * dt;
46-
particle.rotation += 90 * dt;
48+
timeElapsed_ += dt;
49+
50+
auto it = begin(particles_);
51+
while (it != end(particles_)) {
52+
Particle& particle = *it;
53+
particle.life += dt;
54+
if (particle.life >= particle.maxLife) {
55+
particles_.erase(it);
56+
}
57+
else {
58+
this->updateParticle(particle, dt);
59+
it++;
60+
}
61+
}
62+
63+
float numParticles = emissionRate_ * dt;
64+
numParticlesToSpawn_ += numParticles;
65+
66+
uint32_t count = 0;
67+
if (particles_.size() < maxParticleCount_) {
68+
count = min((int)(maxParticleCount_ - particles_.size()), (int)numParticlesToSpawn_);
69+
}
70+
71+
numParticlesToSpawn_ -= count;
72+
73+
for (uint32_t i = 0; i < count; i++) {
74+
Particle particle;
75+
this->spawnParticle(&particle);
76+
particles_.push_back(particle);
4777
}
4878
}
79+
80+
void ParticleSystem::spawnParticle(Particle *particle)
81+
{
82+
83+
}
84+
85+
void ParticleSystem::updateParticle(Particle &particle, float dt)
86+
{
87+
88+
}
89+
90+
uint32_t ParticleSystem::emissionRate() const
91+
{
92+
return emissionRate_;
93+
}
94+
95+
void ParticleSystem::setEmissionRate(int emissionRate)
96+
{
97+
emissionRate_ = emissionRate;
98+
}
99+
100+
uint32_t ParticleSystem::maxParticleCount() const
101+
{
102+
return maxParticleCount_;
103+
}
104+
105+
void ParticleSystem::setMaxParticleCount(int maxParticleCount)
106+
{
107+
maxParticleCount_ = maxParticleCount;
108+
}
109+
110+
111+

src/particlesystem.h

+33-7
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,19 @@
66

77
struct Particle
88
{
9-
// These three rendering related properties must be declared first in this order
9+
// These rendering related properties must be declared first in this order
1010
vec3 position;
1111
float rotation = 0; // in angle
1212
float size = 1;
13-
bool active = true;
13+
Color color = vec3(1.f, 1.f, 1.f);
14+
float opacity = 1.f;
1415

1516
// Other properties
17+
float life = 0;
18+
float maxLife = 0;
19+
20+
bool active = true;
1621
vec3 velocity;
17-
vec3 somethingelse;
1822
};
1923

2024
typedef vector<Particle> Particles;
@@ -26,15 +30,37 @@ class ParticleSystem : public SceneObject
2630
virtual ~ParticleSystem();
2731

2832
virtual void renderGeometry(DrawContext &context) override;
33+
34+
virtual void update(float dt);
35+
36+
// to be overrided
37+
virtual void spawnParticle(Particle *particle);
38+
39+
// to be overrided
40+
virtual void updateParticle(Particle& particle, float dt);
2941

3042
void setParticleTexture(Texture* texture);
31-
32-
virtual void update(float dt);
3343

44+
uint32_t emissionRate() const;
45+
void setEmissionRate(int emissionRate);
46+
47+
uint32_t maxParticleCount() const;
48+
void setMaxParticleCount(int maxParticleCount);
49+
50+
protected:
3451
vector<Particle> particles_;
52+
53+
private:
54+
// time elapsed since the particle system was created
55+
float timeElapsed_ = 0;
56+
57+
// max number of particles allowed
58+
uint32_t maxParticleCount_ = 0;
59+
60+
// number of particles per second
61+
uint32_t emissionRate_ = 0;
3562

36-
int numParticlesMax_;
37-
int emissionRate_;
63+
float numParticlesToSpawn_ = 0;
3864
};
3965

4066
#endif // PARTICLESYSTEM_H

0 commit comments

Comments
 (0)