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
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 ¢er);
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue