+! (c)2009 Joe Groff, Doug Coleman. bsd license
USING: accessors arrays combinators game-input game-loop
game-input.scancodes grouping kernel literals locals
math math.constants math.functions math.matrices math.order
sequences sequences.product specialized-arrays.float
terrain.generation terrain.shaders ui ui.gadgets
ui.gadgets.worlds ui.pixel-formats game-worlds method-chains
-math.affine-transforms noise ui.gestures ;
+math.affine-transforms noise ui.gestures combinators.short-circuit
+destructors grid-meshes ;
IN: terrain
-CONSTANT: FOV $[ 2.0 sqrt 1+ ]
+CONSTANT: FOV $[ 2.0 sqrt 1 + ]
CONSTANT: NEAR-PLANE $[ 1.0 1024.0 / ]
CONSTANT: FAR-PLANE 2.0
CONSTANT: PLAYER-START-LOCATION { 0.5 0.51 0.5 }
+CONSTANT: VELOCITY-MODIFIER-NORMAL { 1.0 1.0 1.0 }
+CONSTANT: VELOCITY-MODIFIER-FAST { 2.0 1.0 2.0 }
CONSTANT: PLAYER-HEIGHT $[ 1.0 256.0 / ]
CONSTANT: GRAVITY $[ 1.0 4096.0 / ]
CONSTANT: JUMP $[ 1.0 1024.0 / ]
CONSTANT: SKY-SPEED 0.0005
CONSTANT: terrain-vertex-size { 512 512 }
-CONSTANT: terrain-vertex-distance { $[ 1.0 512.0 / ] $[ 1.0 512.0 / ] }
-CONSTANT: terrain-vertex-row-length $[ 512 1 + 2 * ]
TUPLE: player
- location yaw pitch velocity velocity-modifier ;
+ location yaw pitch velocity velocity-modifier
+ reverse-time ;
TUPLE: terrain-world < game-world
player
sky-image sky-texture sky-program
terrain terrain-segment terrain-texture terrain-program
- terrain-vertex-buffer ;
+ terrain-mesh
+ history ;
+
+: <player> ( -- player )
+ player new
+ PLAYER-START-LOCATION >>location
+ 0.0 >>yaw
+ 0.0 >>pitch
+ { 0.0 0.0 0.0 } >>velocity
+ VELOCITY-MODIFIER-NORMAL >>velocity-modifier ;
M: terrain-world tick-length
drop 1000 30 /i ;
[ yaw>> 0.0 1.0 0.0 glRotatef ]
[ location>> vneg first3 glTranslatef ] tri ;
-: vertex-array-vertex ( x z -- vertex )
- [ terrain-vertex-distance first * ]
- [ terrain-vertex-distance second * ] bi*
- [ 0 ] dip float-array{ } 3sequence ;
-
-: vertex-array-row ( z -- vertices )
- dup 1 + 2array
- terrain-vertex-size first 1 + iota
- 2array [ first2 swap vertex-array-vertex ] product-map
- concat ;
-
-: vertex-array ( -- vertices )
- terrain-vertex-size second iota
- [ vertex-array-row ] map concat ;
-
-: >vertex-buffer ( bytes -- buffer )
- [ GL_ARRAY_BUFFER ] dip GL_STATIC_DRAW <gl-buffer> ;
-
-: draw-vertex-buffer-row ( i -- )
- [ GL_TRIANGLE_STRIP ] dip
- terrain-vertex-row-length * terrain-vertex-row-length
- glDrawArrays ;
-
-: draw-vertex-buffer ( buffer -- )
- [ GL_ARRAY_BUFFER ] dip [
- 3 GL_FLOAT 0 f glVertexPointer
- terrain-vertex-size second iota [ draw-vertex-buffer-row ] each
- ] with-gl-buffer ;
-
: degrees ( deg -- rad )
pi 180.0 / * ;
yaw>> 0.0
${ MOVEMENT-SPEED 0.0 0.0 } eye-rotate ;
: clamp-pitch ( pitch -- pitch' )
- 90.0 min -90.0 max ;
-
+ -90.0 90.0 clamp ;
: walk-forward ( player -- )
dup forward-vector [ v+ ] curry change-velocity drop ;
:: handle-input ( world -- )
world player>> :> player
read-keyboard keys>> :> keys
- key-left-shift keys nth [
- { 2.0 1.0 2.0 } player (>>velocity-modifier)
- ] when
- key-left-shift keys nth [
- { 1.0 1.0 1.0 } player (>>velocity-modifier)
- ] unless
+
+ key-left-shift keys nth
+ VELOCITY-MODIFIER-FAST VELOCITY-MODIFIER-NORMAL ? player (>>velocity-modifier)
+
+ {
+ [ key-1 keys nth 1 f ? ]
+ [ key-2 keys nth 2 f ? ]
+ [ key-3 keys nth 3 f ? ]
+ [ key-4 keys nth 4 f ? ]
+ [ key-5 keys nth 10000 f ? ]
+ } 0|| player (>>reverse-time)
key-w keys nth [ player walk-forward ] when
key-s keys nth [ player walk-backward ] when
: scaled-velocity ( player -- velocity )
[ velocity>> ] [ velocity-modifier>> ] bi v* ;
-: tick-player ( world player -- )
+: save-history ( world player -- )
+ clone swap history>> push ;
+
+:: tick-player-reverse ( world player -- )
+ player reverse-time>> :> reverse-time
+ world history>> :> history
+ history length 0 > [
+ history length reverse-time 1 - - 1 max history set-length
+ history pop world (>>player)
+ ] when ;
+
+: tick-player-forward ( world player -- )
+ 2dup save-history
[ apply-friction apply-gravity ] change-velocity
dup scaled-velocity [ v+ [ terrain-segment>> ] dip collide ] curry with change-location
drop ;
+: tick-player ( world player -- )
+ dup reverse-time>> [
+ tick-player-reverse
+ ] [
+ tick-player-forward
+ ] if ;
+
M: terrain-world tick*
[ dup focused?>> [ handle-input ] [ drop ] if ]
[ dup player>> tick-player ] bi ;
GL_DEPTH_TEST glEnable
GL_TEXTURE_2D glEnable
GL_VERTEX_ARRAY glEnableClientState
- PLAYER-START-LOCATION 0.0 0.0 { 0.0 0.0 0.0 } { 1.0 1.0 1.0 } player boa >>player
+ <player> >>player
+ V{ } clone >>history
<perlin-noise-table> 0.01 0.01 <scale> { 512 512 } perlin-noise-image
[ >>sky-image ] keep
make-texture [ set-texture-parameters ] keep >>sky-texture
>>sky-program
terrain-vertex-shader terrain-pixel-shader <simple-gl-program>
>>terrain-program
- vertex-array >vertex-buffer >>terrain-vertex-buffer
+ terrain-vertex-size <grid-mesh> >>terrain-mesh
drop ;
AFTER: terrain-world end-world
{
- [ terrain-vertex-buffer>> delete-gl-buffer ]
+ [ terrain-mesh>> dispose ]
[ terrain-program>> delete-gl-program ]
[ terrain-texture>> delete-texture ]
[ sky-program>> delete-gl-program ]
[ GL_DEPTH_TEST glEnable dup terrain-program>> [
[ "heightmap" glGetUniformLocation 0 glUniform1i ]
[ "component_scale" glGetUniformLocation COMPONENT-SCALE first4 glUniform4f ] bi
- terrain-vertex-buffer>> draw-vertex-buffer
+ terrain-mesh>> draw-grid-mesh
] with-gl-program ]
} cleave gl-error ;