making code for particle batch modular.

This commit is contained in:
Andreas Ortmann 2016-10-02 17:22:47 +02:00
parent a81b549126
commit 57e6e56217
4 changed files with 73 additions and 46 deletions

View file

@ -1,7 +1,8 @@
#version 120 #version 120
attribute vec2 in_vertex; attribute vec2 in_geometry;
attribute vec3 in_position; attribute vec3 in_position;
attribute vec3 in_velocity; attribute vec3 in_velocity;
attribute float in_maxDist;
uniform float age; uniform float age;
uniform float size; uniform float size;
@ -28,11 +29,17 @@ void main()
decay = ageMod / halfAge; decay = ageMod / halfAge;
// faster particles are smaller // faster particles are smaller
// TODO: scale by time too! scale down fast after 3 halfAges
float scaleBySpeed = (1.0 - 0.95*length(in_velocity)/maxVelocity); float scaleBySpeed = (1.0 - 0.95*length(in_velocity)/maxVelocity);
float finalSize = size * scaleBySpeed; float finalSize = size * scaleBySpeed;
vec2 base = in_vertex; vec2 base = in_geometry;
vec3 p = finalSize*vec3(base, 0.0); vec3 p = finalSize*vec3(base, 0.0);
vec3 offset = (0.2*age + log(1.0+age*5.0)) * in_velocity + in_position; vec3 move = (0.2*age + log(1.0+age*5.0)) * in_velocity;
float md = length(move);
if (md > in_maxDist) {
move *= in_maxDist / md;
}
vec3 offset = move + in_position;
p += offset; p += offset;
gl_Position = vec4(p, 1.0); gl_Position = vec4(p, 1.0);

View file

