diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Main.hs | 120 |
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 |
