{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-} -- | This module provides an entry point for your gelatin -- apps that run on sdl2. module Gelatin.SDL2 ( -- * Backend definitions SDL2Backends(..) -- * Getting a window and the backends , initSDL2Window , startupSDL2BackendsWithWindow -- * Obtaining the backends without a window , startupSDL2BackendsWithConfig , startupSDL2Backends -- * Re-exports , module Gelatin.GL ) where import Control.Monad.Except (MonadError) import Control.Monad.IO.Class (MonadIO, liftIO) import Data.String (fromString) import Gelatin.GL import SDL hiding (Rectangle, Renderer, glBindTexture, glUnbindTexture) -- | A record containing both V2V4 and V2V2 backends. data SDL2Backends = SDL2Backends { backendV2V4 :: Backend GLuint Event V2V4 (V2 Float) Float Raster , backendV2V2 :: Backend GLuint Event V2V2 (V2 Float) Float Raster } -- | Creates and returns an SDL2 window. initSDL2Window :: MonadIO m => WindowConfig -- ^ The window configuration -> String -- ^ The window title. -> m Window initSDL2Window cfg title = liftIO $ do initializeAll w <- createWindow (fromString title) cfg _ <- glCreateContext w return w -- | Start up and return the sdl2 backends using the given window. startupSDL2BackendsWithWindow :: (MonadIO m, MonadError String m) => Window -- ^ The 'Window' to use render into. -> m SDL2Backends startupSDL2BackendsWithWindow window = do sh <- loadSimple2DShader liftIO $ do glEnable GL_BLEND glBlendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA let wsize = do V2 x y <- get $ windowSize window return (fromIntegral x, fromIntegral y) fsize = do V2 x y <- glGetDrawableSize window return (fromIntegral x, fromIntegral y) ctx = Context { ctxFramebufferSize = fsize , ctxWindowSize = wsize } rz = Rez sh ctx ops = glOps rz (updateWindowSDL2 window) pollEvents v2v4 = Backend ops $ glV2V4Compiler rz v2v2 = Backend ops $ glV2V2Compiler rz return $ SDL2Backends v2v4 v2v2 -- | Start up and return the sdl2 backends according to the given -- sdl2 'WindowConfig'. startupSDL2BackendsWithConfig :: (MonadIO m, MonadError String m) => WindowConfig -- ^ The configuration used to set up the window. -> String -- ^ The window title -> m SDL2Backends startupSDL2BackendsWithConfig cfg str = do w <- initSDL2Window cfg str startupSDL2BackendsWithWindow w -- | Start up and return the default backends. -- Uses OpenGL 3.3 with debugging turned on. startupSDL2Backends :: (MonadIO m, MonadError String m) => Int -- ^ Window width -> Int -- ^ Window height -> String -- ^ Window title -> Bool -- ^ Whether or not to request a high DPI window. -- Passing 'True' typically results in a framebuffer with 2x -- the window size. -> m SDL2Backends startupSDL2Backends ww wh ws highDPI = do let openGL = defaultOpenGL{ glProfile = Core Debug 3 3 } window = defaultWindow{ windowInitialSize = V2 (fromIntegral ww) (fromIntegral wh) , windowOpenGL = Just openGL , windowResizable = True , windowHighDPI = highDPI } startupSDL2BackendsWithConfig window ws updateWindowSDL2 :: Window -> IO () updateWindowSDL2 = glSwapWindow