@ -4,7 +4,7 @@
// TODO: use VAO's as soon as this is working // TODO: use VAO's as soon as this is working
int getDivisorForIndex(int index) int getDivisorForIndex(size_t index)
{ {
// 0 or 1? // 0 or 1?
return (index == 0) ? 0 : 3; return (index == 0) ? 0 : 3;
@ -20,42 +20,52 @@ namespace endofthejedi {
, m_maxVelocity(1.0) , m_maxVelocity(1.0)
, m_center(glm::vec3(0.0f, 0.0f, 0.0f)) , m_center(glm::vec3(0.0f, 0.0f, 0.0f))
// 2d quad drawn as a triangle fan // 2d quad drawn as a triangle fan.
, m_data_quad({ //
// TODO
// it is transformed before uploading so it looks at the camera
, m_data_geometry({
1.0f, -1.0f, 1.0f, -1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f, 1.0f,
-1.0f, -1.0f}) -1.0f, -1.0f})
{ {
m_num_vertex_buffers = 4;
//std::cout<<"[ParticleBatch] create for " << numParticles << " num particles" << std::endl; //std::cout<<"[ParticleBatch] create for " << numParticles << " num particles" << std::endl;
m_attr_locations.resize(m_num_vertex_buffers);
m_data_vbos.resize(m_num_vertex_buffers);
m_data_position.resize(m_numParticles); m_data_position.resize(m_numParticles);
m_data_velocity.resize(m_numParticles); m_data_velocity.resize(m_numParticles);
m_data_kind.resize(m_numParticles); m_data_max_distance.resize(m_numParticles);
m_data_max_age.resize(m_numParticles);
for (size_t i=0; i<m_num_vertex_buffers; i++) {
m_attr_locations[i] = -1;
m_data_vbos[i] = 0;
}
} }
ParticleBatch::~ParticleBatch() ParticleBatch::~ParticleBatch()
{ {
// TODO: find out if stuff must be deallocated // TODO: find out if stuff must be deallocated
glDeleteBuffers(5, m_data_vbos); glDeleteBuffers(m_num_vertex_buffers, m_data_vbos.data());
} }
void ParticleBatch::setup(Shader *shader) void ParticleBatch::setup(Shader *shader)
{ {
const char *names[] = { static const char *names[] = {
"in_vertex", "in_geometry",
"in_position", "in_position",
"in_velocity", "in_velocity",
"XXXunusedXXX", "in_maxDist"
"XXXunusedXXX"
}; };
for (int i=0; i<5; i++) { for (size_t i=0; i<m_num_vertex_buffers; i++) {
const char *name = names[i]; const char *name = names[i];
GLint loc = glGetAttribLocation(shader->program(), name); GLint loc = glGetAttribLocation(shader->program(), name);
m_attr_locations[i] = loc; m_attr_locations[i] = loc;
//std::cout<<"attr location " << i << " " << loc << " " << name << std::endl; //std::cout<<"attr location for " << name << " (#" << i << ") is " << loc << std::endl;
} }
} }
@ -69,7 +79,7 @@ namespace endofthejedi {
m_maxVelocity = maxVelocity; m_maxVelocity = maxVelocity;
} }
void ParticleBatch::setParticle(size_t index, const glm::vec3 &p, const glm::vec3 &v) void ParticleBatch::setParticle(size_t index, const glm::vec3 &p, const glm::vec3 &v, float maxDist)
{ {
if (index >= m_numParticles) { if (index >= m_numParticles) {
return; return;
@ -77,17 +87,16 @@ namespace endofthejedi {
//std::cout<<"[ParticleBatch] setParticle " << index << std::endl; //std::cout<<"[ParticleBatch] setParticle " << index << std::endl;
m_data_position[index] = p; m_data_position[index] = p;
m_data_velocity[index] = v; m_data_velocity[index] = v;
m_data_kind[index] = 0.0; m_data_max_distance[index] = maxDist;
m_data_max_age[index] = 0.0;
} }
void ParticleBatch::bind() void ParticleBatch::bind()
{ {
//std::cout<<"[ParticleBatch] bind" << std::endl; //std::cout<<"[ParticleBatch] bind" << std::endl;
for (size_t i=0; i<5; i++) { for (size_t i=0; i<m_num_vertex_buffers; i++) {
//std::cout<<"vbo #" << i << ": " << m_data_vbos[i] << std::endl; //std::cout<<"vbo #" << i << ": " << m_data_vbos[i] << std::endl;
glEnableVertexAttribArray(m_attr_locations[i]); glEnableVertexAttribArray(m_attr_locations[i]);
glBindBuffer(GL_ARRAY_BUFFER, m_data_vbos[i]); glBindBuffer(GL_ARRAY_BUFFER, m_data_vbos[i]);
@ -109,9 +118,9 @@ namespace endofthejedi {
{ {
//std::cout<<"[ParticleBatch] upload to vbo's " << std::endl; //std::cout<<"[ParticleBatch] upload to vbo's " << std::endl;
glGenBuffers(5, m_data_vbos); // Generate buffer glGenBuffers(m_num_vertex_buffers, m_data_vbos.data()); // Generate buffer
for (size_t i=0; i<5; i++) { for (size_t i=0; i<m_num_vertex_buffers; i++) {
size_t bufferDataSize = dataSizeForIndex(i) * m_numParticles * sizeof(float); size_t bufferDataSize = dataSizeForIndex(i) * m_numParticles * sizeof(float);
glEnableVertexAttribArray(i); glEnableVertexAttribArray(i);
@ -148,7 +157,7 @@ namespace endofthejedi {
#if 0 #if 0
glBegin(GL_QUADS); glBegin(GL_QUADS);
for (size_t index=0; index<m_numParticles; index++) { for (size_t index=0; index<m_numParticles; index++) {
for (int i=0; i<4; i++) { for (size_t i=0; i<4; i++) {
glm::vec2 p = m_data_position[index] + triangles[i]; glm::vec2 p = m_data_position[index] + triangles[i];
//glColor3f(1.0, 0.0, 0.0); //glColor3f(1.0, 0.0, 0.0);
glVertex2f(p.x, p.y); glVertex2f(p.x, p.y);
@ -159,9 +168,9 @@ namespace endofthejedi {
} }
size_t ParticleBatch::dataSizeForIndex(int i) size_t ParticleBatch::dataSizeForIndex(size_t index)
{ {
switch(i) { switch(index) {
case 0: case 0:
return 2; return 2;
@ -170,25 +179,23 @@ namespace endofthejedi {
return 3; return 3;
case 3: case 3:
case 4:
return 1; return 1;
default: default:
std::cerr << "bad" << std::endl; std::cerr << "dataSizeForIndex() bad" << std::endl;
exit(-1); exit(-1);
} }
} }
void *ParticleBatch::dataSourceForIndex(int i) void *ParticleBatch::dataSourceForIndex(size_t index)
{ {
switch(i) { switch(index) {
case 0: return (void *) m_data_quad.data(); case 0: return (void *) m_data_geometry.data();
case 1: return (void *) m_data_position.data(); case 1: return (void *) m_data_position.data();
case 2: return (void *) m_data_velocity.data(); case 2: return (void *) m_data_velocity.data();
case 3: return (void *) m_data_kind.data(); case 3: return (void *) m_data_max_distance.data();
case 4: return (void *) m_data_max_age.data();
default: default:
std::cerr << "bad" << std::endl; std::cerr << "dataSourceForIndex() bad" << std::endl;
exit(-1); exit(-1);
} }
} }

View file

@ -7,6 +7,14 @@
#include "glclasses.hpp" #include "glclasses.hpp"
//class VertexAttribute {
// std::string nameInShader;
// Guint attributeIndex;
// Type type;
// modifictaion
// void *dataSource;
//};
namespace endofthejedi { namespace endofthejedi {
class ParticleBatch { class ParticleBatch {
public: public:
@ -17,7 +25,7 @@ namespace endofthejedi {
size_t numParticles() const { return m_numParticles; } size_t numParticles() const { return m_numParticles; }
void setParticle(size_t index, const glm::vec3 &p, const glm::vec3 &v); void setParticle(size_t index, const glm::vec3 &p, const glm::vec3 &v, float maxDistance);
void setCenter(const glm::vec3 &center); void setCenter(const glm::vec3 &center);
void setMaxVelocity(float maxVelocity); void setMaxVelocity(float maxVelocity);
@ -33,11 +41,14 @@ namespace endofthejedi {
size_t id() const { return m_id; } size_t id() const { return m_id; }
private: private:
size_t dataSizeForIndex(int i); size_t dataSizeForIndex(size_t index);
void *dataSourceForIndex(int i); void *dataSourceForIndex(size_t index);
private: private:
// id of explosion
size_t m_id; size_t m_id;
// uniforms for the shader
size_t m_numParticles; size_t m_numParticles;
float m_particleRadius; float m_particleRadius;
const float m_halfAge; const float m_halfAge;
@ -45,14 +56,15 @@ namespace endofthejedi {
float m_maxVelocity; float m_maxVelocity;
glm::vec3 m_center; glm::vec3 m_center;
GLuint m_data_vbos[5]; // meta data
size_t m_num_vertex_buffers;
std::vector<GLuint> m_data_vbos;
std::vector<GLuint> m_attr_locations;
std::vector<float> m_data_quad; // vertex attributes
std::vector<float> m_data_geometry;
std::vector<glm::vec3> m_data_position; std::vector<glm::vec3> m_data_position;
std::vector<glm::vec3> m_data_velocity; std::vector<glm::vec3> m_data_velocity;
std::vector<float> m_data_kind; std::vector<float> m_data_max_distance;
std::vector<float> m_data_max_age;
GLuint m_attr_locations[5];
}; };
} }

View file

@ -124,7 +124,8 @@ namespace endofthejedi {
glm::vec3 v = glm::ballRand(maxVelocity); glm::vec3 v = glm::ballRand(maxVelocity);
v *= util::randf_0_1() * util::randf_0_1() * util::randf_0_1(); v *= util::randf_0_1() * util::randf_0_1() * util::randf_0_1();
batch->setParticle(i, glm::vec3(pos, 0.0) + glm::ballRand(explCoreSize), v); float maxDist = 0.2;
batch->setParticle(i, glm::vec3(pos, 0.0) + glm::ballRand(explCoreSize), v, maxDist);
} }
batch->upload(); batch->upload();