diff --git a/src/matrix.cpp b/src/matrix.cpp
index 8f5044b9..ef721d64 100644
--- a/src/matrix.cpp
+++ b/src/matrix.cpp
@@ -80,6 +80,51 @@ template<> void mat4::printf() const
                p[0][3], p[1][3], p[2][3], p[3][3]);
 }
 
+template<> std::ostream &operator<<(std::ostream &stream, ivec2 const &v)
+{
+    return stream << "(" << v.x << ", " << v.y << ")";
+}
+
+template<> std::ostream &operator<<(std::ostream &stream, ivec3 const &v)
+{
+    return stream << "(" << v.x << ", " << v.y << ", " << v.z << ")";
+}
+
+template<> std::ostream &operator<<(std::ostream &stream, ivec4 const &v)
+{
+    return stream << "(" << v.x << ", " << v.y << ", "
+                         << v.z << ", " << v.w << ")";
+}
+
+template<> std::ostream &operator<<(std::ostream &stream, vec2 const &v)
+{
+    return stream << "(" << v.x << ", " << v.y << ")";
+}
+
+template<> std::ostream &operator<<(std::ostream &stream, vec3 const &v)
+{
+    return stream << "(" << v.x << ", " << v.y << ", " << v.z << ")";
+}
+
+template<> std::ostream &operator<<(std::ostream &stream, vec4 const &v)
+{
+    return stream << "(" << v.x << ", " << v.y << ", "
+                         << v.z << ", " << v.w << ")";
+}
+
+template<> std::ostream &operator<<(std::ostream &stream, mat4 const &m)
+{
+    stream << "((" << m[0][0] << ", " << m[1][0]
+            << ", " << m[2][0] << ", " << m[3][0] << "), ";
+    stream << "(" << m[0][1] << ", " << m[1][1]
+           << ", " << m[2][1] << ", " << m[3][1] << "), ";
+    stream << "(" << m[0][2] << ", " << m[1][2]
+           << ", " << m[2][2] << ", " << m[3][2] << "), ";
+    stream << "(" << m[0][3] << ", " << m[1][3]
+           << ", " << m[2][3] << ", " << m[3][3] << "))";
+    return stream;
+}
+
 template<> mat4 mat4::ortho(float left, float right, float bottom,
                             float top, float near, float far)
 {
diff --git a/src/matrix.h b/src/matrix.h
index c5159bf1..6c4ea5d2 100644
--- a/src/matrix.h
+++ b/src/matrix.h
@@ -17,6 +17,7 @@
 #define __LOL_MATRIX_H__
 
 #include <cmath>
+#include <iostream>
 
 namespace lol
 {
@@ -125,7 +126,11 @@ namespace lol
     { \
         using namespace std; \
         return sqrtf((float)sqlen()); \
-    }
+    } \
+    \
+    template<typename U> \
+    friend std::ostream &operator<<(std::ostream &stream, \
+                                    Vec##elems<U> const &v);
 
 template <typename T> struct Vec2;
 template <typename T> struct Vec3;
@@ -232,6 +237,9 @@ template <typename T> struct Mat4
 
     void printf() const;
 
+    template<class U>
+    friend std::ostream &operator<<(std::ostream &stream, Mat4<U> const &m);
+
     inline Mat4<T> operator +(Mat4<T> const val) const
     {
         Mat4<T> ret;