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
attribute vec2 in_vertex;
attribute vec2 in_geometry;
attribute vec3 in_position;
attribute vec3 in_velocity;
attribute float in_maxDist;
uniform float age;
uniform float size;
@ -28,11 +29,17 @@ void main()
decay = ageMod / halfAge;
// 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 finalSize = size * scaleBySpeed;
vec2 base = in_vertex;
vec2 base = in_geometry;
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;
gl_Position = vec4(p, 1.0);

View file

@ -4,7 +4,7 @@
// TODO: use VAO's as soon as this is working
int getDivisorForIndex(int index)
int getDivisorForIndex(size_t index)
{
// 0 or 1?
return (index == 0) ? 0 : 3;
@ -20,42 +20,52 @@ namespace endofthejedi {
, m_maxVelocity(1.0)
, m_center(glm::vec3(0.0f, 0.0f, 0.0f))
// 2d quad drawn as a triangle fan
, m_data_quad({
// 2d quad drawn as a triangle fan.
//
// 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})
{
m_num_vertex_buffers = 4;
//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_velocity.resize(m_numParticles);
m_data_kind.resize(m_numParticles);
m_data_max_age.resize(m_numParticles);
m_data_max_distance.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()
{
// 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)
{
const char *names[] = {
"in_vertex",
static const char *names[] = {
"in_geometry",
"in_position",
"in_velocity",
"XXXunusedXXX",
"XXXunusedXXX"
"in_maxDist"
};
for (int i=0; i<5; i++) {
for (size_t i=0; i<m_num_vertex_buffers; i++) {
const char *name = names[i];
GLint loc = glGetAttribLocation(shader->program(), name);
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;
}
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) {
return;
@ -79,15 +89,14 @@ namespace endofthejedi {
m_data_position[index] = p;
m_data_velocity[index] = v;
m_data_kind[index] = 0.0;
m_data_max_age[index] = 0.0;
m_data_max_distance[index] = maxDist;
}
void ParticleBatch::bind()
{
//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;
glEnableVertexAttribArray(m_attr_locations[i]);
glBindBuffer(GL_ARRAY_BUFFER, m_data_vbos[i]);
@ -109,9 +118,9 @@ namespace endofthejedi {
{
//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);
glEnableVertexAttribArray(i);
@ -148,7 +157,7 @@ namespace endofthejedi {
#if 0
glBegin(GL_QUADS);
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];
//glColor3f(1.0, 0.0, 0.0);
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:
return 2;
@ -170,25 +179,23 @@ namespace endofthejedi {
return 3;
case 3:
case 4:
return 1;
default:
std::cerr << "bad" << std::endl;
std::cerr << "dataSizeForIndex() bad" << std::endl;
exit(-1);
}
}
void *ParticleBatch::dataSourceForIndex(int i)
void *ParticleBatch::dataSourceForIndex(size_t index)
{
switch(i) {
case 0: return (void *) m_data_quad.data();
switch(index) {
case 0: return (void *) m_data_geometry.data();
case 1: return (void *) m_data_position.data();
case 2: return (void *) m_data_velocity.data();
case 3: return (void *) m_data_kind.data();
case 4: return (void *) m_data_max_age.data();
case 3: return (void *) m_data_max_distance.data();
default:
std::cerr << "bad" << std::endl;
std::cerr << "dataSourceForIndex() bad" << std::endl;
exit(-1);
}
}

View file

@ -7,6 +7,14 @@
#include "glclasses.hpp"
//class VertexAttribute {
// std::string nameInShader;
// Guint attributeIndex;
// Type type;
// modifictaion
// void *dataSource;
//};
namespace endofthejedi {
class ParticleBatch {
public:
@ -17,7 +25,7 @@ namespace endofthejedi {
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 setMaxVelocity(float maxVelocity);
@ -33,11 +41,14 @@ namespace endofthejedi {
size_t id() const { return m_id; }
private:
size_t dataSizeForIndex(int i);
void *dataSourceForIndex(int i);
size_t dataSizeForIndex(size_t index);
void *dataSourceForIndex(size_t index);
private:
// id of explosion
size_t m_id;
// uniforms for the shader
size_t m_numParticles;
float m_particleRadius;
const float m_halfAge;
@ -45,14 +56,15 @@ namespace endofthejedi {
float m_maxVelocity;
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_velocity;
std::vector<float> m_data_kind;
std::vector<float> m_data_max_age;
GLuint m_attr_locations[5];
std::vector<float> m_data_max_distance;
};
}

View file

@ -124,7 +124,8 @@ namespace endofthejedi {
glm::vec3 v = glm::ballRand(maxVelocity);
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();