diff options
author | Joe Crayne <joe@jerkface.net> | 2019-04-07 10:03:04 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-04-07 10:03:04 -0400 |
commit | 31b12994b0f5273282271ff3ed04596f49bc8003 (patch) | |
tree | d1095608f459b47b9cb87d04381bad0a7ff50808 /Triangle.hs | |
parent | 7438449949b42538e88a7829a3422826412a4d6a (diff) |
Example using GLArea without gtk-declarative.
Diffstat (limited to 'Triangle.hs')
-rw-r--r-- | Triangle.hs | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/Triangle.hs b/Triangle.hs new file mode 100644 index 0000000..cf26fe6 --- /dev/null +++ b/Triangle.hs | |||
@@ -0,0 +1,117 @@ | |||
1 | {-# LANGUAGE QuasiQuotes #-} | ||
2 | module Triangle where | ||
3 | |||
4 | import Graphics.Rendering.OpenGL as GL | ||
5 | import GI.Gtk as Gtk | ||
6 | import GI.Gdk.Objects | ||
7 | |||
8 | import Control.Concurrent | ||
9 | import Control.Monad | ||
10 | import Data.ByteString (ByteString) | ||
11 | import Foreign.Marshal (newArray) | ||
12 | import Foreign.Ptr | ||
13 | import Foreign.Storable | ||
14 | |||
15 | import UtilGL | ||
16 | |||
17 | fragment_source :: ByteString | ||
18 | fragment_source = [glslFragment| | ||
19 | #version 330 | ||
20 | in vec4 inputColor; | ||
21 | out vec4 outputColor; | ||
22 | void main() { | ||
23 | outputColor = vec4(1.0f, 0.0f, 0.0f, 0.0f); //constant red. I know it's a poor shader | ||
24 | } | ||
25 | |] | ||
26 | |||
27 | vertex_source :: ByteString | ||
28 | vertex_source = [glslVertex| | ||
29 | #version 330 | ||
30 | in vec4 position; | ||
31 | void main() { gl_Position = position; } | ||
32 | |] | ||
33 | |||
34 | data State = State | ||
35 | { stProgram :: Maybe Program | ||
36 | , stBuffer :: Maybe BufferObject | ||
37 | } | ||
38 | |||
39 | initState :: IO (MVar State) | ||
40 | initState = newMVar State | ||
41 | { stProgram = Nothing | ||
42 | , stBuffer = Nothing | ||
43 | } | ||
44 | |||
45 | drawTriangle :: MVar State -> IO () | ||
46 | drawTriangle svar = withMVar svar $ \st -> do | ||
47 | forM_ ((,) <$> stProgram st <*> stBuffer st) $ \(program,position_buffer) -> do | ||
48 | |||
49 | -- Use our shaders | ||
50 | GL.currentProgram $= Just program | ||
51 | |||
52 | -- Use the vertices in our buffer | ||
53 | GL.bindBuffer ArrayBuffer $= Just position_buffer | ||
54 | GL.vertexAttribArray (GL.AttribLocation 0) $= GL.Enabled | ||
55 | GL.vertexAttribPointer (GL.AttribLocation 0) $= (GL.ToFloat,VertexArrayDescriptor 4 GL.Float 0 nullPtr) | ||
56 | -- Draw the three vertices as a triangle | ||
57 | GL.drawArrays Triangles 0 3 | ||
58 | |||
59 | -- We finished using the buffers and program | ||
60 | GL.vertexAttribArray (GL.AttribLocation 0) $= GL.Disabled | ||
61 | GL.bindBuffer ArrayBuffer $= Nothing | ||
62 | |||
63 | render :: MVar State -> GLArea -> GLContext -> IO Bool | ||
64 | render svar w gl = do | ||
65 | putStrLn "render!" | ||
66 | me <- gLAreaGetError w | ||
67 | maybe id (\e _ -> print e) me $ do | ||
68 | -- Clear the viewport | ||
69 | GL.clearColor $= GL.Color4 0 0 0 1 | ||
70 | GL.clear [ColorBuffer] | ||
71 | -- draw our object | ||
72 | drawTriangle svar | ||
73 | GL.flush | ||
74 | |||
75 | return True | ||
76 | |||
77 | realize :: MVar State -> GLArea -> IO () | ||
78 | realize svar w = do | ||
79 | putStrLn "realize!" | ||
80 | gLAreaMakeCurrent w | ||
81 | me <- gLAreaGetError w | ||
82 | maybe id (\e _ -> print e) me $ do | ||
83 | ctx <- gLAreaGetContext w | ||
84 | |||
85 | -- We only use one VAO, so we always keep it bound | ||
86 | vao <- GL.genObjectName | ||
87 | GL.bindVertexArrayObject $= Just vao | ||
88 | |||
89 | (vertex_data_sz,vertex_data) <- do | ||
90 | ptr <- newArray [ GL.Vertex4 0 0.5 0 1 | ||
91 | , GL.Vertex4 0.5 (-0.366) 0 1 | ||
92 | , GL.Vertex4 (-0.5) (-0.366) 0 1 | ||
93 | ] | ||
94 | return ( fromIntegral $ 3 * sizeOf (GL.Vertex4 0 0 0 (0 :: Float) ) | ||
95 | , ptr :: Ptr (GL.Vertex4 Float) ) | ||
96 | |||
97 | -- This is the buffer that holds the vertices | ||
98 | buffer <- GL.genObjectName | ||
99 | GL.bindBuffer ArrayBuffer $= Just buffer | ||
100 | GL.bufferData ArrayBuffer $= (vertex_data_sz, vertex_data, StaticDraw) | ||
101 | GL.bindBuffer ArrayBuffer $= Nothing | ||
102 | |||
103 | mfrag <- makeShader FragmentShader fragment_source | ||
104 | mvert <- makeShader VertexShader vertex_source | ||
105 | mprog <- makeProgram mfrag mvert | ||
106 | |||
107 | modifyMVar_ svar $ \_ -> return State | ||
108 | { stProgram = mprog | ||
109 | , stBuffer = Just buffer | ||
110 | } | ||
111 | |||
112 | return () | ||
113 | |||
114 | |||
115 | unrealize :: GLArea -> IO () | ||
116 | unrealize _ = do | ||
117 | putStrLn "unrealize!" | ||