PageRenderTime 26ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Graphics/Rendering/OpenGL/GL/Shaders/ProgramObjects.hs

http://github.com/haskell-opengl/OpenGL
Haskell | 163 lines | 89 code | 31 blank | 43 comment | 5 complexity | ec195a4dce34b778dab00d3eb0f58075 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. -----------------------------------------------------------------------------
  2. -- |
  3. -- Module : Graphics.Rendering.OpenGL.GL.Shaders.ProgramObjects
  4. -- Copyright : (c) Sven Panne 2006-2019
  5. -- License : BSD3
  6. --
  7. -- Maintainer : Sven Panne <svenpanne@gmail.com>
  8. -- Stability : stable
  9. -- Portability : portable
  10. --
  11. -- This module corresponds to section 7.3 (Program Objects) of the OpenGL 4.4
  12. -- spec.
  13. --
  14. -----------------------------------------------------------------------------
  15. module Graphics.Rendering.OpenGL.GL.Shaders.ProgramObjects (
  16. -- * Program Objects
  17. Program, createProgram, programDeleteStatus,
  18. attachShader, detachShader, attachedShaders,
  19. linkProgram, linkStatus,
  20. validateProgram, validateStatus,
  21. programInfoLog,
  22. currentProgram,
  23. programSeparable, programBinaryRetrievableHint,
  24. -- TODOs:
  25. -- glCreateShaderProgramv
  26. -- ProgramInterface type (from 7.3.1)
  27. -- glGetProgramInterfaceiv
  28. -- glGetProgramResourceIndex
  29. -- glGetProgramResourceName
  30. -- glGetProgramResourceiv
  31. -- glGetProgramResourceLocation
  32. -- glGetProgramResourceLocationIndex
  33. -- * Fragment Data
  34. bindFragDataLocation, getFragDataLocation
  35. ) where
  36. import Data.List
  37. import Data.Maybe
  38. import Data.StateVar
  39. import Foreign.Marshal.Array
  40. import Foreign.Ptr
  41. import Graphics.Rendering.OpenGL.GL.ByteString
  42. import Graphics.Rendering.OpenGL.GL.Framebuffer
  43. import Graphics.Rendering.OpenGL.GL.GLboolean
  44. import Graphics.Rendering.OpenGL.GL.QueryUtils
  45. import Graphics.Rendering.OpenGL.GL.Shaders.Program
  46. import Graphics.Rendering.OpenGL.GL.Shaders.Shader
  47. import Graphics.GL
  48. --------------------------------------------------------------------------------
  49. createProgram :: IO Program
  50. createProgram = fmap Program glCreateProgram
  51. --------------------------------------------------------------------------------
  52. attachShader :: Program -> Shader -> IO ()
  53. attachShader p s = glAttachShader (programID p) (shaderID s)
  54. detachShader :: Program -> Shader -> IO ()
  55. detachShader p s = glDetachShader (programID p) (shaderID s)
  56. attachedShaders :: Program -> StateVar [Shader]
  57. attachedShaders program =
  58. makeStateVar (getAttachedShaders program) (setAttachedShaders program)
  59. getAttachedShaders :: Program -> IO [Shader]
  60. getAttachedShaders program = do
  61. numShaders <- get (numAttachedShaders program)
  62. ids <- allocaArray (fromIntegral numShaders) $ \buf -> do
  63. glGetAttachedShaders (programID program) numShaders nullPtr buf
  64. peekArray (fromIntegral numShaders) buf
  65. return $ map Shader ids
  66. setAttachedShaders :: Program -> [Shader] -> IO ()
  67. setAttachedShaders program newShaders = do
  68. currentShaders <- getAttachedShaders program
  69. mapM_ (attachShader program) (newShaders \\ currentShaders)
  70. mapM_ (detachShader program) (currentShaders \\ newShaders)
  71. --------------------------------------------------------------------------------
  72. linkProgram :: Program -> IO ()
  73. linkProgram = glLinkProgram . programID
  74. currentProgram :: StateVar (Maybe Program)
  75. currentProgram =
  76. makeStateVar
  77. (do p <- fmap Program $ getInteger1 fromIntegral GetCurrentProgram
  78. return $ if p == noProgram then Nothing else Just p)
  79. (glUseProgram . programID . fromMaybe noProgram)
  80. noProgram :: Program
  81. noProgram = Program 0
  82. validateProgram :: Program -> IO ()
  83. validateProgram = glValidateProgram . programID
  84. programInfoLog :: Program -> GettableStateVar String
  85. programInfoLog =
  86. makeGettableStateVar .
  87. fmap unpackUtf8 .
  88. stringQuery programInfoLogLength (glGetProgramInfoLog . programID)
  89. --------------------------------------------------------------------------------
  90. programSeparable :: Program -> StateVar Bool
  91. programSeparable = programStateVarBool ProgramSeparable
  92. programBinaryRetrievableHint :: Program -> StateVar Bool
  93. programBinaryRetrievableHint = programStateVarBool ProgramBinaryRetrievableHint
  94. programStateVarBool :: GetProgramPName -> Program -> StateVar Bool
  95. programStateVarBool pname program =
  96. makeStateVar
  97. (get (programVar1 unmarshalGLboolean pname program))
  98. (glProgramParameteri (programID program)
  99. (marshalGetProgramPName pname) . marshalGLboolean)
  100. --------------------------------------------------------------------------------
  101. programDeleteStatus :: Program -> GettableStateVar Bool
  102. programDeleteStatus = programVar1 unmarshalGLboolean ProgramDeleteStatus
  103. linkStatus :: Program -> GettableStateVar Bool
  104. linkStatus = programVar1 unmarshalGLboolean LinkStatus
  105. validateStatus :: Program -> GettableStateVar Bool
  106. validateStatus = programVar1 unmarshalGLboolean ValidateStatus
  107. programInfoLogLength :: Program -> GettableStateVar GLsizei
  108. programInfoLogLength = programVar1 fromIntegral ProgramInfoLogLength
  109. numAttachedShaders :: Program -> GettableStateVar GLsizei
  110. numAttachedShaders = programVar1 fromIntegral AttachedShaders
  111. --------------------------------------------------------------------------------
  112. -- | 'bindFragDataLocation' binds a varying variable, specified by program and name, to a
  113. -- drawbuffer. The effects only take place after succesfull linking of the program.
  114. -- invalid arguments and conditions are
  115. -- - an index larger than maxDrawBufferIndex
  116. -- - names starting with 'gl_'
  117. -- linking failure will ocure when
  118. -- - one of the arguments was invalid
  119. -- - more than one varying varuable name is bound to the same index
  120. -- It's not an error to specify unused variables, those will be ingored.
  121. bindFragDataLocation :: Program -> String -> SettableStateVar DrawBufferIndex
  122. bindFragDataLocation (Program program) varName = makeSettableStateVar $ \ind ->
  123. withGLstring varName $ glBindFragDataLocation program ind
  124. -- | query the binding of a given variable, specified by program and name. The program has to be
  125. -- linked. The result is Nothing if an error occures or the name is not a name of a varying
  126. -- variable. If the program hasn't been linked an 'InvalidOperation' error is generated.
  127. getFragDataLocation :: Program -> String -> IO (Maybe DrawBufferIndex)
  128. getFragDataLocation (Program program) varName = do
  129. r <- withGLstring varName $ glGetFragDataLocation program
  130. if r < 0
  131. then return Nothing
  132. else return . Just $ fromIntegral r