staticModelResource :: StaticProgramChannels
                    -> Material
                    -> Texture
                    -> Model
                    -> Game s StaticModelResource

staticModelResource (StaticProgramChannels vertChan normChan texChan) material texture model = do
    RenderModel elements _ numVertices <- gameIO . renderModelFromModel $ model
    elementBuf <- newBuffer
    vao        <- newVAO
    boxes      <- gameIO $ modelBoxes model

    gameIO $ do

        let elemSize  = 32
            elemSize' = fromIntegral elemSize
            n         = numVertices

        bindVAO vao

        bindBuffer ArrayBuffer elementBuf
        bufferData' ArrayBuffer (fromIntegral $ elemSize*n) elements StaticDraw

        attribVAOPointer vertChan 3 gl_FLOAT False elemSize' 0
        attribVAOPointer normChan 3 gl_FLOAT False elemSize' 12
        attribVAOPointer texChan  2 gl_FLOAT False elemSize' 24

        enableVAOAttrib vertChan
        enableVAOAttrib normChan
        enableVAOAttrib texChan

    rkey <- register $ do
        putStrLn "Releasing static model resource"
        clean vao
        clean elementBuf

    return $ StaticModelResource
        vao (unsafeCoerce numVertices) material texture boxes rkey

-- | Create a renderer from the given model resource.
staticModelResource :: StaticProgramChannels
                    -> Material
                    -> Texture
                    -> Model
                    -> Game s StaticModelResource
staticModelResource (StaticProgramChannels vertChan normChan texChan) material texture model = do
    RenderModel elements _ numVertices <- gameIO . renderModelFromModel $ model
    elementBuf <- newBuffer
    vao        <- newVAO
    boxes      <- gameIO $ modelBoxes model

    gameIO $ do

        let elemSize  = 32
            elemSize' = fromIntegral elemSize
            n         = numVertices

        bindVAO vao

        bindBuffer ArrayBuffer elementBuf
        bufferData' ArrayBuffer (fromIntegral $ elemSize*n) elements StaticDraw

        attribVAOPointer vertChan 3 gl_FLOAT False elemSize' 0
        attribVAOPointer normChan 3 gl_FLOAT False elemSize' 12
        attribVAOPointer texChan  2 gl_FLOAT False elemSize' 24

        enableVAOAttrib vertChan
        enableVAOAttrib normChan
        enableVAOAttrib texChan

    rkey <- register $ do
        putStrLn "Releasing static model resource"
        clean vao
        clean elementBuf

    return $ StaticModelResource
        vao (unsafeCoerce numVertices) material texture boxes rkey

-- | Create a renderer from the given model resource.
staticModelResource (StaticProgramChannels vertChan normChan texChan) material texture model = do
    RenderModel elements _ numVertices <- gameIO . renderModelFromModel $ model
    elementBuf <- newBuffer
    vao        <- newVAO
    boxes      <- gameIO $ modelBoxes model

    gameIO $ do

        let elemSize  = 32
            elemSize' = fromIntegral elemSize
            n         = numVertices

        bindVAO vao

        bindBuffer ArrayBuffer elementBuf
        bufferData' ArrayBuffer (fromIntegral $ elemSize*n) elements StaticDraw

        attribVAOPointer vertChan 3 gl_FLOAT False elemSize' 0
        attribVAOPointer normChan 3 gl_FLOAT False elemSize' 12
        attribVAOPointer texChan  2 gl_FLOAT False elemSize' 24

        enableVAOAttrib vertChan
        enableVAOAttrib normChan
        enableVAOAttrib texChan

    rkey <- register $ do
        putStrLn "Releasing static model resource"
        clean vao
        clean elementBuf

    return $ StaticModelResource
        vao (unsafeCoerce numVertices) material texture boxes rkey

-- | Create a renderer from the given model resource.