def OnInit(self):
        """Initialize the context"""
        '''== Phong and Blinn Reflectance ==

        A shiny surface will tend to have a "bright spot" at the point 
        on the surface where the angle of incidence for the reflected
        light ray and the viewer's ray are (close to) equal.  
        A perfect mirror would have the brights spot solely when the 
        two vectors are exactly equal, while a perfect Lambertian
        surface would have the "bright spot" spread across the entire
        surface.
        
        The Phong rendering process models this as a setting, traditionally
        called material "shininess" in Legacy OpenGL.  This setting acts 
        as a power which raises the cosine (dot product) of the 
        angle between the reflected ray and the eye.  The calculation of 
        the cosine (dot product) of the two angles requires that we do 
        a dot product of the two angles once for each vertex/fragment 
        for which we wish to calculate the specular reflectance, we also 
        have to find the angle of reflectance before we can do the 
        calculation:'''
        """
            L_dir = (V_pos-L_pos)
            R = 2N*(dot( N, L_dir))-L_dir
            // Note: in eye-coordinate system, Eye_pos == (0,0,0)
            Spec_factor = pow( dot( R, V_pos-Eye_pos ), shininess)
        """
        '''which, as we can see, involves the vertex position in a number 
        of stages of the operation, so requires recalculation all through 
        the rendering operation.
        
        There is, however, a simplified version of Phong Lighting called 
        [http://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model Blinn-Phong]
        which notes that if we were to do all of our calculations in 
        "eye space", and were to assume that (as is normal), the eye 
        and light coordinates will not change for a rendering pass,
        (note: this limits us to directional lights!) we 
        can use a pre-calculated value which is the bisecting angle
        between the light-vector and the view-vector, called the 
        "half vector" to 
        perform approximately the same calculation.  With this value:'''
        """
            // note that in Eye coordinates, Eye_EC_dir == 0,0,-1
            H = normalize( Eye_EC_dir + Light_EC_dir )
            Spec_factor = pow( dot( H, N ), shininess )
        """
        '''Note: however, that the resulting Spec_factor is not *precisely*
        the same value as the original calculation, so the "shininess"
        exponent must be slightly lower to approximate the value that
        Phong rendering would achieve.  The value is, however, considered
        close to "real world" materials, so the Blinn method is generally 
        preferred to Phong.
        
        Traditionally, n_dot_pos would be cut off at 0.0, but that would 
        create extremely hard-edged cut-offs for specular color.  Here 
        we "fudge" the result by 0.05
        '''
        phong_weightCalc = """
        vec2 phong_weightCalc( 
            in vec3 light_pos, // light position
            in vec3 half_light, // half-way vector between light and view
            in vec3 frag_normal, // geometry normal
            in float shininess
        ) {
            // returns vec2( ambientMult, diffuseMult )
            float n_dot_pos = max( 0.0, dot( 
                frag_normal, light_pos
            ));
            float n_dot_half = 0.0;
            if (n_dot_pos > -.05) {
                n_dot_half = pow(max(0.0,dot( 
                    half_light, frag_normal
                )), shininess);
            }
            return vec2( n_dot_pos, n_dot_half);
        }		
        """
        '''We are going to use per-fragment rendering.
        As a result, our vertex shader becomes very simple, just arranging
        for the Normals to be varied across the surface.
        '''
        vertex = shaders.compileShader(
            """
        attribute vec3 Vertex_position;
        attribute vec3 Vertex_normal;
        
        varying vec3 baseNormal;
        void main() {
            gl_Position = gl_ModelViewProjectionMatrix * vec4( 
                Vertex_position, 1.0
            );
            baseNormal = gl_NormalMatrix * normalize(Vertex_normal);
        }""", GL_VERTEX_SHADER)
        '''Our fragment shader looks much like our previous tutorial's 
        vertex shader.  As before, we have lots of uniform values,
        but now we also calculate the light's half-vector (in eye-space 
        coordinates).  The phong_weightCalc function does the core Blinn 
        calculation, and we simply use the resulting factor to add to 
        the colour value for the fragment.
        
        Note the use of the eye-coordinate-space to simplify the 
        half-vector calculation, the eye-space eye-vector is always 
        the same value (pointing down the negative Z axis), 
        and the eye-space eye-coordinate is always (0,0,0), so the 
        eye-to-vertex vector is always the eye-space vector position.
        '''
        fragment = shaders.compileShader(
            phong_weightCalc + """
        uniform vec4 Global_ambient;
        
        uniform vec4 Light_ambient;
        uniform vec4 Light_diffuse;
        uniform vec4 Light_specular;
        uniform vec3 Light_location;
        
        uniform float Material_shininess;
        uniform vec4 Material_specular;
        uniform vec4 Material_ambient;
        uniform vec4 Material_diffuse;
        
        varying vec3 baseNormal;
        void main() {
            // normalized eye-coordinate Light location
            vec3 EC_Light_location = normalize(
                gl_NormalMatrix * Light_location
            );
            // half-vector calculation 
            vec3 Light_half = normalize(
                EC_Light_location - vec3( 0,0,-1 )
            );
            vec2 weights = phong_weightCalc(
                EC_Light_location,
                Light_half,
                baseNormal,
                Material_shininess
            );
            
            gl_FragColor = clamp( 
            (
                (Global_ambient * Material_ambient)
                + (Light_ambient * Material_ambient)
                + (Light_diffuse * Material_diffuse * weights.x)
                // material's shininess is the only change here...
                + (Light_specular * Material_specular * weights.y)
            ), 0.0, 1.0);
        }
        """, GL_FRAGMENT_SHADER)

        self.shader = shaders.compileProgram(vertex, fragment)
        '''Here's the call that creates the two VBOs and the 
        count of records to render from them. If you're curious 
        you can read through the source code of the 
        OpenGLContext.scenegraph.quadrics module to read the 
        mechanism that generates the values.
        
        The sphere is a simple rendering mechanism, as for a 
        unit-sphere at the origin, the sphere's normals are the 
        same as the sphere's vertex coordinate.  The complexity 
        comes primarily in generating the triangle indices that 
        link the points generated.
        '''
        #self.coords,self.indices,self.count = Sphere(
        #    radius = 3
        #).compile()

        self.coords, self.indices, self.count = Sphere(radius=3).compile()
        '''We have a few more uniforms to control the specular 
        components.  Real-world coding would also calculate the 
        light's half-vector and provide it as a uniform (so that 
        it would only need to be calculated once), but we are going 
        to do the half-vector calculation in the shader to make 
        it obvious what is going on.  The legacy OpenGL pipeline 
        provides the value pre-calculated as part of the light structure 
        in GLSL.
        '''
        for uniform in (
                'Global_ambient',
                'Light_ambient',
                'Light_diffuse',
                'Light_location',
                'Light_specular',
                'Material_ambient',
                'Material_diffuse',
                'Material_shininess',
                'Material_specular',
        ):
            location = glGetUniformLocation(self.shader, uniform)
            if location in (None, -1):
                print 'Warning, no uniform: %s' % (uniform)
            setattr(self, uniform + '_loc', location)
        for attribute in (
                'Vertex_position',
                'Vertex_normal',
        ):
            location = glGetAttribLocation(self.shader, attribute)
            if location in (None, -1):
                print 'Warning, no attribute: %s' % (uniform)
            setattr(self, attribute + '_loc', location)

        #Add a timer
        self.time = Timer(duration=8.0, repeating=1)
        self.time.addEventHandler("fraction", self.OnTimerFraction)
        self.time.register(self)
        self.time.start()
        self.rotation = 0
        self.sensor = PhotoSensor()
        self.sensor.calibrate_ambient()
    def OnInit( self ):
        """Initialize the context"""
        '''== Phong and Blinn Reflectance ==

        A shiny surface will tend to have a "bright spot" at the point 
        on the surface where the angle of incidence for the reflected
        light ray and the viewer's ray are (close to) equal.  
        A perfect mirror would have the brights spot solely when the 
        two vectors are exactly equal, while a perfect Lambertian
        surface would have the "bright spot" spread across the entire
        surface.
        
        The Phong rendering process models this as a setting, traditionally
        called material "shininess" in Legacy OpenGL.  This setting acts 
        as a power which raises the cosine (dot product) of the 
        angle between the reflected ray and the eye.  The calculation of 
        the cosine (dot product) of the two angles requires that we do 
        a dot product of the two angles once for each vertex/fragment 
        for which we wish to calculate the specular reflectance, we also 
        have to find the angle of reflectance before we can do the 
        calculation:'''
        """
            L_dir = (V_pos-L_pos)
            R = 2N*(dot( N, L_dir))-L_dir
            // Note: in eye-coordinate system, Eye_pos == (0,0,0)
            Spec_factor = pow( dot( R, V_pos-Eye_pos ), shininess)
        """
        '''which, as we can see, involves the vertex position in a number 
        of stages of the operation, so requires recalculation all through 
        the rendering operation.
        
        There is, however, a simplified version of Phong Lighting called 
        [http://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model Blinn-Phong]
        which notes that if we were to do all of our calculations in 
        "eye space", and were to assume that (as is normal), the eye 
        and light coordinates will not change for a rendering pass,
        (note: this limits us to directional lights!) we 
        can use a pre-calculated value which is the bisecting angle
        between the light-vector and the view-vector, called the 
        "half vector" to 
        perform approximately the same calculation.  With this value:'''
        """
            // note that in Eye coordinates, Eye_EC_dir == 0,0,-1
            H = normalize( Eye_EC_dir + Light_EC_dir )
            Spec_factor = pow( dot( H, N ), shininess )
        """
        '''Note: however, that the resulting Spec_factor is not *precisely*
        the same value as the original calculation, so the "shininess"
        exponent must be slightly lower to approximate the value that
        Phong rendering would achieve.  The value is, however, considered
        close to "real world" materials, so the Blinn method is generally 
        preferred to Phong.
        
        Traditionally, n_dot_pos would be cut off at 0.0, but that would 
        create extremely hard-edged cut-offs for specular color.  Here 
        we "fudge" the result by 0.05
        '''
        phong_weightCalc = """
        vec2 phong_weightCalc( 
            in vec3 light_pos, // light position
            in vec3 half_light, // half-way vector between light and view
            in vec3 frag_normal, // geometry normal
            in float shininess
        ) {
            // returns vec2( ambientMult, diffuseMult )
            float n_dot_pos = max( 0.0, dot( 
                frag_normal, light_pos
            ));
            float n_dot_half = 0.0;
            if (n_dot_pos > -.05) {
                n_dot_half = pow(max(0.0,dot( 
                    half_light, frag_normal
                )), shininess);
            }
            return vec2( n_dot_pos, n_dot_half);
        }		
        """
        '''We are going to use per-fragment rendering.
        As a result, our vertex shader becomes very simple, just arranging
        for the Normals to be varied across the surface.
        '''
        vertex = shaders.compileShader( 
        """
        attribute vec3 Vertex_position;
        attribute vec3 Vertex_normal;
        
        varying vec3 baseNormal;
        void main() {
            gl_Position = gl_ModelViewProjectionMatrix * vec4( 
                Vertex_position, 1.0
            );
            baseNormal = gl_NormalMatrix * normalize(Vertex_normal);
        }""", GL_VERTEX_SHADER)
        '''Our fragment shader looks much like our previous tutorial's 
        vertex shader.  As before, we have lots of uniform values,
        but now we also calculate the light's half-vector (in eye-space 
        coordinates).  The phong_weightCalc function does the core Blinn 
        calculation, and we simply use the resulting factor to add to 
        the colour value for the fragment.
        
        Note the use of the eye-coordinate-space to simplify the 
        half-vector calculation, the eye-space eye-vector is always 
        the same value (pointing down the negative Z axis), 
        and the eye-space eye-coordinate is always (0,0,0), so the 
        eye-to-vertex vector is always the eye-space vector position.
        '''
        fragment = shaders.compileShader( phong_weightCalc + """
        uniform vec4 Global_ambient;
        
        uniform vec4 Light_ambient;
        uniform vec4 Light_diffuse;
        uniform vec4 Light_specular;
        uniform vec3 Light_location;
        
        uniform float Material_shininess;
        uniform vec4 Material_specular;
        uniform vec4 Material_ambient;
        uniform vec4 Material_diffuse;
        
        varying vec3 baseNormal;
        void main() {
            // normalized eye-coordinate Light location
            vec3 EC_Light_location = normalize(
                gl_NormalMatrix * Light_location
            );
            // half-vector calculation 
            vec3 Light_half = normalize(
                EC_Light_location - vec3( 0,0,-1 )
            );
            vec2 weights = phong_weightCalc(
                EC_Light_location,
                Light_half,
                baseNormal,
                Material_shininess
            );
            
            gl_FragColor = clamp( 
            (
                (Global_ambient * Material_ambient)
                + (Light_ambient * Material_ambient)
                + (Light_diffuse * Material_diffuse * weights.x)
                // material's shininess is the only change here...
                + (Light_specular * Material_specular * weights.y)
            ), 0.0, 1.0);
        }
        """, GL_FRAGMENT_SHADER)
        
        self.shader = shaders.compileProgram(vertex,fragment)
        '''Here's the call that creates the two VBOs and the 
        count of records to render from them. If you're curious 
        you can read through the source code of the 
        OpenGLContext.scenegraph.quadrics module to read the 
        mechanism that generates the values.
        
        The sphere is a simple rendering mechanism, as for a 
        unit-sphere at the origin, the sphere's normals are the 
        same as the sphere's vertex coordinate.  The complexity 
        comes primarily in generating the triangle indices that 
        link the points generated.
        '''
        #self.coords,self.indices,self.count = Sphere( 
        #    radius = 3 
        #).compile()

        self.coords,self.indices,self.count = Sphere(radius=3).compile()

        '''We have a few more uniforms to control the specular 
        components.  Real-world coding would also calculate the 
        light's half-vector and provide it as a uniform (so that 
        it would only need to be calculated once), but we are going 
        to do the half-vector calculation in the shader to make 
        it obvious what is going on.  The legacy OpenGL pipeline 
        provides the value pre-calculated as part of the light structure 
        in GLSL.
        '''
        for uniform in (
            'Global_ambient',
            'Light_ambient','Light_diffuse','Light_location',
            'Light_specular',
            'Material_ambient','Material_diffuse',
            'Material_shininess','Material_specular',
        ):
            location = glGetUniformLocation( self.shader, uniform )
            if location in (None,-1):
                print 'Warning, no uniform: %s'%( uniform )
            setattr( self, uniform+ '_loc', location )
        for attribute in (
            'Vertex_position','Vertex_normal',
        ):
            location = glGetAttribLocation( self.shader, attribute )
            if location in (None,-1):
                print 'Warning, no attribute: %s'%( uniform )
            setattr( self, attribute+ '_loc', location )

        #Add a timer
        self.time = Timer( duration = 8.0, repeating = 1 )
        self.time.addEventHandler( "fraction", self.OnTimerFraction )
        self.time.register (self)
        self.time.start ()
        self.rotation =  0
        self.sensor = PhotoSensor()
        self.sensor.calibrate_ambient()
