packages feed

GLUtil 0.6.7.1 → 0.7

raw patch · 5 files changed

+73/−160 lines, 5 filesdep ~OpenGLPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: OpenGL

API changes (from Hackage documentation)

- Graphics.GLUtil.ShaderProgram: loadGeoProgram :: FilePath -> FilePath -> FilePath -> IO ShaderProgram
- Graphics.GLUtil.ShaderProgram: loadGeoProgramWith :: FilePath -> FilePath -> FilePath -> (Program -> IO ()) -> IO ShaderProgram
- Graphics.GLUtil.ShaderProgram: loadShaderExplicit :: FilePath -> FilePath -> ([String], [String]) -> IO ShaderProgram
- Graphics.GLUtil.ShaderProgram: loadShaderProgram :: FilePath -> FilePath -> IO ShaderProgram
- Graphics.GLUtil.Shaders: instance Eq GeometryShader
- Graphics.GLUtil.Shaders: instance ObjectName GeometryShader
- Graphics.GLUtil.Shaders: instance Ord GeometryShader
- Graphics.GLUtil.Shaders: instance Show GeometryShader
- Graphics.GLUtil.Shaders: linkGeoProgram :: [VertexShader] -> [GeometryShader] -> [FragmentShader] -> IO Program
- Graphics.GLUtil.Shaders: linkGeoProgramWith :: [VertexShader] -> [GeometryShader] -> [FragmentShader] -> (Program -> IO ()) -> IO Program
- Graphics.GLUtil.Shaders: loadGeoShader :: FilePath -> IO GeometryShader
+ Graphics.GLUtil.ShaderProgram: simpleShaderExplicit :: FilePath -> FilePath -> ([String], [String]) -> IO ShaderProgram
+ Graphics.GLUtil.ShaderProgram: simpleShaderProgram :: FilePath -> FilePath -> IO ShaderProgram
+ Graphics.GLUtil.ShaderProgram: simpleShaderProgramWith :: FilePath -> FilePath -> (Program -> IO ()) -> IO ShaderProgram
+ Graphics.GLUtil.Textures: class MipMappable t
+ Graphics.GLUtil.Textures: instance MipMappable TextureTarget2D
+ Graphics.GLUtil.Textures: instance MipMappable TextureTargetCubeMap
- Graphics.GLUtil.ShaderProgram: loadShaderProgramWith :: FilePath -> FilePath -> (Program -> IO ()) -> IO ShaderProgram
+ Graphics.GLUtil.ShaderProgram: loadShaderProgramWith :: [(ShaderType, FilePath)] -> (Program -> IO ()) -> IO ShaderProgram
- Graphics.GLUtil.Shaders: linkShaderProgram :: [VertexShader] -> [FragmentShader] -> IO Program
+ Graphics.GLUtil.Shaders: linkShaderProgram :: [Shader] -> IO Program
- Graphics.GLUtil.Shaders: linkShaderProgramWith :: [VertexShader] -> [FragmentShader] -> (Program -> IO ()) -> IO Program
+ Graphics.GLUtil.Shaders: linkShaderProgramWith :: [Shader] -> (Program -> IO ()) -> IO Program
- Graphics.GLUtil.Shaders: loadShader :: Shader s => FilePath -> IO s
+ Graphics.GLUtil.Shaders: loadShader :: ShaderType -> FilePath -> IO Shader
- Graphics.GLUtil.Textures: generateMipmap' :: TextureTarget -> IO ()
+ Graphics.GLUtil.Textures: generateMipmap' :: MipMappable t => t -> IO ()
- Graphics.GLUtil.Textures: withTextures :: TextureTarget -> [TextureObject] -> IO a -> IO a
+ Graphics.GLUtil.Textures: withTextures :: BindableTextureTarget t => t -> [TextureObject] -> IO a -> IO a
- Graphics.GLUtil.Textures: withTexturesAt :: TextureTarget -> [(TextureObject, GLuint)] -> IO a -> IO a
+ Graphics.GLUtil.Textures: withTexturesAt :: BindableTextureTarget t => t -> [(TextureObject, GLuint)] -> IO a -> IO a

Files

