createShaderProgram :: FilePath -> FilePath -> IO GLProgram
createShaderProgram vertexShaderPath fragmentShaderPath =
  do vertexShader <- glCreateShader GL_VERTEX_SHADER
     compileShader vertexShaderPath vertexShader
     fragmentShader <- glCreateShader GL_FRAGMENT_SHADER
     compileShader fragmentShaderPath fragmentShader
     shaderProg <- glCreateProgram
     glAttachShader shaderProg vertexShader
     glAttachShader shaderProg fragmentShader
     mapM_ (\(x,y) ->
              withCString x
                          (glBindAttribLocation shaderProg y))
           [("in_Position",positionAttribute)
           ,("in_Normal",normalAttribute)
           ,("in_Tangent",tangentAttribute)
           ,("in_Bitangent",bitangentAttribute)
           ,("in_UV",uvAttribute)]
     glLinkProgram shaderProg
     linked <- overPtr (glGetProgramiv shaderProg GL_LINK_STATUS)
     when (linked == GL_FALSE)
          (do maxLength <- overPtr (glGetProgramiv shaderProg GL_INFO_LOG_LENGTH)
              logLines <- allocaArray
                            (fromIntegral maxLength)
                            (\p ->
                               alloca (\lenP ->
                                         do glGetProgramInfoLog shaderProg maxLength lenP p
                                            len <- peek lenP
                                            peekCStringLen (p,fromIntegral len)))
              putStrLn logLines)
     return (GLProgram shaderProg)
  where compileShader path shader =
          do src <- getDataFileName path >>= Text.readFile
             BS.useAsCString
               (Text.encodeUtf8 src)
               (\ptr ->
                  withArray [ptr]
                            (\srcs ->
                               glShaderSource shader 1 srcs nullPtr))
             glCompileShader shader -- GL.get (GL.shaderInfoLog shader) >>= putStrLn
createShaderProgram :: FilePath -> FilePath -> IO GLProgram
createShaderProgram vertexShaderPath fragmentShaderPath =
  do vertexShader <- glCreateShader GL_VERTEX_SHADER
     compileShader vertexShaderPath vertexShader
     fragmentShader <- glCreateShader GL_FRAGMENT_SHADER
     compileShader fragmentShaderPath fragmentShader
     shaderProg <- glCreateProgram
     glAttachShader shaderProg vertexShader
     glAttachShader shaderProg fragmentShader
     mapM_ (\(x,y) ->
              withCString x
                          (glBindAttribLocation shaderProg y))
           [("in_Position",positionAttribute)
           ,("in_Normal",normalAttribute)
           ,("in_Tangent",tangentAttribute)
           ,("in_Bitangent",bitangentAttribute)
           ,("in_UV",uvAttribute)]
     glLinkProgram shaderProg
     linked <- overPtr (glGetProgramiv shaderProg GL_LINK_STATUS)
     when (linked == GL_FALSE)
          (do maxLength <- overPtr (glGetProgramiv shaderProg GL_INFO_LOG_LENGTH)
              logLines <- allocaArray
                            (fromIntegral maxLength)
                            (\p ->
                               alloca (\lenP ->
                                         do glGetProgramInfoLog shaderProg maxLength lenP p
                                            len <- peek lenP
                                            peekCStringLen (p,fromIntegral len)))
              putStrLn logLines)
     return (GLProgram shaderProg)
  where compileShader path shader =
          do src <- getDataFileName path >>= Text.readFile
             BS.useAsCString
               (Text.encodeUtf8 src)
               (\ptr ->
                  withArray [ptr]
                            (\srcs ->
                               glShaderSource shader 1 srcs nullPtr))
             glCompileShader shader -- GL.get (GL.shaderInfoLog shader) >>= putStrLn
createShaderProgram vertexShaderPath fragmentShaderPath =
  do vertexShader <- glCreateShader GL_VERTEX_SHADER
     compileShader vertexShaderPath vertexShader
     fragmentShader <- glCreateShader GL_FRAGMENT_SHADER
     compileShader fragmentShaderPath fragmentShader
     shaderProg <- glCreateProgram
     glAttachShader shaderProg vertexShader
     glAttachShader shaderProg fragmentShader
     mapM_ (\(x,y) ->
              withCString x
                          (glBindAttribLocation shaderProg y))
           [("in_Position",positionAttribute)
           ,("in_Normal",normalAttribute)
           ,("in_Tangent",tangentAttribute)
           ,("in_Bitangent",bitangentAttribute)
           ,("in_UV",uvAttribute)]
     glLinkProgram shaderProg
     linked <- overPtr (glGetProgramiv shaderProg GL_LINK_STATUS)
     when (linked == GL_FALSE)
          (do maxLength <- overPtr (glGetProgramiv shaderProg GL_INFO_LOG_LENGTH)
              logLines <- allocaArray
                            (fromIntegral maxLength)
                            (\p ->
                               alloca (\lenP ->
                                         do glGetProgramInfoLog shaderProg maxLength lenP p
                                            len <- peek lenP
                                            peekCStringLen (p,fromIntegral len)))
              putStrLn logLines)
     return (GLProgram shaderProg)
  where compileShader path shader =
          do src <- getDataFileName path >>= Text.readFile
             BS.useAsCString
               (Text.encodeUtf8 src)
               (\ptr ->
                  withArray [ptr]
                            (\srcs ->
                               glShaderSource shader 1 srcs nullPtr))
             glCompileShader shader -- GL.get (GL.shaderInfoLog shader) >>= putStrLn