Commits

David Lin  committed eb8012c

plastic program

  • Participants
  • Parent commits 75f21b9

Comments (0)

Files changed (3)

File data/assets/programs/plastic.program.yml

+---
+:attribs: 
+  in_Position: 0
+:frag_datas:
+  fs_FragColor: 0
+:shaders:
+  - :type: :vertex
+    :code: |
+           #version 150 core
+           in vec4 in_Position;
+           uniform mat4 u_ModelView;
+           void main()
+           { // BEGIN
+             gl_Position = u_ModelView * in_Position;
+           } // END
+  - :type: :geometry
+    :code: |
+           # version 150 core
+           uniform mat4 u_Projection;
+           layout(triangles) in;
+           layout(triangle_strip, max_vertices=3) out;
+           out vec3 gs_Position; // view space
+           out vec3 gs_Normal; // view space
+           void main()
+           { // BEGIN
+             vec3 v[3];
+             for (int i = 0; i < 3; ++i)
+               v[i] = gl_in[i].gl_Position.xyz;
+             vec3 normal = normalize(cross(v[1]-v[0], v[2]-v[0]));
+             for (int i = 0; i < 3; ++i) {
+               gl_Position = u_Projection * vec4(v[i], 1.0);
+               gs_Position = v[i];
+               gs_Normal = normal;
+               EmitVertex();
+             } // END FOR
+             EndPrimitive();
+           } // END
+  - :type: :fragment
+    :code: |
+           #version 150 core
+           uniform vec3 u_Ka;
+           uniform vec3 u_Kd;
+           uniform vec3 u_Ks;
+           uniform float u_Ns;
+           uniform vec3 u_Light_Ka;
+           uniform vec3 u_Light_Kd;
+           uniform vec3 u_Light_Ks;
+           uniform vec3 u_Light_Pos;
+           uniform vec3 u_Light_SpotDir;
+           uniform float u_Light_SpotCosCutoff;
+           in vec3 gs_Position;
+           in vec3 gs_Normal;
+           out vec4 fs_FragColor;
+           void main()
+           { // BEGIN
+             // Light Vector (from point to light)
+             vec3 lv = normalize(u_Light_Pos - gs_Position);
+             // Half Vector (from point)
+             vec3 hv = normalize(lv + vec3(0,0,1));
+             // Ambient
+             vec3 ka = u_Ka * u_Light_Ka;
+             // Diffuse
+             vec3 kd = u_Kd * u_Light_Kd;
+             kd *= max(0, dot(gs_Normal, lv));
+             // Specular
+             vec3 ks = u_Ks * u_Light_Ks;
+             ks *= pow(max(0, dot(gs_Normal, hv)), u_Ns);
+             // Spot cutoff
+             float cut = dot(lv, -u_Light_SpotDir) - u_Light_SpotCosCutoff;
+             cut = max(0.0, sign(cut));
+             kd *= cut; ks *= cut;
+             // Final
+             vec3 color = ka + kd + ks;
+             fs_FragColor = vec4(color, 1.0);
+           } // END
+

File lib/program.rb

       @id = nil
     end
     
+    def set_1i(name, v)
+      if loc = glGetUniformLocation(@id, name)
+        glUniform1i(loc, v)
+      end
+    end
+    
+    def set_1f(name, v)
+      if loc = glGetUniformLocation(@id, name)
+        glUniform1f(loc, v)
+      end
+    end
+    
+    def set_3f(name, vec)
+      if loc = glGetUniformLocation(@id, name)
+        glUniform3f(loc, vec.x, vec.y, vec.z)
+      end
+    end
+    
+    def set_4f(name, vec)
+      if loc = glGetUniformLocation(@id, name)
+        glUniform4f(loc, vec.x, vec.y, vec.z, vec.w)
+      end
+    end
+    
     def set_matrix_4x4f(name, mat)
       if loc = glGetUniformLocation(@id, name)
         ::FFI::Buffer.new_in(:GLfloat, 16) do |ptr|
     
     class LinkerError < Exception
     end
+    
   end
 end
 
 class Render
   include OpenGL::Constants
+  include OpenGL::Kit
   
   def initialize(gl)
     self.extend gl
     
     @geom = My::Cube.new(gl).tap do |g| g.prepare end
     @program = My::Program.new(gl).tap do |program|
-      program.prepare 'cube'
+      program.prepare 'plastic'
     end
   end
   
     glUseProgram(@program.id)
     @program.set_matrix_4x4f 'u_Projection', self[:projection]
     @program.set_matrix_4x4f 'u_ModelView', self[:view] * self[:world]
+    @program.set_3f 'u_Ka', Vector[0.0, 0.0, 0.0]
+    @program.set_3f 'u_Kd', Vector[0.4, 0.4, 0.4]
+    @program.set_3f 'u_Ks', Vector[0.5, 0.5, 0.5]
+    @program.set_1f 'u_Ns', 2.0
+    @program.set_3f 'u_Light_Ka', Vector[0.0, 0.0, 0.0]
+    @program.set_3f 'u_Light_Kd', Vector[1.0, 1.0, 1.0]
+    @program.set_3f 'u_Light_Ks', Vector[1.0, 1.0, 1.0]
+    @program.set_3f 'u_Light_Pos', (self[:view] * Vector[1.3, 1.3, 1.3, 1.0])
+    @program.set_3f 'u_Light_SpotDir', (self[:view] * Vector[-1.0, -1.0, -1.0, 0.0]).normalize
+    @program.set_1f 'u_Light_SpotCosCutoff', Math.cos(Math::PI * 0.25)
     
     glEnable GL_DEPTH_TEST
     @geom.bind_vertex_attrib