class TestContext(BaseContext):
    """Demonstrates use of attribute types in GLSL
    """
    def OnInit(self):
        """Initialize the context"""
        '''== Phong and Blinn Reflectance ==

        A shiny surface will tend to have a "bright spot" at the point 
        on the surface where the angle of incidence for the reflected
        light ray and the viewer's ray are (close to) equal.  
        A perfect mirror would have the brights spot solely when the 
        two vectors are exactly equal, while a perfect Lambertian
        surface would have the "bright spot" spread across the entire
        surface.
        
        The Phong rendering process models this as a setting, traditionally
        called material "shininess" in Legacy OpenGL.  This setting acts 
        as a power which raises the cosine (dot product) of the 
        angle between the reflected ray and the eye.  The calculation of 
        the cosine (dot product) of the two angles requires that we do 
        a dot product of the two angles once for each vertex/fragment 
        for which we wish to calculate the specular reflectance, we also 
        have to find the angle of reflectance before we can do the 
        calculation:'''
        """
            L_dir = (V_pos-L_pos)
            R = 2N*(dot( N, L_dir))-L_dir
            // Note: in eye-coordinate system, Eye_pos == (0,0,0)
            Spec_factor = pow( dot( R, V_pos-Eye_pos ), shininess)
        """
        '''which, as we can see, involves the vertex position in a number 
        of stages of the operation, so requires recalculation all through 
        the rendering operation.
        
        There is, however, a simplified version of Phong Lighting called 
        [http://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model Blinn-Phong]
        which notes that if we were to do all of our calculations in 
        "eye space", and were to assume that (as is normal), the eye 
        and light coordinates will not change for a rendering pass,
        (note: this limits us to directional lights!) we 
        can use a pre-calculated value which is the bisecting angle
        between the light-vector and the view-vector, called the 
        "half vector" to 
        perform approximately the same calculation.  With this value:'''
        """
            // note that in Eye coordinates, Eye_EC_dir == 0,0,-1
            H = normalize( Eye_EC_dir + Light_EC_dir )
            Spec_factor = pow( dot( H, N ), shininess )
        """
        '''Note: however, that the resulting Spec_factor is not *precisely*
        the same value as the original calculation, so the "shininess"
        exponent must be slightly lower to approximate the value that
        Phong rendering would achieve.  The value is, however, considered
        close to "real world" materials, so the Blinn method is generally 
        preferred to Phong.
        
        Traditionally, n_dot_pos would be cut off at 0.0, but that would 
        create extremely hard-edged cut-offs for specular color.  Here 
        we "fudge" the result by 0.05
        '''
        phong_weightCalc = """
        vec2 phong_weightCalc( 
            in vec3 light_pos, // light position
            in vec3 half_light, // half-way vector between light and view
            in vec3 frag_normal, // geometry normal
            in float shininess
        ) {
            // returns vec2( ambientMult, diffuseMult )
            float n_dot_pos = max( 0.0, dot( 
                frag_normal, light_pos
            ));
            float n_dot_half = 0.0;
            if (n_dot_pos > -.05) {
                n_dot_half = pow(max(0.0,dot( 
                    half_light, frag_normal
                )), shininess);
            }
            return vec2( n_dot_pos, n_dot_half);
        }		
        """
        '''We are going to use per-fragment rendering.
        As a result, our vertex shader becomes very simple, just arranging
        for the Normals to be varied across the surface.
        '''
        vertex = shaders.compileShader(
            """
        attribute vec3 Vertex_position;
        attribute vec3 Vertex_normal;
        
        varying vec3 baseNormal;
        void main() {
            gl_Position = gl_ModelViewProjectionMatrix * vec4( 
                Vertex_position, 1.0
            );
            baseNormal = gl_NormalMatrix * normalize(Vertex_normal);
        }""", GL_VERTEX_SHADER)
        '''Our fragment shader looks much like our previous tutorial's 
        vertex shader.  As before, we have lots of uniform values,
        but now we also calculate the light's half-vector (in eye-space 
        coordinates).  The phong_weightCalc function does the core Blinn 
        calculation, and we simply use the resulting factor to add to 
        the colour value for the fragment.
        
        Note the use of the eye-coordinate-space to simplify the 
        half-vector calculation, the eye-space eye-vector is always 
        the same value (pointing down the negative Z axis), 
        and the eye-space eye-coordinate is always (0,0,0), so the 
        eye-to-vertex vector is always the eye-space vector position.
        '''
        fragment = shaders.compileShader(
            phong_weightCalc + """
        uniform vec4 Global_ambient;
        
        uniform vec4 Light_ambient;
        uniform vec4 Light_diffuse;
        uniform vec4 Light_specular;
        uniform vec3 Light_location;
        
        uniform float Material_shininess;
        uniform vec4 Material_specular;
        uniform vec4 Material_ambient;
        uniform vec4 Material_diffuse;
        
        varying vec3 baseNormal;
        void main() {
            // normalized eye-coordinate Light location
            vec3 EC_Light_location = normalize(
                gl_NormalMatrix * Light_location
            );
            // half-vector calculation 
            vec3 Light_half = normalize(
                EC_Light_location - vec3( 0,0,-1 )
            );
            vec2 weights = phong_weightCalc(
                EC_Light_location,
                Light_half,
                baseNormal,
                Material_shininess
            );
            
            gl_FragColor = clamp( 
            (
                (Global_ambient * Material_ambient)
                + (Light_ambient * Material_ambient)
                + (Light_diffuse * Material_diffuse * weights.x)
                // material's shininess is the only change here...
                + (Light_specular * Material_specular * weights.y)
            ), 0.0, 1.0);
        }
        """, GL_FRAGMENT_SHADER)

        self.shader = shaders.compileProgram(vertex, fragment)
        '''Here's the call that creates the two VBOs and the 
        count of records to render from them. If you're curious 
        you can read through the source code of the 
        OpenGLContext.scenegraph.quadrics module to read the 
        mechanism that generates the values.
        
        The sphere is a simple rendering mechanism, as for a 
        unit-sphere at the origin, the sphere's normals are the 
        same as the sphere's vertex coordinate.  The complexity 
        comes primarily in generating the triangle indices that 
        link the points generated.
        '''
        #self.coords,self.indices,self.count = Sphere(
        #    radius = 3
        #).compile()

        self.coords, self.indices, self.count = Sphere(radius=3).compile()
        '''We have a few more uniforms to control the specular 
        components.  Real-world coding would also calculate the 
        light's half-vector and provide it as a uniform (so that 
        it would only need to be calculated once), but we are going 
        to do the half-vector calculation in the shader to make 
        it obvious what is going on.  The legacy OpenGL pipeline 
        provides the value pre-calculated as part of the light structure 
        in GLSL.
        '''
        for uniform in (
                'Global_ambient',
                'Light_ambient',
                'Light_diffuse',
                'Light_location',
                'Light_specular',
                'Material_ambient',
                'Material_diffuse',
                'Material_shininess',
                'Material_specular',
        ):
            location = glGetUniformLocation(self.shader, uniform)
            if location in (None, -1):
                print 'Warning, no uniform: %s' % (uniform)
            setattr(self, uniform + '_loc', location)
        for attribute in (
                'Vertex_position',
                'Vertex_normal',
        ):
            location = glGetAttribLocation(self.shader, attribute)
            if location in (None, -1):
                print 'Warning, no attribute: %s' % (uniform)
            setattr(self, attribute + '_loc', location)

        #Add a timer
        self.time = Timer(duration=8.0, repeating=1)
        self.time.addEventHandler("fraction", self.OnTimerFraction)
        self.time.register(self)
        self.time.start()
        self.rotation = 0
        self.sensor = PhotoSensor()
        self.sensor.calibrate_ambient()

    def OnTimerFraction(self, event):
        r = self.sensor.getSensorReading()
        angle = self.sensor.getAngle(r)
        self.rotation = angle / 180.0 * pi

    def getLightLocation(self):
        # read from serial port
        return [math.cos(self.rotation), math.sin(self.rotation), 0] * 5

    def Render(self, mode=None):
        """Render the geometry for the scene."""
        BaseContext.Render(self, mode)
        glUseProgram(self.shader)
        try:
            '''==Indexed VBO Rendering==
            
            You'll notice here that we are binding two different VBO 
            objects.  As we mentioned above, the Sphere renderer 
            generated both VBOs, but doesn't the second binding replace 
            the first binding?  That is, why doesn't OpenGL try to read 
            the Vertex data out of the indices VBO?
            
            OpenGL defines multiple binding "targets" for VBOs, the 
            first VBO (vertices) was bound to the GL_ARRAY_BUFFER
            target (the default for the class), which is used for reading 
            per-vertex data arrays, while the indices buffer was defined
            as targetting the GL_ELEMENT_ARRAY_BUFFER, which is used
            solely for reading indices.
            
            Each target can be bound to a different VBO, and thus we can
            bind both VBOs at the same time without confusion.
            '''
            self.coords.bind()
            self.indices.bind()
            '''Here, being lazy, we use the numpy array's nbytes value 
            to specify the stride between records.  The VBO object has 
            a "data" value which is the data-set which was initially 
            passed to the VBO constructor.  The first element in this 
            array is a single vertex record.  This array happens to have 
            8 floating-point values (24 bytes), the first three being 
            the vertex position, the next two being the texture coordinate 
            and the last three being the vertex normal.  We'll ignore 
            the texture coordinate for now.
            '''
            stride = self.coords.data[0].nbytes
            try:
                glUniform4f(self.Global_ambient_loc, .05, .05, .05, .1)
                glUniform4f(self.Light_ambient_loc, .1, .1, .1, 1.0)
                glUniform4f(self.Light_diffuse_loc, .25, .25, .25, 1)
                '''We set up a yellow-ish specular component in the 
                light and move it to rest "just over our right shoulder"
                in relation to the initial camera.'''
                glUniform4f(self.Light_specular_loc, 0.0, 1.0, 0, 1)

                lloc = self.getLightLocation()
                glUniform3f(self.Light_location_loc, lloc[0], lloc[1], lloc[2])

                glUniform4f(self.Material_ambient_loc, .1, .1, .1, 1.0)
                glUniform4f(self.Material_diffuse_loc, .15, .15, .15, 1)
                '''We make the material have a bright specular white 
                colour and an extremely "shiny" surface.  The shininess 
                value has the effect of reducing the area of the
                highlight, as the cos of the angle is raised 
                to the power of the (fractional) shininess.'''
                glUniform4f(self.Material_specular_loc, 1.0, 1.0, 1.0, 1.0)
                glUniform1f(self.Material_shininess_loc, .95)
                glEnableVertexAttribArray(self.Vertex_position_loc)
                glEnableVertexAttribArray(self.Vertex_normal_loc)
                glVertexAttribPointer(self.Vertex_position_loc, 3, GL_FLOAT,
                                      False, stride, self.coords)
                glVertexAttribPointer(self.Vertex_normal_loc, 3, GL_FLOAT,
                                      False, stride, self.coords + (5 * 4))
                '''Here we introduce the OpenGL call which renders via 
                an index-array rather than just rendering vertices in 
                definition order.  The last two arguments tell OpenGL 
                what data-type we've used for the indices (the Sphere 
                renderer uses shorts).  The indices VBO is actually 
                just passing the value c_void_p( 0 ) (i.e. a null pointer),
                which causes OpenGL to use the currently bound VBO for 
                the GL_ELEMENT_ARRAY_BUFFER target.
                '''
                glDrawElements(GL_TRIANGLES, self.count, GL_UNSIGNED_SHORT,
                               self.indices)
            finally:
                '''Note the need to unbind *both* VBOs, we have to free 
                *both* VBO targets to avoid any other rendering operation 
                from trying to access the VBOs.'''
                self.coords.unbind()
                self.indices.unbind()
                glDisableVertexAttribArray(self.Vertex_position_loc)
                glDisableVertexAttribArray(self.Vertex_normal_loc)
        finally:
            glUseProgram(0)
