- Timestamp:
- 06/08/16 20:14:43 (9 years ago)
- Location:
- trunk/src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/engine/particle_engine.cc
r499 r500 20 20 "varying vec4 v_color;\n" 21 21 "varying vec2 v_texcoord;\n" 22 "varying vec3 v_position;\n" 22 23 "uniform mat4 nv_m_view;\n" 23 24 "uniform mat4 nv_m_projection;\n" 24 25 "void main(void)\n" 25 26 "{\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" 29 31 "}\n"; 30 32 static const char *nv_particle_engine_vertex_shader_local = … … 35 37 "varying vec4 v_color;\n" 36 38 "varying vec2 v_texcoord;\n" 39 "varying vec3 v_position;\n" 37 40 "uniform mat4 nv_m_mvp;\n" 38 41 "void main(void)\n" 39 42 "{\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" 43 47 "}\n"; 44 48 static const char *nv_particle_engine_fragment_shader = … … 47 51 "varying vec4 v_color;\n" 48 52 "varying vec2 v_texcoord;\n" 53 "varying vec3 v_position;\n" 49 54 "void main(void)\n" 50 55 "{\n" 51 56 " 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" 53 59 "}\n"; 54 60 … … 205 211 if ( datap->average ) 206 212 { 207 float norm_factor = nv::min( factor, 1.0f );213 float norm_factor = nv::min( factor, 1.0f, p->lifetime ); 208 214 for ( uint32 i = 0; i < count; ++i ) 209 215 p[i].velocity = datap->force_vector * norm_factor + p[i].velocity * ( 1.0f - norm_factor ); … … 211 217 else 212 218 { 213 vec3 scvector = datap->force_vector * factor;219 vec3 scvector = datap->force_vector * nv::min( factor, p->lifetime ); 214 220 for ( uint32 i = 0; i < count; ++i ) p[i].velocity += scvector; 215 221 } … … 241 247 { 242 248 particle& pt = p[i]; 243 vec3 direction = pt.velocity * factor;249 vec3 direction = pt.velocity * nv::min( factor, p->lifetime ); 244 250 if ( math::dot( datap->plane_normal, pt.position + direction ) + datap->distance <= 0.0f ) 245 251 { … … 270 276 { 271 277 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 ); 273 279 for ( uint32 i = 0; i < count; ++i ) 274 280 { … … 293 299 { 294 300 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 ); 296 302 for ( uint32 i = 0; i < count; ++i ) 297 303 { … … 399 405 edata.velocity_max = element.get<float>("velocity_max", velocity ); 400 406 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 ); 403 409 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 ); 406 412 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 ); 409 415 410 416 edata.rate = element.get<float>("rate", 1.0f ); … … 464 470 m_program_local = m_device->create_program( nv_particle_engine_vertex_shader_local, nv_particle_engine_fragment_shader ); 465 471 m_program_world = m_device->create_program( nv_particle_engine_vertex_shader_world, nv_particle_engine_fragment_shader ); 466 m_last_update = 0;467 472 468 473 register_standard_emmiters(); … … 472 477 nv::particle_system nv::particle_engine::create_system( const string_view& id, particle_system_group group ) 473 478 { 479 particle_system_group_info* ginfo = m_groups.get( group ); 480 if ( !ginfo ) return nv::particle_system(); 481 474 482 auto it = m_names.find( id ); 475 483 if ( it == m_names.end() ) … … 486 494 { 487 495 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; 491 498 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 ); 493 500 494 501 } … … 496 503 info->count = 0; 497 504 info->particles = new particle[ data->quota ]; 498 info->last_update = m_last_update;505 ginfo->ref_counter++; 499 506 500 507 return result; … … 531 538 info->vtx_array = m_context->create_vertex_array( desc ); 532 539 info->quads = new particle_quad[info->quota]; 540 info->ref_counter = 0; 533 541 return result; 534 542 } … … 546 554 register_standard_emmiters(); 547 555 register_standard_affectors(); 556 } 557 558 bool nv::particle_engine::loaded( const string_view& system_id ) 559 { 560 return m_names.find( system_id ) != m_names.end(); 548 561 } 549 562 … … 558 571 m_names.clear(); 559 572 m_data.clear(); 560 m_last_update = 0;561 573 } 562 574 … … 567 579 if ( info ) 568 580 { 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; 570 584 m_systems.destroy( system ); 571 585 } … … 583 597 } 584 598 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 ) 599 void nv::particle_engine::render( particle_system system, const scene_state& s ) 595 600 { 596 601 particle_system_info* info = m_systems.get( system ); 597 602 if ( info ) 598 603 { 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 608 void nv::particle_engine::update( particle_system system, float dtime ) 609 609 { 610 610 particle_system_info* info = m_systems.get( system ); 611 611 if ( info ) 612 612 { 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 631 void 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 642 void nv::particle_engine::generate_data( particle_system_info* info, const scene_state& s ) 620 643 { 621 644 // void* rawptr = m_context->map_buffer( info->vtx_buffer, nv::WRITE_UNSYNCHRONIZED, offset, info->count*sizeof( particle_quad ) ); … … 661 684 vec3 pdir( 0.0f, 1.0f, 0.0f ); 662 685 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() ); 670 688 671 689 for ( uint32 i = 0; i < info->count; ++i ) … … 675 693 particle_quad& rdata = group->quads[i + group->count]; 676 694 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 ); 679 697 680 698 switch ( orientation ) … … 682 700 case particle_orientation::POINT : 683 701 right = math::normalize( math::cross( view_dir, vec3( 0, 1, 0 ) ) ); 702 right = math::rotate( right, pdata.rotation, view_dir ); 684 703 rot_mat = mat3( right, math::cross( right, -view_dir ), -view_dir ); 685 704 break; … … 704 723 } 705 724 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 706 733 vec3 size( pdata.size.x, pdata.size.y, 0.0f ); 707 734 vec3 s0 = rot_mat * ( ( size * sm[0] ) ); … … 735 762 } 736 763 737 void nv::particle_engine::destroy_particles( particle_system_info* info, uint32 ms)764 void nv::particle_engine::destroy_particles( particle_system_info* info, float dtime ) 738 765 { 739 766 if ( info->count > 0 ) … … 741 768 { 742 769 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 ) 745 772 { 746 773 info->count--; … … 750 777 } 751 778 752 void nv::particle_engine::create_particles( particle_system_info* info, uint32 ms)779 void nv::particle_engine::create_particles( particle_system_info* info, float dtime ) 753 780 { 754 781 uint32 ecount = info->data->emmiter_count; … … 759 786 mat3 orient; 760 787 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 // } 768 793 769 794 for ( uint32 i = 0; i < ecount; ++i ) … … 773 798 if ( einfo.active ) 774 799 { 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 ) 777 803 { 778 804 if ( info->count < info->data->quota-1 ) … … 780 806 particle& pinfo = info->particles[info->count]; 781 807 edata.emmiter_func( &(info->data->emmiters[i]), &pinfo, 1 ); 782 783 if ( !local ) pinfo.position = orient * pinfo.position + source;784 pinfo.position 785 pinfo.color 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 ? 786 812 edata.color_min : r.range( edata.color_min, edata.color_max ); 787 pinfo.size 813 pinfo.size = edata.size_min == edata.size_max ? 788 814 edata.size_min : r.range( edata.size_min, edata.size_max ); 789 815 if ( edata.square ) pinfo.size.y = pinfo.size.x; 790 float velocity 816 float velocity = edata.velocity_min == edata.velocity_max ? 791 817 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]; 795 824 796 825 pinfo.velocity = edata.dir; … … 811 840 info->count++; 812 841 } 813 einfo. last_create +=period;842 einfo.next += fperiod; 814 843 } 844 815 845 } 816 846 } 817 847 } 818 848 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; 849 void nv::particle_engine::update_particles( particle_system_info* info, float dtime ) 850 { 851 if ( dtime <= 0.0f ) return; 824 852 825 853 uint32 acount = info->data->affector_count; … … 827 855 { 828 856 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 ); 830 858 } 831 859 … … 834 862 { 835 863 particle& pdata = info->particles[i]; 864 float factor = min( dtime, pdata.lifetime ); 836 865 pdata.position += pdata.velocity * factor; 837 866 } 838 info->last_update = ms; 839 } 840 841 void nv::particle_engine::update_emmiters( particle_system_info* info, uint32 ms ) 867 } 868 869 void nv::particle_engine::update_emmiters( particle_system_info* info, float dtime ) 842 870 { 843 871 uint32 ecount = info->data->emmiter_count; … … 850 878 auto& einfo = info->emmiters[i]; 851 879 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 ) 853 887 { 854 888 if ( einfo.active ) 855 889 { 856 890 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 ); 859 893 else 860 einfo. next_toggle = 0;894 einfo.pause = 0.0f; 861 895 } 862 896 else 863 897 { 864 898 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 ); 867 900 } 868 901 } … … 896 929 } 897 930 931 nv::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 898 941 void nv::particle_engine::register_standard_affectors() 899 942 { -
trunk/src/gl/gl_context.cc
r499 r500 132 132 } 133 133 134 void nv::gl_context::attach( framebuffer f, output_slot slot, texture t )134 void nv::gl_context::attach( framebuffer f, output_slot slot, texture t, int layer /* = -1*/ ) 135 135 { 136 136 // TODO: framebuffer variable, so no re-binding? … … 143 143 glBindFramebuffer( GL_FRAMEBUFFER, info->glid ); 144 144 unsigned gl_type = texture_type_to_enum( tinfo->type ); 145 146 if ( tinfo ) 147 { 148 // if ( tinfo->size.y == 0 ) 149 // glFramebufferTexture1D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+(unsigned)slot, GL_TEXTURE_1D, tinfo->glid, 0 ); 150 glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+unsigned( slot ), gl_type, tinfo->glid, 0 ); 145 unsigned tglid = tinfo ? tinfo->glid : 0; 146 147 if ( layer >= 0 ) 148 { 149 glFramebufferTextureLayer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + unsigned( slot ), tglid, 0, layer ); 151 150 } 152 151 else 153 152 { 154 glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 +unsigned( slot ), gl_type, 0, 0 );153 glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + unsigned( slot ), gl_type, tglid, 0 ); 155 154 } 156 155 … … 171 170 if ( layer >= 0 ) 172 171 { 173 glFramebufferTextureLayer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, tinfo->glid, 0, layer );172 glFramebufferTextureLayer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, glid, 0, layer ); 174 173 } 175 174 else -
trunk/src/gl/gl_enum.cc
r499 r500 202 202 case R32I : return GL_RED_INTEGER; 203 203 case R32UI : return GL_RED_INTEGER; 204 case RGBA8I : return GL_RGBA; 205 case RGBA8UI : return GL_RGBA; 206 case RGBA16I : return GL_RGBA; 207 case RGBA16UI: return GL_RGBA; 208 case RGBA32I : return GL_RGBA; 209 case RGBA32UI: return GL_RGBA; 204 210 NV_RETURN_COVERED_DEFAULT( 0 ); 205 211 } … … 230 236 case R32I : return GL_R32I; 231 237 case R32UI : return GL_R32UI; 238 case RGBA8I : return GL_RGBA8I; 239 case RGBA8UI : return GL_RGBA8UI; 240 case RGBA16I : return GL_RGBA16I; 241 case RGBA16UI: return GL_RGBA16UI; 242 case RGBA32I : return GL_RGBA32I; 243 case RGBA32UI: return GL_RGBA32UI; 244 232 245 NV_RETURN_COVERED_DEFAULT( 0 ); 233 246 }
Note: See TracChangeset
for help on using the changeset viewer.