-
-
Save mohawk2/097de6f55c66d570476903782876df34 to your computer and use it in GitHub Desktop.
pdl opengl example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
use v5.40; use warnings; | |
use Syntax::Keyword::Match; | |
use OpenGL ':all'; | |
use PDL; | |
use PDL::Constants qw'PI E I'; | |
use PDL::Transform; | |
use Time::HiRes qw'gettimeofday tv_interval'; | |
use IPC::Open2 'open2'; | |
my $window; my $w = 800; my $h = 600; my $x = 0; my $y = 0; | |
my %ctl = ( | |
angle => 0, | |
angle_dt => 0, | |
k => 1, | |
cam => [[0,0,3],[0,0,-1],0], # pos dir tilt | |
bg => [0,0,0], # background color | |
z => 1 | |
); | |
my @ids; | |
my $number_of_points = 2048; | |
my $e_init = null; | |
my $e_state = null; | |
my $vertices = null; | |
my $st; | |
init(); | |
sub display { | |
state $s = 0; | |
glClearColor(0.1, 0.2, 0.1, 1.0); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
glLoadIdentity(); | |
gluLookAt($ctl{cam}[0][0], $ctl{cam}[0][1], $ctl{cam}[0][2], 0, 0, 0, 0, 1, 0); | |
glRotatef(-$ctl{angle},0,0,1); | |
glScalef($ctl{z},$ctl{z},0.5); # minimize z component | |
glBindBufferARB(GL_ARRAY_BUFFER_ARB, $ids[0]); | |
# my $data = OpenGL::Array->new_scalar(GL_FLOAT, $vertices->get_dataref, $vertices->dim(0) * 4); # 4 is float size in bytes | |
# glBufferDataARB_p(GL_ARRAY_BUFFER_ARB, $data, GL_DYNAMIC_DRAW_ARB); | |
# or : | |
glBufferDataARB_s(GL_ARRAY_BUFFER_ARB, $vertices->dim(0) * 4, $vertices->get_dataref, GL_DYNAMIC_DRAW_ARB); | |
glInterleavedArrays_c(GL_C4F_N3F_V3F, 0, 0); | |
glDrawArrays(GL_TRIANGLES, 0, $st->dim(2)); | |
$s = sin(do { $ctl{angle} = ($ctl{angle} + $ctl{angle_dt}) % 360; $ctl{angle} / 180 * PI }); | |
glutSwapBuffers(); | |
} | |
sub key_event ($code, @) { | |
match (chr($code) : eq) { | |
case ('q') { term() } | |
case ('f') { glutFullScreen() } | |
case ('e') { glShadeModel(GL_FLAT) } | |
case ('d') { glShadeModel(GL_SMOOTH) } | |
case ('w') { | |
glutReshapeWindow($w, $h); | |
glutPositionWindow($x, $y); | |
} | |
case ('a') { $ctl{k} += 0.1 } | |
case ('s') { $ctl{k} -= 0.1 } | |
case ('u') { $ctl{z} *= 2 } | |
case ('i') { $ctl{z} /= 2 } | |
case ('z') { $ctl{angle_dt} += 1 } | |
case ('x') { $ctl{angle_dt} -= 1 } | |
case ('c') { $ctl{angle_dt} *= -1 } | |
case ('r') { | |
init_data(); | |
#$e_init->slice('0,0:1,:') *= 0; | |
#$e_init->slice('0,0:1,:') += random(1, 2, $number_of_points); | |
} | |
case ('t') { triangulate(1) } | |
case ('l') { glEnable(GL_LIGHTING) } | |
case ('L') { glDisable(GL_LIGHTING) } | |
case ('k') { glEnable(GL_COLOR_MATERIAL) } | |
case ('K') { glDisable(GL_COLOR_MATERIAL) } | |
default { say $code, ': ', chr($code) } | |
} | |
} | |
sub keyup_event ($code, @) { say "$code - ".chr($code) } | |
sub key_special_event { | |
my ($code) = @_; | |
match ($code : ==) { | |
case (GLUT_KEY_LEFT) { $ctl{cam}[0][0] -= 1 } | |
case (GLUT_KEY_RIGHT) { $ctl{cam}[0][0] += 1 } | |
case (GLUT_KEY_UP) { $ctl{cam}[0][1] += 1 } | |
case (GLUT_KEY_DOWN) { $ctl{cam}[0][1] -= 1 } | |
default { say 'code: ', $code } | |
} | |
#say glutGetModifiers(); # shift - 001 ctrl - 010 alt 100 | |
} | |
sub camera { | |
glMatrixMode(GL_PROJECTION); | |
glLoadIdentity(); | |
gluPerspective(35, glutGet(GLUT_WINDOW_WIDTH)/glutGet(GLUT_WINDOW_HEIGHT), 2, 10); | |
#glOrtho(-0.5, 0.5, -0.5, 0.5, 0, 3); | |
glMatrixMode(GL_MODELVIEW); | |
} | |
sub init { | |
glutInit(); | |
glutInitWindowSize($w, $h); | |
glutInitWindowPosition($x, $y); | |
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_ALPHA|GLUT_DEPTH); | |
$window = glutCreateWindow('test'); | |
glutSetCursor(GLUT_CURSOR_NONE); | |
glEnable(GL_DEPTH_TEST); | |
glShadeModel(GL_SMOOTH); | |
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); | |
glBlendFunc(GL_SRC_ALPHA, GL_ONE); | |
glutReshapeFunc(sub { | |
glViewport(0,0, glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT)); | |
camera(); | |
}); | |
glutDisplayFunc(\&display); | |
glutKeyboardFunc(\&key_event); | |
glutSpecialFunc(\&key_special_event); | |
glutKeyboardUpFunc(\&keyup_event); | |
state $light = [[(1) x 3, 1], [(0.1) x 3, 1]]; | |
glMaterialfv_p(GL_FRONT, GL_SPECULAR, @{$light->[0]}); | |
glLightfv_p(GL_LIGHT0, GL_AMBIENT, @{$light->[1]}); | |
glLightfv_p(GL_LIGHT0, GL_SPECULAR, @{$light->[1]}); | |
glLightModelfv_p(GL_LIGHT_MODEL_AMBIENT, @{$light->[0]}); | |
glLightfv_p(GL_LIGHT0, GL_POSITION, 0, 0, 100, 0); | |
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); | |
#glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); | |
glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); | |
glEnable(GL_LIGHT0); | |
#glEnable(GL_DEPTH_TEST); | |
init_data(); | |
refresh(); | |
recalc(); | |
@ids = glGenBuffersARB_p(1); | |
glutIdleFunc(\&looping); | |
say 'entering loop'; | |
glutMainLoop(); | |
}; | |
sub looping { | |
recalc(); | |
refresh(); | |
} | |
sub refresh { glutPostRedisplay() } | |
sub init_data { | |
$e_init = randsym(float, 4, 10, $number_of_points); # amp, freq, phase, add : coord->XYZ normal->UVW color->RGBA : num_of_points | |
$e_init->slice('0,:,:') *= (0.5 - abs($e_init->slice('3,:,:') - 0.5)); # amp *= ( 0.5 - abs(add - 0.5) ) | |
$e_init->slice('0:2,0:1,:') *= 0; # no move XY position, freq and amp=0 or do non realtime version with triangualtion on each step? | |
my $xy = $e_init->slice('3,0:1,:'); | |
do { # assume x - is radius, and y - is angle, and recalc X,Y | |
my $angle = $xy->slice('0,1,:')->mult(PI*2,0)->copy; | |
my $rad = $xy->slice('0,0,:')->copy->pow(4/1.5); # outer is more outer | |
$xy->slice('0,0,:') .= $rad * $angle->sin; | |
$xy->slice('0,1,:') .= $rad * $angle->cos; | |
}; | |
} | |
sub recalc { | |
state $last_t = [gettimeofday]; | |
$e_state = | |
$e_init->slice(0) | |
* sin( | |
tv_interval($last_t) | |
* (PI ** $ctl{k}) | |
* $e_init->slice(1) | |
+ $e_init->slice(2) | |
) | |
+ $e_init->slice(3); | |
triangulate(); | |
} | |
sub triangulate { # get vertices - return vertices indexes | |
my ($force) = @_; | |
state $cache; | |
if (!$cache || $force) { | |
my $pid = open2(my $out, my $in, 'qdelaunay i'); | |
say $in join("\n", 2, $e_state->dim(2), $e_state->slice('0,0:1,:')->list); | |
close $in; | |
my @lines = <$out>; shift @lines; chomp @lines; close $out; | |
waitpid $pid, 0; | |
$cache = [map split(/\s+/, $_), @lines]; | |
} | |
$st = $e_state->dice(0, [6,7,8,9,3,4,5,0,1,2], $cache); | |
$vertices = $st->flat->float; | |
} | |
sub term { | |
glutKeyboardFunc(0); | |
glutSpecialFunc(0); | |
glutReshapeFunc(0); | |
glutDestroyWindow($window); | |
glutLeaveMainLoop(); | |
exit(0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment