making code for particle batch modular.
This commit is contained in:
parent
a81b549126
commit
57e6e56217
4 changed files with 73 additions and 46 deletions
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -79,15 +89,14 @@ namespace endofthejedi {
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ¢er);
|
void setCenter(const glm::vec3 ¢er);
|
||||||
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];
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue