[Perl][OpenGL]积累缓冲区实现烟花效果

There's more than one way to do it!
https://metacpan.org http://perlmonks.org
头像
523066680
Administrator
Administrator
帖子: 340
注册时间: 2016年07月19日 12:14
拥有现金: 锁定
储蓄: 锁定
Has thanked: 30 times
Been thanked: 27 times
联系:

[Perl][OpenGL]积累缓冲区实现烟花效果

帖子 #1 523066680 » 2018年05月12日 15:55

Code: [全选] [展开/收缩] [Download] (firework.pl)
  1. =info
  2.     Auth: 523066680/vicyang
  3.     Date: 2018-02
  4.  
  5.     半径取值,rand(20.0) 改为 sqrt(rand(1.0)) * 20.0
  6.     参考文章:
  7.     http://blog.csdn.net/shakingwaves/article/details/17969025
  8.     https://thecodeway.com/blog/?p=1138
  9. =cut
  10.  
  11. use Modern::Perl;
  12. use IO::Handle;
  13. use List::Util qw/max min/;
  14. use Time::HiRes qw/sleep time/;
  15. use OpenGL qw/ :all /;
  16. use OpenGL::Config;
  17. use Points2D;
  18.  
  19. STDOUT->autoflush(1);
  20.  
  21. BEGIN
  22. {
  23.     our $WinID;
  24.     our $HEIGHT = 600;
  25.     our $WIDTH  = 800;
  26.     our ($show_w$show_h) = (10060);
  27.     our ($half_w$half_h) = ($show_w/2.0$show_h/2.0);
  28.  
  29.     #创建随机颜色表
  30.     our $total = 100;
  31.     our @colormap;
  32.     #srand(0.5);
  33.     grep { push @colormap, [ 0.3+rand(0.7)0.3+rand(0.7)0.3+rand(0.7) ] } ( 0 .. $total*2 );
  34.  
  35.     our @dots;
  36.     my ($inx$iny);
  37.     my ($len$ang);
  38.     my ($vx$vy);   #速度分量
  39.     $inx = 0.0;
  40.     $iny = 0.0;
  41.  
  42.     for ( 0 .. $total )
  43.     {
  44.         ($len$ang) = ( sqrt(rand(1.0)) * 20.0 , rand(6.28) );
  45.         $vx = $len * sin( $ang );
  46.         $vy = $len * cos( $ang );
  47.  
  48.         push @dots, 
  49.                 Points->new( 
  50.                     x => $inx, y => $iny,
  51.                     xs => $vx, ys => $vy,
  52.                     rgb => $colormap[$_],
  53.                     timeply => 2.0,
  54.                 );
  55.     }
  56. }
  57.  
  58. &main();
  59.  
  60. sub display
  61. {
  62.     our (@dots);
  63.     my $t;
  64.     state $iter = 1;
  65.     state $size = 10.0;
  66.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  67.     my ( $ax$ay$bx$by$dot);
  68.  
  69.     $iter ++;
  70.  
  71.     for my $dot ( @dots )
  72.     {
  73.         glBegin(GL_LINES);
  74.             ( $ax$ay$bx$by ) = $dot->curr_pos();
  75.             glColor3f( @{ $dot->{rgb} } );
  76.             glVertex3f( $ax$ay0.0);
  77.             glVertex3f( $bx$by0.0);
  78.             #glVertex3f( $dot->{x}, $dot->{y}, 0.0);
  79.         glEnd();
  80.     }
  81.  
  82.     glAccum(GL_ACCUM, 1.0);
  83.     glAccum(GL_MULT, 0.92);
  84.     glAccum(GL_RETURN, 1.0);
  85.  
  86.     glutSwapBuffers();
  87. }
  88.  
  89. sub idle 
  90. {
  91.     our (@dots, @colormap);
  92.     our ($show_w$show_h$half_w$half_h$total );
  93.     state $times = 0;
  94.     state $size = 10.0;
  95.     sleep 0.02;
  96.     glutPostRedisplay();
  97.  
  98.     $times++;
  99.     $size *0.9 if $size > 1.0;
  100.     #$size *= 1.01;
  101.     glLineWidth( $size );
  102.  
  103.     if ( $times % 50 == 0 )
  104.     {
  105.         $size = 10.0;
  106.         @dots = ();
  107.         my ($inx$iny);
  108.         my ($len$ang);
  109.         my ($vx$vy);   #速度分量
  110.  
  111.         $inx = rand($show_w) - $half_w;
  112.         $iny = rand($show_h) - $half_h;
  113.         for ( 0 .. $total )
  114.         {
  115.             ($len$ang) = ( sqrt(rand(1.0)) * 20.0, rand(6.28) );
  116.             $vx = $len * sin( $ang );
  117.             $vy = $len * cos( $ang );
  118.  
  119.             push @dots, 
  120.                     Points->new( 
  121.                         x => $inx, y => $iny,
  122.                         xs => $vx, ys => $vy,
  123.                         right => $show_w
  124.                         rgb => $colormap[$_],
  125.                         timeply => 1.0,
  126.                     );
  127.         }
  128.     }
  129.  
  130.     # if ( $#dots < 200 )
  131.     # {
  132.     #     my ($inx, $iny);
  133.     #     my ($len, $ang);
  134.     #     push @dots, Points->new( x => 0.0, y => 0.0 , right => $show_w, rgb => $colormap[ $#dots ] );
  135.     # }
  136. }
  137.  
  138. sub init
  139. {
  140.     glClearColor(0.00.00.01.0);
  141.     glClearAccum(0.00.00.00.0);
  142.     glEnable(GL_DEPTH_TEST);
  143.     glPointSize(4.0);
  144. }
  145.  
  146. sub reshape
  147. {
  148.     our ($show_w$show_h$half_w$half_h );
  149.     state $fa = 100.0;
  150.     my ($w$h) = (shiftshift);
  151.     my ($max$min) = (max($w$h), min($w$h) );
  152.  
  153.     glViewport(00$w$h);
  154.     glMatrixMode(GL_PROJECTION);
  155.     glLoadIdentity();
  156.     glOrtho(-$half_w$half_w, -$half_h$half_h0.0$fa*2.0)
  157.     #glFrustum(-100.0, $WIDTH-100.0, -100.0, $HEIGHT-100.0, 800.0, $fa*5.0); 
  158.     glMatrixMode(GL_MODELVIEW);
  159.     glLoadIdentity();
  160.     gluLookAt(0.0,0.0,$fa0.0,0.0,0.00.0,1.0$fa);
  161. }
  162.  
  163. sub hitkey
  164. {
  165.     our $WinID;
  166.     my $k = lc(chr(shift));
  167.     if ( $k eq 'q') { quit() }
  168. }
  169.  
  170. sub quit
  171. {
  172.     our ($WinID);
  173.     glutDestroyWindow( $WinID );
  174.     exit 0;
  175. }
  176.  
  177. sub main
  178. {
  179.     our ($WIDTH$HEIGHT$WinID);
  180.  
  181.     glutInit();
  182.     glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE );
  183.     glutInitWindowSize($WIDTH$HEIGHT);
  184.     glutInitWindowPosition(100100);
  185.     $WinID = glutCreateWindow("Free-fall");
  186.     
  187.     &init();
  188.     glutDisplayFunc(\&display);
  189.     glutReshapeFunc(\&reshape);
  190.     glutKeyboardFunc(\&hitkey);
  191.     glutIdleFunc(\&idle);
  192.     glutMainLoop();
  193. } 


