hypercubes but actually

This commit is contained in:
andromeda
2026-02-07 17:37:05 +01:00
parent 2a3c9bdafb
commit 5474012f89
3 changed files with 133 additions and 92 deletions

View File

@@ -46,13 +46,9 @@ initResources :: [[V4 GL.GLfloat]] -> IO ([Object], GL.Program)
initResources arrays = do initResources arrays = do
objects <- objects <-
listIOsToIOlist listIOsToIOlist
[createObject arr 4 GL.TriangleStrip (GL.AttribLocation 0) | arr <- arrays] [createObject arr 4 GL.Triangles (GL.AttribLocation 0) | arr <- arrays]
[] []
program <- program <- loadColorShader
loadShaders
[ ShaderInfo GL.VertexShader (StringSource vertShader),
ShaderInfo GL.FragmentShader (StringSource fragShader)
]
GL.currentProgram $= Just program GL.currentProgram $= Just program
return (objects, program) return (objects, program)
@@ -67,39 +63,69 @@ listIOsToIOlist (io : ios) out = do
-- u_ uniform -- u_ uniform
-- o_ fragment shader output -- o_ fragment shader output
-- | vertex shader loadBlackShader :: IO GL.Program
loadBlackShader =
loadShaders
[ ShaderInfo GL.VertexShader (StringSource vertShader),
ShaderInfo GL.FragmentShader (StringSource blackFragShader)
]
loadColorShader :: IO GL.Program
loadColorShader =
loadShaders
[ ShaderInfo GL.VertexShader (StringSource vertShader),
ShaderInfo GL.FragmentShader (StringSource colorFragShader)
]
vertShader :: String vertShader :: String
vertShader = vertShader =
"#version 330 core\n" unlines
++ "layout (location = 0) in vec4 a_vPos;\n" [ "#version 330 core",
++ "uniform mat4 u_view;\n" "layout (location = 0) in vec4 a_vPos;",
++ "uniform mat4 u_projection;\n" "uniform mat4 u_view;",
++ "out vec3 v_pos;\n" "uniform mat4 u_projection;",
++ glslProjectTo3d "out vec3 v_pos;",
++ "void main()\n" glslProjectTo3d,
++ "{\n" "void main()",
++ " gl_Position = u_projection * u_view * vec4(projectTo3d(a_vPos), 1.0);\n" "{",
++ " v_pos = a_vPos.xyz;\n" " vec3 vPos = projectTo3d(a_vPos);",
++ "}\n" " gl_Position = u_projection * u_view * vec4(vPos, 1.0);",
" v_pos = vPos;",
"}"
]
-- | fragment shader colorFragShader :: String
fragShader :: String colorFragShader =
fragShader = unlines
"#version 330 core\n" [ "#version 330 core",
++ "out vec4 o_vColor;\n" "out vec4 o_vColor;",
++ "in vec3 v_pos;\n" "in vec3 v_pos;",
++ "void main()\n" "void main()",
++ "{\n" "{",
++ " o_vColor = vec4(0.5 + 0.5 * normalize(v_pos), 1);\n" " o_vColor = vec4((0.5 + 0.5 * normalize(v_pos)) / 2, 1.0);",
++ "}\n" "}"
]
blackFragShader :: String
blackFragShader =
unlines
[ "#version 330 core",
"out vec4 o_vColor;",
"void main()",
"{",
" o_vColor = vec4(0.0, 0.0, 0.0, 1.0);",
"}"
]
glslProjectTo3d :: String glslProjectTo3d :: String
glslProjectTo3d = glslProjectTo3d =
"vec3 projectTo3d(vec4 point)\n" unlines
++ "{\n" [ "vec3 projectTo3d(vec4 point)",
++ " float perspective = 1.0 / (1.0 + point.w);\n" "{",
++ " return perspective * point.xyz;\n" " float perspective = 1.0 / (1.0 + point.w);",
++ "}\n" " return perspective * point.xyz;",
"}"
]
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Objects -- Objects

View File

@@ -11,7 +11,7 @@
module Game.Internal.Types module Game.Internal.Types
( Object (..), ( Object (..),
toGLMatrix, toGLMatrix,
Model (camera, objects, cursorDeltaPos, cursorPos, program, keys, wprop), Model (camera, objects, cursorDeltaPos, cursorPos, keys, program, wprop),
mkModel, mkModel,
Camera (camPos, camPitch, camYaw, camReference, mouseSensitivity, camVel, strafeStrength, jumpStrength, hasJumped, airTime), Camera (camPos, camPitch, camYaw, camReference, mouseSensitivity, camVel, strafeStrength, jumpStrength, hasJumped, airTime),
mkCamera, mkCamera,
@@ -70,7 +70,6 @@ data Model = Model
keys :: [GLFW.Key], keys :: [GLFW.Key],
-- | draw calls -- | draw calls
objects :: [Object], objects :: [Object],
-- | shader program
program :: GL.Program, program :: GL.Program,
wprop :: WorldProperties wprop :: WorldProperties
} }

View File

