Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/samples/particle_system/ParticleSystem.cpp
1694 views
1
//
2
// Copyright 2014 The ANGLE Project Authors. All rights reserved.
3
// Use of this source code is governed by a BSD-style license that can be
4
// found in the LICENSE file.
5
//
6
7
// Based on ParticleSystem.c from
8
// Book: OpenGL(R) ES 2.0 Programming Guide
9
// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
10
// ISBN-10: 0321502795
11
// ISBN-13: 9780321502797
12
// Publisher: Addison-Wesley Professional
13
// URLs: http://safari.informit.com/9780321563835
14
// http://www.opengles-book.com
15
16
#include "SampleApplication.h"
17
18
#include "common/vector_utils.h"
19
#include "tga_utils.h"
20
#include "util/random_utils.h"
21
#include "util/shader_utils.h"
22
23
#define _USE_MATH_DEFINES
24
#include <math.h>
25
26
#include <string>
27
28
using namespace angle;
29
30
class ParticleSystemSample : public SampleApplication
31
{
32
public:
33
ParticleSystemSample(int argc, char **argv) : SampleApplication("ParticleSystem", argc, argv) {}
34
35
bool initialize() override
36
{
37
constexpr char kVS[] = R"(uniform float u_time;
38
uniform vec3 u_centerPosition;
39
attribute float a_lifetime;
40
attribute vec3 a_startPosition;
41
attribute vec3 a_endPosition;
42
varying float v_lifetime;
43
void main()
44
{
45
if (u_time <= a_lifetime)
46
{
47
gl_Position.xyz = a_startPosition + (u_time * a_endPosition);
48
gl_Position.xyz += u_centerPosition;
49
gl_Position.w = 1.0;
50
}
51
else
52
{
53
gl_Position = vec4(-1000, -1000, 0, 0);
54
}
55
v_lifetime = 1.0 - (u_time / a_lifetime);
56
v_lifetime = clamp(v_lifetime, 0.0, 1.0);
57
gl_PointSize = (v_lifetime * v_lifetime) * 40.0;
58
})";
59
60
constexpr char kFS[] = R"(precision mediump float;
61
uniform vec4 u_color;
62
varying float v_lifetime;
63
uniform sampler2D s_texture;
64
void main()
65
{
66
vec4 texColor;
67
texColor = texture2D(s_texture, gl_PointCoord);
68
gl_FragColor = vec4(u_color) * texColor;
69
gl_FragColor.a *= v_lifetime;
70
})";
71
72
mProgram = CompileProgram(kVS, kFS);
73
if (!mProgram)
74
{
75
return false;
76
}
77
78
// Get the attribute locations
79
mLifetimeLoc = glGetAttribLocation(mProgram, "a_lifetime");
80
mStartPositionLoc = glGetAttribLocation(mProgram, "a_startPosition");
81
mEndPositionLoc = glGetAttribLocation(mProgram, "a_endPosition");
82
83
// Get the uniform locations
84
mTimeLoc = glGetUniformLocation(mProgram, "u_time");
85
mCenterPositionLoc = glGetUniformLocation(mProgram, "u_centerPosition");
86
mColorLoc = glGetUniformLocation(mProgram, "u_color");
87
mSamplerLoc = glGetUniformLocation(mProgram, "s_texture");
88
89
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
90
91
// Fill in particle data array
92
for (size_t i = 0; i < mParticleCount; i++)
93
{
94
mParticles[i].lifetime = mRNG.randomFloatBetween(0.0f, 1.0f);
95
96
float endAngle = mRNG.randomFloatBetween(0, 2.0f * float(M_PI));
97
float endRadius = mRNG.randomFloatBetween(0.0f, 2.0f);
98
mParticles[i].endPosition.x() = sinf(endAngle) * endRadius;
99
mParticles[i].endPosition.y() = cosf(endAngle) * endRadius;
100
mParticles[i].endPosition.z() = 0.0f;
101
102
float startAngle = mRNG.randomFloatBetween(0, 2.0f * float(M_PI));
103
float startRadius = mRNG.randomFloatBetween(0.0f, 0.25f);
104
mParticles[i].startPosition.x() = sinf(startAngle) * startRadius;
105
mParticles[i].startPosition.y() = cosf(startAngle) * startRadius;
106
mParticles[i].startPosition.z() = 0.0f;
107
}
108
109
mParticleTime = 1.0f;
110
111
std::stringstream smokeStr;
112
smokeStr << angle::GetExecutableDirectory() << "/smoke.tga";
113
114
TGAImage img;
115
if (!LoadTGAImageFromFile(smokeStr.str(), &img))
116
{
117
return false;
118
}
119
mTextureID = LoadTextureFromTGAImage(img);
120
if (!mTextureID)
121
{
122
return false;
123
}
124
125
return true;
126
}
127
128
void destroy() override { glDeleteProgram(mProgram); }
129
130
void step(float dt, double totalTime) override
131
{
132
// Use the program object
133
glUseProgram(mProgram);
134
135
mParticleTime += dt;
136
if (mParticleTime >= 1.0f)
137
{
138
mParticleTime = 0.0f;
139
140
// Pick a new start location and color
141
Vector3 centerPos(mRNG.randomFloatBetween(-0.5f, 0.5f),
142
mRNG.randomFloatBetween(-0.5f, 0.5f),
143
mRNG.randomFloatBetween(-0.5f, 0.5f));
144
glUniform3fv(mCenterPositionLoc, 1, centerPos.data());
145
146
// Random color
147
Vector4 color(mRNG.randomFloatBetween(0.0f, 1.0f), mRNG.randomFloatBetween(0.0f, 1.0f),
148
mRNG.randomFloatBetween(0.0f, 1.0f), 0.5f);
149
glUniform4fv(mColorLoc, 1, color.data());
150
}
151
152
// Load uniform time variable
153
glUniform1f(mTimeLoc, mParticleTime);
154
}
155
156
void draw() override
157
{
158
// Set the viewport
159
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
160
161
// Clear the color buffer
162
glClear(GL_COLOR_BUFFER_BIT);
163
164
// Use the program object
165
glUseProgram(mProgram);
166
167
// Load the vertex attributes
168
glVertexAttribPointer(mLifetimeLoc, 1, GL_FLOAT, GL_FALSE, sizeof(Particle),
169
&mParticles[0].lifetime);
170
glVertexAttribPointer(mEndPositionLoc, 3, GL_FLOAT, GL_FALSE, sizeof(Particle),
171
&mParticles[0].endPosition);
172
glVertexAttribPointer(mStartPositionLoc, 3, GL_FLOAT, GL_FALSE, sizeof(Particle),
173
&mParticles[0].startPosition);
174
175
glEnableVertexAttribArray(mLifetimeLoc);
176
glEnableVertexAttribArray(mEndPositionLoc);
177
glEnableVertexAttribArray(mStartPositionLoc);
178
179
// Blend particles
180
glEnable(GL_BLEND);
181
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
182
183
// Bind the texture
184
glActiveTexture(GL_TEXTURE0);
185
glBindTexture(GL_TEXTURE_2D, mTextureID);
186
187
// Set the sampler texture unit to 0
188
glUniform1i(mSamplerLoc, 0);
189
190
glDrawArrays(GL_POINTS, 0, mParticleCount);
191
}
192
193
private:
194
// Handle to a program object
195
GLuint mProgram;
196
197
// Attribute locations
198
GLint mLifetimeLoc;
199
GLint mStartPositionLoc;
200
GLint mEndPositionLoc;
201
202
// Uniform location
203
GLint mTimeLoc;
204
GLint mColorLoc;
205
GLint mCenterPositionLoc;
206
GLint mSamplerLoc;
207
208
// Texture handle
209
GLuint mTextureID;
210
211
// Particle vertex data
212
struct Particle
213
{
214
float lifetime;
215
Vector3 startPosition;
216
Vector3 endPosition;
217
};
218
static const size_t mParticleCount = 1024;
219
std::array<Particle, mParticleCount> mParticles;
220
float mParticleTime;
221
RNG mRNG;
222
};
223
224
int main(int argc, char **argv)
225
{
226
ParticleSystemSample app(argc, argv);
227
return app.run();
228
}
229
230