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 ] } times1000 (V4 a b c d) = V4 (f a) (f b) (f c) d where f = (* 10000.0) -- | 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 ] } -- | This represents the xz-plane as a large triangle. This makes it easier -- to interpolate 3d world coordinates in the fragment. xzplane :: LambdaCubeGL.Mesh xzplane = Mesh { mAttributes = Map.singleton "position" $ A_V4F $ V.fromList $ map times1000 [ V4 0 0 1 1 , V4 (1/sqrt 2) 0 ((-1)/sqrt 2) 1 , V4 ((-1)/sqrt 2) 0 ((-1)/sqrt 2) 1 ] , mPrimitive = P_TrianglesI $ V.fromList [ 0, 1, 2 ] }