Chinaunix首页 | 论坛 | 博客
  • 博客访问: 8545502
  • 博文数量: 1413
  • 博客积分: 11128
  • 博客等级: 上将
  • 技术积分: 14685
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-13 10:03
个人简介

follow my heart...

文章分类

全部博文(1413)

文章存档

2013年(1)

2012年(5)

2011年(45)

2010年(176)

2009年(148)

2008年(190)

2007年(293)

2006年(555)

分类:

2006-11-26 19:50:14

' ________________________________________________________________________
' TrueVision3D (web: http://www.truevision3d.com)
' ????????????????????????????????????
' Tutorial 7 : A landscape.
' ?????
' Description : In this 7th tutorial, we keep the movement code from
' ?????? the last tutorial but change the room for a land.
' Terrain/Landscape is another big feature of TV3D
' It allows to render really huge and realistic outdoors scene
' using detailed terrain and texture.
'
'
' Update on the basic steps : Since the beginning, we have been playing
' ????????????? with all the objects included in TV3D. Now,
' it's time to add extra functionnality by
' adding DirectX8 to our project. So, just
' like the first time you referenced TV3D to
' your project, reference "DirectX8 for
' Visual Basic Type Library"
.

' Force explicit declarations
Option Explicit

' We declare TrueVision3D.
Private TV3D As TVEngine

' We declare the landscape
Private Land As TVLandscape

' Defines the texture factory. To apply a texture to the land, we have
' to use and other object that will hold all the textures needed
' in our project.
Private TextureFactory As TVTextureFactory

' We the declare the scene
Private Scene As TVScene

' We declare the input engine.
Private InputEngine As TVInputEngine

' We declare the atmosphere
Private Atmos As TVAtmosphere

' The loop.
Private DoLoop As Boolean

' We are going to use camera (point of view) angles, as well as the
' camera position and look at vectors.
Private sngPositionX As Single
Private sngPositionY As Single
Private sngPositionZ As Single
Private snglookatX As Single
Private snglookatY As Single
Private snglookatZ As Single
Private sngAngleX As Single
Private sngAngleY As Single

' We could have done this in many ways, but we added some smoothing to
' the movement se we need to declare two additional variables.
Private sngWalk As Single
Private sngStrafe As Single

' We declare a variable which will hold the water height.
Private sngWaterHeight As Single

Private Sub cmdQuit_Click()

    ' We have clicked on the "Quit" button, so we change the DoLoop.
    DoLoop = False

End Sub

