lowgl 0.3.0.0 → 0.3.1.0
raw patch · 8 files changed
+253/−84 lines, 8 files
Files
- Graphics/GL/Low.hs +2/−1
- Graphics/GL/Low/Error.hs +9/−0
- Graphics/GL/Low/Framebuffer.hs +38/−7
- Graphics/GL/Low/ImageFormat.hs +1/−1
- Graphics/GL/Low/Stencil.hs +9/−6
- Graphics/GL/Low/Texture.hs +190/−64
- Graphics/GL/Low/VertexAttrib.hs +2/−3
- lowgl.cabal +2/−2
Graphics/GL/Low.hs view
@@ -428,7 +428,7 @@ -- * Framebuffers -- | See also "Graphics.GL.Low.Framebuffer"- DefaultFramebuffer,+ DefaultFramebuffer(..), FBO, bindFramebuffer, newFBO,@@ -445,6 +445,7 @@ -- * Errors GLError(..), getGLError,+ assertNoGLError, -- * Image Formats Alpha,
Graphics/GL/Low/Error.hs view
@@ -11,6 +11,7 @@ module Graphics.GL.Low.Error ( GLError(..), getGLError,+ assertNoGLError, ) where import Control.Exception@@ -57,3 +58,11 @@ GL_INVALID_FRAMEBUFFER_OPERATION -> Just InvalidFramebufferOperation GL_OUT_OF_MEMORY -> Just OutOfMemory _ -> error ("unknown GL error " ++ show n)++-- | Throws an exception if 'getGLError' returns non-Nothing.+assertNoGLError :: IO ()+assertNoGLError = do+ me <- getGLError+ case me of+ Nothing -> return ()+ Just e -> throwIO e
Graphics/GL/Low/Framebuffer.hs view
@@ -1,16 +1,48 @@+-- | Framebuffers, FBO, RBO...+--+-- == Example+--+-- This example program renders an animating object to an off-screen+-- framebuffer. The resulting texture is then show on a full-screen quad+-- with an effect.+--+-- @+--+-- @+--+-- The vertex shader for this program is+--+-- @+--+-- @+--+-- The two fragment shaders, one for the object, one for the effect, are+--+-- @+--+-- @+--+-- @+--+-- @+--+-- And the output looks like+--+-- <<framebuffer.gif Animated screenshot showing post-processing effect>>+ {-# LANGUAGE RankNTypes #-} module Graphics.GL.Low.Framebuffer (- FBO,- RBO,- DefaultFramebuffer,- bindFramebuffer, newFBO,+ bindFramebuffer, deleteFBO, attachTex2D, attachCubeMap, attachRBO, newRBO,- deleteRBO+ deleteRBO,+ FBO,+ DefaultFramebuffer(..),+ RBO, ) where import Foreign.Ptr@@ -35,8 +67,7 @@ -- you can do with an RBO is attach it to an FBO. data RBO a = RBO { unRBO :: GLuint } deriving Show --- | The default framebuffer. Bind this to render to the screen as usual.--- Use the Default instance method 'def' to construct it.+-- | The default framebuffer. data DefaultFramebuffer = DefaultFramebuffer deriving Show instance Default DefaultFramebuffer where
Graphics/GL/Low/ImageFormat.hs view
@@ -26,7 +26,7 @@ data Depth24Stencil8 = Depth24Stencil8 deriving Show instance InternalFormat RGB where- internalFormat _ = GL_RGB8+ internalFormat _ = GL_RGB instance InternalFormat RGBA where internalFormat _ = GL_RGBA instance InternalFormat Alpha where
Graphics/GL/Low/Stencil.hs view
@@ -16,13 +16,16 @@ -- - When the stencil test fails or -- - When the stencil test passes then the depth test fails or -- - When both tests pass.------ An example way of updating the stencil buffer is to write zero, or to write--- the ref value mentioned above to the location being tested.------ > example program here -module Graphics.GL.Low.Stencil where+module Graphics.GL.Low.Stencil (+ enableStencil,+ disableStencil,+ clearStencilBuffer,+ basicStencil,+ Stencil(..),+ StencilFunc(..),+ StencilOp(..)+) where import Data.Default import Data.Bits
Graphics/GL/Low/Texture.hs view
@@ -1,21 +1,140 @@+-- | Textures are objects that contain image data that can be sampled by+-- a shader. While an obvious application of this is texture mapping, there+-- are many other uses for textures (the image data doesn't have to be an+-- image at all, it can represent anything).+--+-- Each sampler uniform in your shader points to a texture unit (zero by+-- default). This texture unit is where it will read texture data from. To+-- assign a texture to a texture unit, use 'setActiveTextureUnit' then bind+-- a texture. This will not only bind it to the relevant texture binding target+-- but also to the active texture unit. You can change which unit a sampler+-- points to by setting it using the 'Graphics.GL.Low.Shader.setUniform1i'+-- command. You can avoid dealing with active texture units if theres only one+-- sampler because the default unit is zero.+--+-- == Example+--+-- This example loads a 256x256 PNG file with JuicyPixels and displays the+-- image on a square. Of course without a correction for aspect ratio the+-- square will only be square if you adjust your window to be square.+--+-- @+-- module Main where+-- +-- import Control.Monad.Loops (whileM_)+-- import Data.Functor ((\<$\>))+-- import qualified Data.Vector.Storable as V+-- import Codec.Picture+-- import Data.Word+-- +-- import qualified Graphics.UI.GLFW as GLFW+-- import Linear+-- import Graphics.GL.Low+-- +-- main = do+-- GLFW.init+-- GLFW.windowHint (GLFW.WindowHint'ContextVersionMajor 3)+-- GLFW.windowHint (GLFW.WindowHint'ContextVersionMinor 2)+-- GLFW.windowHint (GLFW.WindowHint'OpenGLForwardCompat True)+-- GLFW.windowHint (GLFW.WindowHint'OpenGLProfile GLFW.OpenGLProfile'Core)+-- mwin <- GLFW.createWindow 640 480 \"Texture\" Nothing Nothing+-- case mwin of+-- Nothing -> putStrLn "createWindow failed"+-- Just win -> do+-- GLFW.makeContextCurrent (Just win)+-- GLFW.swapInterval 1+-- (vao, prog, texture) <- setup+-- whileM_ (not \<$\> GLFW.windowShouldClose win) $ do+-- GLFW.pollEvents+-- draw vao prog texture+-- GLFW.swapBuffers win+-- +-- setup = do+-- -- establish a VAO+-- vao <- newVAO+-- bindVAO vao+-- -- load the shader+-- vsource <- readFile "texture.vert"+-- fsource <- readFile "texture.frag"+-- prog <- newProgram vsource fsource+-- useProgram prog+-- -- load the vertices+-- let blob = V.fromList -- a quad has four vertices+-- [ -0.5, -0.5, 0, 1+-- , -0.5, 0.5, 0, 0+-- , 0.5, -0.5, 1, 1+-- , 0.5, 0.5, 1, 0 ] :: V.Vector Float+-- vbo <- newVBO blob StaticDraw+-- bindVBO vbo+-- setVertexLayout [ Attrib "position" 2 GLFloat+-- , Attrib "texcoord" 2 GLFloat ]+-- -- load the element array to draw a quad with two triangles+-- indices <- newElementArray (V.fromList [0,1,2,3,2,1] :: V.Vector Word8) StaticDraw+-- bindElementArray indices+-- -- load the texture with JuicyPixels+-- let fromRight (Right x) = x+-- ImageRGBA8 (Image w h image) <- fromRight \<$\> readImage "logo.png"+-- texture <- newTexture2D image (Dimensions w h) :: IO (Tex2D RGBA)+-- setTex2DFiltering Linear+-- return (vao, prog, texture)+-- +-- draw vao prog texture = do+-- clearColorBuffer (0.5, 0.5, 0.5)+-- bindVAO vao+-- useProgram prog+-- bindTexture2D texture+-- drawIndexedTriangles 6 UByteIndices+-- @+--+-- The vertex shader for this example looks like+--+-- @+-- #version 150+-- in vec2 position;+-- in vec2 texcoord;+-- out vec2 Texcoord;+-- void main()+-- {+-- gl_Position = vec4(position, 0.0, 1.0);+-- Texcoord = texcoord;+-- }+-- @+--+-- And the fragment shader looks like+--+-- @+-- #version 150+-- in vec2 Texcoord;+-- out vec4 outColor;+-- uniform sampler2D tex;+-- void main()+-- {+-- outColor = texture(tex, Texcoord);+-- }+-- @+--+-- Should produce output like+--+-- <<texture.png Screenshot of Texture Example>>+ module Graphics.GL.Low.Texture (- Tex2D,- CubeMap,- Filtering(..),- Wrapping(..),- Dimensions(..), newTexture2D,- deleteTexture, newCubeMap, newEmptyTexture2D, newEmptyCubeMap,+ deleteTexture, bindTexture2D, bindTextureCubeMap, setActiveTextureUnit, setTex2DFiltering, setCubeMapFiltering, setTex2DWrapping,- setCubeMapWrapping+ setCubeMapWrapping,+ Tex2D,+ CubeMap,+ Filtering(..),+ Wrapping(..),+ Dimensions(..), ) where import Foreign.Ptr@@ -32,55 +151,14 @@ import Graphics.GL.Low.Common import Graphics.GL.Low.Cube --- | A 2D texture. A program can sample a texture if it has been bound to--- the appropriate texture unit.-newtype Tex2D a = Tex2D GLuint deriving Show --- | A cubemap texture is just six 2D textures. A program can sample a cubemap--- texture if it has been bound to the appropriate texture unit.-newtype CubeMap a = CubeMap GLuint deriving Show---- | Texture filtering modes.-data Filtering =- Nearest | -- ^ No interpolation.- Linear -- ^ Linear interpolation.- deriving Show--instance ToGL Filtering where- toGL Nearest = GL_NEAREST- toGL Linear = GL_LINEAR---- | Texture wrapping modes.-data Wrapping =- Repeat | -- ^ Tile the texture past the boundary.- MirroredRepeat | -- ^ Tile the texture but mirror every other tile.- ClampToEdge -- ^ Use the edge color for anything past the boundary.- deriving Show--instance ToGL Wrapping where- toGL Repeat = GL_REPEAT- toGL MirroredRepeat = GL_MIRRORED_REPEAT- toGL ClampToEdge = GL_CLAMP_TO_EDGE---- | The size of an image in pixels.-data Dimensions = Dimensions- { imageWidth :: Int- , imageHeight :: Int }- deriving (Show)--instance Texture (Tex2D a) where--instance Texture (CubeMap a) where--instance GLObject (Tex2D a) where- glObjectName (Tex2D n) = fromIntegral n--instance GLObject (CubeMap a) where- glObjectName (CubeMap n) = fromIntegral n---- | Create a new 2D texture from a blob and its image format.--- Dimensions should be powers of two.-newTexture2D :: InternalFormat a => Vector Word8 -> Dimensions -> IO (Tex2D a)+-- | Create a new 2D texture from a blob and its dimensions. Dimensions should+-- be powers of two. The internal format type determines how the data is+-- interpreted.+newTexture2D :: (Storable a, InternalFormat b)+ => Vector a+ -> Dimensions+ -> IO (Tex2D b) newTexture2D bytes (Dimensions w h) = do n <- alloca (\ptr -> glGenTextures 1 ptr >> peek ptr) glBindTexture GL_TEXTURE_2D n@@ -95,26 +173,25 @@ (internalFormat tex) GL_UNSIGNED_BYTE (castPtr ptr)+ glGenerateMipmap GL_TEXTURE_2D return tex --- | Delete a texture.-deleteTexture :: Texture a => a -> IO ()-deleteTexture x = withArray [glObjectName x] (\ptr -> glDeleteTextures 1 ptr)---- | Create a new cube map texture from six blobs and their respective formats.+-- | Create a new cube map texture from six blobs and their respective dimensions. -- Dimensions should be powers of two.-newCubeMap :: InternalFormat a- => Cube (Vector Word8, Dimensions)- -> IO (CubeMap a)+newCubeMap :: (Storable a, InternalFormat b)+ => Cube (Vector a, Dimensions)+ -> IO (CubeMap b) newCubeMap images = do n <- alloca (\ptr -> glGenTextures 1 ptr >> peek ptr) glBindTexture GL_TEXTURE_CUBE_MAP n cm <- return (CubeMap n) let fmt = internalFormat cm sequenceA (liftA2 (loadCubeMapSide fmt) images cubeSideCodes)+ glGenerateMipmap GL_TEXTURE_CUBE_MAP return cm+ -loadCubeMapSide :: GLenum -> (Vector Word8, Dimensions) -> GLenum -> IO ()+loadCubeMapSide :: Storable a => GLenum -> (Vector a, Dimensions) -> GLenum -> IO () loadCubeMapSide fmt (bytes, (Dimensions w h)) side = do unsafeWith bytes $ \ptr -> glTexImage2D side@@ -159,6 +236,9 @@ glTexImage2D GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0 fmt w' h' 0 fmt' GL_UNSIGNED_BYTE nullPtr return tex +-- | Delete a texture.+deleteTexture :: Texture a => a -> IO ()+deleteTexture x = withArray [glObjectName x] (\ptr -> glDeleteTextures 1 ptr) -- | Bind a 2D texture to the 2D texture binding target and the currently -- active texture unit.@@ -204,3 +284,49 @@ glTexParameteri GL_TEXTURE_CUBE_MAP GL_TEXTURE_WRAP_S (toGL wrap) glTexParameteri GL_TEXTURE_CUBE_MAP GL_TEXTURE_WRAP_T (toGL wrap) glTexParameteri GL_TEXTURE_CUBE_MAP GL_TEXTURE_WRAP_R (toGL wrap)++-- | A 2D texture. A program can sample a texture if it has been bound to+-- the appropriate texture unit.+newtype Tex2D a = Tex2D GLuint deriving Show++-- | A cubemap texture is just six 2D textures. A program can sample a cubemap+-- texture if it has been bound to the appropriate texture unit.+newtype CubeMap a = CubeMap GLuint deriving Show++-- | Texture filtering modes.+data Filtering =+ Nearest | -- ^ No interpolation.+ Linear -- ^ Linear interpolation.+ deriving Show++instance ToGL Filtering where+ toGL Nearest = GL_NEAREST+ toGL Linear = GL_LINEAR++-- | Texture wrapping modes.+data Wrapping =+ Repeat | -- ^ Tile the texture past the boundary.+ MirroredRepeat | -- ^ Tile the texture but mirror every other tile.+ ClampToEdge -- ^ Use the edge color for anything past the boundary.+ deriving Show++instance ToGL Wrapping where+ toGL Repeat = GL_REPEAT+ toGL MirroredRepeat = GL_MIRRORED_REPEAT+ toGL ClampToEdge = GL_CLAMP_TO_EDGE++-- | The size of an image in pixels.+data Dimensions = Dimensions+ { imageWidth :: Int+ , imageHeight :: Int }+ deriving (Show)++instance Texture (Tex2D a) where++instance Texture (CubeMap a) where++instance GLObject (Tex2D a) where+ glObjectName (Tex2D n) = fromIntegral n++instance GLObject (CubeMap a) where+ glObjectName (CubeMap n) = fromIntegral n
Graphics/GL/Low/VertexAttrib.hs view
@@ -43,12 +43,11 @@ Unused Int -- ^ Size in bytes of an unused section of the vertex data. deriving Show --- | The size and interpretation of a vertex attribute component. Normalized--- components will be mapped to floats in the range [0, 1].+-- | The size and interpretation of a vertex attribute component. data DataType = GLFloat | -- ^ 4-byte float- GLUnsignedByte | -- ^ unsigned byte GLByte | -- ^ signed byte+ GLUnsignedByte | -- ^ unsigned byte GLShort | -- ^ 2-byte signed integer GLUnsignedShort | -- ^ 2-byte unsigned integer GLInt | -- ^ 4-byte signed integer
lowgl.cabal view
@@ -10,7 +10,7 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 0.3.0.0+version: 0.3.1.0 -- A short (one-line) description of the package. synopsis: Basic gl wrapper and reference@@ -89,4 +89,4 @@ source-repository this type: git location: https://github.com/evanrinehart/lowgl- tag: 0.3.0.0+ tag: 0.3.1.0