diff --git a/Graphics/Gloss/Internals/Data/Picture.hs b/Graphics/Gloss/Internals/Data/Picture.hs
--- a/Graphics/Gloss/Internals/Data/Picture.hs
+++ b/Graphics/Gloss/Internals/Data/Picture.hs
@@ -63,7 +63,7 @@
         -- | A blank picture, with nothing in it.
         = Blank
 
-        -- | A convex polygon filled with a solid color.
+        -- | A polygon filled with a solid color.
         | Polygon       Path
 
         -- | A line along an arbitrary path.
diff --git a/Graphics/Gloss/Internals/Rendering/Picture.hs b/Graphics/Gloss/Internals/Rendering/Picture.hs
--- a/Graphics/Gloss/Internals/Rendering/Picture.hs
+++ b/Graphics/Gloss/Internals/Rendering/Picture.hs
@@ -7,6 +7,7 @@
 import Graphics.Gloss.Internals.Rendering.State
 import Graphics.Gloss.Internals.Rendering.Common
 import Graphics.Gloss.Internals.Rendering.Circle
+import Graphics.Gloss.Internals.Rendering.Polygon
 import Graphics.Gloss.Internals.Rendering.Bitmap
 import Graphics.Gloss.Internals.Data.Picture
 import Graphics.Gloss.Internals.Data.Color
@@ -65,8 +66,7 @@
                 $ vertexPFs path
 
          | otherwise
-         -> GL.renderPrimitive GL.Polygon
-                $ vertexPFs path
+         -> renderComplexPolygon path
 
         -- circle
         Circle radius
diff --git a/Graphics/Gloss/Internals/Rendering/Polygon.hs b/Graphics/Gloss/Internals/Rendering/Polygon.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Gloss/Internals/Rendering/Polygon.hs
@@ -0,0 +1,72 @@
+{-# OPTIONS_HADDOCK hide #-}
+
+module Graphics.Gloss.Internals.Rendering.Polygon(renderComplexPolygon) where
+import Graphics.Gloss.Internals.Rendering.Common
+import Graphics.Rendering.OpenGL.GLU.Tessellation
+import qualified Graphics.Rendering.OpenGL.GL           as GL
+
+combiner :: a -> b -> ()
+combiner _ _ = ()
+
+
+-- written this way to measurably improve performance
+zipLoop :: [a] -> [(a,a)]
+zipLoop [] = []
+zipLoop (x:xs) = go x xs where
+  go y [] = [(y,x)]
+  go y (z:rs) = (y,z) : go z rs
+
+zipWithLoop :: (a->a->b) -> [a] -> [b]
+zipWithLoop f = map (uncurry f) . zipLoop
+
+-- signed angle between 2 vectors
+-- https://stackoverflow.com/a/16544330/1779797
+-- Note: `isConvex` would remain correct if this returned a value between theta*7/2pi and theta*7/4pi which probably provides an opportunity for optimisation
+angle :: (Float,Float) -> (Float,Float) -> Float
+angle (x1,y1) (x2,y2) = let dot = x1*x2 + y1*y2 -- cos theta * |v1||v2|
+                            det = y2*x1 - x2*y1 -- sin theta * |v1||v2|
+                        in atan2 det dot
+
+
+-- Approximating 2pi by 7 is reasonable here.
+-- The total rotation theoretically must be a multiple of 2pi,
+-- so a little generosity doesn't break anything, but might save some cases that would fail due to floating point errors
+isConvex :: [(Float,Float)] -> Bool
+isConvex ps =
+    -- check that it doesn't turn more than one full circle in total
+    all (\theta -> (theta <= 7) && (theta > -7)) $
+    scanl angleAdd 0 $ -- check that the path's direction is consistent
+    zipWithLoop angle $ -- compute angles of turns at each vertex
+    filter (/= (0,0)) $ -- discard edges arising from duplicated vertices
+    zipWithLoop (\(x1,y1) (x2,y2) -> (x2-x1,y2-y1) ) -- produce vectors for each edge
+        ps
+  where
+    -- Combine angles, but return a value greater than 7 if they have opposite signs
+    angleAdd :: Float -> Float -> Float
+    angleAdd a b = if signum a*signum b < -0.5 then 10 else a + b
+
+renderComplexPolygon :: [(Float,Float)] -> IO ()
+renderComplexPolygon path = if isConvex path
+  then GL.renderPrimitive GL.Polygon $ vertexPFs path
+  else do
+    Triangulation ts <- triangulate TessWindingOdd 0 ( GL.Normal3 0 0 1) combiner
+      (ComplexPolygon [ComplexContour [AnnotatedVertex (GL.Vertex3 (realToFrac a) (realToFrac b) 0) () | (a,b) <- path]])
+    GL.renderPrimitive GL.Triangles (trisToGLVertices ts)
+    return ()
+
+trisToGLVertices ::    [Triangle a] -> IO ()
+trisToGLVertices []    = return ()
+trisToGLVertices ((Triangle (AnnotatedVertex v1 _) (AnnotatedVertex v2 _) (AnnotatedVertex v3 _)) : rest)
+ = do   GL.vertex $ v1
+        GL.vertex $ v2
+        GL.vertex $ v3
+        trisToGLVertices rest
+{-# INLINE trisToGLVertices #-}
+
+
+vertexPFs ::    [(Float, Float)] -> IO ()
+vertexPFs []    = return ()
+vertexPFs ((x, y) : rest)
+ = do   GL.vertex $ GL.Vertex2 (gf x) (gf y)
+        vertexPFs rest
+{-# INLINE vertexPFs #-}
diff --git a/gloss-rendering.cabal b/gloss-rendering.cabal
--- a/gloss-rendering.cabal
+++ b/gloss-rendering.cabal
@@ -1,5 +1,5 @@
 name:           gloss-rendering
-version:        1.13.1.2
+version:        1.13.2.1
 license:        MIT
 license-file:   LICENSE
 author:         Elise Huard
@@ -35,12 +35,13 @@
         Graphics.Gloss.Internals.Rendering.Common
         Graphics.Gloss.Internals.Rendering.Picture
         Graphics.Gloss.Internals.Rendering.State
+        Graphics.Gloss.Internals.Rendering.Polygon
 
   build-depends:
           base                          >= 4.8 && < 5
         , bmp                           == 1.2.*
-        , bytestring                    == 0.11.*
-        , containers                    >= 0.5 && < 0.7
+        , bytestring                    >= 0.11 && < 0.13
+        , containers                    >= 0.5 && < 0.8
         , GLUT                          == 2.7.*
         , OpenGL                        >= 2.12 && < 3.1
 