@@ -22,7 +22,7 @@ import Game.Internal.Types
import Graphics.Rendering.OpenGL (($=)) import Graphics.Rendering.OpenGL (($=))
import qualified Graphics.Rendering.OpenGL as GL import qualified Graphics.Rendering.OpenGL as GL
import qualified Graphics.UI.GLFW as GLFW import qualified Graphics.UI.GLFW as GLFW
import Linear (V3 (..), V4 (..), _y) import Linear (V3 (..), V4 (..), (*^), _y)
import qualified Linear as L import qualified Linear as L
-- | Main function runs game -- | Main function runs game
@@ -48,8 +48,9 @@ main = do
GLFW.setCursorPosCallback window $ Just (cursorPosHandler Nothing) GLFW.setCursorPosCallback window $ Just (cursorPosHandler Nothing)
(objects, program) <- (objects, program) <-
initResources $ initResources $
-- [map (v3tov4 0) $ map (+ V3 a 0 0) cube | a <- take 100 [0, 2 ..]] [map (v3tov4 0) $ map (+ V3 a 0 0) cube | a <- take 100 [4, 6 ..]]
[hCube] ++ [hCube]
++ [map (\v -> rotate4 0 3 (g90 / 3) (v + V4 0 3 0 0)) hCube]
let model = let model =
mkModel mkModel
@@ -75,34 +76,13 @@ main = do
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Arrays -- Arrays
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
top :: [V3 GL.GLfloat]
top =
[ V3 p 0 p,
V3 p 0 m,
V3 m 0 p,
V3 m 0 m
]
side :: [V3 GL.GLfloat]
side =
[ V3 0 p p,
V3 0 p m,
V3 0 m p,
V3 0 m m
]
front :: [V3 GL.GLfloat]
front =
[ V3 p p 0,
V3 p m 0,
V3 m p 0,
V3 m m 0
]
m = (0 - p) m = (0 - p)
p = 0.5 p = 0.5
g90 = pi / 2
v3tov4 :: GL.GLfloat -> V3 GL.GLfloat -> V4 GL.GLfloat v3tov4 :: GL.GLfloat -> V3 GL.GLfloat -> V4 GL.GLfloat
v3tov4 w (V3 x y z) = V4 x y z w v3tov4 w (V3 x y z) = V4 x y z w
@@ -115,41 +95,77 @@ v3tov4'' w (V3 x y z) = V4 x w y z
v3tov4''' :: GL.GLfloat -> V3 GL.GLfloat -> V4 GL.GLfloat v3tov4''' :: GL.GLfloat -> V3 GL.GLfloat -> V4 GL.GLfloat
v3tov4''' w (V3 x y z) = V4 w x y z v3tov4''' w (V3 x y z) = V4 w x y z
-- | TODO optimise cube rotate :: V3 GL.GLfloat -> GL.GLfloat -> V3 GL.GLfloat -> V3 GL.GLfloat
cube :: [V3 GL.GLfloat] rotate axis angle point = L.fromQuaternion (L.axisAngle axis angle) L.!* point
cube =
[ V3 p p p, -- front rotate4 :: Int -> Int -> GL.GLfloat -> V4 GL.GLfloat -> V4 GL.GLfloat
V3 p m p, rotate4 i0 i1 angle (V4 x y z w) =
V3 m p p, let coords = [x, y, z, w]
V3 m m p, -- down cos' = cos angle
V3 m m m, sin' = sin angle
V3 p m p, xi = coords !! i0
V3 p m m, -- right xj = coords !! i1
V3 p p m, coords' =
V3 p m p, [ if k == i0
V3 p p p, -- up then cos' * xi - sin' * xj
V3 m p p, else
V3 p p m, if k == i1
V3 m p m, -- back then sin' * xi + cos' * xj
V3 p m m, else coords !! k
V3 p p m, | k <- [0 .. 3]
V3 m m m, -- left ]
V3 m p m, in V4 (coords' !! 0) (coords' !! 1) (coords' !! 2) (coords' !! 3)
V3 m m p,
V3 m p p cycle3r :: V3 GL.GLfloat -> V3 GL.GLfloat
cycle3r (V3 a b c) = V3 c a b
cycle3l :: V3 GL.GLfloat -> V3 GL.GLfloat
cycle3l (V3 a b c) = V3 b c a
face :: [V3 GL.GLfloat]
face =
[ V3 m m 0,
V3 p m 0,
V3 m p 0,
V3 m p 0,
V3 p m 0,
V3 p p 0
] ]
-- | TODO optimise hCube -- | cube, side length 1, centered on 0 0 0
cube :: [V3 GL.GLfloat]
cube =
concatMap
( \faceSpec ->
map
(\v -> (rotate (fst faceSpec) g90 v) L.^+^ (rotate (fst faceSpec) g90 (snd faceSpec)))
face
)
[ (V3 0 0 1, V3 0 0 p),
(V3 0 1 0, V3 0 0 p),
(V3 1 0 0, V3 0 0 p),
(V3 0 0 (-1), V3 0 0 m), -- no clue
(V3 0 (-1) 0, V3 0 0 p),
(V3 (-1) 0 0, V3 0 0 p)
]
hCube :: [V4 GL.GLfloat] hCube :: [V4 GL.GLfloat]
hCube = hCube =
(map (v3tov4 m) cube) concatMap
++ (map (v3tov4 p) cube) ( \(w, i0, i1) ->
++ (map (v3tov4' m) cube) map
++ (map (v3tov4' p) cube) (rotate4 i0 i1 g90 . v3tov4 w)
++ (map (v3tov4'' m) cube) cube
++ (map (v3tov4'' p) cube) )
++ (map (v3tov4''' m) cube) [ (p, 3, 0),
++ (map (v3tov4''' p) cube) (p, 0, 3),
(p, 1, 3),
(p, 2, 3),
(m, 3, 0),
(m, 0, 3),
(m, 1, 3),
(m, 2, 3)
]
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Elm-like data structures -- Elm-like data structures