-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathParticleSystem.cpp
More file actions
121 lines (88 loc) · 4.18 KB
/
ParticleSystem.cpp
File metadata and controls
121 lines (88 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include "ParticleSystem.h"
#include <glad.h>
#include <stdlib.h>
#include "logger.h"
#define NUM_PARTICLES 1024*1024 * 1 // total number of particles to move
#define WORK_GROUP_SIZE 128 // # work-items per work-group
float quadVertices[] = {
// positions // colors
-0.05f, 0.05f, 1.0f, 0.0f, 0.0f,
0.05f, -0.05f, 0.0f, 1.0f, 0.0f,
-0.05f, -0.05f, 0.0f, 0.0f, 1.0f,
-0.05f, 0.05f, 1.0f, 0.0f, 0.0f,
0.05f, 0.05f, 0.0f, 1.0f, 1.0f,
0.05f, -0.05f, 0.0f, 1.0f, 0.0f
};
namespace Engine {
ParticleSystem::ParticleSystem(glm::vec3 boundBoxMin, glm::vec3 boundBoxMax, float minVelocity, float maxVelocity)
{
//--------------------------------------------------------------Compute------------------------
m_boundBoxMin = boundBoxMin;
m_boundBoxMax = boundBoxMax;
//---------------------------------------------------Position
glGenBuffers(1, &posSSbo);//Create buffer
glBindBuffer(GL_SHADER_STORAGE_BUFFER, posSSbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, NUM_PARTICLES * sizeof(struct pos), nullptr, GL_STATIC_DRAW);// Initialize memory
GLint bufMask = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT; // the invalidate makes a big difference when re-writing
//Map buffer addres to points array
points = (struct pos*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, NUM_PARTICLES * sizeof(struct pos), bufMask);
for (int i = 0; i < NUM_PARTICLES; i++)
{
points[i].x = + random(m_boundBoxMin.x, m_boundBoxMax.x);
points[i].y = random(m_boundBoxMin.y, m_boundBoxMax.y);
points[i].z = random(m_boundBoxMin.z, m_boundBoxMax.z);
points[i].w = 1.f;
}
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
//---------------------------------------------------Velocity
glGenBuffers(1, &velSSbo);//Create buffer
glBindBuffer(GL_SHADER_STORAGE_BUFFER, velSSbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, NUM_PARTICLES * sizeof(struct vel), nullptr, GL_STATIC_DRAW);// Initialize memory
//Map buffer addres to points array
struct vel* vels = (struct vel*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, NUM_PARTICLES * sizeof(struct vel), bufMask);
for (int i = 0; i < NUM_PARTICLES; i++)
{
vels[i].vx = random(-maxVelocity/2, maxVelocity);
vels[i].vy = random(-maxVelocity/2, maxVelocity);
vels[i].vz = random(-maxVelocity/2, maxVelocity);
vels[i].vw = 0.f;
}
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
cShader = (ComputeShader*)ShaderManager::Instance()->getShader("TestCompute");
//--------------------------------------------------------------Render------------------------
glGenVertexArrays(1, &quadVAO);
glGenBuffers(1, &quadVBO);
//Create Quad vertices buffer
glBindVertexArray(quadVAO);
glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), quadVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);// atribute 0: position
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);// atribute 1: color
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2 * sizeof(float)));
glBindBuffer(GL_ARRAY_BUFFER, posSSbo); // this attribute comes from a different vertex buffer
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);// atribute 2: instance_position
glBindBuffer(GL_ARRAY_BUFFER, 0);
//atribute pointer instances using same value
glVertexAttribDivisor(2 , 1 ); // tell OpenGL this is an instanced vertex attribute.
shader = ShaderManager::Instance()->getShader("ParticleShader");
log_printf_info("Particle system initialized");
}
void ParticleSystem::Update()
{
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, posSSbo);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, velSSbo);
cShader->Dispatch(NUM_PARTICLES / WORK_GROUP_SIZE, 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);//Aply changes
}
void ParticleSystem::Draw(Camera* cam)
{
//TODO: Render meshes using instancing
shader->bind();
shader->setMat4("viewProjection", cam->GetViewProjectionMatrix());
glBindVertexArray(quadVAO);
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, NUM_PARTICLES); // NUM_PARTICLES triangles of 6 vertices each
glBindVertexArray(0);
}
}