{-| Draw and update line graphs with OpenGL. Based on: You probably want to use "Graphics.DynamicGraph.TextureLine" as it is better. -} module Graphics.DynamicGraph.SimpleLine ( graph ) where import Control.Monad import Graphics.UI.GLFW as G import Graphics.Rendering.OpenGL import Graphics.GLUtil import Control.Monad.Trans.Class import Control.Monad.Trans.Either import Foreign.Storable import Foreign.Ptr import Paths_dynamic_graph {-| @(graph windowWidth windowHeight bufLen)@ creates a window of width @windowWidth@ and height @windowHeight@ for displaying a line graph. A function is returned for updating the line graph. It takes a pointer to a c array of length @bufLen@ consisting of pairs of \ coordinates for updating the graph as this is the format that OpenGL requires. -} graph :: Int -> Int -> Int -> EitherT String IO (Ptr GLfloat -> IO ()) graph width height bufLen = do res' <- lift $ createWindow width height "" Nothing Nothing win <- maybe (left "error creating window") return res' lift $ do makeContextCurrent (Just win) --Load the shaders vertFN <- getDataFileName "shaders/simple_line.vert" fragFN <- getDataFileName "shaders/simple_line.frag" vs <- loadShader VertexShader vertFN fs <- loadShader FragmentShader fragFN p <- linkShaderProgram [vs, fs] --Set stuff clearColor $= Color4 1 1 1 1 currentProgram $= Just p ab <- genObjectName loc <- get $ attribLocation p "coord" let stride = fromIntegral $ sizeOf (undefined::GLfloat) * 2 vad = VertexArrayDescriptor 2 Float stride offset0 bindBuffer ArrayBuffer $= Just ab vertexAttribArray loc $= Enabled vertexAttribPointer loc $= (ToFloat, vad) return $ \ptr -> do makeContextCurrent (Just win) clear [ColorBuffer] bufferData ArrayBuffer $= (fromIntegral $ 2 * bufLen * sizeOf (undefined :: GLfloat), ptr, StaticDraw) drawArrays LineStrip 0 (fromIntegral bufLen) swapBuffers win