1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
module InfinitePlane where
import LambdaCube.GL.Mesh as LambdaCubeGL
import LambdaCube.GL
import qualified Data.Vector as V
import qualified Data.Map as Map
-- | You can draw an infinite plane using the standard rasterization pipeline.
-- The homogeneous coordinates it uses can represent "ideal" points (otherwise
-- known as vanishing points or points at infinity) just as happily as regular
-- Euclidean points, and likewise it is perfectly practical to set up a
-- projection matrix which places the far plane at infinity.
--
-- A simple way to do this would be to use one triangle per quadrant, as
-- follows:
xyplane_inf :: LambdaCubeGL.Mesh
xyplane_inf = Mesh
-- vertices [x,y,z,w], for drawing an (x,y) coordinate plane, at (z==0):
{ mAttributes = Map.singleton "position" $ A_V4F $ V.fromList
[ V4 0 0 0 1
, V4 1 0 0 0
, V4 0 1 0 0
, V4 (-1) 0 0 0
, V4 0 (-1) 0 0
]
-- draw 4 triangles using indices: (0,1,2); (0,2,3); (0,3,4); (0,4,1)
, mPrimitive = P_TrianglesI $ V.fromList
[ 0, 1, 2
, 0, 2, 3
, 0, 3, 4
, 0, 4, 1
]
}
-- | This represents the xy-plane as a large triangle. This makes it easier
-- to interpolate 3d world coordinates in the fragment.
xyplane :: LambdaCubeGL.Mesh
xyplane = Mesh
{ mAttributes = Map.singleton "position" $ A_V4F $ V.fromList $ map times1000
[ V4 0 1 0 1
, V4 (1/sqrt 2) ((-1)/sqrt 2) 0 1
, V4 ((-1)/sqrt 2) ((-1)/sqrt 2) 0 1
]
, mPrimitive = P_TrianglesI $ V.fromList
[ 0, 1, 2
]
}
where times1000 (V4 a b c d) = V4 (f a) (f b) (f c) d where f = (* 10000.0)
|