anchor.diff:                                  , TextureParameterName.TextureWrapT
                                   , int(TextureWrapMode.ClampToBorder) )
               checkGLError()
  -            let imageLoc = GL.GetUniformLocation( bgshader.Value.progHandle, "image")
  -            GL.Uniform1( imageLoc, int(TextureUnit.Texture0 - TextureUnit.Texture0) )
  +            bgshader.Value.setUniform( "image", 0)
               checkGLError()
               GL.Disable( EnableCap.CullFace )
               GL.Disable( EnableCap.DepthTest )
               GL.Disable( EnableCap.StencilTest )
               GL.Enable( EnableCap.Blend )
  -            GL.BlendFuncSeparate( BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha, BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha )
  +            GL.BlendFuncSeparate( BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha
  +                                    , BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha )
               GL.DrawElements( BeginMode.Triangles, 6, DrawElementsType.UnsignedInt, 0 )
               GL.BindBuffer( BufferTarget.ArrayBuffer, 0 )
               GL.BindBuffer( BufferTarget.ElementArrayBuffer, 0 )
               GL.DisableVertexAttribArray( 0 )
               checkGLError()
  +        
  +    let renderPyramid( aspect ) =
  +        checkPyramidData()
  +        if pyramidshder.IsSome then
  +            GL.UseProgram( pyramidshder.Value.progHandle )
               
  +            GL.BindBuffer( BufferTarget.ArrayBuffer, pyramidvert )
  +            GL.EnableVertexAttribArray( 0 )
  +            GL.VertexAttribPointer( 0, 3, VertexAttribPointerType.Float, true, 12, 0)
  +            GL.BindBuffer( BufferTarget.ElementArrayBuffer, pyramididx )
  +            (*build mvp*)
  +            let mutable mvp = buildMVPFromModel( model.rotation, model.scale, model.translation, aspect )
  +            pyramidshder.Value.setUniform( "mvp", &mvp )
  +            pyramidshder.Value.setUniform( "mv", &mvp )
  +            GL.Disable( EnableCap.CullFace )
  +            GL.Enable( EnableCap.DepthTest )
  +            GL.Disable( EnableCap.StencilTest )
  +            GL.Enable( EnableCap.Blend )
  +            GL.BlendFuncSeparate( BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha
  +                                , BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha )
               
  -
  -    member this.checkBuffers() = 
  -        if bgimagevert = 0 then
  -            bgimagevert <- createAndUploadDataf32([|-1.f;-1.f;
  -                                      -1.f; 1.f; 
  -                                       1.f; 1.f; 
  -                                       1.f; -1.f |]
  -                                       , BufferTarget.ArrayBuffer
  -                                       , BufferUsageHint.StaticDraw )
  -            bgimageidx <- createAndUploadDatai32( [|0;1;2;2;3;0|]
  -                                       , BufferTarget.ArrayBuffer
  -                                       , BufferUsageHint.StaticDraw )
  -
  -            bgshader <- compileShaderProgram( bgimage_vert, bgimage_frag )
  -
  +            GL.DrawElements( BeginMode.Triangles, 9, DrawElementsType.UnsignedInt, 0 )
  +            GL.BindBuffer( BufferTarget.ArrayBuffer, 0 )
  +            GL.BindBuffer( BufferTarget.ElementArrayBuffer, 0 )
  +            GL.DisableVertexAttribArray( 0 )
  +            checkGLError()
           
  -
  +            
   
       member this.render(width, height) =
  +        let mutable targetAspect = 1.0f
           if (width > 0 && height > 0) then 
               GL.Viewport( 0, 0, width, height)
               GL.ClearColor( 1.0f, 1.0f, 1.0f, 1.0f )
               GL.Clear( ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit )
  +            checkSourceImage()
               checkGLError()
  -            this.checkBuffers()
  +            //setup viewport to match the aspect ratio
  +            if bgtex.IsSome then
  +                let img = bgtex.Value
  +                targetAspect <- float32(img.width) / float32(img.height)
  +                let existingAspect = float32(width)/float32(height)
  +                //we need to pad the top and the bottom till the aspects match
  +                if targetAspect > existingAspect then
  +                    let targetHeight = int32(float32(width) / targetAspect)
  +                    let diff = (height - int32(targetHeight)) / 2
  +                    GL.Viewport( 0, diff, width, targetHeight )
  +                else
  +                    let targetWidth = int32(targetAspect * float32(height))
  +                    let diff = (width - targetWidth) / 2
  +                    GL.Viewport( diff, 0, targetWidth, height)
  +
               renderSourceImage()
  -
  -
  +            renderPyramid(targetAspect)
  +
  +        targetAspect
  + 
           
  -        
  -
  +let buildTargetBitmap( model:ModelData, img : Image, aspect ) = 
  +    try
  +        let mvp = buildMVPFromModel( -1.0f * model.rotation, model.scale, model.translation, aspect )
  +        let length = model.destsize * model.destsize * 4;
  +        let destbytes : byte array = Array.zeroCreate length
  +        let (bytes,srcbits) = loadBitmapBytes( model.source )
  +        pyramidProject( ByteImage( bytes, srcbits.Width, srcbits.Height )
  +                    , ByteImage(destbytes, model.destsize, model.destsize)
  +                    , mvp )
  +        let bmap = new System.Drawing.Bitmap(model.destsize, model.destsize)
  +        let bmapbits = bmap.LockBits( Drawing.Rectangle( 0, 0, model.destsize, model.destsize)
  +                                    , Drawing.Imaging.ImageLockMode.WriteOnly
  +                                    , Drawing.Imaging.PixelFormat.Format32bppArgb );
  +        Marshal.Copy( destbytes, 0, bmapbits.Scan0, length )
  +        let ms = new MemoryStream ();
  +        bmap.Save (ms, Drawing.Imaging.ImageFormat.Png);
  +        ms.Seek(int64(0), SeekOrigin.Begin) |> ignore
  +        let pmap = new Gdk.Pixbuf(ms)
  +        img.Pixbuf <- pmap;
  +        if model.destination.Length > 0 then
  +            try
  +                bmap.Save( model.destination )
  +            with
  +                | except -> ()
  +    with
  +        | except -> ()
  +
  +
  +    
   
   [<EntryPoint>]
   let main argv = 
  
positive.code:         let alloc = renderer.Allocation 
          let width = alloc.Width
          let height = alloc.Height
          rc.render(width, height)
  
      
      let toolkit = Toolkit.Init()
  
negative.code:         else
              None
  
      member this.setUniform( name, value:int ) =
          let uniLoc = this.getUniLoc( name )
          if uniLoc.IsSome then
              GL.Uniform1( uniLoc.Value, value )
  
      member this.setUniform( name, value:Matrix4 byref ) =
          let uniLoc = this.getUniLoc( name )
          if uniLoc.IsSome then
              GL.UniformMatrix4( uniLoc.Value, false, &value )
          
  
  let compileShader( code, stype ) =
  