Private Sub Form_Load()

    ' We have to create the TV3D object before anything else.
    Set TV3D = New TVEngine

    ' Set the search directory of the objects, textures, ...
    TV3D.SetSearchDirectory App.Path
    
    ' We initialize TV3D in the picture box of the form.
    TV3D.Init3DWindowedMode Picture1.hWnd

    ' We want to see the FPS.
    TV3D.DisplayFPS = True

    ' We create the input object.
    Set InputEngine = New TVInputEngine

    ' We create the scene (the world).
    Set Scene = New TVScene
    
    ' We create the atmosphere for the sky
    Set Atmos = New TVAtmosphere

    ' We need to create a new object which will
    ' hold all the textures needed for our land.
    Set TextureFactory = New TVTextureFactory


    ' We load the sky textures.
    TextureFactory.LoadTexture "..\..\..\Media\sky\sunset\up.jpg", "SkyTop"
    TextureFactory.LoadTexture "..\..\..\Media\sky\sunset\down.jpg", "SkyBottom"
    TextureFactory.LoadTexture "..\..\..\Media\sky\sunset\left.jpg", "SkyLeft"
    TextureFactory.LoadTexture "..\..\..\Media\sky\sunset\right.jpg", "SkyRight"
    TextureFactory.LoadTexture "..\..\..\Media\sky\sunset\front.jpg", "SkyFront"
    TextureFactory.LoadTexture "..\..\..\Media\sky\sunset\back.jpg", "SkyBack"
    
    ' We set the sky textures, into on each face of the skycube.

    Atmos.SkyBox_SetTexture GetTex("SkyFront"), GetTex("SkyBack"), GetTex("SkyLeft"), GetTex("SkyRight"), GetTex("SkyTop"), GetTex("SkyBottom")
    Atmos.SkyBox_Enable True


    ' New : the land generation. This is so much fun because it's
    ' so You load a texture as a height map, the engine
    ' does the rest. But before this, we create the land object.
    '设置地形
    Set Land = New TVLandscape
        
    ' Generate the height of the land from the grayscale of the image.
    ' Black is altitude 0 for the engine, and White is altitude 255.
    ' See the FAQ of JohnnyC on the site, for further information
    ' about all the subtilities of Terrain generation.
    '生成巨大地形根据灰度图形,黑色海拔为0,白色海拔为255
    Land.GenerateHugeTerrain "..\..\..\Media\heightmap.jpg", TV_PRECISION_LOW, 8, 8, 0, 0, True
    
    ' Then, we load the land texture that will be applied to the land
    ' here we take a grass texture.
    '加载材质
    TextureFactory.LoadTexture "..\..\..\Media\grass9.jpg", "LandTexture"
    
    ' We assign a texture to that land.
    '将材质赋给地面
    Land.SetTexture GetTex("LandTexture")
    
    ' Change the tiling of the texture, this means that you can repeat the texture motif
    ' several times per landscape chunk (part of terrain) or several times.
    ' Here we will repeat the grass motif 2x2 on a chunk
    '设置材质刻度
    Land.SetTextureScale 2, 2
    
    ' Now we set simply the viewdistance
    '设置视图距离
    Scene.SetViewFrustum 60, 5000
    
    ' We set the camera vectors (position and look at) and angles.
    ' at the center of the landscape.
    sngPositionX = 512
    sngPositionY = 20
    sngPositionZ = 512
    snglookatX = 512
    snglookatY = 20
    snglookatZ = 550
    sngAngleX = 0
    sngAngleY = 0
    
    ' We set the initial values of movement
    sngWalk = 0
    sngStrafe = 0
    
    ' We pop the form over everything else.
    Form1.Show
        
    ' We start the main loop.
    DoLoop = True
    Main_Loop

End Sub

Private Sub Form_Unload(Cancel As Integer)

    ' The user asked to quit but clicked on the 'X' button at up right.
    DoLoop = False
    
    ' And ask to quit.
    Main_Quit

End Sub

Private Sub Main_Loop()
    ' The main loop
    Do
        ' Let us the capacity to use buttons of the form.
        DoEvents
        
        ' New : We moved the movement code in an other sub to make
        ' the code clearer.
        '检测输入
        Check_Input
        
        ' New : We moved the checking of maximum camera "look at" and
        ' also the camera movement smoothing in an other sub too.
        '检没移动
        Check_Movement

        ' Clear the the last frame.
        TV3D.Clear
        
        ' New have to render the sky.
        Atmos.Atmosphere_Render
        
        ' New : we have to render the landscape.
        Land.Render True
                
        ' We render all the 3D objects contained in the scene.
        Scene.RenderAllMeshes
                
        ' We display everything that we have rendered
       TV3D.RenderToScreen
        
     
    'We loop all of this until the DoLoop isn't True.
    Loop Until DoLoop = False
    
    ' We ask to quit.
    Main_Quit

End Sub

Private Sub Check_Input()
        
        ' Check if we pressed the UP arrow key, if so, then we are
        ' walking forward.
        If InputEngine.IsKeyPressed(TV_KEY_UP) = True Then
            
            sngWalk = 1
            
        ' If we are not walking forward, maybe we are walking backward
        ' by using the DOWN arrow? If so, set walk speed to negative.
        ElseIf InputEngine.IsKeyPressed(TV_KEY_DOWN) = True Then
            
            sngWalk = -1
        
        End If

        ' Check if we pressed the LEFT arrow key, if so, then strafe
        ' on the left.
        If InputEngine.IsKeyPressed(TV_KEY_LEFT) = True Then
            
            sngStrafe = 1
                
        ' If we are not strafing left, maybe we want to strafe to the
        ' right, using the RIGHT arrow? If so, set strafe to negative.
        ElseIf InputEngine.IsKeyPressed(TV_KEY_RIGHT) = True Then
        
            sngStrafe = -1
        
        End If

        ' Now, for the mouse input...
        Dim tmpMouseX As Long, tmpMouseY As Long
        Dim tmpMouseB1 As Integer, tmpMouseB2 As Integer, tmpMouseB3 As Integer
        Dim tmpMouseScrollOld As Long, tmpMouseScrollNew As Long

        ' Actual value to old mouse scroller value.
        tmpMouseScrollOld = tmpMouseScrollNew

        ' Get the movement of the mouse.
        InputEngine.GetMouseState tmpMouseX, tmpMouseY, tmpMouseB1, tmpMouseB2, tmpMouseB3, tmpMouseScrollNew

        ' Update the camera angles.
        sngAngleX = sngAngleX - (tmpMouseY / 100)
        sngAngleY = sngAngleY - (tmpMouseX / 100)

End Sub

Private Sub Check_Movement()
        
        ' Simple check of the mouse.
        If sngAngleX > 1.3 Then sngAngleX = 1.3
        If sngAngleX < -1.3 Then sngAngleX = -1.3

        ' Okay, now for the smothing of the movement... Update
        ' the forward and backward (walk) movement.
        Select Case sngWalk
        Case Is > 0
            sngWalk = sngWalk - 0.005 * TV3D.TimeElapsed
            If sngWalk < 0 Then sngWalk = 0
        Case Is < 0
            sngWalk = sngWalk + 0.005 * TV3D.TimeElapsed
            If sngWalk > 0 Then sngWalk = 0
        End Select
        
        ' Now, we update the left and right (strafe) movement.
        Select Case sngStrafe
        Case Is > 0
            sngStrafe = sngStrafe - 0.005 * TV3D.TimeElapsed
            If sngStrafe < 0 Then sngStrafe = 0
        Case Is < 0
            sngStrafe = sngStrafe + 0.005 * TV3D.TimeElapsed
            If sngStrafe > 0 Then sngStrafe = 0
        End Select
        
        ' Update the vectors using the angles and positions.
        sngPositionX = sngPositionX + (Cos(sngAngleY) * sngWalk / 5 * TV3D.TimeElapsed) + (Cos(sngAngleY + 3.141596 / 2) * sngStrafe / 5 * TV3D.TimeElapsed)
        sngPositionZ = sngPositionZ + (Sin(sngAngleY) * sngWalk / 5 * TV3D.TimeElapsed) + (Sin(sngAngleY + 3.141596 / 2) * sngStrafe / 5 * TV3D.TimeElapsed)
        
        ' New : because we are using a landscape with up and down, we
        ' can't let the camera at the same height. We want the camera to
        ' follow the height of the map, so we use the "get height". Also,
        ' because we want to have the effect that we are not a mouse,
        ' we will add some height to the height returned...
        sngPositionY = Land.GetHeight(sngPositionX, sngPositionZ) + 10
        
        ' We update the look at position.
        snglookatX = sngPositionX + Cos(sngAngleY)
        snglookatY = sngPositionY + Tan(sngAngleX)
        snglookatZ = sngPositionZ + Sin(sngAngleY)

        ' With the new values of the camera vectors (position and
        ' look at), we update the scene's camera.
        '设置摄像视角
        Scene.SetCamera sngPositionX, sngPositionY, sngPositionZ, snglookatX, snglookatY, snglookatZ

End Sub

Private Sub Main_Quit()
        
    ' We want to quit the project, so we start by desroyng
    ' the texture factory.
    Set TextureFactory = Nothing
    
    ' We destroy the land object.
    Set Land = Nothing
    
    ' Don't forget to destroy the inputengine object...
    Set InputEngine = Nothing
    
    ' Then, we destroy the scene object.
    Set Scene = Nothing
    
    ' We finish the frenetic destroy with the TV3D object.
    Set TV3D = Nothing
    
    ' We end the application.
    End

End Sub

 

阅读(2450) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~