-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathShader.hs
94 lines (80 loc) · 2.85 KB
/
Shader.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
module Shader (prepareShaders, setUniform, setVarying, bind, unbind,
ShaderTag(Tag), getTagType, shaderTags, TograShader,
resetVarying) where
import Data.ObjectName
import Data.StateVar
import Data.IORef
import Foreign.Ptr
import Graphics.Rendering.OpenGL
import Control.Monad
import TograUtil
import Vao
import Vbo
instance Show (IORef a) where
show a = "an IORef"
data TograShader = TograShader Program (IORef VAO)
deriving (Eq, Show)
instance Bindable a => Bindable (IORef a) where
bind v = do
vo <- get v
bind vo
unbind v = do
vo <- get v
unbind vo
instance Bindable TograShader where
bind (TograShader program vao) = do
currentProgram $= Just program
bind vao
unbind (TograShader program vao) = do
currentProgram $= Nothing
unbind vao
compileAndCheckShader :: Shader s => s -> IO ()
compileAndCheckShader s = do
compileShader s
result <- get (compileStatus s)
check result (get (shaderInfoLog s))
prepareShaders :: [String] -> [String] -> IO TograShader
prepareShaders vertexShaderProgram fragmentShaderProgram = do
(vertexShader):[] <- (genObjectNames 1) :: IO [VertexShader]
(shaderSource vertexShader) $= vertexShaderProgram
compileAndCheckShader vertexShader
(fragmentShader):[] <- (genObjectNames 1) :: IO [FragmentShader]
(shaderSource fragmentShader) $= fragmentShaderProgram
compileAndCheckShader fragmentShader
(program):[] <- (genObjectNames 1) :: IO [Program]
(attachedShaders program) $= ([vertexShader], [fragmentShader])
linkProgram program
result <- get (linkStatus program)
check result (get (programInfoLog program))
validateProgram program
result <- get (validateStatus program)
check result (get (programInfoLog program))
vao <- newIORef emptyVAO
return (TograShader program vao)
setUniform :: Uniform a => TograShader -> String -> a -> IO ()
setUniform (TograShader program vao) name value = do
loc <- get (uniformLocation program name)
uniform loc $= value
checkGlErrors
--setVarying :: VertexAttrib a => Program -> String -> Ptr a -> IO ()
-- loc <- get (attribLocation program name)
-- vertexAttribv ToFloat loc value
setVarying :: TograShader -> String -> DVBO -> IO ()
setVarying (TograShader program vao) name dvbo = do
loc <- get (attribLocation program name)
vao $~ addDVBO dvbo loc
-- ensure that if this program is bound then the newly set varying value
-- is bound too
current <- get currentProgram
if current == Just program then bind vao else return ()
checkGlErrors
resetVarying :: TograShader -> IO ()
resetVarying (TograShader program vao) = do
vao $= emptyVAO
data ShaderTag = Tag GLint VariableType String
getTagType :: ShaderTag -> VariableType
getTagType (Tag _ vt _) = vt
shaderTags :: TograShader -> IO [ShaderTag]
shaderTags (TograShader p vao) = do
l <- get $ activeAttribs p
return $ map (\(n,v,s) -> Tag n v s) l