忘记密码   免费注册 查看新帖 | 论坛精华区

ChinaUnix.net

  平台 论坛 博客 认证专区 大话IT HPC论坛 徽章 文库 沙龙 自测 下载 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
12下一页
最近访问板块 发新帖
查看: 2127 | 回复: 13

[Perl]使用 POGL Shader 实现高效渲染 Julia集 动画 [复制链接]

论坛徽章:
10
子鼠
日期:2014-10-11 16:46:482016科比退役纪念章
日期:2017-09-02 15:42:4715-16赛季CBA联赛之佛山
日期:2017-08-28 17:11:5515-16赛季CBA联赛之浙江
日期:2017-08-24 16:55:1715-16赛季CBA联赛之青岛
日期:2017-08-17 19:55:2415-16赛季CBA联赛之天津
日期:2017-06-29 10:34:4315-16赛季CBA联赛之四川
日期:2017-05-16 16:38:55黑曼巴
日期:2016-07-19 15:03:112015亚冠之萨济拖拉机
日期:2015-05-22 11:38:5315-16赛季CBA联赛之山东
日期:2017-11-10 14:32:14
发表于 2017-07-24 15:23 |显示全部楼层
推荐 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]

论坛徽章:
0
发表于 2017-07-24 22:28 |显示全部楼层
本帖最后由 hztj2005 于 2017-07-29 12:55 编辑

我想学习下,下载OpenGL-0.70安装后,说时间戳没有更新,不知是否重要,又如何手动更新?
D:\strawberryportable\OpenGL-0.70>dmake install
"D:\strawberryportable\perl\bin\perl.exe" -MExtUtils::Command::MM -e cp_nonempty -- OpenGL.bs blib\arch\auto\OpenGL\OpenGL.bs 644
Files found in blib\arch: installing files in blib\lib into architecture dependent library tree
Installing D:\strawberryportable\perl\site\lib\auto\OpenGL\freeglut.dll
Installing D:\strawberryportable\perl\site\lib\auto\OpenGL\OpenGL.xs.dll
Installing D:\strawberryportable\perl\site\lib\OpenGL.pm
Installing D:\strawberryportable\perl\site\lib\OpenGL.pod
Installing D:\strawberryportable\perl\site\lib\auto\OpenGL\autosplit.ix
Installing D:\strawberryportable\perl\site\lib\OpenGL\Array.pod
Installing D:\strawberryportable\perl\site\lib\OpenGL\Config.pm
Installing D:\strawberryportable\perl\site\lib\OpenGL\Tessellation.pod
Appending installation info to D:\strawberryportable\perl\lib/perllocal.pod
dmake:  Warning: -- Target [install] was made but the time stamp has not been updated.


接着,下载OpenGL-Shader-1.01,安装不能通过测试。#version directive missing

