aboutsummaryrefslogtreecommitdiffstats
path: root/src/Vivant/Terrain.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Vivant/Terrain.hs')
-rw-r--r--src/Vivant/Terrain.hs38
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 =