should work - but GL crashes internally somewhere with unlimited allocation of memory
This commit is contained in:
parent
0c1bdad465
commit
ce055339ec
@ -28,5 +28,6 @@ executable Pioneers
|
|||||||
distributive >=0.3.2 && <0.4,
|
distributive >=0.3.2 && <0.4,
|
||||||
linear >=1.3.1 && <1.4,
|
linear >=1.3.1 && <1.4,
|
||||||
lens >=3.10.1 && <3.11,
|
lens >=3.10.1 && <3.11,
|
||||||
SDL2 >= 0.1.0
|
SDL2 >= 0.1.0,
|
||||||
|
time >=1.4.0 && <1.5
|
||||||
|
|
||||||
|
123
src/Main.hs
123
src/Main.hs
@ -5,14 +5,19 @@ module Main where
|
|||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
import Control.Monad (unless, void, when)
|
import Control.Monad (unless, void, when)
|
||||||
import Control.Monad.Trans.Maybe (MaybeT (..), runMaybeT)
|
import Control.Monad.Trans.Maybe (MaybeT (..), runMaybeT)
|
||||||
-- data consistency
|
|
||||||
|
-- data consistency/conversion
|
||||||
|
import Control.Concurrent (threadDelay)
|
||||||
import Control.Concurrent.STM (TQueue, atomically,
|
import Control.Concurrent.STM (TQueue, atomically,
|
||||||
newTQueueIO,
|
newTQueueIO,
|
||||||
tryReadTQueue,
|
tryReadTQueue,
|
||||||
writeTQueue)
|
writeTQueue, isEmptyTQueue,
|
||||||
|
STM)
|
||||||
import Control.Monad.RWS.Strict (RWST, ask, asks,
|
import Control.Monad.RWS.Strict (RWST, ask, asks,
|
||||||
evalRWST, get, liftIO,
|
evalRWST, get, liftIO,
|
||||||
modify, put)
|
modify, put)
|
||||||
|
import Data.Distributive (distribute, collect)
|
||||||
|
|
||||||
-- FFI
|
-- FFI
|
||||||
import Foreign (Ptr, castPtr, with)
|
import Foreign (Ptr, castPtr, with)
|
||||||
import Foreign.C (CFloat)
|
import Foreign.C (CFloat)
|
||||||
@ -27,6 +32,7 @@ import Graphics.UI.SDL as SDL
|
|||||||
-- Render
|
-- Render
|
||||||
import qualified Graphics.Rendering.OpenGL.GL as GL
|
import qualified Graphics.Rendering.OpenGL.GL as GL
|
||||||
import Graphics.Rendering.OpenGL.Raw.Core31
|
import Graphics.Rendering.OpenGL.Raw.Core31
|
||||||
|
import Data.Time (getCurrentTime, UTCTime, diffUTCTime)
|
||||||
|
|
||||||
-- Our modules
|
-- Our modules
|
||||||
import Map.Map
|
import Map.Map
|
||||||
@ -36,6 +42,8 @@ import Render.Misc (checkError,
|
|||||||
import Render.Render (initRendering,
|
import Render.Render (initRendering,
|
||||||
initShader)
|
initShader)
|
||||||
|
|
||||||
|
import qualified Debug.Trace as D (trace)
|
||||||
|
|
||||||
--Static Read-Only-State
|
--Static Read-Only-State
|
||||||
data Env = Env
|
data Env = Env
|
||||||
{ envEventsChan :: TQueue Event
|
{ envEventsChan :: TQueue Event
|
||||||
@ -49,6 +57,7 @@ data State = State
|
|||||||
{ stateWindowWidth :: !Int
|
{ stateWindowWidth :: !Int
|
||||||
, stateWindowHeight :: !Int
|
, stateWindowHeight :: !Int
|
||||||
, stateWinClose :: !Bool
|
, stateWinClose :: !Bool
|
||||||
|
, stateClock :: !UTCTime
|
||||||
--- IO
|
--- IO
|
||||||
, stateXAngle :: !Double
|
, stateXAngle :: !Double
|
||||||
, stateYAngle :: !Double
|
, stateYAngle :: !Double
|
||||||
@ -81,21 +90,24 @@ type Pioneers = RWST Env () State IO
|
|||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
SDL.withInit [InitEverything] $ do --also: InitNoParachute -> faster, without parachute!
|
SDL.withInit [InitVideo, InitAudio] $ do --also: InitNoParachute -> faster, without parachute!
|
||||||
window <- SDL.createWindow "Pioneers" (Position 100 100) (Size 1024 768) [WindowOpengl -- we want openGL
|
window <- SDL.createWindow "Pioneers" (Position 1500 100) (Size 1024 768) [WindowOpengl -- we want openGL
|
||||||
,WindowShown -- window should be visible
|
,WindowShown -- window should be visible
|
||||||
,WindowResizable -- and resizable
|
,WindowResizable -- and resizable
|
||||||
,WindowInputFocus -- focused (=> active)
|
,WindowInputFocus -- focused (=> active)
|
||||||
,WindowMouseFocus -- Mouse into it
|
,WindowMouseFocus -- Mouse into it
|
||||||
--,WindowInputGrabbed-- never let go of input (KB/Mouse)
|
--,WindowInputGrabbed-- never let go of input (KB/Mouse)
|
||||||
]
|
]
|
||||||
|
|
||||||
(Size fbWidth fbHeight) <- glGetDrawableSize window
|
(Size fbWidth fbHeight) <- glGetDrawableSize window
|
||||||
initRendering
|
initRendering
|
||||||
--generate map vertices
|
--generate map vertices
|
||||||
(mapBuffer, vert) <- getMapBufferObject
|
(mapBuffer, vert) <- getMapBufferObject
|
||||||
(ci, ni, vi, pri, vii, mi, nmi) <- initShader
|
(ci, ni, vi, pri, vii, mi, nmi) <- initShader
|
||||||
|
putStrLn "foo"
|
||||||
eventQueue <- newTQueueIO :: IO (TQueue Event)
|
eventQueue <- newTQueueIO :: IO (TQueue Event)
|
||||||
|
putStrLn "foo"
|
||||||
|
now <- getCurrentTime
|
||||||
|
putStrLn "foo"
|
||||||
|
|
||||||
let zDistClosest = 10
|
let zDistClosest = 10
|
||||||
zDistFarthest = zDistClosest + 20
|
zDistFarthest = zDistClosest + 20
|
||||||
@ -135,23 +147,83 @@ main = do
|
|||||||
, mapVert = vert
|
, mapVert = vert
|
||||||
, stateFrustum = frust
|
, stateFrustum = frust
|
||||||
, stateWinClose = False
|
, stateWinClose = False
|
||||||
|
, stateClock = now
|
||||||
}
|
}
|
||||||
|
|
||||||
|
putStrLn "init done."
|
||||||
void $ evalRWST (adjustWindow >> run) env state
|
void $ evalRWST (adjustWindow >> run) env state
|
||||||
|
|
||||||
destroyWindow window
|
destroyWindow window
|
||||||
|
|
||||||
|
-- Render-Pipeline
|
||||||
|
|
||||||
|
draw :: Pioneers ()
|
||||||
|
draw = do
|
||||||
|
env <- ask
|
||||||
|
state <- get
|
||||||
|
let xa = stateXAngle state
|
||||||
|
ya = stateYAngle state
|
||||||
|
(GL.UniformLocation proj) = shdrProjMatIndex state
|
||||||
|
(GL.UniformLocation nmat) = shdrNormalMatIndex state
|
||||||
|
(GL.UniformLocation vmat) = shdrViewMatIndex state
|
||||||
|
vi = shdrVertexIndex state
|
||||||
|
ni = shdrNormalIndex state
|
||||||
|
ci = shdrColorIndex state
|
||||||
|
numVert = mapVert state
|
||||||
|
map' = stateMap state
|
||||||
|
frust = stateFrustum state
|
||||||
|
camX = statePositionX state
|
||||||
|
camY = statePositionY state
|
||||||
|
zDist = stateZDist state
|
||||||
|
liftIO $ do
|
||||||
|
--(vi,GL.UniformLocation proj) <- initShader
|
||||||
|
GL.clear [GL.ColorBuffer, GL.DepthBuffer]
|
||||||
|
checkError "foo"
|
||||||
|
--set up projection (= copy from state)
|
||||||
|
with (distribute $ frust) $ \ptr ->
|
||||||
|
glUniformMatrix4fv proj 1 0 (castPtr (ptr :: Ptr (M44 CFloat)))
|
||||||
|
checkError "foo"
|
||||||
|
|
||||||
|
--set up camera
|
||||||
|
let ! cam = getCam (camX,camY) zDist xa ya
|
||||||
|
with (distribute $ cam) $ \ptr ->
|
||||||
|
glUniformMatrix4fv vmat 1 0 (castPtr (ptr :: Ptr (M44 CFloat)))
|
||||||
|
checkError "foo"
|
||||||
|
|
||||||
|
--set up normal--Mat transpose((model*camera)^-1)
|
||||||
|
let normal = (case inv33 ((fmap (^._xyz) cam) ^. _xyz) of
|
||||||
|
(Just a) -> a
|
||||||
|
Nothing -> eye3) :: M33 CFloat
|
||||||
|
nmap = (collect (fmap id) normal) :: M33 CFloat --transpose...
|
||||||
|
|
||||||
|
with (distribute $ nmap) $ \ptr ->
|
||||||
|
glUniformMatrix3fv nmat 1 0 (castPtr (ptr :: Ptr (M33 CFloat)))
|
||||||
|
|
||||||
|
checkError "nmat"
|
||||||
|
|
||||||
|
GL.bindBuffer GL.ArrayBuffer GL.$= Just map'
|
||||||
|
GL.vertexAttribPointer ci GL.$= fgColorIndex
|
||||||
|
GL.vertexAttribArray ci GL.$= GL.Enabled
|
||||||
|
GL.vertexAttribPointer ni GL.$= fgNormalIndex
|
||||||
|
GL.vertexAttribArray ni GL.$= GL.Enabled
|
||||||
|
GL.vertexAttribPointer vi GL.$= fgVertexIndex
|
||||||
|
GL.vertexAttribArray vi GL.$= GL.Enabled
|
||||||
|
checkError "beforeDraw"
|
||||||
|
|
||||||
|
GL.drawArrays GL.Triangles 0 numVert
|
||||||
|
checkError "draw"
|
||||||
|
|
||||||
|
|
||||||
-- Main game loop
|
-- Main game loop
|
||||||
|
|
||||||
run :: Pioneers ()
|
run :: Pioneers ()
|
||||||
run = do
|
run = do
|
||||||
win <- asks envWindow
|
win <- asks envWindow
|
||||||
events <- asks envEventsChan
|
|
||||||
|
|
||||||
-- draw Scene
|
-- draw Scene
|
||||||
--draw
|
--draw
|
||||||
liftIO $ do
|
liftIO $ do
|
||||||
glSwapWindow win
|
glSwapWindow win
|
||||||
submitEvents events
|
|
||||||
-- getEvents & process
|
-- getEvents & process
|
||||||
processEvents
|
processEvents
|
||||||
|
|
||||||
@ -209,9 +281,19 @@ run = do
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
-}
|
-}
|
||||||
|
mt <- liftIO $ do
|
||||||
|
now <- getCurrentTime
|
||||||
unless (stateWinClose state) run
|
diff <- return $ diffUTCTime now (stateClock state) -- get time-diffs
|
||||||
|
sleepAmount <- return $ floor (max 0 (0.04 - diff))*1000000 -- get time until next frame in microseconds
|
||||||
|
threadDelay sleepAmount
|
||||||
|
return now
|
||||||
|
-- set state with new clock-time
|
||||||
|
modify $ \s -> s
|
||||||
|
{
|
||||||
|
stateClock = mt
|
||||||
|
}
|
||||||
|
shouldClose <- return $ stateWinClose state
|
||||||
|
unless shouldClose run
|
||||||
|
|
||||||
adjustWindow :: Pioneers ()
|
adjustWindow :: Pioneers ()
|
||||||
adjustWindow = do
|
adjustWindow = do
|
||||||
@ -229,16 +311,15 @@ adjustWindow = do
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
-- | Writes all Events atomically to global Queue for further processing.
|
|
||||||
submitEvents :: TQueue Event -> IO ()
|
|
||||||
submitEvents q = do
|
|
||||||
event <- pollEvent
|
|
||||||
case event of
|
|
||||||
Nothing -> return ()
|
|
||||||
Just e -> do
|
|
||||||
atomically $ writeTQueue q e
|
|
||||||
submitEvents q
|
|
||||||
|
|
||||||
processEvents :: Pioneers ()
|
processEvents :: Pioneers ()
|
||||||
processEvents = do
|
processEvents = do
|
||||||
return ()
|
me <- liftIO pollEvent
|
||||||
|
case me of
|
||||||
|
Just e -> do
|
||||||
|
processEvent e
|
||||||
|
processEvents
|
||||||
|
Nothing -> return ()
|
||||||
|
|
||||||
|
processEvent :: Event -> Pioneers ()
|
||||||
|
processEvent e = do
|
||||||
|
liftIO $ putStrLn (show e)
|
Loading…
Reference in New Issue
Block a user