Chinaunix首页 | 论坛 | 博客
  • 博客访问: 8699062
  • 博文数量: 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:57:00

' ________________________________________________________________________
' TrueVision3D                        (web: )
' ????????????????????????????????????
' Tutorial 16 : Add trees to landscape
' ??????
' Description : In this 16th tutorial, we go back a bit. We are going to
' ??????  generate a simple landscape and add trees at random
'               positions. Those trees won't be nothing else than
'               billboards.

'               Billboards are 2d sprites that are set in the 3d world.
'               they can simulate quite cylindrical objects, like trees
'               or explosion sprites. It's a good way to reduce the number
'               of polys to render.

' Force explicit declarations
Option Explicit

' We declare TrueVision3D.
Private TV3D As TVEngine

' We declare the landscape
Private Land As TVLandscape
   
' New : we declare the trees. Note that we don't know yet how much
' trees we are going to place on the land so we will use a dynamic
' array that will be set at run time.
Private TheTree() As TVMesh

' This will be quantity of trees
Private intTreeQuantity As Integer

' The texture factory
Private TextureFactory As TVTextureFactory

' We the declare the scene
Private Scene As TVScene

' We declare the input engine.
Private InputEngine As TVInputEngine

' 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

Private Sub cmdQuit_Click()

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

End Sub

Private Sub Form_Load()

    ' New : because we want random value, we will use this random
    ' method to be sure that we won't get the same random values
    ' each time we play with this tutorial.
    Randomize Timer

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

    ' Set search directory of Textures, Objects, ...
    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 set the scene color
    Scene.SetSceneBackGround 0.3, 0.7, 0.9

    ' We set the tex factory
    Set TextureFactory = New TVTextureFactory

    ' The land generation
    Set Land = New TVLandscape
               
    ' Generate the height of the land from the grayscale of the image.
    Land.GenerateHugeTerrain "..\..\..\Media\Heightmaps\heightmap.jpg", TV_PRECISION_LOW, 4, 4, 0, 0, True
   
    ' Then, we load the land texture.
    TextureFactory.LoadTexture "..\..\..\Media\grass9.jpg", "LandTexture"
   
    ' We assign a texture to that land.
    Land.SetTexture GetTex("LandTexture")
   
    ' New and fun part : we add the trees to the land by using billboards.
    ' what are billboard? There are simply a 2d texture placed somewhere
    ' in a 3D world. They have a height and a width but they don't have
    ' any depth. What the use of using 2D in a 3D world? If you 5 trees,
    ' there are none : create your trees in 3D. If you have 2,500 trees,
    ' then you have a big FPS problem because the engine has to compute
    ' every polygons of each tree. This is where the billboards become
    ' handy because each billboard has only 2 polygons : 2 triangles
    ' that makes the billboard rectangle. Let's start by loading the
    ' tree texture. The texture that we will be using is in a dds format.
    ' DDS format is nothing more than 2 BMP files layered : the first one
    ' is the texture, the second one is the alpha layer. You can create
    ' your own DDS files by using the "DirectX Texture Tool" that come
    ' in the directX9 sdk, or you can also create it with TexED
    ' that comes with the TV3D SDK
    '在材质库加载树的材质,使用dds文件(可以用directx 纹理工具)制作
    '树的制作并不是通过3d模式进行,而是一种叫做“广告牌"的东西制作而成。
    '这种方法只要有树的贴图即可
    TextureFactory.LoadTexture "..\..\..\Media\Tree.dds", "TreeTexture", , , TV_COLORKEY_BLACK
   
    ' We define how much trees we are going to create
    '设定树的数量
    intTreeQuantity = 200
   
    ' We redim (set) the size of the tree array
    '重定义树数组
    ReDim TheTree(intTreeQuantity)
   
    ' We find a random position for each tree
    Dim i As Integer, x As Single, y As Single, z As Single
    For i = 1 To intTreeQuantity
   
        x = (1024 * Rnd)
        z = (1024 * Rnd)
        y = Land.GetHeight(x, z)
       
        ' We create the mesh in the scene and place it. Something important
        ' to remember : if you created your billboard images topdown, you
        ' will have to invert it's texture in a paint editor or by setting
        ' the billboard height negative. And because you create your tree's
        ' billboard with a negative height value, you will have to add extra
        ' height to the Y position.
        '将树作为广告牌
        Set TheTree(i) = Scene.CreateBillboard(GetTex("TreeTexture"), x, y + 64, z, 64, -64)
        '设置广告牌形式
        TheTree(i).SetBillboardType TV_BILLBOARD_YAXIS
        TheTree(i).SetAlphaTest True, 32
    Next i
   
    ' We set the camera vectors (position and look at) and angles.
    sngPositionX = 80
    sngPositionY = 20
    sngPositionZ = 80
    snglookatX = 80
    snglookatY = 20
    snglookatZ = 150
    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
       
        ' We check the input
        Check_Input
       
        ' We check and update the movement
        Check_Movement

        ' Clear the the last frame.
        TV3D.Clear
       
        ' We 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)
        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 destroying
    ' the texture factory.
    Set TextureFactory = Nothing
   
    ' We destroy each tree
    Dim i As Integer
    For i = 1 To intTreeQuantity
        Set TheTree(i) = Nothing
    Next i
   
    ' 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

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