summaryrefslogtreecommitdiff
path: root/Triangle.hs
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-04-07 10:03:04 -0400
committerJoe Crayne <joe@jerkface.net>2019-04-07 10:03:04 -0400
commit31b12994b0f5273282271ff3ed04596f49bc8003 (patch)
treed1095608f459b47b9cb87d04381bad0a7ff50808 /Triangle.hs
parent7438449949b42538e88a7829a3422826412a4d6a (diff)
Example using GLArea without gtk-declarative.
Diffstat (limited to 'Triangle.hs')
-rw-r--r--Triangle.hs117
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 #-}
2module Triangle where
3
4import Graphics.Rendering.OpenGL as GL
5import GI.Gtk as Gtk
6import GI.Gdk.Objects
7
8import Control.Concurrent
9import Control.Monad
10import Data.ByteString (ByteString)
11import Foreign.Marshal (newArray)
12import Foreign.Ptr
13import Foreign.Storable
14
15import UtilGL
16
17fragment_source :: ByteString
18fragment_source = [glslFragment|
19#version 330
20in vec4 inputColor;
21out vec4 outputColor;
22void main() {
23outputColor = vec4(1.0f, 0.0f, 0.0f, 0.0f); //constant red. I know it's a poor shader
24}
25|]
26
27vertex_source :: ByteString
28vertex_source = [glslVertex|
29#version 330
30in vec4 position;
31void main() { gl_Position = position; }
32|]
33
34data State = State
35 { stProgram :: Maybe Program
36 , stBuffer :: Maybe BufferObject
37 }
38
39initState :: IO (MVar State)
40initState = newMVar State
41 { stProgram = Nothing
42 , stBuffer = Nothing
43 }
44
45drawTriangle :: MVar State -> IO ()
46drawTriangle 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
63render :: MVar State -> GLArea -> GLContext -> IO Bool
64render 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
77realize :: MVar State -> GLArea -> IO ()
78realize 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
115unrealize :: GLArea -> IO ()
116unrealize _ = do
117 putStrLn "unrealize!"