D:\strawberryportable\OpenGL-Shader-1.01>dmake test
"D:\strawberryportable\perl\bin\perl.exe" "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness(0, 'blib\lib', 'blib\arch')" t/*.t
t/OpenGL-Shader.t ..
________________________________________
Testing OpenGL::Shader
----------------------------------------
* ok: Installed: OpenGL v0.7
* ok: OpenGL::Shader module loaded: v1.01
Available shader types:
  ARB v1.0 - ARBfp1.0 and ARBvp1.0 Assembly
  GLSL v4.40 - OpenGL Shader Language
* ok: 2 shader type(s) reported
Use of uninitialized value $type in uc at D:\strawberryportable\OpenGL-Shader-1.01\blib\lib/OpenGL/Shader/Common.pm line 109.
Instantiated ARB v1.0
* ok: Loaded ARB shader from: fragment.arb, vertex.arb
Use of uninitialized value $type in uc at D:\strawberryportable\OpenGL-Shader-1.01\blib\lib/OpenGL/Shader/Common.pm line 109.
Instantiated GLSL v4.40
* fail: Unable to load GLSL shader: Fragment shader: WARNING: 0:2: '' :  #version directive missing

* skip: CG shader test
________________________________________
t/OpenGL-Shader.t .. Failed 1/6 subtests
        (less 1 skipped subtest: 4 okay)
Test Summary Report
-------------------
t/OpenGL-Shader.t (Wstat: 0 Tests: 6 Failed: 1)
  Failed test:  5
Files=1, Tests=6,  0 wallclock secs ( 0.05 usr +  0.02 sys =  0.06 CPU)
Result: FAIL
Failed 1/1 test programs. 1/6 subtests failed.
dmake:  Error code 255, while making 'test_dynamic'

论坛徽章:
10
子鼠
日期:2014-10-11 16:46:482016科比退役纪念章
日期:2017-09-02 15:42:4715-16赛季CBA联赛之佛山
日期:2017-08-28 17:11:5515-16赛季CBA联赛之浙江
日期:2017-08-24 16:55:1715-16赛季CBA联赛之青岛
日期:2017-08-17 19:55:2415-16赛季CBA联赛之天津
日期:2017-06-29 10:34:4315-16赛季CBA联赛之四川
日期:2017-05-16 16:38:55黑曼巴
日期:2016-07-19 15:03:112015亚冠之萨济拖拉机
日期:2015-05-22 11:38:5315-16赛季CBA联赛之山东
日期:2017-11-10 14:32:14
发表于 2017-07-25 11:27 |显示全部楼层

各种魔改公式后生成的图片

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

浩瀚



旋转的阶梯

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58每日论坛发贴之星
日期:2015-08-28 06:20:00每日论坛发贴之星
日期:2015-12-28 06:20:00
发表于 2017-07-25 20:46 |显示全部楼层
lz威武。

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
发表于 2017-07-26 23:09 |显示全部楼层
O~~ BTF!!
3 Q ~~:

论坛徽章:
10
子鼠
日期:2014-10-11 16:46:482016科比退役纪念章
日期:2017-09-02 15:42:4715-16赛季CBA联赛之佛山
日期:2017-08-28 17:11:5515-16赛季CBA联赛之浙江
日期:2017-08-24 16:55:1715-16赛季CBA联赛之青岛
日期:2017-08-17 19:55:2415-16赛季CBA联赛之天津
日期:2017-06-29 10:34:4315-16赛季CBA联赛之四川
日期:2017-05-16 16:38:55黑曼巴
日期:2016-07-19 15:03:112015亚冠之萨济拖拉机
日期:2015-05-22 11:38:5315-16赛季CBA联赛之山东
日期:2017-11-10 14:32:14
发表于 2017-07-28 21:43 |显示全部楼层
Colorful


  

Mandbrot: Z=Z^4+C

论坛徽章:
0
发表于 2017-07-31 11:33 |显示全部楼层
楼主,我在2楼说到,安装 OpenGL::Shader不能通过测试,然后我在下面链接中发帖问,仍然没有成功。
http://www.perlmonks.com/?node_id=1196261
但是,上面链接中有这么一段建议:
A somewhat more recent version of OpenGL bindings is OpenGL::Modern, which also tries to be compatible to OpenGL and OpenGL::Shader, so maybe you want to try that if you want to do shader oriented programming.
与OpenGL相绑定的某种程度更新版本是OpenGL :: Modern,它也尝试兼容OpenGL和OpenGL :: Shader,所以也许你想尝试这样做,如果你想做着色器方向编程。

楼主能否尝试一下,把上面代码用OpenGL::Modern模块修改一下。

论坛徽章:
0
发表于 2017-07-31 11:47 |显示全部楼层
楼主,我从安装包中D:\strawberryportable\OpenGL-Shader-1.01\blib\lib\OpenGL 找到的下面代码: shader-test.pl 是可以运行的。

  1. #!/usr/bin/perl

  2. # Purpose: Simple demo of per-pixel lighting with GLSL and OpenGL::Shader

  3. # Copyright (c) 2007, Geoff Broadwell; this script is released
  4. # as open source and may be distributed and modified under the terms
  5. # of either the Artistic License or the GNU General Public License,
  6. # in the same manner as Perl itself.  These licenses should have been
  7. # distributed to you as part of your Perl distribution, and can be
  8. # read using `perldoc perlartistic` and `perldoc perlgpl` respectively.

  9. use strict;
  10. use warnings;
  11. use OpenGL ':all';
  12. use OpenGL::Shader;
  13. use Time::HiRes 'time';

  14. our $VERSION = '0.1.0';

  15. my $width  = 1000;
  16. my $height = 1000;
  17. my ($frames, $start);
  18. my ($window, $teapot);
  19. my ($shader, $shader_enabled);

  20. go();

  21. sub go {
  22.     # Simple usage
  23.     print "Press 'Q' or 'Esc' to exit, or any other key to toggle shader.\n";

  24.     # GLUT setup
  25.     glutInit;
  26.     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  27.     glutInitWindowSize($width, $height);

  28.     $window = glutCreateWindow('Shader Test');

  29.     glutIdleFunc    (\&cb_draw);
  30.     glutDisplayFunc (\&cb_draw);
  31.     glutKeyboardFunc(\&cb_keyboard);

  32.     # Shader program
  33.     $shader      = new OpenGL::Shader('GLSL');
  34.     die "This program requires support for GLSL shaders.\n" unless $shader;

  35.     my $fragment = fragment_shader();
  36.     my $vertex   = vertex_shader();
  37.     my $info     = $shader->Load($fragment, $vertex);
  38.     print $info if $info;
  39.     toggle_shader();

  40.     # Display list for teapot
  41.     $teapot = glGenLists(1);
  42.     glNewList($teapot, GL_COMPILE);
  43.     glutSolidTeapot(1);
  44.     glEndList;

  45.     # Unchanging GL config
  46.     glViewport(0, 0, $width, $height);

  47.     glEnable(GL_DEPTH_TEST);

  48.     glMatrixMode(GL_PROJECTION);
  49.     glLoadIdentity;
  50.     gluPerspective(90, $width/$height, 1, 10);
  51.     glMatrixMode(GL_MODELVIEW);

  52.     glShadeModel(GL_SMOOTH);
  53.     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
  54.     glEnable(GL_LIGHTING);
  55.     glEnable(GL_LIGHT0);
  56.     glLightfv_p(GL_LIGHT0, GL_POSITION, 4, 4, 4, 1);

  57.     glMaterialfv_p(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, 1, .7, .7, 1);
  58.     glMaterialfv_p(GL_FRONT_AND_BACK, GL_SPECULAR,            1,  1,  1, 1);
  59.     glMaterialf   (GL_FRONT_AND_BACK, GL_SHININESS,           50          );

  60.     # Actually start the test
  61.     $start = time;
  62.     glutMainLoop;
  63. }

  64. sub cb_draw {
  65.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  66.     glLoadIdentity;
  67.     glTranslatef(0, 0, -3);

  68.     my $slow_time = time / 5;
  69.     my $frac_time = $slow_time - int $slow_time;
  70.     my $angle     = $frac_time * 360;
  71.     glRotatef($angle, 0, 1, 0);
  72.     glRotatef(30, 1, 0, 0);

  73.     glCallList($teapot);

  74.     glutSwapBuffers;

  75.     $frames++;
  76. }

  77. sub cb_keyboard {
  78.     my $key = shift;
  79.     my $chr = lc chr $key;

  80.     if ($key == 27 or $chr eq 'q') {
  81.         my $time = time - $start;
  82.         my $fps  = $frames / $time;
  83.         printf "%.3f FPS\n", $fps;

  84.         glutDestroyWindow($window);
  85.         exit(0);
  86.     }
  87.     else {
  88.         toggle_shader();
  89.     }
  90. }

  91. sub toggle_shader {
  92.     $shader_enabled = !$shader_enabled;
  93.     $shader_enabled ? $shader->Enable : $shader->Disable;
  94. }

  95. sub vertex_shader {
  96.     return <<'VERTEX';

  97. varying vec3 Normal;
  98. varying vec3 Position;

  99. void main(void) {
  100.     gl_Position = ftransform();
  101.     Position    = vec3(gl_ModelViewMatrix * gl_Vertex);
  102.     Normal      = gl_NormalMatrix * gl_Normal;
  103. }

  104. VERTEX
  105. }

  106. sub fragment_shader {
  107.     return <<'FRAGMENT';

  108. varying vec3 Position;
  109. varying vec3 Normal;

  110. void main(void) {
  111.     vec3 normal    = normalize(Normal);
  112.     vec3 reflected = normalize(reflect(Position, normal));
  113.     vec3 light_dir = normalize(vec3(gl_LightSource[0].position) - Position);

  114.     float diffuse  = max  (dot(light_dir, normal   ), 0.0);
  115.     float spec     = clamp(dot(light_dir, reflected), 0.0, 1.0);
  116.           spec     = pow  (spec, gl_FrontMaterial.shininess);

  117.     gl_FragColor   =             gl_FrontLightModelProduct.sceneColor
  118.                      +           gl_FrontLightProduct[0].ambient
  119.                      + diffuse * gl_FrontLightProduct[0].diffuse
  120.                      + spec    * gl_FrontLightProduct[0].specular;
  121. }

  122. FRAGMENT
  123. }
复制代码

论坛徽章:
10
子鼠
日期:2014-10-11 16:46:482016科比退役纪念章
日期:2017-09-02 15:42:4715-16赛季CBA联赛之佛山
日期:2017-08-28 17:11:5515-16赛季CBA联赛之浙江
日期:2017-08-24 16:55:1715-16赛季CBA联赛之青岛
日期:2017-08-17 19:55:2415-16赛季CBA联赛之天津
日期:2017-06-29 10:34:4315-16赛季CBA联赛之四川
日期:2017-05-16 16:38:55黑曼巴
日期:2016-07-19 15:03:112015亚冠之萨济拖拉机
日期:2015-05-22 11:38:5315-16赛季CBA联赛之山东
日期:2017-11-10 14:32:14
发表于 2017-07-31 14:32 |显示全部楼层
回复 8# hztj2005

那就更省事啦~ 我的可能是有什么变动导致……

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
发表于 2017-08-02 01:42 |显示全部楼层
本帖最后由 rubyish 于 2017-08-01 21:45 编辑



1: ppm
tnm.png

评分

参与人数 1信誉积分 +5 收起 理由
523066680 + 5 赞一个!

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802020122
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP