B23. Saltare
Ora che possiamo camminare, perchè non mettersi a saltare? Il meccanismo del salto è abbastanza semplice, ma implica un minimo
di conoscenza del moto parabolico. Per prima cosa, dobbiamo stabilire le variabili che servono per questo scopo:
Modifichiamo quindi il metodo Update per far leggere la pressione del testo spazio:
E inseriamo il codice di calcolo vero e proprio, nel metodo UpdatePosition:
Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.Input
Imports Microsoft.Xna.Framework.Graphics
Imports System.Runtime.InteropServices
Public Class Game
Inherits Microsoft.Xna.Framework.Game
#Region "Strutture aggiuntive"
Private Shared DoubleSize As Byte = Marshal.SizeOf(GetType(Double))
Private Structure VertexPositionNormalColor
Public Position As Vector3
Public Normal As Vector3
Public Color As Color
Public Shared SizeInBytes As Int16 = 7 * 4
Public Shared VertexElements() As VertexElement = New VertexElement() _
{ _
New VertexElement(0, 0, VertexElementFormat.Vector3, _
VertexElementMethod.Default, _
VertexElementUsage.Position, 0), _
New VertexElement(0, DoubleSize * 3, _
VertexElementFormat.Color, _
VertexElementMethod.Default, _
VertexElementUsage.Color, 0), _
New VertexElement(0, DoubleSize * 4, _
VertexElementFormat.Vector3, _
VertexElementMethod.Default, _
VertexElementUsage.Normal, 0) _
}
End Structure
Private Structure VertexPositionNormalMultitexture
Public Position As Vector3
Public Normal As Vector3
Public TextureCoordinate As Vector4
Public TextureWeight As Vector4
Public Shared SizeInBytes As Int16 = (3 + 3 + 4 + 4) * 4
Public Shared VertexElements As VertexElement() = New VertexElement() _
{ _
New VertexElement(0, 0, VertexElementFormat.Vector3, _
VertexElementMethod.Default, _
VertexElementUsage.Position, 0), _
New VertexElement(0, 4 * 3, _
VertexElementFormat.Vector3, _
VertexElementMethod.Default, _
VertexElementUsage.Normal, 0), _
New VertexElement(0, 4 * 6, _
VertexElementFormat.Vector4, _
VertexElementMethod.Default, _
VertexElementUsage.TextureCoordinate, 0), _
New VertexElement(0, 4 * 10, _
VertexElementFormat.Vector4, _
VertexElementMethod.Default, _
VertexElementUsage.TextureCoordinate, 1) _
}
End Structure
Private Structure SkyCubeFace
Public Vertices() As VertexPositionTexture
Public Indices() As Int32
Public Texture As Texture2D
End Structure
#End Region
#Region "Variabili globali"
Private AppPath As String = _
My.Application.Info.DirectoryPath
Private Graphics As GraphicsDeviceManager
'VERTICI, INDICI E BUFFER ------------------------
Private Shader As Effect
Private Vertices() As VertexPositionNormalMultitexture
Private Indices() As Int32
Private VBuffer As VertexBuffer
Private IBuffer As IndexBuffer
Private VDeclaration As VertexDeclaration
Private SDeclaration As VertexDeclaration
Private WDeclaration As VertexDeclaration
'MATRICI -----------------------------------------
Private ViewMatrix As Matrix
Private ProjectionMatrix As Matrix
Private WorldMatrix As Matrix
Private ReflectionViewMatrix As Matrix
'HEIGHTDATA --------------------------------------
Private HeightData(,) As Single
Private Const MinHeight As Single = 0
Private Const MaxHeight As Single = 30
Private TerrainWidth, TerrainLength As Int32
'TELECAMERA -------------------------------------
Private PrevMouseState As MouseState
Private LeftRightRotation As Single = MathHelper.PiOver2
Private UpDownRotation As Single = -MathHelper.Pi / 10.0F
Private CameraPosition As Vector3
Private RotationSpeed As Single = 0.3
Private MoveSpeed As Single = 0.08
'TEXTURE ----------------------------------------
Private Grass As Texture2D
Private Sand As Texture2D
Private Rock As Texture2D
Private Snow As Texture2D
'CIELO ------------------------------------------
Private SkyFaces(4) As Texture2D
Private SkyCube(4) As SkyCubeFace
'ACQUA ------------------------------------------
Private WaterHeight As Single = 5.0
Private RefractionTarget As RenderTarget2D
Private RefractionMap As Texture2D
Private ReflectionTarget As RenderTarget2D
Private ReflectionMap As Texture2D
Private WaterVertices() As VertexPositionTexture
Private WaterVBuffer As VertexBuffer
Private BumpMap As Texture2D
'SALTO ------------------------------------------
Private IsJumping As Boolean = False
Private JumpingYVelocity As Single
Private JumpStart As TimeSpan
Private JumpTime As Single
Private Const JumpingYInitial As Single = 0.17
Private Const Gravity As Single = 0.9
#End Region
#Region "Funzioni utili"
Private Function GetEffect(ByVal FileName As String) As Effect
Dim CompEffect As CompiledEffect = _
Effect.CompileEffectFromFile(FileName, _
Nothing, Nothing, _
CompilerOptions.None, _
TargetPlatform.Windows)
Return New Effect(Me.GraphicsDevice, _
CompEffect.GetEffectCode, _
CompilerOptions.None, Nothing)
End Function
Private Function GetTexture(ByVal FileName As String)
Return Texture2D.FromFile(Me.GraphicsDevice, FileName)
End Function
#End Region
#Region "Caricamento Heightmap"
Private Sub LoadHeightMap(ByVal HeightMap As Texture2D)
TerrainWidth = HeightMap.Width
TerrainLength = HeightMap.Height
Dim Colors(TerrainWidth * TerrainLength - 1) As Color
HeightMap.GetData(Colors)
For I As Int32 = 0 To TerrainWidth - 1
ReDim HeightData(I, TerrainLength - 1)
Next
For X As Int32 = 0 To TerrainWidth - 1
For Z As Int32 = 0 To TerrainLength - 1
HeightData(X, Z) = MinHeight + _
(Colors(X + Z * TerrainWidth).R / 255) * _
(MaxHeight - MinHeight)
Next
Next
VDeclaration = New VertexDeclaration(Me.GraphicsDevice, _
VertexPositionNormalMultitexture.VertexElements)
End Sub
Private Sub SetVertices()
ReDim Vertices(TerrainWidth * TerrainLength - 1)
Dim Strip As Single = (MaxHeight - MinHeight) / 4
For X As Int32 = 0 To TerrainWidth - 1
For Z As Int32 = 0 To TerrainLength - 1
With Vertices(X + Z * TerrainWidth)
Dim Y As Single = HeightData(X, Z)
.Position = New Vector3(X, Y, -Z)
.TextureCoordinate.X = X / 32
.TextureCoordinate.Y = Z / 32
.TextureWeight.X = MathHelper.Clamp(1.0F - Math.Abs(Y - 0) / 8.0F, 0, 1)
.TextureWeight.Y = MathHelper.Clamp(1.0F - Math.Abs(Y - 12) / 6.0F, 0, 1)
.TextureWeight.Z = MathHelper.Clamp(1.0F - Math.Abs(Y - 20) / 6.0F, 0, 1)
.TextureWeight.W = MathHelper.Clamp(1.0F - Math.Abs(Y - 30) / 6.0F, 0, 1)
Dim Total As Single = .TextureWeight.X
Total += .TextureWeight.Y
Total += .TextureWeight.Z
Total += .TextureWeight.W
.TextureWeight.X /= Total
.TextureWeight.Y /= Total
.TextureWeight.Z /= Total
.TextureWeight.W /= Total
End With
Next
Next
End Sub
Private Sub SetIndices()
ReDim Indices((TerrainWidth - 1) * (TerrainLength - 1) * 6 - 1)
Dim Counter As Int32 = 0
For X As Int32 = 0 To TerrainWidth - 2
For Z As Int32 = 0 To TerrainLength - 2
Dim LowerLeft As Int16 = X + Z * TerrainWidth
Dim LowerRight As Int16 = (X + 1) + Z * TerrainWidth
Dim TopLeft As Int16 = X + (Z + 1) * TerrainWidth
Dim TopRight As Int16 = (X + 1) + (Z + 1) * TerrainWidth
Indices(Counter) = TopLeft
Indices(Counter + 1) = LowerRight
Indices(Counter + 2) = LowerLeft
Counter += 3
Indices(Counter) = TopLeft
Indices(Counter + 1) = TopRight
Indices(Counter + 2) = LowerRight
Counter += 3
Next
Next
End Sub
Private Sub SetNormals()
For I As Int32 = 0 To Vertices.Length - 1
Vertices(I).Normal = New Vector3(0, 0, 0)
Next
For I As Int16 = 0 To (Indices.Length / 3) - 1
Dim Index1 As Int16 = Indices(I * 3)
Dim Index2 As Int16 = Indices(I * 3 + 1)
Dim Index3 As Int16 = Indices(I * 3 + 2)
Dim Side1 As Vector3 = _
Vertices(Index1).Position - Vertices(Index3).Position
Dim Side2 As Vector3 = _
Vertices(Index1).Position - Vertices(Index2).Position
Dim Normal As Vector3 = Vector3.Cross(Side1, Side2)
Vertices(Index1).Normal += Normal
Vertices(Index2).Normal += Normal
Vertices(Index3).Normal += Normal
Next
For Each V As VertexPositionNormalMultitexture In Vertices
V.Normal.Normalize()
Next
End Sub
Private Sub CopyToBuffer()
VBuffer = New VertexBuffer(Me.GraphicsDevice, _
Vertices.Length * VertexPositionNormalMultitexture.SizeInBytes, _
BufferUsage.WriteOnly)
VBuffer.SetData(Vertices)
IBuffer = New IndexBuffer(Me.GraphicsDevice, _
GetType(Int32), Indices.Length, BufferUsage.WriteOnly)
IBuffer.SetData(Indices)
Me.GraphicsDevice.Indices = IBuffer
Me.GraphicsDevice.Vertices(0).SetSource( _
VBuffer, 0, VertexPositionNormalMultitexture.SizeInBytes)
End Sub
#End Region
#Region "Cielo"
Private Function GetElements(Of T)(ByVal Sources() As T, ByVal ParamArray Indices() As Int32) As T()
Dim Result(Indices.Length - 1) As T
For I As Int16 = 0 To Indices.Length - 1
Result(I) = Sources(Indices(I))
Next
Return Result
End Function
Private Sub LoadSkyDome()
Dim SkyVertices(7) As VertexPositionTexture
Dim HalfSize As Int16 = 200
Dim HalfHeight As Int16 = 150
SkyVertices(0).Position = New Vector3(-HalfSize, 200, HalfSize)
SkyVertices(1).Position = New Vector3(-HalfSize, 200, -HalfSize)
SkyVertices(2).Position = New Vector3(HalfSize, 200, HalfSize)
SkyVertices(3).Position = New Vector3(HalfSize, 200, -HalfSize)
SkyVertices(4).Position = New Vector3(-HalfSize, 0, HalfSize)
SkyVertices(5).Position = New Vector3(-HalfSize, 0, -HalfSize)
SkyVertices(6).Position = New Vector3(HalfSize, 0, HalfSize)
SkyVertices(7).Position = New Vector3(HalfSize, 0, -HalfSize)
SkyCube(0).Vertices = GetElements(SkyVertices, 0, 1, 2, 3)
SkyCube(1).Vertices = GetElements(SkyVertices, 5, 1, 4, 0)
SkyCube(2).Vertices = GetElements(SkyVertices, 4, 0, 6, 2)
SkyCube(3).Vertices = GetElements(SkyVertices, 6, 2, 7, 3)
SkyCube(4).Vertices = GetElements(SkyVertices, 7, 3, 5, 1)
With SkyCube(0)
.Indices = New Int32() {0, 1, 2, 2, 1, 3}
.Texture = SkyFaces(0)
.Vertices(0).TextureCoordinate = New Vector2(0, 1)
.Vertices(1).TextureCoordinate = New Vector2(0, 0)
.Vertices(2).TextureCoordinate = New Vector2(1, 1)
.Vertices(3).TextureCoordinate = New Vector2(1, 0)
End With
For I As Byte = 1 To 4
With SkyCube(I)
.Indices = New Int32() {0, 1, 2, 2, 1, 3}
.Texture = SkyFaces(I)
.Vertices(0).TextureCoordinate = New Vector2(0, 0.5)
.Vertices(1).TextureCoordinate = New Vector2(0, 0)
.Vertices(2).TextureCoordinate = New Vector2(1, 0.5)
.Vertices(3).TextureCoordinate = New Vector2(1, 0)
End With
Next
SDeclaration = New VertexDeclaration(Me.GraphicsDevice, VertexPositionTexture.VertexElements)
End Sub
Private Sub DrawSky(ByVal View As Matrix)
Dim Prev As CullMode = Me.GraphicsDevice.RenderState.CullMode
Me.GraphicsDevice.RenderState.CullMode = CullMode.None
For I As Byte = 0 To 4
Shader.CurrentTechnique = Shader.Techniques("Textured")
Shader.Parameters("View").SetValue(View)
Shader.Parameters("Projection").SetValue(ProjectionMatrix)
Shader.Parameters("World").SetValue(Matrix.Identity)
Shader.Parameters("LightEnabled").SetValue(False)
Shader.Parameters("ATexture").SetValue(SkyFaces(I))
Shader.Begin()
For Each Pass As EffectPass In Shader.CurrentTechnique.Passes
Pass.Begin()
With Me.GraphicsDevice
.VertexDeclaration = SDeclaration
.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, SkyCube(I).Vertices, 0, SkyCube(I).Vertices.Length, SkyCube(I).Indices, 0, SkyCube(I).Indices.Length / 3)
End With
Pass.End()
Next
Shader.End()
Next
Me.GraphicsDevice.RenderState.CullMode = Prev
End Sub
#End Region
#Region "Acqua"
Private Function CreatePlane(ByVal Height As Single, ByVal View As Matrix, _
ByVal Normal As Vector3, ByVal ClipAbove As Boolean)
Normal.Normalize()
Dim PlaneCoef As New Vector4(Normal, Height)
Dim HSMatrix As Matrix = _
Matrix.Transpose( _
Matrix.Invert(View * ProjectionMatrix))
If ClipAbove Then
PlaneCoef *= -1
End If
PlaneCoef = Vector4.Transform(PlaneCoef, HSMatrix)
Return New Plane(PlaneCoef)
End Function
Private Sub DrawRefractionMap()
Dim RefractionPlane As Plane = _
CreatePlane(WaterHeight + 1.5F, ViewMatrix, New Vector3(0, -1, 0), False)
Me.GraphicsDevice.ClipPlanes(0).Plane = RefractionPlane
Me.GraphicsDevice.ClipPlanes(0).IsEnabled = True
Me.GraphicsDevice.SetRenderTarget(0, RefractionTarget)
Me.GraphicsDevice.Clear(ClearOptions.Target Or ClearOptions.DepthBuffer, Color.Black, 1.0F, 0)
DrawTerrain(ViewMatrix)
Me.GraphicsDevice.ClipPlanes(0).IsEnabled = False
Me.GraphicsDevice.SetRenderTarget(0, Nothing)
RefractionMap = RefractionTarget.GetTexture()
Me.GraphicsDevice.Clear(Color.CornflowerBlue)
End Sub
Private Sub DrawReflectionMap()
Dim Rotation As Matrix = _
Matrix.CreateRotationX(UpDownRotation) * _
Matrix.CreateRotationY(LeftRightRotation)
Dim Forward As New Vector3(0, 0, -1)
Dim Right As New Vector3(1, 0, 0)
Dim TargetPos As Vector3 = _
CameraPosition + Vector3.Transform(Forward, Rotation)
Dim ReflectionPos As Vector3 = CameraPosition
Dim ReflectionTargetPos As Vector3 = TargetPos
ReflectionPos.Y = 2 * WaterHeight - ReflectionPos.Y
ReflectionTargetPos.Y = 2 * WaterHeight - ReflectionTargetPos.Y
Dim ReflectionUp As Vector3 = Vector3.Cross( _
Vector3.Transform(Right, Rotation), ReflectionTargetPos - ReflectionPos)
ReflectionViewMatrix = Matrix.CreateLookAt( _
ReflectionPos, ReflectionTargetPos, ReflectionUp)
Dim ReflectionPlane As Plane = _
CreatePlane(WaterHeight - 0.5F, ReflectionViewMatrix, New Vector3(0, -1, 0), True)
Me.GraphicsDevice.ClipPlanes(0).Plane = ReflectionPlane
Me.GraphicsDevice.ClipPlanes(0).IsEnabled = True
Me.GraphicsDevice.SetRenderTarget(0, ReflectionTarget)
Me.GraphicsDevice.Clear(ClearOptions.Target Or _
ClearOptions.DepthBuffer, Color.Black, 1.0F, 0)
DrawTerrain(ReflectionViewMatrix)
DrawSky(ReflectionViewMatrix)
Me.GraphicsDevice.ClipPlanes(0).IsEnabled = False
Me.GraphicsDevice.SetRenderTarget(0, Nothing)
ReflectionMap = ReflectionTarget.GetTexture()
Me.GraphicsDevice.Clear(Color.CornflowerBlue)
End Sub
Private Sub SetWaterVertices()
ReDim WaterVertices(5)
Dim HalfSize As Int16 = 400
WaterVertices(0).Position = New Vector3(-HalfSize, WaterHeight, HalfSize)
WaterVertices(1).Position = New Vector3(-HalfSize, WaterHeight, -HalfSize)
WaterVertices(2).Position = New Vector3(HalfSize, WaterHeight, HalfSize)
WaterVertices(3).Position = New Vector3(HalfSize, WaterHeight, HalfSize)
WaterVertices(4).Position = New Vector3(-HalfSize, WaterHeight, -HalfSize)
WaterVertices(5).Position = New Vector3(HalfSize, WaterHeight, -HalfSize)
WaterVertices(0).TextureCoordinate = New Vector2(0, 1)
WaterVertices(1).TextureCoordinate = New Vector2(0, 0)
WaterVertices(2).TextureCoordinate = New Vector2(1, 1)
WaterVertices(3).TextureCoordinate = New Vector2(1, 1)
WaterVertices(4).TextureCoordinate = New Vector2(0, 0)
WaterVertices(5).TextureCoordinate = New Vector2(1, 0)
WaterVBuffer = New VertexBuffer(Me.GraphicsDevice, _
WaterVertices.Length * VertexPositionTexture.SizeInBytes, _
BufferUsage.WriteOnly)
WaterVBuffer.SetData(WaterVertices)
WDeclaration = New VertexDeclaration(Me.GraphicsDevice, VertexPositionTexture.VertexElements)
End Sub
Private Sub DrawWater(ByVal Time As Single)
Shader.CurrentTechnique = Shader.Techniques("Water")
Shader.Parameters("View").SetValue(ViewMatrix)
Shader.Parameters("Projection").SetValue(ProjectionMatrix)
Shader.Parameters("World").SetValue(Matrix.Identity)
Shader.Parameters("ReflectionView").SetValue(ReflectionViewMatrix)
Shader.Parameters("RefractionMap").SetValue(RefractionMap)
Shader.Parameters("ReflectionMap").SetValue(ReflectionMap)
Shader.Parameters("BumpMap").SetValue(BumpMap)
Shader.Parameters("WaveLength").SetValue(0.01F)
Shader.Parameters("WaveHeight").SetValue(0.3F)
Shader.Parameters("CameraPosition").SetValue(CameraPosition)
Shader.Parameters("Time").SetValue(Time)
Shader.Parameters("WindDirection").SetValue(New Vector3(0, 0, 1))
Shader.Parameters("WindForce").SetValue(0.0002F)
Dim Prev As CullMode = Me.GraphicsDevice.RenderState.CullMode
Me.GraphicsDevice.RenderState.CullMode = CullMode.None
Me.GraphicsDevice.Vertices(0).SetSource( _
WaterVBuffer, 0, VertexPositionTexture.SizeInBytes)
Shader.Begin()
For Each Pass As EffectPass In Shader.CurrentTechnique.Passes
Pass.Begin()
With Me.GraphicsDevice
.VertexDeclaration = WDeclaration
Me.GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, WaterVertices.Length / 3)
End With
Pass.End()
Next
Shader.End()
Me.GraphicsDevice.RenderState.CullMode = Prev
End Sub
#End Region
#Region "Gestione telecamera"
Private Sub ProcessMouseInput(ByVal ElapsedTime As Single)
Dim CurrentMouseState As MouseState = Mouse.GetState
If CurrentMouseState <> PrevMouseState Then
Dim DX As Single = _
CurrentMouseState.X - PrevMouseState.X
Dim DY As Single = _
CurrentMouseState.Y - PrevMouseState.Y
LeftRightRotation -= DX * RotationSpeed * ElapsedTime
UpDownRotation -= DY * RotationSpeed * ElapsedTime
Mouse.SetPosition(Me.GraphicsDevice.Viewport.Width / 2, _
Me.GraphicsDevice.Viewport.Height / 2)
UpdateView()
End If
End Sub
Private Sub ProcessKeyboardInput()
Dim Motion As New Vector3(0, 0, 0)
Dim KeyState As KeyboardState = Keyboard.GetState
If KeyState.IsKeyDown(Keys.W) Then
Motion += New Vector3(0, 0, -1)
End If
If KeyState.IsKeyDown(Keys.S) Then
Motion += New Vector3(0, 0, 1)
End If
If KeyState.IsKeyDown(Keys.D) Then
Motion += New Vector3(1, 0, 0)
End If
If KeyState.IsKeyDown(Keys.A) Then
Motion += New Vector3(-1, 0, 0)
End If
If KeyState.IsKeyDown(Keys.Up) Then
Motion += New Vector3(0, 1, 0)
End If
If KeyState.IsKeyDown(Keys.Down) Then
Motion += New Vector3(0, -1, 0)
End If
UpdatePosition(Motion)
End Sub
Private Sub UpdateView()
Dim Rotation As Matrix = _
Matrix.CreateRotationX(UpDownRotation) * _
Matrix.CreateRotationY(LeftRightRotation)
Dim Forward As New Vector3(0, 0, -1)
Dim Up As New Vector3(0, 1, 0)
Dim RotForward As Vector3 = _
Vector3.Transform(Forward, Rotation)
Dim RotUp As Vector3 = Vector3.Transform(Up, Rotation)
Dim Target As Vector3 = CameraPosition + RotForward
ViewMatrix = Matrix.CreateLookAt(CameraPosition, Target, RotUp)
End Sub
Private Sub UpdatePosition(ByVal Motion As Vector3)
Dim Rotation As Matrix = _
Matrix.CreateRotationX(UpDownRotation) * _
Matrix.CreateRotationY(LeftRightRotation)
Dim RotMotion As Vector3 = Vector3.Transform(Motion, Rotation)
CameraPosition += RotMotion * MoveSpeed
Dim Y As Single
If (Math.Abs(CameraPosition.X) < Me.TerrainWidth / 2) And _
(Math.Abs(CameraPosition.Z) < Me.TerrainLength / 2) Then
Dim X1, X2, Z1, Z2 As Int32
With CameraPosition
X1 = CInt(Math.Floor(.X))
X2 = CInt(Math.Ceiling(.X))
Z1 = CInt(Math.Floor(.Z))
Z2 = CInt(Math.Ceiling(.Z))
End With
If X1 <> X2 And Z1 <> Z2 Then
Dim Q11, Q12, Q21, Q22 As Single
Q11 = HeightData(X1 + Me.TerrainWidth / 2, -Z1 + Me.TerrainLength / 2)
Q12 = HeightData(X1 + Me.TerrainWidth / 2, -Z2 + Me.TerrainLength / 2)
Q21 = HeightData(X2 + Me.TerrainWidth / 2, -Z1 + Me.TerrainLength / 2)
Q22 = HeightData(X2 + Me.TerrainWidth / 2, -Z2 + Me.TerrainLength / 2)
Dim X, Z As Single
X = CameraPosition.X
Z = CameraPosition.Z
Y = (Q11 * (X2 - X) * (Z2 - Z) + _
Q21 * (X - X1) * (Z2 - Z) + _
Q12 * (X2 - X) * (Z - Z1) + _
Q22 * (X - X1) * (Z - Z1)) / ((X2 - X1) * (Z2 - Z1))
Else
Y = HeightData(X1 + Me.TerrainWidth / 2, -Z1 + Me.TerrainLength / 2)
End If
End If
If (IsJumping) And (CameraPosition.Y + JumpingYVelocity) > Y + 0.5 Then
CameraPosition.Y += JumpingYVelocity
JumpingYVelocity = JumpingYInitial - Gravity * JumpTime
Else
CameraPosition.Y = Y + 0.5
IsJumping = False
End If
UpdateView()
End Sub
#End Region
#Region "Gestione risorse"
Sub New()
Me.Graphics = New GraphicsDeviceManager(Me)
Me.Content.RootDirectory = "content"
End Sub
Protected Overrides Sub Initialize()
MyBase.Initialize()
End Sub
Protected Overrides Sub LoadContent()
Shader = GetEffect(AppPath & "\SimpleShader.fx")
Grass = GetTexture(AppPath & "\grass.dds")
Sand = GetTexture(AppPath & "\sand.dds")
Rock = GetTexture(AppPath & "\rock.dds")
Snow = GetTexture(AppPath & "\snow.dds")
BumpMap = GetTexture(AppPath & "\BumpMap.jpg")
For I As Byte = 0 To 4
SkyFaces(I) = GetTexture(AppPath & "\skyface" & (I + 1) & ".png")
Next
Dim Params As PresentationParameters = _
Me.GraphicsDevice.PresentationParameters
RefractionTarget = New RenderTarget2D(Me.GraphicsDevice, _
Params.BackBufferWidth, Params.BackBufferHeight, 1, _
Me.GraphicsDevice.DisplayMode.Format)
ReflectionTarget = New RenderTarget2D(Me.GraphicsDevice, _
Params.BackBufferWidth, Params.BackBufferHeight, 1, _
Me.GraphicsDevice.DisplayMode.Format)
LoadHeightMap(GetTexture(AppPath & "\HeightMap.bmp"))
LoadSkyDome()
SetVertices()
SetIndices()
SetNormals()
SetWaterVertices()
CopyToBuffer()
ProjectionMatrix = Matrix.CreatePerspectiveFieldOfView( _
MathHelper.PiOver4, _
Me.GraphicsDevice.Viewport.AspectRatio, _
0.1, 1000)
CameraPosition = New Vector3(0, 40, TerrainLength / 2)
Mouse.SetPosition(Me.GraphicsDevice.Viewport.Width / 2, _
Me.GraphicsDevice.Viewport.Height / 2)
PrevMouseState = Mouse.GetState
UpdateView()
MyBase.LoadContent()
End Sub
Protected Overrides Sub UnloadContent()
MyBase.UnloadContent()
End Sub
#End Region
#Region "Aggiornamento mondo 3D"
Private Sub DrawTerrain(ByVal View As Matrix)
Shader.CurrentTechnique = Shader.Techniques("MultiTextured")
Shader.Parameters("View").SetValue(View)
Shader.Parameters("Projection").SetValue(ProjectionMatrix)
Shader.Parameters("World").SetValue( _
Matrix.CreateTranslation( _
New Vector3(-TerrainWidth / 2, 0, TerrainLength / 2)))
Dim LightDirection As New Vector3(27.73, -17.67, 6.14)
LightDirection.Normalize()
Shader.Parameters("LightEnabled").SetValue(True)
Shader.Parameters("LightDirection").SetValue(LightDirection)
Shader.Parameters("AmbientFactor").SetValue(0.3F)
Shader.Parameters("Texture0").SetValue(Sand)
Shader.Parameters("Texture1").SetValue(Grass)
Shader.Parameters("Texture2").SetValue(Rock)
Shader.Parameters("Texture3").SetValue(Snow)
Me.GraphicsDevice.Indices = IBuffer
Me.GraphicsDevice.Vertices(0).SetSource( _
VBuffer, 0, VertexPositionNormalMultitexture.SizeInBytes)
Shader.Begin()
For Each Pass As EffectPass In Shader.CurrentTechnique.Passes
Pass.Begin()
With Me.GraphicsDevice
.VertexDeclaration = VDeclaration
Me.GraphicsDevice.DrawIndexedPrimitives( _
PrimitiveType.TriangleList, 0, 0, _
Vertices.Length, 0, Indices.Length / 3)
End With
Pass.End()
Next
Shader.End()
End Sub
Protected Overrides Sub Update(ByVal GameTime As GameTime)
ProcessMouseInput(GameTime.ElapsedGameTime.TotalSeconds)
ProcessKeyboardInput()
Dim k As KeyboardState = Keyboard.GetState
If k.IsKeyDown(Keys.M) Then
ReflectionMap.Save("prova.jpg", ImageFileFormat.Jpg)
Me.Exit()
End If
If k.IsKeyDown(Keys.Space) And (IsJumping = False) Then
JumpStart = GameTime.TotalGameTime
JumpingYVelocity = JumpingYInitial
IsJumping = True
ElseIf IsJumping Then
JumpTime = (GameTime.TotalGameTime - JumpStart).TotalSeconds
End If
MyBase.Update(GameTime)
End Sub
Protected Overrides Sub Draw(ByVal gameTime As GameTime)
Me.Graphics.GraphicsDevice.Clear(Color.CornflowerBlue)
DrawRefractionMap()
DrawReflectionMap()
DrawSky(ViewMatrix)
DrawTerrain(ViewMatrix)
DrawWater(gameTime.TotalGameTime.TotalMilliseconds / 100.0F)
MyBase.Draw(gameTime)
End Sub
#End Region
End Class