diff --git a/linear-opengl.cabal b/linear-opengl.cabal
--- a/linear-opengl.cabal
+++ b/linear-opengl.cabal
@@ -1,5 +1,5 @@
 name:                linear-opengl
-version:             0.1.0.2
+version:             0.2.0.0
 synopsis:            Isomorphisms between linear and OpenGL types
 description:         This provides various useful utilities for mapping OpenGL vectors, vertices, and matrices to their analogues in the `linear` package
 homepage:            http://www.github.com/bgamari/linear-opengl
@@ -18,9 +18,13 @@
 
 library
   exposed-modules:     Linear.OpenGL
+  other-modules:       Linear.OpenGL.MatrixUniforms
   build-depends:       base >=4.6 && <4.8,
                        linear >=1.10 && <1.11,
+                       lens >=4.2 && <4.3,
+                       distributive >=0.4 && <0.5,
+                       tagged >= 0.7 && < 0.8,
                        OpenGL >=2.9 && <2.10,
-                       lens >=4.2 && <4.3
+                       OpenGLRaw >= 1.5 && <1.6
   hs-source-dirs:      src
   default-language:    Haskell2010
diff --git a/src/Linear/OpenGL.hs b/src/Linear/OpenGL.hs
--- a/src/Linear/OpenGL.hs
+++ b/src/Linear/OpenGL.hs
@@ -1,6 +1,13 @@
+-- | In addition to providing isomorphisms between GL and linear
+-- vector, point, and matrix types, this module also provides
+-- @Uniform@ instances for linear's matrix types.
+
 module Linear.OpenGL
