aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Final.hs1
-rw-r--r--Graphics/Glyph/Util.hs13
-rw-r--r--Resources.hs43
-rw-r--r--shaders/snow.frag13
-rw-r--r--shaders/snow.geom26
-rw-r--r--shaders/snow.vert20
6 files changed, 113 insertions, 3 deletions
diff --git a/Final.hs b/Final.hs
index 3b3e2c4..8676b13 100644
--- a/Final.hs
+++ b/Final.hs
@@ -122,6 +122,7 @@ colorArray marr = do
- 2 things:
- A map of water bodies ids to elevations (to detect if you are under water
- A builder that will generate all of the quads for the water. -}
+
getWaterQuads :: Array (Int,Int) Tile -> IOArray (Int,Int) Int -> IO ( Map.Map Int GLfloat, BuilderM GLfloat () )
getWaterQuads marr arr = do
let (_,(w,h)) = bounds marr
diff --git a/Graphics/Glyph/Util.hs b/Graphics/Glyph/Util.hs
index 21e219a..2a3e060 100644
--- a/Graphics/Glyph/Util.hs
+++ b/Graphics/Glyph/Util.hs
@@ -322,3 +322,16 @@ fpart x = x - (fromIntegral (floor x::Int))
ifNaN :: (RealFloat a) => a -> a -> a
ifNaN reg def = if' (isNaN reg) def reg
+
+everyN :: Int -> [a] -> [a]
+everyN _ [] = []
+everyN n (x : xs) = x : (everyN n $ drop n xs)
+
+chunkList :: [a] -> [(a,a)]
+chunkList l = zip [x | x <- everyN 1 l] [x | x <- everyN 1 (tail l)]
+
+chunkList3 :: [a] -> [(a,a,a)]
+chunkList3 l = zip3
+ [x | x <- everyN 2 l]
+ [x | x <- everyN 2 (tail l)]
+ [x | x <- everyN 2 (tail $ tail l)]
diff --git a/Resources.hs b/Resources.hs
index c0a947c..a04afa7 100644
--- a/Resources.hs
+++ b/Resources.hs
@@ -43,6 +43,7 @@ import Data.Time.Clock.POSIX
import Control.Concurrent
import Text.Printf
import System.IO
+import System.Random
{- Types of terrain which are possible -}
data TileType = Forest | Beach | Water | Grass | Jungle | Mountains |
@@ -282,7 +283,6 @@ eventHandle event res = do
return $ setSpeedMultiplier 1 res
_ -> return res
- where oracle = if (mode res == FirstPerson) then 1 else 3
{- Callback for the display -}
displayHandle :: Resources -> IO Resources
@@ -448,6 +448,41 @@ buildTerrainObject builder = do
-- uniform lightposU $= rcLightPos rc
-- setupTexturing3D density densityU 0
+buildSnowVal :: Array (Int,Int) Tile -> StdGen -> BuilderM GLfloat ()
+buildSnowVal arr gen =
+ let (_,(w,h)) = bounds arr
+ run :: [Int] -> (Int,Int) -> BuilderM GLfloat [Int]
+ run rs (x,y) = do
+ let (seed:npart:t) = rs
+ nStdGen = mkStdGen seed
+ height = elevation (arr ! (x,y))
+ when (tileType (arr ! (x,y)) == Tundra) $
+ forM_ (take (npart`mod`50) $ chunkList3 $ randomRs (0::GLfloat,1) nStdGen ) $ \(a,b,c) -> do
+ let (x',y') = (int x + a, int y + b)
+ bVertex3 (x',c*100,y')
+ bColor4 (int $ height `div` 10,1, 0, 0)
+
+ return t
+ in
+
+ foldM_ run (randoms gen) [(x,y) | x <- [1..w], y <- [1..h]]
+
+buildSnowObject :: Array (Int,Int) Tile -> StdGen -> IO (ResourcesClosure -> IO ())
+buildSnowObject arr gen = do
+ snowProgram <- loadProgramSafe' "shaders/snow.vert" "shaders/snow.frag" (Just "shaders/snow.geom")
+ obj <-
+ liftM (setPrimitiveMode Ex.Points) $
+ newDefaultGlyphObjectWithClosure (buildSnowVal arr gen) () $ \_ -> do
+ currentProgram $= Just snowProgram
+
+ [globalAmbientU,pjMatrixU,mvMatrixU,timeU] <-
+ getUniformsSafe snowProgram ["globalAmbient","pjMatrix","mvMatrix","time"]
+ return $ \rc -> do
+ draw $ (prepare obj) $ \_ -> do
+ uniform mvMatrixU $= rcMVMatrix rc
+ uniform pjMatrixU $= rcPMatrix rc
+ uniform timeU $= (Index1 $ (rcTime rc/75))
+ uniform globalAmbientU $= rcGlobalAmbient rc
buildForestObject :: Seq.Seq GLfloat -> String -> String -> IO (ResourcesClosure -> IO ())
buildForestObject a_seq obj tex =
@@ -532,7 +567,7 @@ buildWaterObject builder = do
uniform (UniformLocation 5) $= rcMVMatrix rc
uniform (UniformLocation 7) $= rcNormalMatrix rc
uniform (UniformLocation 8) $= rcLightPos rc
- uniform (UniformLocation 9) $= Index1 (rcTime rc / 20.0)
+ uniform (UniformLocation 9) $= Index1 (rcTime rc / 20.0);
uniform (UniformLocation 10) $= rcGlobalAmbient rc
bool <- (resourcesUnderWater $ rcResources rc)
if bool then
@@ -548,6 +583,7 @@ makeResources surf builder forestB jungleB water arr waterarr = do
hSetBuffering stdout NoBuffering
let pMatrix' = perspectiveMatrix 50 1.8 0.1 100
+ stdgen <- newStdGen
let l_routines = sequence [
skyboxObject,
(return $ \_ -> do
@@ -560,7 +596,8 @@ makeResources surf builder forestB jungleB water arr waterarr = do
blendFunc $= (GL.SrcAlpha,OneMinusSrcAlpha)),
buildWaterObject water,
buildForestObject forestB "tree.obj" "textures/wood_low.png",
- buildForestObject jungleB "jungletree.obj" "textures/jungle_tree.png"
+ buildForestObject jungleB "jungletree.obj" "textures/jungle_tree.png",
+ buildSnowObject arr stdgen
-- cloudProgram
]
Resources
diff --git a/shaders/snow.frag b/shaders/snow.frag
new file mode 100644
index 0000000..d494633
--- /dev/null
+++ b/shaders/snow.frag
@@ -0,0 +1,13 @@
+#version 150
+#extension GL_ARB_explicit_attrib_location : enable
+#extension GL_ARB_explicit_uniform_location : enable
+
+layout(location = 0) out vec4 frag_color ;
+
+in float rad ;
+
+uniform vec4 globalAmbient ;
+
+void main() {
+ frag_color = vec4( 1.0,1.0,1.0,(9 - rad*rad)/9) * vec4(normalize(globalAmbient.xyz),globalAmbient.a) ;
+}
diff --git a/shaders/snow.geom b/shaders/snow.geom
new file mode 100644
index 0000000..116a59d
--- /dev/null
+++ b/shaders/snow.geom
@@ -0,0 +1,26 @@
+#version 150
+layout(points) in;
+layout(triangle_strip, max_vertices=28) out;
+
+out float rad ;
+
+void vertex( vec3 pos ) {
+ gl_Position = gl_in[0].gl_Position + vec4(pos,0.0) ;
+ EmitVertex() ;
+}
+
+void main( ) {
+ float r = 0.008 ;
+ float th = 0.00 ;
+ for( ; th < 6.3 ; th += 0.5 ) {
+ rad = 3 ;
+ vertex( vec3(r*sin(th),r*cos(th),0.0) ) ;
+ rad = 0.0 ;
+ vertex( vec3(0.0,0.0,0.0) ) ;
+ }
+ th = 0 ;
+ rad = 3 ;
+ vertex( vec3(r*sin(th),r*cos(th),0.0) ) ;
+ // vertex( vector[0] ) ;
+ EndPrimitive();
+}
diff --git a/shaders/snow.vert b/shaders/snow.vert
new file mode 100644
index 0000000..535c26a
--- /dev/null
+++ b/shaders/snow.vert
@@ -0,0 +1,20 @@
+#version 150
+#extension GL_ARB_explicit_attrib_location : enable
+#extension GL_ARB_explicit_uniform_location : enable
+
+layout(location = 0) in vec3 in_position ;
+layout(location = 2) in vec3 in_range ;
+
+uniform mat4 pjMatrix ;
+uniform mat4 mvMatrix ;
+
+uniform float time ;
+
+void main() {
+ float tmp = in_position.y + time ;
+ float ipart ;
+ float fpart = modf( tmp, ipart ) ;
+ float newy = in_range.y - (int(ipart) % int(in_range.y) + fpart) + in_range.x ;
+ vec3 newp = vec3( in_position.x, newy, in_position.z ) ;
+ gl_Position = pjMatrix * (mvMatrix * vec4(newp,1.0)) ;
+}