module Vivant.Renderer (Renderer (..), getUniformLocation, destroyRenderer, render, setVertexAttribute) where import Foreign.Marshal.Alloc (free) import Foreign.Ptr import Foreign.Storable (sizeOf) import qualified Graphics.GL.Functions as GL (glUniformMatrix4fv) import Graphics.Rendering.OpenGL (($=)) import qualified Graphics.Rendering.OpenGL as GL import Linear data Renderer = Renderer { rendererProgram :: Maybe GL.Program, rendererVao :: Maybe GL.VertexArrayObject, rendererModelP :: Ptr (M44 Float), rendererTriangleNum :: Int } deriving (Show) getUniformLocation :: GL.UniformLocation -> GL.GLint getUniformLocation (GL.UniformLocation i) = i render :: Renderer -> IO () render r@Renderer {rendererProgram = Just p} = do -- GL.currentProgram $= rendererProgram r GL.bindVertexArrayObject $= rendererVao r model <- getUniformLocation <$> GL.uniformLocation p "model" GL.glUniformMatrix4fv model 1 1 (castPtr (rendererModelP r)) GL.drawArrays GL.Triangles 0 (fromIntegral $ rendererTriangleNum r) destroyRenderer :: Renderer -> IO () destroyRenderer r = free $ rendererModelP r setVertexAttribute :: GL.Program -> String -> Int -> Int -> Int -> IO () setVertexAttribute program name vertices stride offset = do let floatSize = sizeOf (1.0 :: Float) attrib <- GL.get $ GL.attribLocation program name GL.vertexAttribPointer attrib $= ( GL.ToFloat, GL.VertexArrayDescriptor (fromIntegral vertices) GL.Float (fromIntegral $ stride * floatSize) (plusPtr nullPtr (offset * floatSize)) ) GL.vertexAttribArray attrib $= GL.Enabled