Points2D.pm
Code: [全选] [展开/收缩] [Download] (Points2D.pm)
  1. package Points;
  2. use Modern::Perl;
  3. use Time::HiRes qw/time/;
  4.  
  5. our $g = 9.8;
  6. our $id = 0;
  7.  
  8. sub new
  9. {
  10.     my $class = shift;
  11.     my $ref =
  12.         {
  13.             id => $id++ ,
  14.             time => time() ,
  15.             timeply => 2.0,             #时间倍率
  16.             xs => 10.0 + rand(5.0) ,
  17.             ys => 15.0 + rand(10.0) ,
  18.             @_ ,
  19.         };
  20.        
  21.     $ref->{prvx} = $ref->{x};
  22.     $ref->{prvy} = $ref->{y};
  23.     bless $ref, $class;
  24.     return $ref;
  25. }
  26.  
  27. sub show_info
  28. {
  29.     my $self = shift;
  30.     printf "%.2f %.2f %.3f\n", $self->{x}, $self->{y}, $self->{time};
  31. }
  32.  
  33. sub curr_pos
  34. {
  35.     my $self = shift;
  36.     # 速度分量
  37.     my ($vx, $vy) = ( $self->{xs}, $self->{ys} );
  38.     my ($x, $y, $prvx, $prvy);
  39.     $prvx = $self->{prvx};
  40.     $prvy = $self->{prvy};
  41.  
  42.     # 时间差 * 2
  43.     my $t = ( time() - $self->{time} ) * $self->{timeply};
  44.  
  45.     # y = V0t - 1/2 * gt^2
  46.     $x = $self->{x} + $vx * $t;
  47.     $y = $self->{y} + $vy * $t - $g /2.0* $t * $t;
  48.  
  49.     $self->{prvx} = $x;
  50.     $self->{prvy} = $y;
  51.  
  52.     return ( $prvx, $prvy, $x, $y );
  53. }
  54.  
  55. 1;

回到 “Perl”

在线用户

用户浏览此论坛: 没有注册用户 和 1 访客