diff --git a/package.yaml b/package.yaml index 301d34146..bee679f58 100644 --- a/package.yaml +++ b/package.yaml @@ -42,6 +42,7 @@ dependencies: - deepseq - transformers - foldl +- linear library: source-dirs: src diff --git a/shader/arc.vert b/shader/arc.vert index 9f1d9b726..69e1eb501 100644 --- a/shader/arc.vert +++ b/shader/arc.vert @@ -9,27 +9,11 @@ uniform vec2 winSize; uniform float zoom; uniform vec2 translation; uniform float rotation; - -vec2 tran(vec2 v) -{ - return (v - translation); -} -vec2 rot(vec2 v) -{ - return vec2 ( v.x * cos(-rotation) - v.y * sin(-rotation) - , v.x * sin(-rotation) + v.y * cos(-rotation) - ); -} -vec2 scal(vec2 v) -{ - return vec2 ( 2 * v.x * zoom / winSize.x - , 2 * v.y * zoom / winSize.y - ); -} +uniform mat4 worldMat; void main() { - gl_Position = vec4(scal(rot(tran(position.xy))),position.z,1); + gl_Position = worldMat * vec4(position.xyz,1); vColor = color; vparams = saEaRadWdth; } diff --git a/shader/background.vert b/shader/background.vert index 791c26dcf..48c0908a5 100644 --- a/shader/background.vert +++ b/shader/background.vert @@ -8,6 +8,7 @@ uniform vec2 winSize; uniform float zoom; uniform vec2 translation; uniform float rotation; +uniform mat4 worldMat; void main() { diff --git a/shader/basic.vert b/shader/basic.vert index 748c5ebfc..7eb0a062d 100644 --- a/shader/basic.vert +++ b/shader/basic.vert @@ -7,26 +7,28 @@ uniform vec2 winSize; uniform float zoom; uniform float rotation; uniform vec2 translation; +uniform mat4 worldMat; -vec2 tran(vec2 v) -{ - return (v - translation); -} -vec2 rot(vec2 v) -{ - return vec2 ( v.x * cos(-rotation) - v.y * sin(-rotation) - , v.x * sin(-rotation) + v.y * cos(-rotation) - ); -} -vec2 scal(vec2 v) -{ - return vec2 ( 2 * v.x * zoom / winSize.x - , 2 * v.y * zoom / winSize.y - ); -} - +mat4 tranMat = mat4 + ( 1.0, 0.0, 0.0, 0.0 + , 0.0, 1.0, 0.0, 0.0 + , 0.0, 0.0, 1.0, 0.0 + , -translation.x, -translation.y, 0.0, 1.0 + ) ; +mat4 rotMat = mat4 + ( cos(rotation), sin(-rotation), 0.0, 0.0 + , sin(rotation), cos(rotation), 0.0, 0.0 + , 0.0, 0.0, 1.0, 0.0 + , 0.0, 0.0, 0.0, 1.0 + ) ; +mat4 scalMat = mat4 + ( 2*zoom/winSize.x, 0.0, 0.0, 0.0 + , 0.0, 2*zoom/winSize.y, 0.0, 0.0 + , 0.0, 0.0, 1.0, 0.0 + , 0.0, 0.0, 0.0, 1.0 + ) ; void main() { - gl_Position = vec4(scal(rot(tran(position.xy))),position.z,1); + gl_Position = worldMat * vec4(position.xyz,1); vColor = color; } diff --git a/shader/circle.vert b/shader/circle.vert index 108c229d1..471579c43 100644 --- a/shader/circle.vert +++ b/shader/circle.vert @@ -9,26 +9,29 @@ uniform vec2 winSize; uniform float zoom; uniform vec2 translation; uniform float rotation; +uniform mat4 worldMat; -vec2 tran(vec2 v) -{ - return (v - translation); -} -vec2 rot(vec2 v) -{ - return vec2 ( v.x * cos(-rotation) - v.y * sin(-rotation) - , v.x * sin(-rotation) + v.y * cos(-rotation) - ); -} -vec2 scal(vec2 v) -{ - return vec2 ( 2 * v.x * zoom / winSize.x - , 2 * v.y * zoom / winSize.y - ); -} +mat4 tranMat = mat4 + ( 1.0, 0.0, 0.0, 0.0 + , 0.0, 1.0, 0.0, 0.0 + , 0.0, 0.0, 1.0, 0.0 + , -translation.x, -translation.y, 0.0, 1.0 + ) ; +mat4 rotMat = mat4 + ( cos(rotation), sin(-rotation), 0.0, 0.0 + , sin(rotation), cos(rotation), 0.0, 0.0 + , 0.0, 0.0, 1.0, 0.0 + , 0.0, 0.0, 0.0, 1.0 + ) ; +mat4 scalMat = mat4 + ( 2*zoom/winSize.x, 0.0, 0.0, 0.0 + , 0.0, 2*zoom/winSize.y, 0.0, 0.0 + , 0.0, 0.0, 1.0, 0.0 + , 0.0, 0.0, 0.0, 1.0 + ) ; void main() { - gl_Position = vec4(scal(rot(tran(position.xy))),position.z,1); + gl_Position = scalMat * rotMat * tranMat * vec4(position.xyz,1); vColor = color; vRad = rad; } diff --git a/shader/fadeCircle.vert b/shader/fadeCircle.vert index 8dc4ad405..0498314fe 100644 --- a/shader/fadeCircle.vert +++ b/shader/fadeCircle.vert @@ -6,6 +6,7 @@ uniform vec2 winSize; uniform float zoom; uniform vec2 translation; uniform float rotation; +uniform mat4 worldMat; void main() { diff --git a/shader/wallShadow.vert b/shader/wallShadow.vert index a1eeb778f..adf30c0c2 100644 --- a/shader/wallShadow.vert +++ b/shader/wallShadow.vert @@ -8,6 +8,7 @@ uniform vec2 winSize; uniform float zoom; uniform float rotation; uniform vec2 translation; +uniform mat4 worldMat; void main() { diff --git a/src/Picture/Render.hs b/src/Picture/Render.hs index 7cb6253b0..763f7b5e6 100644 --- a/src/Picture/Render.hs +++ b/src/Picture/Render.hs @@ -4,23 +4,27 @@ module Picture.Render where import Control.Lens import Control.Monad -import Control.Monad.Trans.State +--import Control.Monad.Trans.State +-- +-- +import Linear.Matrix +import Linear.V4 import qualified Control.Foldl as F import Data.Bifunctor -import Picture +import Picture.Data import Geometry import Picture.Preload --import Control.Lens -import Foreign +import Foreign hiding (rotate) import Codec.Picture -import Graphics.Rendering.OpenGL hiding (Line,get,translate,scale,imageHeight,imageWidth,Polygon,Color,T) +import Graphics.Rendering.OpenGL hiding (Line,translate,scale,imageHeight,imageWidth,Polygon,Color,T) import qualified Graphics.Rendering.OpenGL as GL import Data.Foldable @@ -30,6 +34,9 @@ import qualified Data.IntMap as IM import Control.DeepSeq +white = (1,1,1,1) +black = (0,0,0,1) + polyToTris :: [s] -> [s] {-# INLINE polyToTris #-} polyToTris (a:b:c:as) = a : intercalate [a] (zipWith (\x y->[x,y]) (init (b:c:as)) (c:as)) @@ -311,6 +318,26 @@ renderPicture' :: RenderData -> Float -> Float -> (Float,Float) -> (Float,Float) renderPicture' pdata rot zoom (tranx,trany) (winx,winy) wallPoints lightPoints pic = do depthFunc $= Just Lequal +-- calculate world transformation matrix + let scalMat = Linear.Matrix.transpose $ + V4 (V4 (2*zoom/winx) 0 0 (0::GLfloat)) + (V4 0 (2*zoom/winy) 0 0) + (V4 0 0 1 0) + (V4 0 0 0 1) + let rotMat = Linear.Matrix.transpose $ + V4 (V4 (cos rot) (sin (-rot)) 0 0) + (V4 (sin rot) (cos rot) 0 0) + (V4 0 0 1 0) + (V4 0 0 0 1) + let tranMat = Linear.Matrix.transpose $ + V4 (V4 1 0 0 0) + (V4 0 1 0 0) + (V4 0 0 1 0) + (V4 (-tranx) (-trany) 0 1) + let wmat = scalMat !*! rotMat !*! tranMat + vToL (V4 a b c d) = [a,b,c,d] + wmata <- (newMatrix RowMajor $ concatMap vToL $ vToL wmat) :: IO (GLmatrix GLfloat) + -- set common uniforms forM_ [_basicShader pdata ,_textShader pdata @@ -326,6 +353,11 @@ renderPicture' pdata rot zoom (tranx,trany) (winx,winy) wallPoints lightPoints p uniform (snd shad !! 2) $= rot uniform (snd shad !! 3) $= Vector2 tranx trany +-- matrixMode $= Projection +-- loadIdentity + uniform (snd shad !! 4) $= wmata + + -- draw lightmap bindVertexArrayObject $= Just (_vao $ _wallVAO pdata) let wallPtr = (\(_,x,_) -> x) $ head $ _vaoBufferTargets $ _wallVAO pdata @@ -370,9 +402,9 @@ renderPicture' pdata rot zoom (tranx,trany) (winx,winy) wallPoints lightPoints p ,_textShader pdata ,_circShader pdata ,_arcShader pdata - ,_fadeCircleShader pdata - ,_backShader pdata - ,_wallShadowShader pdata +-- ,_fadeCircleShader pdata +-- ,_backShader pdata +-- ,_wallShadowShader pdata ] $ \shad -> do currentProgram $= Just (fst shad) uniform (snd shad !! 0) $= Vector2 (2::Float) 2 diff --git a/src/Shaders.hs b/src/Shaders.hs index e8a423469..7d127d140 100644 --- a/src/Shaders.hs +++ b/src/Shaders.hs @@ -22,7 +22,7 @@ makeSourcedShader :: String -> [ShaderType] -> IO (Program, [UniformLocation]) makeSourcedShader s sts = do sources <- forM sts $ \st -> BS.readFile ("shader/" ++ s ++ shaderTypeExt st) prog <- makeShaderProgram' s $ zip sts sources - uniformLocations <- forM ["winSize","zoom","rotation","translation"] + uniformLocations <- forM ["winSize","zoom","rotation","translation","worldMat"] $ \uniString -> uniformLocation prog uniString return (prog,uniformLocations)