aboutsummaryrefslogtreecommitdiffstats
path: root/src/Vivant/Renderer.hs
blob: f66b0d7997ef68b34f59051f7c634677a509dd04 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
module Vivant.Renderer
  (Renderer(..), getUniformLocation, destroyRenderer, render, setVertexAttribute)
where

import qualified Graphics.Rendering.OpenGL as GL
import Linear
import Foreign.Ptr
import qualified Graphics.GL.Functions as GL (glUniformMatrix4fv)
import Graphics.Rendering.OpenGL (($=))
import Foreign.Marshal.Alloc (free)
import Foreign.Storable (sizeOf)

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