diff options
Diffstat (limited to 'src/Vivant/Terrain.hs')
-rw-r--r-- | src/Vivant/Terrain.hs | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/src/Vivant/Terrain.hs b/src/Vivant/Terrain.hs index 3099177..befee88 100644 --- a/src/Vivant/Terrain.hs +++ b/src/Vivant/Terrain.hs @@ -8,7 +8,7 @@ import qualified Graphics.Rendering.OpenGL as GL import SDL (($=)) import Foreign.Marshal.Alloc (free, malloc) import Foreign.Ptr -import Vivant.Common (vectorSize) +import Vivant.Common (vectorSize, uncurry3) import Foreign.Storable (poke) import Linear @@ -16,27 +16,42 @@ data Terrain = Terrain { terrainWidth :: Int, terrainHeight :: Int, - terrainGeometry :: [[Int]], + terrainGeometry :: [[Float]], terrainRenderer :: Renderer } deriving (Show) +normal :: Num c => (c, c, c) -> (c, c, c) -> (c, c, c) -> (c, c, c) +normal a b c = + transform $ cross (uncurry3 V3 b ^-^ uncurry3 V3 a) (uncurry3 V3 c ^-^ uncurry3 V3 a) + where + transform (V3 a b c) = (a, b, c) + partition - :: (V.Storable a1, Integral a2, Num a1) => [[a2]] -> V.Vector a1 + :: (V.Storable a1, Enum a1, Num a1) => [[a1]] -> V.Vector a1 partition r = - V.fromList . fmap fromIntegral . concat . concat . + V.fromList . concat . concat . fmap (\(e, y) -> fmap (generateP y) $ zip (zip (uncurry zip e) $ tail (uncurry zip e)) [0..]) $ zip (zip r $ tail r) [0..] where generateP y (((z1, z2), (z3, z4)), x) = + let (n1x, n1y, n1z) = normal (x, y, z1) (x, y+1, z2) (x+1, y, z3) + (n2x, n2y, n2z) = normal (x+1, y+1, z4) (x, y+1, z2) (x+1, y, z3) + in [ x, y, z1 + , -n1x, -n1y, -n1z , x, y+1, z2 + , -n1x, -n1y, -n1z , x+1, y, z3 + , -n1x, -n1y, -n1z , x, y+1, z2 + , n2x, n2y, n2z , x+1, y, z3 + , n2x, n2y, n2z , x+1, y+1, z4 + , n2x, n2y, n2z ] -initTerrain :: [[Int]] -> GL.Program -> IO Terrain +initTerrain :: [[Float]] -> GL.Program -> IO Terrain initTerrain g p = do vao <- GL.genObjectName GL.bindVertexArrayObject $= Just vao @@ -48,17 +63,20 @@ initTerrain g p = do V.unsafeWith g' $ \ptr -> GL.bufferData GL.ArrayBuffer $= (vectorSize g', castPtr ptr, GL.StaticDraw) - setVertexAttribute p "position" 3 0 0 + setVertexAttribute p "position" 3 6 0 + setVertexAttribute p "normal" 3 6 3 GL.bindVertexArrayObject $= Nothing + let h = length g + w = length (head g) + modelMatrix = mkTransformation (axisAngle (V3 0 0 0) 0) + (V3 (- fromIntegral w / 2) (- fromIntegral h / 2) 0) + modelP <- malloc - let modelMatrix = mkTransformation (axisAngle (V3 0 0 0) 0) (V3 (-2.5) (-2.5) 0) poke modelP modelMatrix - let h = length g - w = length (head g) - return $ Terrain w h g (Renderer (Just p) (Just vao) modelP 72) + return $ Terrain w h g (Renderer (Just p) (Just vao) modelP ((w + 2) * (h + 2) * 8)) destroyTerrain :: Terrain -> IO () destroyTerrain t = |