Ignore:
Timestamp:
06/08/16 20:14:43 (9 years ago)
Author:
epyon
Message:
  • massive particle_engine updates
  • more image data types
  • texture layers for framebuffers
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/engine/particle_engine.cc

    r499 r500  
    2020        "varying vec4 v_color;\n"
    2121        "varying vec2 v_texcoord;\n"
     22        "varying vec3 v_position;\n"
    2223        "uniform mat4 nv_m_view;\n"
    2324        "uniform mat4 nv_m_projection;\n"
    2425        "void main(void)\n"
    2526        "{\n"
    26         "       gl_Position = nv_m_projection * nv_m_view * vec4 (nv_position, 1.0);\n"
    27         "       v_texcoord  = nv_texcoord;\n"
    28         "       v_color     = nv_color;\n"
     27        "       v_position    = nv_position;\n"
     28        "       v_texcoord    = nv_texcoord;\n"
     29        "       v_color       = nv_color;\n"
     30        "       gl_Position   = nv_m_projection * nv_m_view * vec4 (nv_position, 1.0);\n"
    2931        "}\n";
    3032static const char *nv_particle_engine_vertex_shader_local =
     
    3537        "varying vec4 v_color;\n"
    3638        "varying vec2 v_texcoord;\n"
     39        "varying vec3 v_position;\n"
    3740        "uniform mat4 nv_m_mvp;\n"
    3841        "void main(void)\n"
    3942        "{\n"
    40         "       gl_Position = nv_m_mvp * vec4 (nv_position, 1.0);\n"
    41         "       v_texcoord  = nv_texcoord;\n"
    42         "       v_color     = nv_color;\n"
     43        "       v_position    = nv_position;\n"
     44        "       v_texcoord    = nv_texcoord;\n"
     45        "       v_color       = nv_color;\n"
     46        "       gl_Position   = nv_m_mvp * vec4 (nv_position, 1.0);\n"
    4347        "}\n";
    4448static const char *nv_particle_engine_fragment_shader =
     
    4751        "varying vec4 v_color;\n"
    4852        "varying vec2 v_texcoord;\n"
     53        "varying vec3 v_position;\n"
    4954        "void main(void)\n"
    5055        "{\n"
    5156        "       vec4 tex_color = texture2D( nv_t_diffuse, v_texcoord );\n"
    52         "       gl_FragColor   = v_color * tex_color;\n"
     57        "       float edge = smoothstep( 0.0, 0.1, v_position.y );\n"
     58        "       gl_FragColor   = v_color * tex_color * edge;\n"
    5359        "}\n";
    5460
     
    205211        if ( datap->average )
    206212        {
    207                 float norm_factor = nv::min( factor, 1.0f );
     213                float norm_factor = nv::min( factor, 1.0f, p->lifetime );
    208214                for ( uint32 i = 0; i < count; ++i )
    209215                        p[i].velocity = datap->force_vector * norm_factor + p[i].velocity * ( 1.0f - norm_factor );
     
    211217        else
    212218        {
    213                 vec3 scvector = datap->force_vector * factor;
     219                vec3 scvector = datap->force_vector * nv::min( factor, p->lifetime );
    214220                for ( uint32 i = 0; i < count; ++i ) p[i].velocity += scvector;
    215221        }
     
    241247        {
    242248                particle& pt = p[i];
    243                 vec3 direction  = pt.velocity * factor;
     249                vec3 direction  = pt.velocity * nv::min( factor, p->lifetime );
    244250                if ( math::dot( datap->plane_normal, pt.position + direction ) + datap->distance <= 0.0f )
    245251                {
     
    270276{
    271277        const nvpe_color_fader_data* datap = reinterpret_cast<const nvpe_color_fader_data*>( data->paramters );
    272         vec4 adjustment = datap->adjustment * factor;
     278        vec4 adjustment = datap->adjustment * nv::min( factor, p->lifetime );
    273279        for ( uint32 i = 0; i < count; ++i )
    274280        {
     
    293299{
    294300        const nvpe_scaler_data* datap = reinterpret_cast<const nvpe_scaler_data*>( data->paramters );
    295         vec2 adjustment = datap->adjustment * factor;
     301        vec2 adjustment = datap->adjustment * nv::min( factor, p->lifetime );
    296302        for ( uint32 i = 0; i < count; ++i )
    297303        {
     
    399405                                edata.velocity_max = element.get<float>("velocity_max", velocity );
    400406                                float lifetime     = element.get<float>("lifetime", 1.0f );
    401                                 edata.lifetime_min = uint32( element.get<float>("lifetime_min", lifetime ) * 1000.f );
    402                                 edata.lifetime_max = uint32( element.get<float>("lifetime_max", lifetime ) * 1000.f );
     407                                edata.lifetime_min = element.get<float>("lifetime_min", lifetime );
     408                                edata.lifetime_max = element.get<float>("lifetime_max", lifetime );
    403409                                float duration     = element.get<float>("duration", 0.0f );
    404                                 edata.duration_min = uint32( element.get<float>("duration_min", duration ) * 1000.f );
    405                                 edata.duration_max = uint32( element.get<float>("duration_max", duration ) * 1000.f );
     410                                edata.duration_min = element.get<float>("duration_min", duration );
     411                                edata.duration_max = element.get<float>("duration_max", duration );
    406412                                float repeat       = element.get<float>("repeat_delay", 0.0f );
    407                                 edata.repeat_min   = uint32( element.get<float>("repeat_delay_min", repeat ) * 1000.f );
    408                                 edata.repeat_max   = uint32( element.get<float>("repeat_delay_max", repeat ) * 1000.f );
     413                                edata.repeat_min   = element.get<float>("repeat_delay_min", repeat );
     414                                edata.repeat_max   = element.get<float>("repeat_delay_max", repeat );
    409415
    410416                                edata.rate         = element.get<float>("rate", 1.0f );
     
    464470        m_program_local = m_device->create_program( nv_particle_engine_vertex_shader_local, nv_particle_engine_fragment_shader );
    465471        m_program_world = m_device->create_program( nv_particle_engine_vertex_shader_world, nv_particle_engine_fragment_shader );
    466         m_last_update = 0;
    467472
    468473        register_standard_emmiters();
     
    472477nv::particle_system nv::particle_engine::create_system( const string_view& id, particle_system_group group )
    473478{
     479        particle_system_group_info* ginfo = m_groups.get( group );
     480        if ( !ginfo ) return nv::particle_system();
     481
    474482        auto it = m_names.find( id );
    475483        if ( it == m_names.end() )
     
    486494        {
    487495                info->emmiters[i].active      = true;
    488                 info->emmiters[i].last_create = float( m_last_update );
    489                 if ( data->emmiters[i].duration_max == 0 )
    490                         info->emmiters[i].next_toggle = 0;
     496                if ( data->emmiters[i].duration_max == 0.0f )
     497                        info->emmiters[i].pause = 0;
    491498                else
    492                         info->emmiters[i].next_toggle = m_last_update + random::get().urange( data->emmiters[i].duration_min, data->emmiters[i].duration_max );
     499                        info->emmiters[i].pause = random::get().frange( data->emmiters[i].duration_min, data->emmiters[i].duration_max );
    493500
    494501        }
     
    496503        info->count = 0;
    497504        info->particles = new particle[ data->quota ];
    498         info->last_update = m_last_update;
     505        ginfo->ref_counter++;
    499506
    500507        return result;
     
    531538        info->vtx_array = m_context->create_vertex_array( desc );
    532539        info->quads     = new particle_quad[info->quota];
     540        info->ref_counter = 0;
    533541        return result;
    534542}
     
    546554        register_standard_emmiters();
    547555        register_standard_affectors();
     556}
     557
     558bool nv::particle_engine::loaded( const string_view& system_id )
     559{
     560        return m_names.find( system_id ) != m_names.end();
    548561}
    549562
     
    558571        m_names.clear();
    559572        m_data.clear();
    560         m_last_update = 0;
    561573}
    562574
     
    567579        if ( info )
    568580        {
    569                 delete[] info->particles;
     581                particle_system_group_info* ginfo = m_groups.get( info->group );
     582                if ( ginfo ) ginfo->ref_counter--;
     583                                delete[] info->particles;
    570584                m_systems.destroy( system );
    571585        }
     
    583597}
    584598
    585 void nv::particle_engine::update( const scene_state& s, uint32 ms )
    586 {
    587         m_last_update += ms;
    588         m_view_matrix  = s.get_view();
    589         m_model_matrix = s.get_model();
    590         m_camera_pos   = s.get_camera().get_position();
    591         m_inv_view_dir = math::normalize(-s.get_camera().get_direction());
    592 }
    593 
    594 void nv::particle_engine::update( particle_system system )
     599void nv::particle_engine::render( particle_system system, const scene_state& s )
    595600{
    596601        particle_system_info* info = m_systems.get( system );
    597602        if ( info )
    598603        {
    599                 update_emmiters( info, m_last_update );
    600                 destroy_particles( info, m_last_update );
    601                 create_particles( info, m_last_update );
    602                 update_particles( info, m_last_update );
    603 
    604                 generate_data( info );
    605         }
    606 }
    607 
    608 void nv::particle_engine::set_texcoords( particle_system system, vec2 a, vec2 b )
     604                generate_data( info, s );
     605        }
     606}
     607
     608void nv::particle_engine::update( particle_system system, float dtime )
    609609{
    610610        particle_system_info* info = m_systems.get( system );
    611611        if ( info )
    612612        {
    613                 vec2 texcoords[4] = { a, vec2( b.x, a.y ), vec2( a.x, b.y ), b };
    614                 for ( uint32 i = 0; i < 4; ++i )
    615                         info->texcoords[i] = texcoords[i];
    616         }
    617 }
    618 
    619 void nv::particle_engine::generate_data( particle_system_info* info )
     613//              while ( dtime > 0.2 )
     614//              {
     615//                      update_emmiters( info, 0.2 );
     616//                      destroy_particles( info, 0.2 );
     617//                      create_particles( info, 0.2 );
     618//                      update_particles( info, 0.2 );
     619//                      dtime -= 0.2;
     620//              }
     621
     622                update_emmiters( info, dtime );
     623                destroy_particles( info, dtime );
     624                create_particles( info, dtime );
     625                update_particles( info, dtime );
     626
     627//              generate_data( info );
     628        }
     629}
     630
     631void nv::particle_engine::set_texcoords( particle_system system, vec2 a, vec2 b )
     632{
     633
     634        particle_system_info* info = m_systems.get( system );
     635        if ( info )
     636        {
     637                info->texcoords[0] = a;
     638                info->texcoords[1] = b;
     639        }
     640}
     641
     642void nv::particle_engine::generate_data( particle_system_info* info, const scene_state& s )
    620643{
    621644//      void* rawptr = m_context->map_buffer( info->vtx_buffer, nv::WRITE_UNSYNCHRONIZED, offset, info->count*sizeof( particle_quad ) );
     
    661684        vec3 pdir( 0.0f, 1.0f, 0.0f );
    662685
    663         vec2 texcoords[4] =
    664         {
    665                 info->texcoords[0],
    666                 info->texcoords[1],
    667                 info->texcoords[2],
    668                 info->texcoords[3],
    669         };
     686        vec3 camera_pos   = s.get_camera().get_position();
     687        vec3 inv_view_dir = math::normalize( -s.get_camera().get_direction() );
    670688
    671689        for ( uint32 i = 0; i < info->count; ++i )
     
    675693                particle_quad& rdata  = group->quads[i + group->count];
    676694
    677                 vec3 view_dir( m_inv_view_dir );
    678                 if ( accurate_facing ) view_dir = math::normalize( m_camera_pos - pdata.position );
     695                vec3 view_dir( inv_view_dir );
     696                if ( accurate_facing ) view_dir = math::normalize( camera_pos - pdata.position );
    679697
    680698                switch ( orientation )
     
    682700                case particle_orientation::POINT :
    683701                        right   = math::normalize( math::cross( view_dir, vec3( 0, 1, 0 ) ) );
     702                        right   = math::rotate( right, pdata.rotation, view_dir );
    684703                        rot_mat = mat3( right, math::cross( right, -view_dir ), -view_dir );
    685704                        break;
     
    704723                }
    705724
     725                vec2 texcoords[4] =
     726                {
     727                        pdata.tcoord_a,
     728                        vec2( pdata.tcoord_b.x, pdata.tcoord_a.y ),
     729                        vec2( pdata.tcoord_a.x, pdata.tcoord_b.y ),
     730                        pdata.tcoord_b
     731                };
     732
    706733                vec3 size( pdata.size.x, pdata.size.y, 0.0f );
    707734                vec3 s0 = rot_mat * ( ( size * sm[0] ) );
     
    735762}
    736763
    737 void nv::particle_engine::destroy_particles( particle_system_info* info, uint32 ms )
     764void nv::particle_engine::destroy_particles( particle_system_info* info, float dtime )
    738765{
    739766        if ( info->count > 0 )
     
    741768                {
    742769                        particle& pinfo = info->particles[i];
    743                         if ( //pdata.position.y < 0.0f ||
    744                                 ms >= pinfo.death )
     770                        pinfo.lifetime += dtime;
     771                        if ( pinfo.lifetime >= pinfo.death )
    745772                        {
    746773                                info->count--;
     
    750777}
    751778
    752 void nv::particle_engine::create_particles( particle_system_info* info, uint32 ms )
     779void nv::particle_engine::create_particles( particle_system_info* info, float dtime )
    753780{
    754781        uint32 ecount = info->data->emmiter_count;
     
    759786        mat3 orient;
    760787        bool local = info->data->local;
    761         if ( !local )
    762         {
    763                 source = vec3( m_model_matrix[3] );
    764                 orient = mat3( m_model_matrix );
    765         }
    766 
    767         float fms = float(ms);
     788//      if ( !local )
     789//      {
     790//              source = vec3( m_model_matrix[3] );
     791//              orient = mat3( m_model_matrix );
     792//      }
    768793
    769794        for ( uint32 i = 0; i < ecount; ++i )
     
    773798                if ( einfo.active )
    774799                {
    775                         float period = 1000.f / edata.rate;
    776                         while ( fms - einfo.last_create > period )
     800                        einfo.next -= dtime;
     801                        float fperiod = 1.0f / edata.rate;
     802                        while ( einfo.next < 0.0f )
    777803                        {
    778804                                if ( info->count < info->data->quota-1 )
     
    780806                                        particle& pinfo = info->particles[info->count];
    781807                                        edata.emmiter_func( &(info->data->emmiters[i]), &pinfo, 1 );
    782 
    783                                         if ( !local ) pinfo.position  = orient * pinfo.position + source;
    784                                         pinfo.position += edata.position;
    785                                         pinfo.color     = edata.color_min == edata.color_max ?
     808                                        pinfo.position = vec3();
     809//                                      if ( !local ) pinfo.position  = orient * pinfo.position + source;
     810                                        pinfo.position+= edata.position;
     811                                        pinfo.color    = edata.color_min == edata.color_max ?
    786812                                                edata.color_min : r.range( edata.color_min, edata.color_max );
    787                                         pinfo.size      = edata.size_min == edata.size_max ?
     813                                        pinfo.size     = edata.size_min == edata.size_max ?
    788814                                                edata.size_min : r.range( edata.size_min, edata.size_max );
    789815                                        if ( edata.square ) pinfo.size.y = pinfo.size.x;
    790                                         float velocity  = edata.velocity_min == edata.velocity_max ?
     816                                        float velocity = edata.velocity_min == edata.velocity_max ?
    791817                                                edata.velocity_min : r.frange( edata.velocity_min, edata.velocity_max );
    792                                         pinfo.death     = ms + ( edata.lifetime_min == edata.lifetime_max ?
    793                                                 edata.lifetime_min : r.urange( edata.lifetime_min, edata.lifetime_max ) );
    794                                         //pinfo.rotation = r.frand( 360.0f );
     818                                        pinfo.lifetime = dtime + einfo.next;
     819                                        pinfo.death = ( edata.lifetime_min == edata.lifetime_max ?
     820                                                edata.lifetime_min : r.frange( edata.lifetime_min, edata.lifetime_max ) );
     821                                        pinfo.rotation = r.frand( 2* math::pi<float>() );
     822                                        pinfo.tcoord_a = info->texcoords[0];
     823                                        pinfo.tcoord_b = info->texcoords[1];
    795824
    796825                                        pinfo.velocity = edata.dir;
     
    811840                                        info->count++;
    812841                                }
    813                                 einfo.last_create += period;
     842                                einfo.next += fperiod;
    814843                        }
     844
    815845                }
    816846        }
    817847}
    818848
    819 void nv::particle_engine::update_particles( particle_system_info* info, uint32 ms )
    820 {
    821         uint32 ticks = ms - info->last_update;
    822         if ( ticks == 0 ) return;
    823         float factor  = 0.001f * ticks;
     849void nv::particle_engine::update_particles( particle_system_info* info, float dtime )
     850{
     851        if ( dtime <= 0.0f ) return;
    824852
    825853        uint32 acount = info->data->affector_count;
     
    827855        {
    828856                const particle_affector_data* padata = &(info->data->affectors[i]);
    829                 padata->process( padata, info->particles, factor, info->count );
     857                padata->process( padata, info->particles, dtime, info->count );
    830858        }
    831859
     
    834862        {
    835863                particle& pdata = info->particles[i];
     864                float factor = min( dtime, pdata.lifetime );
    836865                pdata.position += pdata.velocity * factor;
    837866        }
    838         info->last_update = ms;
    839 }
    840 
    841 void nv::particle_engine::update_emmiters( particle_system_info* info, uint32 ms )
     867}
     868
     869void nv::particle_engine::update_emmiters( particle_system_info* info, float dtime )
    842870{
    843871        uint32 ecount = info->data->emmiter_count;
     
    850878                auto& einfo = info->emmiters[i];
    851879
    852                 if ( einfo.next_toggle != 0 && ms >= einfo.next_toggle )
     880                if ( einfo.pause > 0.0f )
     881                {
     882                        einfo.pause -= dtime;
     883                        if ( einfo.pause == 0.0f ) einfo.pause = -0.001f;
     884                }
     885
     886                if ( einfo.pause < 0.0f )
    853887                {
    854888                        if ( einfo.active )
    855889                        {
    856890                                einfo.active = false;
    857                                 if ( edata.repeat_min > 0 )
    858                                         einfo.next_toggle += r.urange( edata.repeat_min, edata.repeat_max );
     891                                if ( edata.repeat_min > 0.0f )
     892                                        einfo.pause += r.frange( edata.repeat_min, edata.repeat_max );
    859893                                else
    860                                         einfo.next_toggle = 0;
     894                                        einfo.pause = 0.0f;
    861895                        }
    862896                        else
    863897                        {
    864898                                einfo.active = true;
    865                                 einfo.last_create = float( einfo.next_toggle );
    866                                 einfo.next_toggle += r.urange( edata.duration_min, edata.duration_max );
     899                                einfo.pause += r.frange( edata.duration_min, edata.duration_max );
    867900                        }
    868901                }
     
    896929}
    897930
     931nv::particle_render_data nv::particle_engine::get_render_data( particle_system_group group )
     932{
     933        const particle_system_group_info* info = m_groups.get( group );
     934        if ( info )
     935        {
     936                return{ info->count, info->vtx_array };
     937        }
     938        return { 0, nv::vertex_array() };
     939}
     940
    898941void nv::particle_engine::register_standard_affectors()
    899942{
Note: See TracChangeset for help on using the changeset viewer.