class TestContext( BaseContext ):
    """Demonstrates use of attribute types in GLSL
    """
    def OnInit( self ):
        """Initialize the context"""
        '''== Phong and Blinn Reflectance ==

        A shiny surface will tend to have a "bright spot" at the point 
        on the surface where the angle of incidence for the reflected
        light ray and the viewer's ray are (close to) equal.  
        A perfect mirror would have the brights spot solely when the 
        two vectors are exactly equal, while a perfect Lambertian
        surface would have the "bright spot" spread across the entire
        surface.
        
        The Phong rendering process models this as a setting, traditionally
        called material "shininess" in Legacy OpenGL.  This setting acts 
        as a power which raises the cosine (dot product) of the 
        angle between the reflected ray and the eye.  The calculation of 
        the cosine (dot product) of the two angles requires that we do 
        a dot product of the two angles once for each vertex/fragment 
        for which we wish to calculate the specular reflectance, we also 
        have to find the angle of reflectance before we can do the 
        calculation:'''
        """
            L_dir = (V_pos-L_pos)
            R = 2N*(dot( N, L_dir))-L_dir
            // Note: in eye-coordinate system, Eye_pos == (0,0,0)
            Spec_factor = pow( dot( R, V_pos-Eye_pos ), shininess)
        """
        '''which, as we can see, involves the vertex position in a number 
        of stages of the operation, so requires recalculation all through 
        the rendering operation.
        
        There is, however, a simplified version of Phong Lighting called 
        [http://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model Blinn-Phong]
        which notes that if we were to do all of our calculations in 
        "eye space", and were to assume that (as is normal), the eye 
        and light coordinates will not change for a rendering pass,
        (note: this limits us to directional lights!) we 
        can use a pre-calculated value which is the bisecting angle
        between the light-vector and the view-vector, called the 
        "half vector" to 
        perform approximately the same calculation.  With this value:'''
        """
            // note that in Eye coordinates, Eye_EC_dir == 0,0,-1
            H = normalize( Eye_EC_dir + Light_EC_dir )
            Spec_factor = pow( dot( H, N ), shininess )
        """
        '''Note: however, that the resulting Spec_factor is not *precisely*
        the same value as the original calculation, so the "shininess"
        exponent must be slightly lower to approximate the value that
        Phong rendering would achieve.  The value is, however, considered
        close to "real world" materials, so the Blinn method is generally 
        preferred to Phong.
        
        Traditionally, n_dot_pos would be cut off at 0.0, but that would 
        create extremely hard-edged cut-offs for specular color.  Here 
        we "fudge" the result by 0.05
        '''
        phong_weightCalc = """
        vec2 phong_weightCalc( 
            in vec3 light_pos, // light position
            in vec3 half_light, // half-way vector between light and view
            in vec3 frag_normal, // geometry normal
            in float shininess
        ) {
            // returns vec2( ambientMult, diffuseMult )
            float n_dot_pos = max( 0.0, dot( 
                frag_normal, light_pos
            ));
            float n_dot_half = 0.0;
            if (n_dot_pos > -.05) {
                n_dot_half = pow(max(0.0,dot( 
                    half_light, frag_normal
                )), shininess);
            }
            return vec2( n_dot_pos, n_dot_half);
        }		
        """
        '''We are going to use per-fragment rendering.
        As a result, our vertex shader becomes very simple, just arranging
        for the Normals to be varied across the surface.
        '''
        vertex = shaders.compileShader( 
        """
        attribute vec3 Vertex_position;
        attribute vec3 Vertex_normal;
        
        varying vec3 baseNormal;
        void main() {
            gl_Position = gl_ModelViewProjectionMatrix * vec4( 
                Vertex_position, 1.0
            );
            baseNormal = gl_NormalMatrix * normalize(Vertex_normal);
        }""", GL_VERTEX_SHADER)
        '''Our fragment shader looks much like our previous tutorial's 
        vertex shader.  As before, we have lots of uniform values,
        but now we also calculate the light's half-vector (in eye-space 
        coordinates).  The phong_weightCalc function does the core Blinn 
        calculation, and we simply use the resulting factor to add to 
        the colour value for the fragment.
        
        Note the use of the eye-coordinate-space to simplify the 
        half-vector calculation, the eye-space eye-vector is always 
        the same value (pointing down the negative Z axis), 
        and the eye-space eye-coordinate is always (0,0,0), so the 
        eye-to-vertex vector is always the eye-space vector position.
        '''
        fragment = shaders.compileShader( phong_weightCalc + """
        uniform vec4 Global_ambient;
        
        uniform vec4 Light_ambient;
        uniform vec4 Light_diffuse;
        uniform vec4 Light_specular;
        uniform vec3 Light_location;
        
        uniform float Material_shininess;
        uniform vec4 Material_specular;
        uniform vec4 Material_ambient;
        uniform vec4 Material_diffuse;
        
        varying vec3 baseNormal;
        void main() {
            // normalized eye-coordinate Light location
            vec3 EC_Light_location = normalize(
                gl_NormalMatrix * Light_location
            );
            // half-vector calculation 
            vec3 Light_half = normalize(
                EC_Light_location - vec3( 0,0,-1 )
            );
            vec2 weights = phong_weightCalc(
                EC_Light_location,
                Light_half,
                baseNormal,
                Material_shininess
            );
            
            gl_FragColor = clamp( 
            (
                (Global_ambient * Material_ambient)
                + (Light_ambient * Material_ambient)
                + (Light_diffuse * Material_diffuse * weights.x)
                // material's shininess is the only change here...
                + (Light_specular * Material_specular * weights.y)
            ), 0.0, 1.0);
        }
        """, GL_FRAGMENT_SHADER)
        
        self.shader = shaders.compileProgram(vertex,fragment)
        '''Here's the call that creates the two VBOs and the 
        count of records to render from them. If you're curious 
        you can read through the source code of the 
        OpenGLContext.scenegraph.quadrics module to read the 
        mechanism that generates the values.
        
        The sphere is a simple rendering mechanism, as for a 
        unit-sphere at the origin, the sphere's normals are the 
        same as the sphere's vertex coordinate.  The complexity 
        comes primarily in generating the triangle indices that 
        link the points generated.
        '''
        #self.coords,self.indices,self.count = Sphere( 
        #    radius = 3 
        #).compile()

        self.coords,self.indices,self.count = Sphere(radius=3).compile()

        '''We have a few more uniforms to control the specular 
        components.  Real-world coding would also calculate the 
        light's half-vector and provide it as a uniform (so that 
        it would only need to be calculated once), but we are going 
        to do the half-vector calculation in the shader to make 
        it obvious what is going on.  The legacy OpenGL pipeline 
        provides the value pre-calculated as part of the light structure 
        in GLSL.
        '''
        for uniform in (
            'Global_ambient',
            'Light_ambient','Light_diffuse','Light_location',
            'Light_specular',
            'Material_ambient','Material_diffuse',
            'Material_shininess','Material_specular',
        ):
            location = glGetUniformLocation( self.shader, uniform )
            if location in (None,-1):
                print 'Warning, no uniform: %s'%( uniform )
            setattr( self, uniform+ '_loc', location )
        for attribute in (
            'Vertex_position','Vertex_normal',
        ):
            location = glGetAttribLocation( self.shader, attribute )
            if location in (None,-1):
                print 'Warning, no attribute: %s'%( uniform )
            setattr( self, attribute+ '_loc', location )

        #Add a timer
        self.time = Timer( duration = 8.0, repeating = 1 )
        self.time.addEventHandler( "fraction", self.OnTimerFraction )
        self.time.register (self)
        self.time.start ()
        self.rotation =  0
        self.sensor = PhotoSensor()
        self.sensor.calibrate_ambient()


    def OnTimerFraction( self, event ):
        r = self.sensor.getSensorReading()
        angle = self.sensor.getAngle(r)
        self.rotation = angle/180.0 *  pi
        

    def getLightLocation(self):
        # read from serial port
        return [math.cos(self.rotation),
                math.sin(self.rotation),0]*5


    def Render( self, mode = None):
        """Render the geometry for the scene."""
        BaseContext.Render( self, mode )
        glUseProgram(self.shader)
        try:
            '''==Indexed VBO Rendering==
            
            You'll notice here that we are binding two different VBO 
            objects.  As we mentioned above, the Sphere renderer 
            generated both VBOs, but doesn't the second binding replace 
            the first binding?  That is, why doesn't OpenGL try to read 
            the Vertex data out of the indices VBO?
            
            OpenGL defines multiple binding "targets" for VBOs, the 
            first VBO (vertices) was bound to the GL_ARRAY_BUFFER
            target (the default for the class), which is used for reading 
            per-vertex data arrays, while the indices buffer was defined
            as targetting the GL_ELEMENT_ARRAY_BUFFER, which is used
            solely for reading indices.
            
            Each target can be bound to a different VBO, and thus we can
            bind both VBOs at the same time without confusion.
            '''
            self.coords.bind()
            self.indices.bind()
            '''Here, being lazy, we use the numpy array's nbytes value 
            to specify the stride between records.  The VBO object has 
            a "data" value which is the data-set which was initially 
            passed to the VBO constructor.  The first element in this 
            array is a single vertex record.  This array happens to have 
            8 floating-point values (24 bytes), the first three being 
            the vertex position, the next two being the texture coordinate 
            and the last three being the vertex normal.  We'll ignore 
            the texture coordinate for now.
            '''
            stride = self.coords.data[0].nbytes
            try:
                glUniform4f( self.Global_ambient_loc, .05,.05,.05,.1 )
                glUniform4f( self.Light_ambient_loc, .1,.1,.1, 1.0 )
                glUniform4f( self.Light_diffuse_loc, .25,.25,.25,1 )
                '''We set up a yellow-ish specular component in the 
                light and move it to rest "just over our right shoulder"
                in relation to the initial camera.'''
                glUniform4f( self.Light_specular_loc, 0.0,1.0,0,1 )

                lloc = self.getLightLocation()
                glUniform3f( self.Light_location_loc, lloc[0],
                             lloc[1], lloc[2])
                
                glUniform4f( self.Material_ambient_loc, .1,.1,.1, 1.0 )
                glUniform4f( self.Material_diffuse_loc, .15,.15,.15, 1 )
                '''We make the material have a bright specular white 
                colour and an extremely "shiny" surface.  The shininess 
                value has the effect of reducing the area of the
                highlight, as the cos of the angle is raised 
                to the power of the (fractional) shininess.'''
                glUniform4f( self.Material_specular_loc, 1.0,1.0,1.0, 1.0 )
                glUniform1f( self.Material_shininess_loc, .95)
                glEnableVertexAttribArray( self.Vertex_position_loc )
                glEnableVertexAttribArray( self.Vertex_normal_loc )
                glVertexAttribPointer( 
                    self.Vertex_position_loc, 
                    3, GL_FLOAT,False, stride, self.coords
                )
                glVertexAttribPointer( 
                    self.Vertex_normal_loc, 
                    3, GL_FLOAT,False, stride, self.coords+(5*4)
                )
                '''Here we introduce the OpenGL call which renders via 
                an index-array rather than just rendering vertices in 
                definition order.  The last two arguments tell OpenGL 
                what data-type we've used for the indices (the Sphere 
                renderer uses shorts).  The indices VBO is actually 
                just passing the value c_void_p( 0 ) (i.e. a null pointer),
                which causes OpenGL to use the currently bound VBO for 
                the GL_ELEMENT_ARRAY_BUFFER target.
                '''
                glDrawElements(
                    GL_TRIANGLES, self.count,
                    GL_UNSIGNED_SHORT, self.indices
                )
            finally:
                '''Note the need to unbind *both* VBOs, we have to free 
                *both* VBO targets to avoid any other rendering operation 
                from trying to access the VBOs.'''
                self.coords.unbind()
                self.indices.unbind()
                glDisableVertexAttribArray( self.Vertex_position_loc )
                glDisableVertexAttribArray( self.Vertex_normal_loc )
        finally:
            glUseProgram( 0 )