@@ -369,10 +369,46 @@ sub PDL::Graphics::TriD::Lines::primitive {OpenGL::Modern::GL_LINES}
369369
370370{ package # hide from PAUSE
371371 PDL::Graphics::TriD::Spheres;
372- use OpenGL::Modern qw( glShadeModel GL_SMOOTH) ;
373372use PDL::Graphics::OpenGLQ;
373+ my $vertex_shader = <<'EOF' ;
374+ #version 120
375+ varying vec3 vNormal;
376+ varying vec4 vPosition;
377+ void main() {
378+ vNormal = normalize(gl_NormalMatrix * gl_Normal);
379+ vPosition = gl_ModelViewMatrix * gl_Vertex;
380+ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
381+ }
382+ EOF
383+ my $fragment_shader = <<'EOF' ;
384+ #version 120
385+ varying vec3 vNormal;
386+ varying vec4 vPosition;
387+
388+ /* modified from https://community.khronos.org/t/help-with-gouraud-phong-shading-in-shaders/73192/2 */
389+ void light(vec4 position, vec3 norm, out vec4 diffuse, out vec4 spec) {
390+ vec3 n = normalize(norm);
391+ vec3 s = vec3(normalize(gl_LightSource[0].position - position));
392+ vec4 v = normalize(-position);
393+ vec4 r = vec4(reflect(-s, n), 1);
394+ float sDotN = max(dot(s, n), 0.0);
395+ diffuse = gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * sDotN;
396+ spec = gl_LightSource[0].specular * gl_FrontMaterial.specular * pow(max(dot(r,v), 0.0), gl_FrontMaterial.shininess);
397+ }
398+
399+ void main() {
400+ vec4 diffuse, spec;
401+ if (gl_FrontFacing) {
402+ light(vPosition, vNormal, diffuse, spec);
403+ } else {
404+ light(vPosition, -vNormal, diffuse, spec);
405+ }
406+ gl_FragColor = gl_FrontLightProduct[0].ambient + diffuse + spec;
407+ }
408+ EOF
374409my %SPHERE ;
375410my @KEYS = qw( vertices normals idx) ;
411+ my $SHADER_PROGRAM ;
376412sub togl_setup {
377413 my ($this ,$points ) = @_ ;
378414 print " togl_setup $this \n " if $PDL::Graphics::TriD::verbose ;
@@ -383,12 +419,13 @@ sub togl_setup {
383419 $this -> load_buffer(vert_buf => $this -> {Impl }{vertices });
384420 $this -> load_buffer(norm_buf => $this -> {Impl }{normals });
385421 $this -> load_idx_buffer(indx_buf => $this -> {Impl }{idx });
422+ $SHADER_PROGRAM //= $this -> compile_program($vertex_shader , $fragment_shader );
423+ $this -> {Impl }{program_nodestroy } = $SHADER_PROGRAM ;
386424 $this -> togl_unbind;
387425}
388426sub gdraw {
389427 my ($this ,$points ) = @_ ;
390428 $this -> togl_bind;
391- glShadeModel(GL_SMOOTH);
392429 PDL::gl_spheres($points , $this -> {Impl }{idx }-> dims);
393430 $this -> togl_unbind;
394431}
0 commit comments