summaryrefslogtreecommitdiff
path: root/src/Main.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Main.hs')
-rw-r--r--src/Main.hs120
1 files changed, 120 insertions, 0 deletions
diff --git a/src/Main.hs b/src/Main.hs
new file mode 100644
index 0000000..b0dccb9
--- /dev/null
+++ b/src/Main.hs
@@ -0,0 +1,120 @@
+{-# LANGUAGE DisambiguateRecordFields #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedRecordDot #-}
+
+-- |
+-- - Module : Game
+-- - Description : runs game
+-- - Copyright : 2025 Andromeda
+-- - License : BSD 3-clause
+-- - Maintainer : Matrix @Andromeda:tchncs.de
+-- - Stability : Experimental
+module Main
+ ( main,
+ )
+where
+
+import Control.Lens ((^.))
+import Data.IORef (newIORef)
+import Data.List (nub)
+import GHC.Float (double2Float)
+import Game.Internal
+import Game.Internal.Types
+import Graphics.Rendering.OpenGL (($=))
+import qualified Graphics.Rendering.OpenGL as GL
+import qualified Graphics.UI.GLFW as GLFW
+import Linear (V3 (..), V4 (..), (*^), _w, _xyz, _y)
+import qualified Linear as L
+
+-- | Main function runs game
+main :: IO ()
+main = do
+ _ <- GLFW.init
+ GLFW.defaultWindowHints
+ -- OpenGL core >=3.3
+ GLFW.windowHint $ GLFW.WindowHint'ContextVersionMajor 3
+ GLFW.windowHint $ GLFW.WindowHint'ContextVersionMinor 3
+ GLFW.windowHint $ GLFW.WindowHint'OpenGLProfile GLFW.OpenGLProfile'Core
+ -- MSAA
+ GLFW.windowHint $ GLFW.WindowHint'Samples $ Just 8
+ -- alpha
+ -- create window
+ monitor <- GLFW.getPrimaryMonitor
+ Just window <- GLFW.createWindow 256 256 "hs-game" monitor Nothing
+ GLFW.makeContextCurrent $ Just window
+ -- add callbacks
+ GLFW.setWindowCloseCallback window $ Just shutdownWindow
+ GLFW.setWindowSizeCallback window $ Just resizeWindow
+ GLFW.setKeyCallback window $ Just (keyPressed Nothing)
+ GLFW.setCursorInputMode window GLFW.CursorInputMode'Hidden
+ GLFW.setCursorPosCallback window $ Just (cursorPosHandler Nothing)
+
+ loop window 0 update view modelRef
+
+--------------------------------------------------------------------------------
+-- Elm-like data structures
+--------------------------------------------------------------------------------
+
+-- | update function
+update :: Float -> Model -> Model
+update dt model = model
+
+-- | views the model
+view :: GLFW.Window -> Model -> IO ()
+view window model = do
+ let camx = (\(V4 x _ _ _) -> x) model.camera.camPos
+ camy = (\(V4 _ y _ _) -> y) model.camera.camPos
+ camz = (\(V4 _ _ z _) -> z) model.camera.camPos
+ camw = (\(V4 _ _ _ w) -> w) model.camera.camPos
+
+ -- TODO optimise this inefficient pos
+ let objarr = map (v3tov4 camw) $ sliceW camw $ initArr
+ (obj, program) <- initResources objarr
+
+ -- fit viewport to window
+ (w, h) <- GLFW.getFramebufferSize window
+ GL.viewport $= (GL.Position 0 0, GL.Size (fromIntegral w) (fromIntegral h))
+ -- clear screen
+ GL.clearColor $= GL.Color4 1 0 1 1
+ GL.clear [GL.ColorBuffer, GL.DepthBuffer]
+ -- depth
+ GL.depthFunc $= Just GL.Less
+ -- apply transforms
+ let pitch = model.camera.camPitch
+ yaw = model.camera.camYaw
+ forward = V3 (cos pitch * sin yaw) (sin pitch) (cos pitch * cos yaw)
+ viewMatrix =
+ L.lookAt
+ (model.camera.camPos ^. _xyz)
+ ((model.camera.camPos ^. _xyz) - forward)
+ model.wprop.up
+ projectionMatrix =
+ L.perspective 1.2 (fromIntegral w / fromIntegral h) 0.01 1000
+
+ viewGLMatrix <-
+ GL.newMatrix GL.RowMajor $ toGLMatrix viewMatrix ::
+ IO
+ (GL.GLmatrix GL.GLfloat)
+
+ -- load 3d view matrix
+ viewLocation <- GL.get $ GL.uniformLocation program "u_view"
+ GL.uniform viewLocation $= viewGLMatrix
+
+ projectionGLMatrix <-
+ GL.newMatrix GL.RowMajor $ toGLMatrix projectionMatrix ::
+ IO
+ (GL.GLmatrix GL.GLfloat)
+
+ -- load 3d projection matrix
+ projectionLocation <- GL.get $ GL.uniformLocation program "u_projection"
+ GL.uniform projectionLocation $= projectionGLMatrix
+
+ camWLocation <- GL.get $ GL.uniformLocation program "u_cam"
+ GL.uniform camWLocation $= GL.Vector4 camx camy camz camw
+
+ -- draw objects; returns IO []
+ _ <- drawObjects [obj]
+ -- swap to current buffer
+ GLFW.swapBuffers window
+ -- check for interrupts
+ GLFW.pollEvents