GLUtil.cabal view
@@ -1,5 +1,5 @@ Name:                GLUtil-Version:             0.6.7.1+Version:             0.7 Synopsis:            Miscellaneous OpenGL utilities. License:             BSD3 License-file:        LICENSE@@ -51,7 +51,7 @@                        linear >= 1.1.3,                        JuicyPixels >= 3,                        OpenGLRaw >= 1.1,-                       OpenGL >= 2.4 && < 2.9,+                       OpenGL >= 2.9,                        vector >= 0.7   Build-tools:         cpphs   GHC-Options:         -Odph -Wall
examples/example1.hs view
@@ -11,7 +11,7 @@ import Graphics.GLUtil  -- | A value to carry around a shader program and its parameters.-data Shaders = Shaders { program        :: Program+data Shaders = Shaders { getProgram        :: Program                        , fadeFactorU    :: UniformLocation                        , texturesU      :: [UniformLocation]                         , positionA      :: AttribLocation }@@ -40,9 +40,9 @@ -- | Load and compile our GLSL program, and pull out the parameters we -- want. initShaders :: IO Shaders-initShaders = do vs <- loadShader $ "shaders" </> "hello-gl.vert"-                 fs <- loadShader $ "shaders" </> "hello-gl.frag"-                 p <- linkShaderProgram [vs] [fs]+initShaders = do vs <- loadShader VertexShader $ "shaders" </> "hello-gl.vert"+                 fs <- loadShader FragmentShader $ "shaders" </> "hello-gl.frag"+                 p <- linkShaderProgram [vs,fs]                  Shaders p                    <$> get (uniformLocation p "fade_factor")                    <*> mapM (get . uniformLocation p)@@ -84,7 +84,7 @@ drawInit :: Resources -> IO () drawInit r = do clearColor $= Color4 1 1 1 1                 clear [ColorBuffer]-                currentProgram $= Just (program (shaders r))+                currentProgram $= Just (getProgram (shaders r))                 setupTexturing r                 setupGeometry r 
src/Graphics/GLUtil/ShaderProgram.hs view
@@ -1,20 +1,23 @@ -- |Convenience interface for working with GLSL shader -- programs. Provides an interface for setting attributes and -- uniforms.-module Graphics.GLUtil.ShaderProgram (ShaderProgram(..), loadShaderProgram, -                                      loadShaderProgramWith,-                                      loadGeoProgram,-                                      loadGeoProgramWith,-                                      loadShaderExplicit, -                                      getAttrib, enableAttrib, setAttrib, -                                      setUniform, getUniform) where+module Graphics.GLUtil.ShaderProgram +  (-- * The ShaderProgram type+   ShaderProgram(..), +   -- * Simple shader programs utilizing a vertex shader and a+   -- fragment shader+   simpleShaderProgram, simpleShaderProgramWith, simpleShaderExplicit, +   -- * Explicit shader loading+   loadShaderProgramWith,+   -- * Working with ShaderProgram parameters+   getAttrib, enableAttrib, setAttrib, setUniform, getUniform) where import Prelude hiding (lookup) import Control.Applicative ((<$>), (<*>)) import Data.List (find, findIndex, isSuffixOf) import Data.Map.Strict (Map, fromList, lookup) import Data.Maybe (isJust, isNothing, catMaybes)-import Graphics.GLUtil.Shaders (loadShader, loadGeoShader, linkShaderProgram,-                                linkGeoProgramWith)+import Graphics.GLUtil.Shaders (loadShader, linkShaderProgram,+                                linkShaderProgramWith) import Graphics.GLUtil.GLError (throwError) import Graphics.Rendering.OpenGL @@ -29,12 +32,12 @@ -- files. the third argument is a tuple of the attribute names and -- uniform names that will be set in this program. If all attributes -- and uniforms are desired, consider using 'loadShaderProgram'.-loadShaderExplicit :: FilePath -> FilePath -> ([String],[String])-                   -> IO ShaderProgram-loadShaderExplicit vsrc fsrc names =-  do vs <- loadShader vsrc-     fs <- loadShader fsrc-     p <- linkShaderProgram [vs] [fs]+simpleShaderExplicit :: FilePath -> FilePath -> ([String],[String])+                     -> IO ShaderProgram+simpleShaderExplicit vsrc fsrc names =+  do vs <- loadShader VertexShader vsrc+     fs <- loadShader FragmentShader fsrc+     p <- linkShaderProgram [vs,fs]      throwError      (attrs,unis) <- getExplicits p names      return $ ShaderProgram (fromList attrs) (fromList unis) p@@ -42,16 +45,9 @@ -- |Load a 'ShaderProgram' from a vertex shader source file and a -- fragment shader source file. The active attributes and uniforms in -- the linked program are recorded in the 'ShaderProgram'.-loadShaderProgram :: FilePath -> FilePath -> IO ShaderProgram-loadShaderProgram vsrc fsrc = loadShaderProgramWith vsrc fsrc (\_ -> return ())---- |Load a 'ShaderProgram' from a vertex shader source file, a--- geometry shader source file, and a fragment shader source file. The--- active attributes and uniforms in the linked program are recorded--- in the 'ShaderProgram'.-loadGeoProgram :: FilePath -> FilePath -> FilePath -> IO ShaderProgram-loadGeoProgram vsrc gsrc fsrc = -  loadGeoProgramWith vsrc gsrc fsrc (\_ -> return ())+simpleShaderProgram :: FilePath -> FilePath -> IO ShaderProgram+simpleShaderProgram vsrc fsrc = +  simpleShaderProgramWith vsrc fsrc (\_ -> return ())  -- |Load a 'ShaderProgram' from a vertex shader source file and a -- fragment shader source file. The active attributes and uniforms in@@ -60,29 +56,16 @@ -- objects are attached to the program, but before linking. This -- supports the use of 'bindFragDataLocation' to map fragment shader -- outputs.-loadShaderProgramWith :: FilePath -> FilePath -> (Program -> IO ())-                      -> IO ShaderProgram-loadShaderProgramWith vsrc fsrc m = loadProgramWithAux vsrc Nothing fsrc m---- |Load a 'ShaderProgram' from a vertex shader source file, a--- geometry shader source file, and a fragment shader source file. The--- active attributes and uniforms in the linked program are recorded--- in the 'ShaderProgram'. The supplied 'IO' function is applied to--- the new program after shader objects are attached to the program,--- but before linking. This supports the use of 'bindFragDataLocation'--- to map fragment shader outputs.-loadGeoProgramWith :: FilePath -> FilePath -> FilePath -> (Program -> IO ())-                   -> IO ShaderProgram-loadGeoProgramWith vsrc gsrc fsrc m = loadProgramWithAux vsrc (Just gsrc) fsrc m+simpleShaderProgramWith :: FilePath -> FilePath -> (Program -> IO ())+                        -> IO ShaderProgram+simpleShaderProgramWith vsrc fsrc m = +  loadShaderProgramWith [(VertexShader, vsrc), (FragmentShader, fsrc)] m  -- | Helper for @load*Program*@ variants.-loadProgramWithAux :: FilePath -> Maybe FilePath -> FilePath-                   -> (Program -> IO ()) -> IO ShaderProgram-loadProgramWithAux vsrc gsrc fsrc m =-  do vs <- loadShader vsrc-     gs <- maybe (return []) (fmap (:[]) . loadGeoShader) gsrc-     fs <- loadShader fsrc-     p <- linkGeoProgramWith [vs] gs [fs] m+loadShaderProgramWith :: [(ShaderType, FilePath)] -> (Program -> IO ())+                      -> IO ShaderProgram+loadShaderProgramWith sources m =+  do p <- mapM (uncurry loadShader) sources >>= flip linkShaderProgramWith m      throwError      (attrs,unis) <- getActives p      return $ ShaderProgram (fromList attrs) (fromList unis) p
src/Graphics/GLUtil/Shaders.hs view
@@ -1,32 +1,24 @@ -- |Utilities for working with fragment and vertex shader programs.-module Graphics.GLUtil.Shaders (loadShader, loadGeoShader,-                                linkShaderProgram,-                                linkShaderProgramWith, -                                linkGeoProgram, linkGeoProgramWith,+module Graphics.GLUtil.Shaders (loadShader,+                                linkShaderProgram, linkShaderProgramWith,                                 namedUniform,                                  uniformScalar, uniformVec, uniformMat,                                  namedUniformMat, uniformGLMat4) where-import Control.Applicative ((<$>))-import Control.Monad (unless, replicateM)-import Foreign.C.String (peekCStringLen, withCStringLen)-import Foreign.Marshal.Alloc (alloca, allocaBytes)-import Foreign.Marshal.Array (withArray)-import Foreign.Storable (peek)+import Control.Monad (unless)+import qualified Data.ByteString as BS import Graphics.Rendering.OpenGL import Graphics.Rendering.OpenGL.Raw.Core31-import Graphics.Rendering.OpenGL.Raw.ARB.GeometryShader4 import Graphics.GLUtil.GLError import Foreign.Ptr (Ptr) import Unsafe.Coerce (unsafeCoerce) --- This module is based on the ogl2brick example in the GLUT package.+-- 'loadShader' is based on the ogl2brick example in the GLUT package.  -- |Load a shader program from a file.-loadShader :: Shader s => FilePath -> IO s-loadShader filePath = do-  src <- readFile filePath-  [shader] <- genObjectNames 1-  shaderSource shader $= [src]+loadShader :: ShaderType -> FilePath -> IO Shader+loadShader st filePath = do+  shader <- createShader st+  BS.readFile filePath >>= (shaderSourceBS shader $=)   compileShader shader   printError   ok <- get (compileStatus shader)@@ -39,92 +31,26 @@     ioError (userError "shader compilation failed")   return shader --- |Specialized loading for geometry shaders that are not yet fully--- supported by the Haskell OpenGL package.-loadGeoShader :: FilePath -> IO GeometryShader-loadGeoShader filePath = do-  src <- readFile filePath-  [shader@(GeometryShader gid)] <- genObjectNames 1-  setSource gid src-  glCompileShader gid-  printError-  ok <- alloca $ \buf -> do-          glGetShaderiv gid gl_COMPILE_STATUS buf-          fmap (> 0) (peek buf)-  infoLogLen <- alloca $ \ptr -> do glGetShaderiv gid gl_INFO_LOG_LENGTH ptr-                                    peek ptr-  infoLog <- alloca $ \len ->-               allocaBytes (fromIntegral infoLogLen) $ \chars -> do -                 glGetShaderInfoLog gid infoLogLen len chars-                 len' <- fromIntegral <$> peek len-                 peekCStringLen (chars, len')-  unless (null infoLog)-         (mapM_ putStrLn -                ["Shader info log for '" ++ filePath ++ "':", infoLog, ""])-  unless ok $ do-    deleteObjectNames [shader]-    ioError (userError "shader compilation failed")-  return shader-  where setSource i src = -          do withCStringLen src $ \(charBuf,len)-> do-               withArray [charBuf] $ \charBufsBuf ->-                 withArray [fromIntegral len] $ \lengthsBuf ->-                   glShaderSource i 1 charBufsBuf lengthsBuf----- |Link vertex and fragment shaders into a 'Program'.-linkShaderProgram :: [VertexShader] -> [FragmentShader] -> IO Program-linkShaderProgram vs fs = linkShaderProgramWith vs fs (\_ -> return ())---- |Link vertex and fragment shaders into a 'Program'. The supplied--- 'IO' action is run after attaching shader objects to the new--- program, but before linking. This supports the use of--- 'bindFragDataLocation' to map fragment shader outputs.-linkShaderProgramWith :: [VertexShader] -> [FragmentShader]-                      -> (Program -> IO ()) -> IO Program-linkShaderProgramWith vs fs m = linkGeoProgramWith vs [] fs m--newtype GeometryShader = GeometryShader { geometryShaderID :: GLuint }-  deriving (Eq,Ord,Show)--instance ObjectName GeometryShader where-  genObjectNames n = replicateM n $ -                     fmap GeometryShader (glCreateShader gl_GEOMETRY_SHADER)-  deleteObjectNames = mapM_ (glDeleteShader . geometryShaderID)-  isObjectName = fmap (> 0) . glIsShader . geometryShaderID---- |Link vertex, geometry, and fragment shaders into a 'Program'.-linkGeoProgram :: [VertexShader] -> [GeometryShader] -> [FragmentShader]-               -> IO Program-linkGeoProgram vs gs fs = linkGeoProgramWith vs gs fs (\_ -> return ())+-- |Link shaders into a 'Program'.+linkShaderProgram :: [Shader] -> IO Program+linkShaderProgram shaders = linkShaderProgramWith shaders (const $ return ()) --- |Link vertex, geometry, and fragment shaders into a 'Program'. The--- supplied 'IO' action is run after attaching shader objects to the--- new program, but before linking. This supports the use of--- 'bindFragDataLocation' to map fragment shader outputs.-linkGeoProgramWith :: [VertexShader] -> [GeometryShader] -> [FragmentShader]-                   -> (Program -> IO ()) -> IO Program-linkGeoProgramWith vs gs fs m = do-  [prog] <- genObjectNames 1-  attachedShaders prog $= (vs, fs)-  mapM_ (glAttachShader (unsafeCoerce prog) . geometryShaderID) gs-  m prog-  linkProgram prog-  printError-  ok <- get (linkStatus prog)-  infoLog <- get (programInfoLog prog)-  unless (null infoLog)-         (mapM_ putStrLn ["Program info log:", infoLog, ""])-  unless ok $ do-    deleteObjectNames [prog]-    ioError (userError "GLSL linking failed")-  return prog+-- |Link shaders into a 'Program' with the given action performed+-- after attaching shaders, but before linking the program. This is+-- most commonly used to set the 'bindFragDataLocation' state+-- variable.+linkShaderProgramWith :: [Shader] -> (Program -> IO ()) -> IO Program+linkShaderProgramWith shaders prelink = do p <- createProgram+                                           mapM_ (attachShader p) shaders+                                           prelink p+                                           linkProgram p+                                           return p  -- |Work with a named uniform shader parameter. Note that this looks -- up the variable name on each access, so uniform parameters that -- will be accessed frequently should instead be resolved to a -- 'UniformLocation'.-namedUniform :: (Uniform a) => String -> StateVar a+namedUniform :: Uniform a => String -> StateVar a namedUniform name = makeStateVar (loc >>= get) (\x -> loc >>= ($= x))   where loc = do Just p <- get currentProgram                  l <- get (uniformLocation p name)
src/Graphics/GLUtil/Textures.hs view
@@ -95,7 +95,7 @@         sz = TextureSize2D (texWidth tex) (texHeight tex)         pixelType = glType (undefined::Elem a)         loadAux i e = withPixels (texData tex) $ -                      (texImage2D Nothing NoProxy 0 i sz 0 .+                      (texImage2D Texture2D NoProxy 0 i sz 0 .                        PixelData e pixelType)  -- | Set texture coordinate wrapping options for both the 'S' and 'T'@@ -115,7 +115,7 @@  -- | Bind each of the given textures to successive texture units at -- the given 'TextureTarget' starting with texture unit 0.-withTextures :: TextureTarget -> [TextureObject] -> IO a -> IO a+withTextures :: BindableTextureTarget t => t -> [TextureObject] -> IO a -> IO a withTextures tt ts m = do mapM_ aux (zip ts [0..])                           r <- m                           cleanup 0 ts@@ -136,7 +136,8 @@ -- paired with. The given action is run with these bindings, then the -- texture bindings are reset. If you don't care which texture units -- are used, consider using 'withTextures' or 'withTextures2D'.-withTexturesAt :: TextureTarget -> [(TextureObject,GLuint)] -> IO a -> IO a+withTexturesAt :: BindableTextureTarget t+               => t -> [(TextureObject,GLuint)] -> IO a -> IO a withTexturesAt tt ts m = do mapM_ aux ts                             r <- m                             mapM_ (cleanup . snd) ts@@ -146,10 +147,13 @@         cleanup i = do activeTexture $= TextureUnit i                        textureBinding tt $= Nothing --- | Generate a complete set of mipmaps for the currently bound--- texture object.-generateMipmap' :: TextureTarget -> IO ()-generateMipmap' Texture2D = glGenerateMipmap gl_TEXTURE_2D-generateMipmap' TextureCubeMap = glGenerateMipmap gl_TEXTURE_CUBE_MAP-generateMipmap' _ = error $ "generateMipmap' is only defined for "++-                            "2D textures and cube maps."+class MipMappable t where+  -- | Generate a complete set of mipmaps for the currently bound+  -- texture object.+  generateMipmap' :: t -> IO ()++instance MipMappable TextureTarget2D where+  generateMipmap' _ = glGenerateMipmap gl_TEXTURE_2D++instance MipMappable TextureTargetCubeMap where+  generateMipmap' _ = glGenerateMipmap gl_TEXTURE_CUBE_MAP