To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / CollidoscopeApp / src / ParticleController.cpp @ 0:02467299402e

History | View | Annotate | Download (3.83 KB)

1 0:02467299402e f
#include "ParticleController.h"
2
#include "cinder/Rand.h"
3
4
#include <type_traits>
5
6
using namespace ci;
7
using std::list;
8
9
ParticleController::ParticleController() :
10
mNumParticles( 0 )
11
12
{
13
    mParticles.assign( kMaxParticles, Particle() );
14
    mParticlePositions.assign( kMaxParticles, vec2( -1, -1 ) );
15
16
    mParticleVbo = gl::Vbo::create( GL_ARRAY_BUFFER, mParticlePositions, GL_DYNAMIC_DRAW );
17
18
    geom::BufferLayout particleLayout;
19
    particleLayout.append( geom::Attrib::POSITION, 2, sizeof( vec2 ), 0 );
20
21
    auto mesh = gl::VboMesh::create( mParticlePositions.size(), GL_POINTS, { { particleLayout, mParticleVbo } } );
22
23
#if ! defined( CINDER_GL_ES )
24
    auto glsl = gl::GlslProg::create( gl::GlslProg::Format()
25
        .vertex( CI_GLSL( 150,
26
            uniform mat4        ciModelViewProjection;
27
            in vec4                        ciPosition;
28
29
            void main( void ) {
30
                gl_Position = ciModelViewProjection * ciPosition;
31
                gl_PointSize = 1.0;
32
            }
33
            ) )
34
        .fragment( CI_GLSL( 150,
35
            out vec4 oColor;
36
37
            void main( void ) {
38
                oColor = vec4( 1.0f, 1.0f, 1.0f, 1.0f );
39
            }
40
        ) )
41
    );
42
43
    mParticleBatch = gl::Batch::create( mesh, glsl );
44
45
#else
46
    auto glsl = gl::GlslProg::create( gl::GlslProg::Format()
47
        .vertex( CI_GLSL( 100,
48
            uniform mat4        ciModelViewProjection;
49
            attribute vec4                        ciPosition;
50
51
            void main( void ) {
52
                gl_Position = ciModelViewProjection * ciPosition;
53
                gl_PointSize = 1.0;
54
            }
55
        ) )
56
        .fragment( CI_GLSL( 100,
57
            precision highp float;
58
59
            void main( void ) {
60
                gl_FragColor = vec4( 1, 1, 1, 1 );
61
            }
62
        ) )
63
    );
64
65
    mParticleBatch = gl::Batch::create( mesh, glsl );
66
#endif
67
68
69
}
70
71
void ParticleController::updateParticles()
72
{
73
    for ( size_t i = 0; i < mNumParticles; i++ ){
74
75
        Particle &particle = mParticles[i];
76
        vec2 &pos = mParticlePositions[i];
77
78
        particle.mAge++;
79
80
81
        if ( (!particle.mFlyOver && particle.mAge > particle.mLifespan)
82
                || (particle.mFlyOver && particle.mAge >= 300) ){
83
            // dispose particle
84
            mParticles[i] = mParticles[mNumParticles - 1];
85
            mParticlePositions[i] = mParticlePositions[mNumParticles - 1];
86
            mParticlePositions[mNumParticles - 1].x = -1.0f;
87
            mParticlePositions[mNumParticles - 1].y = -1.0f;
88
            mNumParticles--;
89
            continue;
90
        }
91
92
        pos += particle.mVel;
93
        if ( ci::distance( pos, particle.mCloudCenter ) >  particle.mCloudSize && !particle.mFlyOver ){
94
            particle.mVel = rotate<float>( particle.mVel, 5 );
95
        }
96
    }
97
98
    void *gpuMem = mParticleVbo->mapReplace();
99
    memcpy( gpuMem, mParticlePositions.data(), mParticlePositions.size() * sizeof( vec2 ) );
100
    mParticleVbo->unmap();
101
}
102
103
void ParticleController::addParticles(int amount, const vec2 &initialLocation, const float cloudSize)
104
{
105
    int reduction = ci::lmap<int>(mNumParticles, 0, kMaxParticles, 0, kMaxParticleAdd);
106
    amount -= reduction;
107
108
    if ( mNumParticles + amount > kMaxParticles ){
109
                //return;
110
        amount = kMaxParticles - mNumParticles;
111
        }
112
113
    if( amount <= 0 )
114
        return;
115
116
        for( size_t i = 0; i < amount; i++ ){
117
        // init new particle
118
        Particle &particle = mParticles[mNumParticles + i];
119
        vec2 &pos = mParticlePositions[mNumParticles + i];
120
121
        pos = initialLocation + Rand::randVec2() * 5.0f; // find a location nearby the initial location
122
        particle.mCloudCenter = pos;
123
        particle.mVel = Rand::randVec2() * Rand::randFloat( 1.0f, 5.0f );
124
        particle.mCloudSize = cloudSize;
125
        particle.mAge = 0;
126
        particle.mLifespan = Rand::randInt( 30, 60 );
127
        particle.mFlyOver = (Rand::randInt( 500 ) == 0);
128
129
        }
130
131
    mNumParticles += amount ;
132
133
}
134
135