aboutsummaryrefslogtreecommitdiffstats
path: root/src/Vivant.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Vivant.hs')
-rw-r--r--src/Vivant.hs69
1 files changed, 53 insertions, 16 deletions
diff --git a/src/Vivant.hs b/src/Vivant.hs
index 323602f..a3973a5 100644
--- a/src/Vivant.hs
+++ b/src/Vivant.hs
@@ -14,7 +14,7 @@
module Main where
-import Control.Lens ((.~), (^.))
+import Control.Lens ((.~), (^.), (%~))
import Control.Monad
import qualified Data.ByteString as BS
import Data.Fixed (mod')
@@ -23,12 +23,12 @@ import Data.Int (Int32)
import Data.Set (Set)
import qualified Data.Set as Set
import qualified Data.Vector.Storable as V
-import Data.Word (Word32)
+import Data.Word (Word32, Word8)
import Foreign.C.Types
import Foreign.Marshal.Alloc (free, malloc)
import Foreign.Ptr
import Foreign.Storable (poke, sizeOf)
-import qualified Graphics.GL.Functions as GL (glUniformMatrix4fv)
+import qualified Graphics.GL.Compatibility33 as GL
import qualified Graphics.Rendering.OpenGL as GL
import qualified Graphics.Rendering.OpenGL.GL.Shaders.Uniform as GL (UniformLocation (..))
import Linear
@@ -44,6 +44,7 @@ import System.IO
import Vivant.Shader (createProgram)
import Vivant.Renderer
import Vivant.Terrain
+import Vivant.Noise
screenWidth, screenHeight :: CInt
(screenWidth, screenHeight) = (640, 480)
@@ -96,7 +97,8 @@ data MouseInputs = MouseInputs
{ mousePosition :: Point V2 Int32,
mouseRelative :: V2 Int32,
mousePositionOld :: Maybe (V2 Int32),
- mousePressed :: Bool
+ mousePressed :: Bool,
+ mouseWheel :: Int32
}
deriving (Show)
@@ -106,7 +108,8 @@ initialMouse =
{ mousePosition = P (V2 400 300),
mouseRelative = V2 0 0,
mousePositionOld = Nothing,
- mousePressed = False
+ mousePressed = False,
+ mouseWheel = 0
}
main :: IO ()
@@ -137,6 +140,7 @@ main = do
_ <- SDL.glCreateContext window
+ GL.depthFunc $= Just GL.Less
GL.viewport $= (GL.Position 0 0, GL.Size (fromIntegral screenWidth) (fromIntegral screenHeight))
game <- initResources
@@ -173,14 +177,19 @@ parseEvents :: Set SDL.Keysym -> MouseInputs -> IO (Set SDL.Keysym, MouseInputs)
parseEvents keys mouse = do
events <- SDL.pollEvents
let events' = fmap SDL.eventPayload events
- let isMoving = (> 0) . length $ filter mouseMoving events'
let (k, m) = foldr handleEvents (keys, mouse) events'
- return (if isMoving
- then (k, m)
- else (k, m {mouseRelative = V2 0 0}))
+ return
+ . changeIfIn events' mouseWheel (\(k, m) -> (k, m {mouseWheel = 0}))
+ $ changeIfIn events' mouseMoving (\(k, m) -> (k, m {mouseRelative = V2 0 0})) (k, m)
where
mouseMoving (SDL.MouseMotionEvent{}) = True
mouseMoving _ = False
+ mouseWheel (SDL.MouseWheelEvent{}) = True
+ mouseWheel _ = False
+ changeIfIn events event modification initial =
+ if (> 0) . length $ filter event events
+ then initial
+ else modification initial
handleEvents ::
SDL.EventPayload ->
@@ -201,7 +210,7 @@ handleEvents event (k, m) =
SDL.mouseMotionEventRelMotion = vel
}
) ->
- (k, MouseInputs pos vel (mousePositionOld m) (mousePressed m))
+ (k, MouseInputs pos vel (mousePositionOld m) (mousePressed m) (mouseWheel m))
SDL.MouseButtonEvent
(SDL.MouseButtonEventData
{ SDL.mouseButtonEventMotion = SDL.Pressed
@@ -212,6 +221,11 @@ handleEvents event (k, m) =
{ SDL.mouseButtonEventMotion = SDL.Released
}) ->
(k, m {mousePressed = False})
+ SDL.MouseWheelEvent
+ (SDL.MouseWheelEventData
+ { SDL.mouseWheelEventPos = V2 x y
+ }) ->
+ (k, m {mouseWheel = y})
SDL.QuitEvent {} ->
(Set.insert escapeKey k, m)
_ -> (k, m)
@@ -222,8 +236,8 @@ updateMouse mouse game =
{ gameCamera =
(gameCamera game)
{
- cameraPos = newPos,
- cameraFront = normalize (V3 0 0 0 ^-^ newPos),
+ cameraPos = newPos ^+^ (fromIntegral (mouseWheel mouse) *^ newFront),
+ cameraFront = newFront,
cameraUp = newUp
}
}
@@ -235,6 +249,26 @@ updateMouse mouse game =
| otherwise = v
newPos = rotation . cameraPos $ gameCamera game
newUp = rotation . cameraUp $ gameCamera game
+ newFront = normalize (V3 0 0 0 ^-^ newPos)
+
+pixelRenderer :: Double -> Int -> Int -> Word8
+pixelRenderer n x y =
+ doubleToByte $
+ ( ( perlin3
+ permutation
+ ( (fromIntegral x - 32) / 4,
+ (fromIntegral y - 32) / 4,
+ n
+ )
+ )
+ + 1
+ )
+ / 2
+ * 128
+
+createTerrain :: [[Float]]
+createTerrain =
+ fmap (\y -> fmap (\x -> fromIntegral (pixelRenderer 0 x y) / 15) [0..63]) [0..63]
initResources :: IO Game
initResources = do
@@ -254,7 +288,7 @@ initResources = do
viewP <- malloc
projectionP <- malloc
- terrain <- initTerrain [[1, 2, 3, 4], [3, 2, 1, 4], [2, 5, 2, 3], [3, 1, 2, 4]] prog
+ terrain <- initTerrain createTerrain prog
return $
initialGameState
@@ -273,6 +307,9 @@ toRadians = (*) (pi / 180)
scaledMat :: V4 (V4 Float) -> V4 (V4 Float)
scaledMat n = ((n * identity) & _w . _w .~ 1)
+castV3 :: V3 a -> GL.Vector3 a
+castV3 (V3 a b c) = GL.Vector3 a b c
+
draw :: Game -> IO ()
draw game@(Game {gameProgram = Just p, gameVao = Just v, gameTerrain = Just t}) = do
tick <- ticks
@@ -290,7 +327,7 @@ draw game@(Game {gameProgram = Just p, gameVao = Just v, gameTerrain = Just t})
cameraPosition = cameraPos camera
targetPosition = cameraPosition ^+^ cameraFront camera
viewMatrix = lookAt cameraPosition targetPosition (cameraUp camera)
- projectionMatrix = perspective (toRadians 45) (640 / 480) 0.1 100
+ projectionMatrix = perspective (toRadians 45) (640 / 480) 0.1 1000
poke (gameViewP game) viewMatrix
poke (gameProjectionP game) projectionMatrix
@@ -298,8 +335,8 @@ draw game@(Game {gameProgram = Just p, gameVao = Just v, gameTerrain = Just t})
GL.glUniformMatrix4fv view 1 1 (castPtr (gameViewP game))
GL.glUniformMatrix4fv projection 1 1 (castPtr (gameProjectionP game))
- ourColorLoc <- GL.uniformLocation p "ourColour"
- GL.uniform ourColorLoc $= (GL.Vector4 (1 :: Float) 0.5 1 1)
+ ourColorLoc <- GL.uniformLocation p "light_pos"
+ GL.uniform ourColorLoc $= castV3 (cameraPos (gameCamera game))
render $ terrainRenderer t