[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[原创代码] [Perl]使用 POGL Shader 实现高效渲染 Julia集 动画

本帖最后由 523066680 于 2017-7-24 15:32 编辑

推荐 Perl 环境:5.24 Portable Edition
官方链接:Strawberry Perl Releases

Portable 版环境配置说明:Strawberry Perl 环境配置 以及 版本推荐

需要安装的模块:
https://metacpan.org/release/OpenGL
https://metacpan.org/pod/OpenGL::Shader

PDL版本的Strawberry Perl 虽然自带OPENGL模块,但是加载 Shader 有问题,最好下载源码包重新编译安装。



      =info
          Auth:523066680
          Date:2017-07
          https://www.shadertoy.com/view/ld2fzw

          按 '['']' 调整阀值,按 -= 调整迭代深度
          空格键 - 暂停/继续
          q or Q - 退出
      =cut

      use OpenGL qw/ :all /;
      use OpenGL::Config;
      use OpenGL::Shader;
      use Time::HiRes 'sleep';
      use feature 'state';
      use IO::Handle;
      STDOUT->autoflush(1);

      our $ang = 0.0;
      our $iter = 1000.0;
      our $test = 80.0;
      our ($cx, $cy);
      our $vTest;
      our $vIter;
      our $vC;

      our $PAUSE = 0;

      &Main();

      sub display
      {
          glClear(GL_COLOR_BUFFER_BIT);
          glDrawArrays(GL_POINTS, 0, 1);
          glutSwapBuffers();
      }

      sub idle
      {
          sleep 0.03;

          $ang += 0.05 if ($PAUSE == 0);
          $cx = cos($ang);
          $cy = sin($ang);

          glVertexAttrib2fARB($vC, $cx, $cy);

          glutPostRedisplay();
      }

      sub init
      {
          glClearColor(0.0, 0.0, 0.0, 1.0);
          my $shdr = new OpenGL::Shader('GLSL');
          my $ver = $shdr->GetVersion();
          my $stat = $shdr->Load( frag_Shader(), vert_Shader() );
          $shdr->Enable();

          #如果 shader 编译不成功,错误信息会返回到 $stat
          print "$stat $ver\n";
          glPointSize(480.0);
         
          $vTest = $shdr->MapAttr('vTest');
          $vIter = $shdr->MapAttr('vIter');
          $vC = $shdr->MapAttr('vC');

          glVertexAttrib1fARB($vTest, $test);
          glVertexAttrib1fARB($vIter, $iter);
          glVertexAttrib2fARB($vC, $cx, $cy);
      }

      sub hitkey
      {
          my $key = shift;
          my $char = chr($key);

          if ( lc($char) eq 'q' ) { glutDestroyWindow($WinID) }
          elsif ($char eq '[')  { $test -= 1.0 if ( $test > 1.0 ) }
          elsif ($char eq ']')  { $test += 1.0 }
          elsif ($char eq '-')  { $iter -= $iter*0.2 if ( $iter > 1.0 ) }
          elsif ($char eq '=')  { $iter += $iter*0.2  }
          elsif ($char eq ' ')  { $PAUSE = 1 - $PAUSE }

          printf("test: %.2f, iter: %.2f\n", $test, $iter );
          glVertexAttrib1fARB($vTest, $test);
          glVertexAttrib1fARB($vIter, $iter);
      }

      sub Main
      {
          glutInit();
          glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE );
          glutInitWindowSize(500, 500);
          glutInitWindowPosition(1,1);
          our $WinID = glutCreateWindow("title");
          &init();
          glutDisplayFunc(\&display);
          glutKeyboardFunc(\&hitkey);
          glutIdleFunc(\&idle);
          glutMainLoop();
      }

      sub frag_Shader
      {
          return '
          varying float fTest;
          varying float fIter;
          varying vec2 fC;

          void main(void)
          {
              vec2 coord = (gl_FragCoord.xy - 250.0) / 100.0;

              vec4 color;
              vec2 C = fC;
              vec2 Z = coord.xy;

              int iterations = 0;
              int max_iterations = int(fIter);

              float rate;
              float threshold_squared = fTest;

              while ( (iterations < max_iterations) && (dot(Z, Z) < threshold_squared) )
              {
                  vec2 tZ;
                  tZ.x = Z.x * Z.x - Z.y * Z.y + C.x;
                  tZ.y = Z.x * Z.y * 2.0 + C.y;
                  Z = tZ;
                  iterations++;
              }

              if (iterations == max_iterations)
              {
                  color = vec4(0.3, 0.1, 0.1, 1.0);
              }
              else
              {
                  rate =  float(iterations)/float(max_iterations)*100.0;
                  //color = vec4(rate, rate, rate, 1.0);  //default color
                  color = vec4(rate, smoothstep(exp(Z.x), 0.0, 0.5), rate, 1.0);
              }

              gl_FragColor = color;
          }
          '
      }

      sub vert_Shader
      {
          return '
          attribute float vTest;
          attribute float vIter;
          attribute vec2 vC;

          varying float fTest;
          varying float fIter;
          varying vec2 fC;

          void main(void)
          {
              fTest = vTest;
              fIter = vIter;
              fC    = vC;

              gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
          }
          ';
      }
[Finished in 0.3s]
2

评分人数

本帖最后由 523066680 于 2017-7-25 16:37 编辑

回复 4# happy886rr

已上传 Win32 版本,支持全屏
http://523066680.ys168.com/
目录:OpenGL/2017年作品

不知道能不能正常运行,最好是有 Nvidia 显卡。 GT630测试可以
-
按键
  1.     [ or ]  -> threshold_squared
  2.     9 or 0  -> max_iteration
  3.     - or =  -> scale
  4.     w a s d -> move
  5.     f       -> fullscreen/leave fullscreen
  6.    空格键 -> 暂停
复制代码

TOP

回复 4# happy886rr


    如果搞成屏保,那绝对霸气侧漏啊

TOP

回复 3# 523066680
应该整理成屏保发布出来。

TOP

Colorful


  

Mandbrot: Z=Z^4+C
2

评分人数

    • a2002: 前面感觉好污,后面厉害了技术 + 1
    • happy886rr: 奇异世界技术 + 1

TOP

本帖最后由 523066680 于 2017-7-25 11:14 编辑

Sharp
  
迭代公式:
uZ.x = exp(tZ.x) * cos(tZ.y) * C.x;
uZ.y = exp(tZ.x) * sin(tZ.y) * C.y;

Julia之眼

迭代公式:
tZ.x = Z.x * Z.x - Z.y * Z.y + C.x;
tZ.y = Z.x * Z.y * 2.0 + C.y;
着色:
color = vec4(rate, exp(Z.x), rate, 1.0);

机械臂

tZ.x = Z.x * Z.x - Z.y * Z.y + C.x;
tZ.y = Z.x * Z.y * 1.0 + C.y;
着色:
color = vec4(rate, exp(Z.x), rate, 1.0);

图腾


Z=Z^3+C

浩瀚



旋转的阶梯

TOP

返回列表