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 @ 3:7fb593d53361

History | View | Annotate | Download (3.83 KB)

1
#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

    
136