-  ( m44GLmatrix
+  ( -- * Matrices
+    m44GLmatrix
+    -- * Points
   , vertex1P, vertex2P, vertex3P, vertex4P
+    -- * Vectors
   , vector1V, vector2V, vector3V, vector4V
   ) where
 
@@ -10,6 +17,7 @@
 import Control.Lens       
 import Foreign hiding (unsafePerformIO)
 import System.IO.Unsafe (unsafePerformIO)
+import Linear.OpenGL.MatrixUniforms
 
 glMatrixToM44 :: MatrixComponent a => GLmatrix a -> IO (M44 a)
 glMatrixToM44 m = withMatrix m $ \order p ->
@@ -28,15 +36,15 @@
 {-# INLINABLE glMatrixToM44 #-}
 
 m44ToGLmatrix :: MatrixComponent a => M44 a -> IO (GLmatrix a)
-m44ToGLmatrix m = withNewMatrix RowMajor go
-  where
-    go n = undefined
+m44ToGLmatrix m = withNewMatrix RowMajor $ \p->poke (castPtr p) m
 {-# INLINABLE m44ToGLmatrix #-}
   
+-- | An isomorphism between GL and linear four-dimensional matrices
 m44GLmatrix :: MatrixComponent a => Iso' (M44 a) (GLmatrix a)
 m44GLmatrix = iso (unsafePerformIO . m44ToGLmatrix) (unsafePerformIO . glMatrixToM44)
 {-# INLINE m44GLmatrix #-}
 
+-- | An isomorphism between GL and linear one-dimensional points
 vertex1P :: Iso' (Point V1 a) (Vertex1 a)
 vertex1P = iso to from
   where
@@ -44,6 +52,7 @@
     from (Vertex1 x) = P (V1 x)
 {-# INLINABLE vertex1P #-}
 
+-- | An isomorphism between GL and linear two-dimensional points
 vertex2P :: Iso' (Point V2 a) (Vertex2 a)
 vertex2P = iso to from
   where
@@ -51,6 +60,7 @@
     from (Vertex2 x y) = P (V2 x y)
 {-# INLINABLE vertex2P #-}
 
+-- | An isomorphism between GL and linear three-dimensional points
 vertex3P :: Iso' (Point V3 a) (Vertex3 a)
 vertex3P = iso to from
   where
@@ -58,6 +68,7 @@
     from (Vertex3 x y z) = P (V3 x y z)
 {-# INLINABLE vertex3P #-}
 
+-- | An isomorphism between GL and linear four-dimensional points
 vertex4P :: Iso' (Point V4 a) (Vertex4 a)
 vertex4P = iso to from
   where
@@ -65,6 +76,7 @@
     from (Vertex4 x y z w) = P (V4 x y z w)
 {-# INLINABLE vertex4P #-}
 
+-- | An isomorphism between GL and linear one-dimensional vectors
 vector1V :: Iso' (V1 a) (Vector1 a)
 vector1V = iso to from
   where
@@ -72,6 +84,7 @@
     from (Vector1 x) = V1 x
 {-# INLINABLE vector1V #-}
 
+-- | An isomorphism between GL and linear two-dimensional vectors
 vector2V :: Iso' (V2 a) (Vector2 a)
 vector2V = iso to from
   where
@@ -79,6 +92,7 @@
     from (Vector2 x y) = V2 x y
 {-# INLINABLE vector2V #-}
 
+-- | An isomorphism between GL and linear three-dimensional vectors
 vector3V :: Iso' (V3 a) (Vector3 a)
 vector3V = iso to from
   where
@@ -86,6 +100,7 @@
     from (Vector3 x y z) = V3 x y z
 {-# INLINABLE vector3V #-}
 
+-- | An isomorphism between GL and linear four-dimensional vectors
 vector4V :: Iso' (V4 a) (Vector4 a)
 vector4V = iso to from
   where
diff --git a/src/Linear/OpenGL/MatrixUniforms.hs b/src/Linear/OpenGL/MatrixUniforms.hs
new file mode 100644
--- /dev/null
+++ b/src/Linear/OpenGL/MatrixUniforms.hs
@@ -0,0 +1,78 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE UndecidableInstances #-}
+
+module Linear.OpenGL.MatrixUniforms () where
+
+import Data.Maybe (fromJust)
+import Data.Proxy
+import Foreign
+
+import Graphics.Rendering.OpenGL.GL hiding (Proxy)
+import Graphics.Rendering.OpenGL.Raw.Core31
+
+import Data.Distributive
+import Linear
+
+maxComponentSize :: Int
+maxComponentSize = sizeOf (undefined :: GLint) `max` sizeOf (undefined :: GLfloat)
+
+maxNumComponents :: Int
+maxNumComponents = 16
+
+maxUniformBufferSize :: Int
+maxUniformBufferSize = maxComponentSize * maxNumComponents
+
+class UniformMatrix f where
+    setUniformMatrix :: Proxy (f (f a)) -> GLint -> GLsizei -> GLboolean -> Ptr GLfloat -> IO ()
+
+instance UniformMatrix V2 where
+    setUniformMatrix _ = glUniformMatrix2fv
+instance UniformMatrix V3 where
+    setUniformMatrix _ = glUniformMatrix3fv
+instance UniformMatrix V4 where
+    setUniformMatrix _ = glUniformMatrix4fv
+
+getInteger1 :: GLenum -> IO GLint
+getInteger1 e = alloca $ \buf -> do
+    glGetIntegeri_v e 1 buf
+    peek buf
+
+uniformMat :: forall f a.
+              ( Storable (f (f a)), UniformMatrix f
+              , Distributive f, Conjugate a)
+           => UniformLocation -> StateVar (f (f a))
+uniformMat (UniformLocation loc) = makeStateVar getter setter
+  where
+    getter = do
+        -- Use this once @Program@ is exported
+        --Program p <- fmap fromJust $ get currentProgram
+        p <- fromIntegral `fmap` getInteger1 gl_CURRENT_PROGRAM
+        allocaBytes maxUniformBufferSize $ \buf -> do
+            glGetUniformfv p loc (castPtr buf)
+            adjoint `fmap` peek buf
+    setter mat = do
+        program <- fmap fromJust $ get currentProgram
+        allocaBytes maxUniformBufferSize $ \buf -> do
+            poke buf (adjoint mat)
+            setUniformMatrix (Proxy :: Proxy (f (f a))) loc 1 0 (castPtr buf)
+
+uniformvMat :: forall f a. UniformMatrix f
+            => UniformLocation -> GLsizei -> Ptr (f (f a)) -> IO ()
+uniformvMat (UniformLocation loc) count ptr =
+    setUniformMatrix (Proxy :: Proxy (f (f a))) loc count 0 (castPtr ptr)
+
+-- | given in column-major order
+instance Uniform (V2 (V2 GLfloat)) where
+    uniform = uniformMat
+    uniformv = uniformvMat
+
+-- | given in column-major order
+instance Uniform (V3 (V3 GLfloat)) where
+    uniform = uniformMat
+    uniformv = uniformvMat
+
+-- | given in column-major order
+instance Uniform (V4 (V4 GLfloat)) where
+    uniform = uniformMat
+    uniformv = uniformvMat
