A ParticleLayer to force particles to stay in the viewport, with a uniform density. More...
#include <ScreenParticleLayer.h>
Classes | |
struct | ScreenParticle |
Layer specific particle data for managing particles in screen space. More... | |
Public Types | |
enum | status { AGE, OUTSIDE_VIEWPORT, POISSON_DISK } |
The reason why a particle is fading out. More... | |
Public Member Functions | |
ScreenParticleLayer (float radius, ptr< Texture2D > offscreenDepthBuffer) | |
Creates a new ScreenParticleLayer. | |
virtual | ~ScreenParticleLayer () |
Deletes this LifeCycleParticleLayer. | |
float | getParticleRadius () const |
Returns the Poisson-disk radius of each particle, in pixels. | |
void | setParticleRadius (float radius) |
Sets the Poisson-disk radius of each particle, in pixels. | |
ScreenParticle * | getScreenParticle (ParticleStorage::Particle *p) |
Returns the screen space specific data of the given particle. | |
void | setSceneManager (SceneManager *manager) |
Sets the scene manager used to set the world to screen transformation. | |
virtual void | moveParticles (double dt) |
Moves the existing particles. | |
virtual void | removeOldParticles () |
Removes old particles. | |
virtual void | addNewParticles () |
Adds new particles. | |
ScreenParticle ** | getNeighbors (ScreenParticle *s, int &n) |
Returns the neighbors of the given screen particle. | |
Protected Member Functions | |
ScreenParticleLayer () | |
Creates an uninitialized ScreenParticleLayer. | |
void | init (float radius, ptr< Texture2D > offscreenDepthBuffer) |
Initializes this ScreenParticleLayer. | |
virtual void | initialize () |
Initializes this ParticleLayer. | |
virtual void | initParticle (ParticleStorage::Particle *p) |
Initializes the data that is specific to this layer in the given particle. | |
Private Member Functions | |
void | findNeighborRanges (ScreenParticle *p) |
Updates ranges based on the neighbors of the given particle. | |
ScreenParticle * | newScreenParticle (const vec2f &pos) |
Creates a new particle at the given position, and adds it to grid. | |
void | getParticleDepths (const vector< ScreenParticle * > &particles) |
Reads the depths of the given particles from the depth buffer. | |
Private Attributes | |
SceneManager * | scene |
The scene manager, used to get the world to screen transformation. | |
float | radius |
The Poisson-disk radius of each particle, in pixels. | |
box2f | bounds |
The current bounds of the viewport, in pixels. | |
ParticleGrid * | grid |
A ParticleGrid to store particles according to their screen position. | |
RangeList * | ranges |
Data structure used to find where to create new particles, so that they form a Poisson-disk distribution. | |
mat4d | lastWorldToScreen |
The world to screen transformation of the last frame. | |
vec4i | lastViewport |
The viewport of the last frame. | |
bool | depthBufferRead |
True if the camera is not moving, and if the depth buffer has been read into depthArray. | |
int | depthArraySize |
The size of the depthArray array. | |
float * | depthArray |
Array used to get the depth of the particles created at this frame or the depth of all the pixels of the depth buffer. | |
ptr< FrameBuffer > | frameBuffer |
Framebuffer in which to execute the packer program. | |
ptr< Mesh< vec3f, unsigned int > > | mesh |
Mesh used to retrieve depths with the packer program. | |
ptr< UniformSampler > | depthTextureU |
Sampler uniform to access the depthTexture texture. | |
ptr< Uniform3f > | sizeU |
Viewport width and height, plus width of the framebuffer viewport. | |
bool | useOffscreenDepthBuffer |
True if the user provides an offscreen depthbuffer. | |
WorldParticleLayer * | worldLayer |
The layer managing the particles in world space. | |
LifeCycleParticleLayer * | lifeCycleLayer |
The layer managing the particles life cycle. | |
Static Private Attributes | |
static static_ptr< Program > | packer |
Program used to get the depths of a set of particles. | |
static static_ptr< Texture2D > | depthBuffer |
A copy of the depth buffer in the form of a texture. |
A ParticleLayer to force particles to stay in the viewport, with a uniform density.
This layer requires particles initially managed in world space, using a WorldParticleLayer. It then forces these particles to stay in the framebuffer viewport. For that it deletes particles that project outside the viewport, and creates new particles in this viewport to maintain a constant density of particles. In fact particles are not really deleted, but forced to fading out. This requires a LifeCycleParticleLayer.
proland::ScreenParticleLayer::ScreenParticleLayer | ( | float | radius, | |
ptr< Texture2D > | offscreenDepthBuffer | |||
) |
Creates a new ScreenParticleLayer.
radius | the radius of each particle, in pixels. This radius is used as a Poisson-disk radius for maintaining a Poisson distribution of particles in screen space. | |
offscreenDepthBuffer | the offscreen buffer that contains depth. This texture is used to avoid copying the depth buffer at each frame. |
virtual proland::ScreenParticleLayer::~ScreenParticleLayer | ( | ) | [virtual] |
Deletes this LifeCycleParticleLayer.
proland::ScreenParticleLayer::ScreenParticleLayer | ( | ) | [protected] |
Creates an uninitialized ScreenParticleLayer.
virtual void proland::ScreenParticleLayer::addNewParticles | ( | ) | [virtual] |
Adds new particles.
The default implementation of this method does nothing.
Reimplemented from proland::ParticleLayer.
void proland::ScreenParticleLayer::findNeighborRanges | ( | ScreenParticle * | p | ) | [private] |
Updates ranges based on the neighbors of the given particle.
ScreenParticle** proland::ScreenParticleLayer::getNeighbors | ( | ScreenParticle * | s, | |
int & | n | |||
) |
Returns the neighbors of the given screen particle.
s | a screen particle. | |
[out] | n | the number of neighbors of s. |
void proland::ScreenParticleLayer::getParticleDepths | ( | const vector< ScreenParticle * > & | particles | ) | [private] |
Reads the depths of the given particles from the depth buffer.
particles | a list of particles. |
float proland::ScreenParticleLayer::getParticleRadius | ( | ) | const |
Returns the Poisson-disk radius of each particle, in pixels.
ScreenParticle* proland::ScreenParticleLayer::getScreenParticle | ( | ParticleStorage::Particle * | p | ) | [inline] |
Returns the screen space specific data of the given particle.
p | a particle. |
void proland::ScreenParticleLayer::init | ( | float | radius, | |
ptr< Texture2D > | offscreenDepthBuffer | |||
) | [protected] |
Initializes this ScreenParticleLayer.
See ScreenParticleLayer.
virtual void proland::ScreenParticleLayer::initialize | ( | ) | [protected, virtual] |
Initializes this ParticleLayer.
If this layer needs reference to other layers it can initialize them in this method (using the template method ParticleProducer::getLayer()). The default implementation of this method does nothing.
Reimplemented from proland::ParticleLayer.
virtual void proland::ScreenParticleLayer::initParticle | ( | ParticleStorage::Particle * | p | ) | [protected, virtual] |
Initializes the data that is specific to this layer in the given particle.
The default implementation of this method does nothing.
Reimplemented from proland::ParticleLayer.
virtual void proland::ScreenParticleLayer::moveParticles | ( | double | dt | ) | [virtual] |
Moves the existing particles.
The default implementation of this method does nothing.
dt | the elapsed time since the last call to this method, in microseconds. |
Reimplemented from proland::ParticleLayer.
ScreenParticle* proland::ScreenParticleLayer::newScreenParticle | ( | const vec2f & | pos | ) | [private] |
Creates a new particle at the given position, and adds it to grid.
pos | a position in screen space, in pixels. |
virtual void proland::ScreenParticleLayer::removeOldParticles | ( | ) | [virtual] |
Removes old particles.
The default implementation of this method does nothing.
Reimplemented from proland::ParticleLayer.
void proland::ScreenParticleLayer::setParticleRadius | ( | float | radius | ) |
Sets the Poisson-disk radius of each particle, in pixels.
void proland::ScreenParticleLayer::setSceneManager | ( | SceneManager * | manager | ) |
Sets the scene manager used to set the world to screen transformation.
box2f proland::ScreenParticleLayer::bounds [private] |
The current bounds of the viewport, in pixels.
Particles are forced to stay in this viewport by this particle layer.
float* proland::ScreenParticleLayer::depthArray [private] |
Array used to get the depth of the particles created at this frame or the depth of all the pixels of the depth buffer.
int proland::ScreenParticleLayer::depthArraySize [private] |
The size of the depthArray array.
static_ptr<Texture2D> proland::ScreenParticleLayer::depthBuffer [static, private] |
A copy of the depth buffer in the form of a texture.
This texture is needed by the packer program to access the depth of arbitrary pixels in the depth buffer.
bool proland::ScreenParticleLayer::depthBufferRead [private] |
True if the camera is not moving, and if the depth buffer has been read into depthArray.
ptr<UniformSampler> proland::ScreenParticleLayer::depthTextureU [private] |
Sampler uniform to access the depthTexture texture.
ptr<FrameBuffer> proland::ScreenParticleLayer::frameBuffer [private] |
Framebuffer in which to execute the packer program.
This framebuffer uses as color attachment a texture containing the depths read by packer, which are then read back in depthArray.
ParticleGrid* proland::ScreenParticleLayer::grid [private] |
A ParticleGrid to store particles according to their screen position.
This grid is necessary to quickly find the neighbors of particles, which are themselves needed to maintain a Poisson-disk distribution.
vec4i proland::ScreenParticleLayer::lastViewport [private] |
The viewport of the last frame.
Used to determine if the camera moved at this frame.
mat4d proland::ScreenParticleLayer::lastWorldToScreen [private] |
The world to screen transformation of the last frame.
Used to determine if the camera moved at this frame.
The layer managing the particles life cycle.
ptr< Mesh<vec3f, unsigned int> > proland::ScreenParticleLayer::mesh [private] |
Mesh used to retrieve depths with the packer program.
This point mesh contains one point per particle. Each point contains the screen coordinates of a particle, and the index of this particle.
static_ptr<Program> proland::ScreenParticleLayer::packer [static, private] |
Program used to get the depths of a set of particles.
float proland::ScreenParticleLayer::radius [private] |
The Poisson-disk radius of each particle, in pixels.
RangeList* proland::ScreenParticleLayer::ranges [private] |
Data structure used to find where to create new particles, so that they form a Poisson-disk distribution.
SceneManager* proland::ScreenParticleLayer::scene [private] |
The scene manager, used to get the world to screen transformation.
ptr<Uniform3f> proland::ScreenParticleLayer::sizeU [private] |
Viewport width and height, plus width of the framebuffer viewport.
bool proland::ScreenParticleLayer::useOffscreenDepthBuffer [private] |
True if the user provides an offscreen depthbuffer.
This allows to not copy the depthbuffer before reading from it.
The layer managing the particles in world space.