module Graphics.Caramia.Internal.OpenGLVersion
( vendor
, renderer
, gles
, openGLVersion
, OpenGLVersion(..)
, shadingLanguageVersion
, shadingLanguageVersions
) where
import Control.Applicative
import Control.Monad
import Data.List (isPrefixOf)
import Data.Maybe
import Data.Set as Set
import Data.Typeable
import Data.Version
import Foreign.C.String
import Foreign.Marshal.Alloc
import Foreign.Ptr
import Foreign.Storable
import Graphics.GL.Core43
import Graphics.GL.Types
import System.IO.Unsafe
import Text.ParserCombinators.ReadP
parse :: String -> Maybe Version
parse s = case words s of
"OpenGL":"ES":"GLSL":"ES":x:_ -> go x
"OpenGL":"ES":x:_ -> go x
x:_ -> go x
_ -> Nothing
where go xs = listToMaybe [ v | (v,"") <- readP_to_S parseVersion xs ]
getString :: GLenum -> IO String
getString = glGetString >=> peekCString . castPtr
vendor :: String
vendor = unsafePerformIO $ getString GL_VENDOR
renderer :: String
renderer = unsafePerformIO $ getString GL_RENDERER
versionString :: String
versionString = unsafePerformIO $ getString GL_VERSION
gles :: Bool
gles = "OpenGL ES" `isPrefixOf` versionString
version :: Version
version = error ("malformed GL version: " ++ versionString) `fromMaybe` parse versionString
data OpenGLVersion = OpenGLVersion !Int !Int
deriving ( Eq, Show, Read, Typeable )
instance Ord OpenGLVersion where
OpenGLVersion ma1 mi1 `compare` OpenGLVersion ma2 mi2 =
if | ma1 > ma2 -> GT
| ma1 < ma2 -> LT
| mi1 > mi2 -> GT
| mi1 < mi2 -> LT
| otherwise -> EQ
openGLVersion :: OpenGLVersion
#ifndef FIXED_OPENGL_MAJOR_VERSION
openGLVersion = OpenGLVersion (head ver) (head $ tail ver)
where
ver = versionBranch version
#else
openGLVersion = OpenGLVersion FIXED_OPENGL_MAJOR_VERSION FIXED_OPENGL_MINOR_VERSION
#endif
shadingLanguageVersionString :: String
shadingLanguageVersionString = unsafePerformIO $ getString GL_SHADING_LANGUAGE_VERSION
shadingLanguageVersion :: Version
shadingLanguageVersion = Version [] [] `fromMaybe` parse shadingLanguageVersionString
shadingLanguageVersions :: Set Version
shadingLanguageVersions
| version >= Version [4,3] [] = unsafePerformIO $ do
n <- alloca $ \p -> do
poke p 0
glGetIntegerv GL_NUM_SHADING_LANGUAGE_VERSIONS p
peek p
versions <- forM [0..fromIntegral n1] $ \i -> do
cs <- glGetStringi GL_SHADING_LANGUAGE_VERSION i
parse <$> peekCString (castPtr cs)
return $ Set.fromList $ catMaybes versions
| otherwise = Set.singleton shadingLanguageVersion