T.hs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. {-- T.hs - some imperative opengl mess
  2. -- Copyright (C) 2018-2019 caryoscelus
  3. --
  4. -- This program is free software: you can redistribute it and/or modify
  5. -- it under the terms of the GNU General Public License as published by
  6. -- the Free Software Foundation, either version 3 of the License, or
  7. -- (at your option) any later version.
  8. --
  9. -- This program is distributed in the hope that it will be useful,
  10. -- but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. -- GNU General Public License for more details.
  13. --
  14. -- You should have received a copy of the GNU General Public License
  15. -- along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. --}
  17. {-# LANGUAGE
  18. NoMonomorphismRestriction,
  19. TemplateHaskell,
  20. ScopedTypeVariables,
  21. TypeFamilies,
  22. LambdaCase,
  23. GADTs,
  24. FlexibleContexts
  25. #-}
  26. module T where
  27. import Debug.Trace (traceShowId)
  28. import Data.Maybe
  29. import Data.Word (Word32)
  30. import Graphics.GPipe
  31. import qualified Graphics.GPipe.Context.GLFW as GLFW
  32. import Data.IORef
  33. import Control.Monad.IO.Class
  34. import Control.Monad
  35. import Control.Monad.Exception (MonadException)
  36. import Control.Category ((>>>))
  37. import Data.Label
  38. import GL
  39. import Util
  40. import Strokes
  41. -- for agda
  42. inductionOnIntAsNat :: a -> (a -> a) -> Int -> a
  43. inductionOnIntAsNat z f n | n <= 0 = z
  44. inductionOnIntAsNat z f n = f (inductionOnIntAsNat z f (pred n))
  45. avg x y = (x + y) `div` 2
  46. zoomStep = 32
  47. toZoom to from = 2 ** (fromIntegral (to - from) / zoomStep - 8)
  48. drawLine :: Double -> Point -> Point -> [V2 Float]
  49. drawLine _ a b | a == b = []
  50. drawLine q a' b' =
  51. let
  52. tt = realToFrac . (* q) . fromIntegral
  53. toQ = \(V2 x y) -> V2 (tt x) (tt y)
  54. a = toQ a'
  55. b = toQ b'
  56. dt = perp (signorm (a - b)) / 256
  57. in
  58. [ a-dt , a+dt
  59. , b+dt
  60. , a-dt
  61. , b-dt , b+dt
  62. ]
  63. wh = 512
  64. screenToGl :: Int -> Int -> Double -> Double -> V2 Coord
  65. screenToGl w h x y = V2
  66. (- fromIntegral w `div` 2 + floor x)
  67. (fromIntegral h `div` 2 - floor y)
  68. ratioToFloat :: Integer -> Integer -> Float
  69. ratioToFloat x y
  70. | y == 0 = 0 -- duh
  71. | otherwise = fromIntegral x / fromIntegral y
  72. v2to4 :: Num i => V2 i -> V4 i
  73. v2to4 (V2 x y) = V4 x y 0 1
  74. data GLRGBPoint = GLRGBPoint
  75. { glpoint :: V2 Float
  76. , glrgb :: V3 Float
  77. }
  78. -- type Triangles = [ GLRGBPoint ]
  79. data RenderResult app = RenderResult
  80. { newState :: app
  81. , result :: [ GLRGBPoint ]
  82. }
  83. data DrawApp app = DrawApp
  84. { emptyApp :: app
  85. , renderApp :: app -> RenderResult app
  86. , frameCount :: app -> Integer
  87. , nowFrame :: app -> Integer
  88. , isDirty :: Integer -> app -> Bool
  89. , dontClearTexture :: app -> app
  90. , getNeedToClearTexture :: app -> Bool
  91. , mouseCallback
  92. :: ((app -> app) -> IO ())
  93. -> GLFW.MouseButton -> GLFW.MouseButtonState -> GLFW.ModifierKeys
  94. -> IO ()
  95. , cursorCallback
  96. :: ((app -> app) -> IO ())
  97. -> Double -> Double
  98. -> IO ()
  99. , keyCallback
  100. :: ((app -> app) -> IO ())
  101. -> GLFW.Key -> Int -> GLFW.KeyState -> GLFW.ModifierKeys
  102. -> IO ()
  103. }
  104. glPointToV4 :: GLRGBPoint -> (V4 Float , V3 Float)
  105. glPointToV4 p = (v2to4 (glpoint p) , glrgb p)
  106. proceedRender drawApp app clearTex shader tex = do
  107. when (getNeedToClearTexture drawApp app) $ clearTex tex
  108. let
  109. app' = dontClearTexture drawApp app
  110. RenderResult newState lines = renderApp drawApp app
  111. lineBuff :: Buffer os (B4 Float, B3 Float) <- newBuffer (length lines)
  112. unless (null lines) $
  113. writeBuffer lineBuff 0 (fmap glPointToV4 lines)
  114. render $ do
  115. vertexArray <- newVertexArray lineBuff
  116. let brushTriangles = toPrimitiveArray TriangleList vertexArray
  117. img <- getTexture2DImage tex 0
  118. shader (OnTexture img brushTriangles)
  119. pure app'
  120. everything drawApp = runContextT GLFW.defaultHandleConfig $ do
  121. let
  122. void = minBound :: Word32
  123. clearTex t = do
  124. writeTexture2D t 0 0 (V2 wh wh) (repeat (V3 void void void))
  125. bgColor = V3 0.0 0.0 0.0
  126. allColors = V3 True True True
  127. wCfg = (GLFW.defaultWindowConfig "rainynite-linaer")
  128. { GLFW.configWidth = wh , GLFW.configHeight = wh }
  129. eApp = emptyApp drawApp
  130. app <- liftIO $ newIORef eApp
  131. frameTextures <-
  132. sequence . replicate (fromIntegral $ frameCount drawApp eApp) $ newTexture2D RGB8 (V2 wh wh) 1
  133. win <- newWindow (WindowFormatColor RGB8) wCfg
  134. brushTexShader <- compileShader (hsvTrianglesOnTextureShader wh wh)
  135. texShader <- compileShader (singleTextureOnWindowShader win wh wh)
  136. GLFW.setMouseButtonCallback win . pure $
  137. mouseCallback drawApp (modifyIORef app)
  138. GLFW.setCursorPosCallback win . pure $
  139. cursorCallback drawApp (modifyIORef app)
  140. GLFW.setKeyCallback win . pure $
  141. keyCallback drawApp (modifyIORef app)
  142. wholeScreenBuff :: Buffer os (B2 Float) <- newBuffer 4
  143. writeBuffer wholeScreenBuff 0
  144. [ V2 0 0
  145. , V2 0 1
  146. , V2 1 1
  147. , V2 1 0
  148. ]
  149. foreverTil (fromMaybe False <$> GLFW.windowShouldClose win) $ do
  150. appVal <- liftIO $ readIORef app
  151. fi <- liftIO $ nowFrame drawApp <$> readIORef app
  152. let nowTex = frameTextures !! fromIntegral fi
  153. appVal' <- proceedRender drawApp appVal clearTex brushTexShader nowTex
  154. liftIO $ writeIORef app appVal'
  155. -- put that onto window
  156. render $ do
  157. clearWindowColor win bgColor
  158. wholeScreen <- newVertexArray wholeScreenBuff
  159. let wholeScreenTriangles = toPrimitiveArray TriangleFan wholeScreen
  160. texShader (RenderTexture wholeScreenTriangles nowTex)
  161. swapWindowBuffers win
  162. pure ()