summaryrefslogtreecommitdiff
path: root/src/Game/Internal.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Game/Internal.hs')
-rw-r--r--src/Game/Internal.hs125
1 files changed, 84 insertions, 41 deletions
diff --git a/src/Game/Internal.hs b/src/Game/Internal.hs
index 4a41c8f..e05a907 100644
--- a/src/Game/Internal.hs
+++ b/src/Game/Internal.hs
@@ -1,4 +1,5 @@
{-# LANGUAGE DisambiguateRecordFields #-}
+{-# LANGUAGE MultilineStrings #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedRecordDot #-}
@@ -42,19 +43,24 @@ import Linear (V3 (..), V4 (..))
-- Shader creation and object initialisation
--------------------------------------------------------------------------------
-initResources :: [[V4 GL.GLfloat]] -> IO ([Object], GL.Program)
-initResources arrays = do
- objects <-
- listIOsToIOlist
- [createObject arr 4 GL.Triangles (GL.AttribLocation 0) | arr <- arrays]
- []
+initResources :: [V4 GL.GLfloat] -> IO (Object, GL.Program)
+initResources arr = do
+ object <-
+ createObject arr 4 GL.Triangles (GL.AttribLocation 0)
+
+ -- compile shader program
program <-
loadShaders
[ ShaderInfo GL.VertexShader (StringSource vertShader),
ShaderInfo GL.FragmentShader (StringSource fragShader)
]
GL.currentProgram $= Just program
- return (objects, program)
+
+ -- alpha
+ GL.blend $= GL.Enabled
+ GL.blendFunc $= (GL.SrcAlpha, GL.OneMinusSrcAlpha)
+
+ return (object, program)
listIOsToIOlist :: [IO a] -> [a] -> IO [a]
listIOsToIOlist [] out = return out
@@ -69,44 +75,81 @@ listIOsToIOlist (io : ios) out = do
vertShader :: String
vertShader =
- unlines
- [ "#version 330 core",
- "layout (location = 0) in vec4 a_vPos;",
- "uniform mat4 u_view;",
- "uniform mat4 u_projection;",
- "out vec3 v_pos;",
- glslProjectTo3d,
- "void main()",
- "{",
- " vec3 vPos = projectTo3d(a_vPos);",
- " gl_Position = u_projection * u_view * vec4(vPos, 1.0);",
- " v_pos = vPos;",
- "}"
- ]
+ """
+ #version 330 core
+
+ layout (location = 0) in vec4 a_vPos;
+
+ uniform mat4 u_view;
+ uniform mat4 u_projection;
+ uniform vec4 u_cam;
+
+ out vec3 v_pos;
+ out float v_w;
+ out float v_alpha;
+
+ vec3 orthoFrom4d(vec4 point)
+ {
+ return point.xyz;
+ }
+
+ // creates a simple 3d coordinate from a 4d
+ vec3 projectFrom4d(vec4 point)
+ {
+ // TODO don't do camera ops in shader, prefer linear algebra
+ // also use a reasonable projection for god's sake
+ vec4 view = abs(u_cam - point);
+ float perspective = 1.0 / abs(u_cam.w - view.w);
+
+ return perspective * (point.xyz);
+ }
+
+ void main()
+ {
+ vec3 vPos = orthoFrom4d(a_vPos);
+
+ // TODO don't set constant inside of shader :/
+ float wHorizon = 3;
+ float alpha = (wHorizon - abs(u_cam.w - a_vPos.w)) / wHorizon;
+
+ // cull invisible things
+ if (alpha < -1) {
+ gl_Position = vec4(0.0);
+ alpha = 0.0;
+ } else {
+ alpha = max(alpha, 0.0);
+ gl_Position = u_projection * u_view * vec4(vPos, 1.0);
+ }
+
+ v_pos = vPos;
+ v_w = a_vPos.w;
+ v_alpha = alpha;
+ }
+ """
fragShader :: String
fragShader =
- unlines
- [ "#version 330 core",
- "out vec4 o_vColor;",
- "in vec3 v_pos;",
- "void main()",
- "{",
- " // yoinked from https://stackoverflow.com/questions/14980712/how-to-get-flat-normals-on-a-cube/14981446#14981446",
- " vec3 norm = normalize(cross(dFdx(v_pos), dFdy(v_pos)));",
- " o_vColor = vec4((0.5 + 0.5 * norm) / 2, 1.0);",
- "}"
- ]
+ """
+ #version 330 core
+
+ uniform vec4 u_cam;
+
+ out vec4 o_vColor;
+
+ in vec3 v_pos;
+ in float v_w;
+ in float v_alpha;
+
+ void main()
+ {
+ // the normal vector of the face
+ // yoinked from https://stackoverflow.com/questions/14980712/how-to-get-flat-normals-on-a-cube/14981446#14981446
+ vec3 norm = normalize(cross(dFdx(v_pos), dFdy(v_pos)));
-glslProjectTo3d :: String
-glslProjectTo3d =
- unlines
- [ "vec3 projectTo3d(vec4 point)",
- "{",
- " float perspective = 1.0 / (1.0 + point.w);",
- " return perspective * point.xyz;",
- "}"
- ]
+ // creates a color based on the normal direction
+ o_vColor = vec4((0.5 + 0.5 * norm) / 2, v_alpha);
+ }
+ """
--------------------------------------------------------------------------------
-- Objects