Chinaunix首页 | 论坛 | 博客
  • 博客访问: 8609417
  • 博文数量: 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:48:44

' ________________________________________________________________________
' TrueVision3D (web: http://www.truevision3d.com)
' ????????????????????????????????????
' Tutorial 6 : Move in the room.
' ?????
' Description : In this 6th tutorial, we take the previous tutorial,
' ?????? we add a sky box to the scene and add the code to
' allow us to move in this room.

' Force explicit declarations
Option Explicit

' We declare TVEngine.
Private TV3D As TVEngine

' We have to delare the room that we will use for this tutorial.
Private Room As TVMesh

' We declare the scene
Private Scene As TVScene

' We declare the texture factory in order to load textures.
Private TextureFactory As TVTextureFactory

' We declare the input engine.
Private InputEngine As TVInputEngine

' We declare the Atmosphere class for the sky
'设定天空大气
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 '射击

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
    
    ' And the texture factory
    Set TextureFactory = New TVTextureFactory

    ' We create the atmosphere (for sky)
    '为天空设置大气
    Set Atmos = New TVAtmosphere
    
    ' We load the sky textures.
    ' One for each face of the cube.
    '加载材质
    TextureFactory.LoadTexture "..\..\..\Media\top.bmp", "SkyTop"
    TextureFactory.LoadTexture "..\..\..\Media\bottom.bmp", "SkyBottom"
    TextureFactory.LoadTexture "..\..\..\Media\left.bmp", "SkyLeft"
    TextureFactory.LoadTexture "..\..\..\Media\right.bmp", "SkyRight"
    TextureFactory.LoadTexture "..\..\..\Media\front.bmp", "SkyFront"
    TextureFactory.LoadTexture "..\..\..\Media\back.bmp", "SkyBack"
    
    ' New : here is an other truth about 3D games : the sky ain't
    ' a real It's just an immense box that surrounds the map
    ' and stand still, so when we turn around, it looks like
    ' if there was a sky, but no,it's only a box. Also, know that
    ' the TV3D sky boxe is inversed so you have to inverse the order
    ' you set your textures.
    '设置天空材质
    Atmos.SkyBox_SetTexture GetTex("SkyFront"), GetTex("SkyBack"), GetTex("SkyLeft"), GetTex("SkyRight"), GetTex("SkyTop"), GetTex("SkyBottom")
    Atmos.SkyBox_Enable True
    
    ' We load the floor texture and wall texture into the texture factory.
    TextureFactory.LoadTexture "..\..\..\Media\fieldstone.tga", "FloorTexture"
    TextureFactory.LoadTexture "..\..\..\Media\roof1.bmp", "WallTexture"
    
     ' We tell the scene... Note that the mesh object
    ' is directly created by the CreateMeshBuilder function
    ' so you don't need to do Set Mesh = New TVMesh
    '设置墙
    Set Room = Scene.CreateMeshBuilder
    
    ' We create the room's walls.
   Room.AddWall GetTex("WallTexture"), 500, -500, -500, -500, 100, 0, 3, 1
    Room.AddWall GetTex("WallTexture"), -500, -500, -500, 500, 100, 0, 3, 1
    Room.AddWall GetTex("WallTexture"), -500, 500, 500, 500, 100, 0, 3, 1
    Room.AddWall GetTex("WallTexture"), 500, 500, 500, -500, 100, 0, 3, 1
    
    
    ' Like the "add wall" method, we will add a floor to this room.
    Room.AddFloor GetTex("FloorTexture"), -500, -500, 500, 500, 0, 10, 10
    
    ' We set the camera vectors (position and look at) and angles.
    '设置视图矢量值
    sngPositionX = 0
    sngPositionY = 20
    sngPositionZ = 0
    snglookatX = 0
    snglookatY = 20
    snglookatZ = 50
    sngAngleX = 0
    sngAngleY = 0
    
    ' We set the initial values of movement
    sngWalk = 0
    sngStrafe = 0
    
    ' We pop the form over everything else.
    Form1.Show
        
    ' Set The View distance
    '设置场景可视距离
    Scene.SetViewFrustum 60, 10000
    
    ' 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
        
        ' Just like in tutorial 4, where we moved the teapot by using
        ' the keyboard and mouse input, we will move the camera vectors
        ' (position and look at) with the keyboard and mouse. But this
        ' time, we will get hard core with the math. But, don't be too
        ' scared, once you created the right movement code, you don't
        ' need to recreate it : you use CUT and PASTE.
        
        ' 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

        ' We pass the actual value of the mouse scroller to the variable
        ' that holds the old mouse scroller value.
        tmpMouseScrollOld = tmpMouseScrollNew

        ' By using GetMouseState, we get the movement of the mouse
        ' with the speed of the movement. The fastest the mouse movement
        ' will be, the higher will be the return.
        '获取鼠标状态
        InputEngine.GetMouseState tmpMouseX, tmpMouseY, tmpMouseB1, tmpMouseB2, tmpMouseB3, tmpMouseScrollNew

        ' From the mouse return values, we update the camera angles
        ' by adding or substracting the mouse return value.
        '通过加减鼠标返回值,来更新视图角度
        sngAngleX = sngAngleX - (tmpMouseY / 100)
        sngAngleY = sngAngleY - (tmpMouseX / 100)

        ' We will add a simple check, so we can't look up at more
        ' than 80 degrees nor down than -80 degrees.
        If sngAngleX > 1.3 Then sngAngleX = 1.3
        If sngAngleX < -1.3 Then sngAngleX = -1.3

        ' Okay, now for the smothing of the movement... We checked
        ' above if we were pressing a key. If so, then we updated the
        ' movement variable to 1 (positive or negative). Here, we
        ' lower this value until it get to 0. This method give us a
        ' smoother camera movement. We start by updating the forward
        ' and backward (walk) movement.
        
        '前后
        Select Case sngWalk
        Case Is > 0
            sngWalk = sngWalk - 0.05
            If sngWalk < 0 Then sngWalk = 0
        Case Is < 0
            sngWalk = sngWalk + 0.05
            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.05
            If sngStrafe < 0 Then sngStrafe = 0
        Case Is < 0
            sngStrafe = sngStrafe + 0.05
            If sngStrafe > 0 Then sngStrafe = 0
        End Select
        
        ' Update the vectors using the angles and positions.
        ' If you don't understand the trigonometry behind this
        ' you can look up quickly the trigonometry in triangles
        ' cosinus, sinus and tangent.
        sngPositionX = sngPositionX + (Cos(sngAngleY) * sngWalk * TV3D.TimeElapsed) + (Cos(sngAngleY + 3.141596 / 2) * sngStrafe * TV3D.TimeElapsed)
        sngPositionZ = sngPositionZ + (Sin(sngAngleY) * sngWalk * TV3D.TimeElapsed) + (Sin(sngAngleY + 3.141596 / 2) * sngStrafe * TV3D.TimeElapsed)
        snglookatX = sngPositionX + Cos(sngAngleY)
        snglookatY = sngPositionY + Tan(sngAngleX)
        snglookatZ = sngPositionZ + Sin(sngAngleY)
        
        ' or use the easier functions of the TVCamera class.
        ' Camera.MoveRelative
        ' Camera.SetRotation
        ' Camera.RotateX|Y|Z

        ' 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

        ' Clear the the last frame.
        TV3D.Clear
        
        ' New : we have to render the sky. We do this before everything
        ' else. As mentionned before, objects in the 3D digitalized world
        ' needs to be rendered. Because they are not rendered all
        ' together, at the same instant, we have to decide what we render
        ' before then what we render after. If we render the sky after
        ' rendering our room, we wont see the room.
        ' The sky rendering is done in the global atmosphere rendering
        '渲染大气
        Atmos.Atmosphere_Render
        
        
        ' 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 Main_Quit()
        
    ' We want to quit the project, so we destroy the room object.
    Set Room = 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

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