VERSION 5.00 Begin VB.Form Form1 Caption = "Form1" ClientHeight = 8055 ClientLeft = 60 ClientTop = 345 ClientWidth = 8880 LinkTopic = "Form1" ScaleHeight = 8055 ScaleWidth = 8880 StartUpPosition = 3 'Windows Default Begin VB.Timer Timer1 Interval = 40 Left = 3720 Top = 2760 End End Attribute VB_Name = "Form1" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = True Attribute VB_Exposed = False Dim bRunning As Boolean ' Variabile per definire l'usica dal ciclo di rendering ' Tutte le definizioni sono state spostate nel nuovo tipo "SceneObject" Dim D3DX As D3DX8 '//A helper library Dim D3DDevice As Direct3DDevice8 ' // E' stato portato via perche' ora serve ' // Anche nella procedura di caricamento Dim DirAuto As Single Dim VelAuto As Single Dim CamPx, CamPy, CamPz As Single Dim CamTx, CamTy, CamTz As Single ' Massimo numero di modelli diversi sulla scena Const MAX_OBJECT = 32 Dim SceneObjs(MAX_OBJECT) As SceneObject Dim LastSceneObj As Integer ' Massimo numero di transform node distinti sulla scena Const MAX_TRANSFORM_NODE = 1024 Dim TrnNds(MAX_TRANSFORM_NODE) As TransformNode Dim LastTrnNd As Integer ' Tipo di vertici utilizzati Private Type CUSTOMVERTEX X As Single 'x Y As Single 'y Z As Single 'z. Nx As Single ' coordinate delle normali Ny As Single Nz As Single tU As Single ' coordinate di mappatura tV As Single End Type ' Tipo di dati che contiene tutte le informazioni di un oggetto sulla scena Private Type SceneObject V() As CUSTOMVERTEX I() As Integer name As String TotV As Long TotI As Long VBuffer As Direct3DVertexBuffer8 '//Stores our Geometry.... IBuffer As Direct3DIndexBuffer8 '//Stores our indices Material As D3DMATERIAL8 te As Direct3DTexture8 End Type Private Type TransformNode name As String tX As Single ' Translazioni tY As Single tZ As Single rX As Single ' Rotazioni rY As Single rZ As Single sX As Single ' Cambiamenti di scala sY As Single sZ As Single ScObj As Integer End Type ' Crea un vettore Private Function MakeVector(ByVal X As Single, ByVal Y As Single, ByVal Z As Single) As D3DVECTOR MakeVector.X = X MakeVector.Y = Y MakeVector.Z = Z End Function ' Crea un vertice Private Function MakeVertex(ByVal X As Single, ByVal Y As Single, ByVal Z As Single, _ ByVal Nx As Single, ByVal Ny As Single, ByVal Nz As Single, _ ByVal U As Single, ByVal V As Single) As CUSTOMVERTEX MakeVertex.X = X MakeVertex.Y = Y MakeVertex.Z = Z MakeVertex.Nx = Nx MakeVertex.Ny = Ny MakeVertex.Nz = Nz MakeVertex.tU = U MakeVertex.tV = 1 - V End Function ' Attivata quando l'utente clicca sulla finestra, per chiudere l'applicazione Private Sub Form_Click() bRunning = False End Sub Private Function CreateTransformNode(ScObj As Integer, name As String) _ As Integer TrnNds(LastTrnNd).sX = 1 TrnNds(LastTrnNd).sY = 1 TrnNds(LastTrnNd).sZ = 1 TrnNds(LastTrnNd).ScObj = ScObj TrnNds(LastTrnNd).name = name CreateTransformNode = LastTrnNd LastTrnNd = LastTrnNd + 1 End Function Private Function AddObject(FileName As String, TextureName As String) As Integer SceneObjs(LastSceneObj) = LoadObject(FileName, TextureName) AddObject = LastSceneObj LastSceneObj = LastSceneObj + 1 End Function Private Function LoadObject(FileName As String, TextureName As String) _ As SceneObject Dim X, Y, Z, Nx, Ny, Nz, tU, tV As Single Dim I1, I2, I3 As Integer With LoadObject .TotV = 0 .TotI = 0 Open FileName For Input As #1 Input #1, .TotV, .TotI ReDim .V(.TotV), .I(.TotI) For T = 0 To .TotV - 1 Input #1, X, Y, Z, Nx, Ny, Nz, tU, tV .V(T) = MakeVertex(X, Y, Z, Nx, Ny, Nz, tU, tV) Next For T = 0 To .TotI - 1 Step 3 Input #1, I1, I2, I3 .I(T) = I1 .I(T + 1) = I2 .I(T + 2) = I3 Next Close #1 Set .IBuffer = D3DDevice.CreateIndexBuffer(Len(.I(0)) * .TotI, 0, _ D3DFMT_INDEX16, D3DPOOL_DEFAULT) D3DIndexBuffer8SetData .IBuffer, 0, Len(.I(0)) * .TotI, 0, .I(0) Set .VBuffer = D3DDevice.CreateVertexBuffer(Len(.V(0)) * .TotV, 0, _ D3DFVF_XYZ Or D3DFVF_NORMAL Or D3DFVF_TEX1, D3DPOOL_DEFAULT) D3DVertexBuffer8SetData .VBuffer, 0, Len(.V(0)) * .TotV, 0, .V(0) ' Carica la texture Set .te = D3DX.CreateTextureFromFileEx(D3DDevice, _ TextureName, D3DX_DEFAULT, D3DX_DEFAULT, _ 1, 0, D3DFMT_UNKNOWN, _ D3DPOOL_MANAGED, D3DX_FILTER_POINT, _ D3DX_FILTER_POINT, &HFF000000, _ ByVal 0, ByVal 0) ' Imposta il materiale .Material.diffuse.r = 1 .Material.diffuse.g = 1 .Material.diffuse.b = 1 End With End Function Private Function FindShape(name As String) For I = 0 To LastSceneObj - 1 If SceneObjs(I).name = name Then FindShape = I Exit Function End If Next FindShape = -1 End Function Private Function FindTn(name As String) For I = 0 To LastTrnNd - 1 If TrnNds(I).name = name Then FindTn = I Exit Function End If Next FindTn = -1 End Function Private Sub LoadScene(FileName As String) Dim X, Y, Z, Nx, Ny, Nz, tU, tV As Single Dim I1, I2, I3 As Integer Dim ShapeInScene As Integer Dim TNInScene As Integer Dim CurTN As Integer Dim TextureName As String Dim ShName As String Dim TNName As String Dim ShNum As Integer Open FileName For Input As #1 Input #1, ShapeInScene ' Carica le Shapes For U = 0 To ShapeInScene - 1 With SceneObjs(LastSceneObj) .TotV = 0 .TotI = 0 ' Carica la texture Input #1, .name Input #1, TextureName 'MsgBox ("[" & .Name & "]<" & TextureName & ">") If TextureName <> "" Then Set .te = D3DX.CreateTextureFromFileEx(D3DDevice, _ TextureName, D3DX_DEFAULT, D3DX_DEFAULT, _ 1, 0, D3DFMT_UNKNOWN, _ D3DPOOL_MANAGED, D3DX_FILTER_POINT, _ D3DX_FILTER_POINT, &HFF000000, _ ByVal 0, ByVal 0) End If ' Imposta il materiale Input #1, .Material.emissive.r, .Material.emissive.g, .Material.emissive.b Input #1, .Material.Ambient.r, .Material.Ambient.g, .Material.Ambient.b Input #1, .Material.diffuse.r, .Material.diffuse.g, .Material.diffuse.b Input #1, .Material.specular.r, .Material.specular.g, .Material.specular.b, .Material.power ' Carica la geometria Input #1, .TotV, .TotI ReDim .V(.TotV), .I(.TotI) For T = 0 To .TotV - 1 Input #1, X, Y, Z, Nx, Ny, Nz, tU, tV .V(T) = MakeVertex(X, Y, Z, Nx, Ny, Nz, tU, tV) Next For T = 0 To .TotI - 1 Step 3 Input #1, I1, I2, I3 .I(T) = I1 .I(T + 1) = I2 .I(T + 2) = I3 Next Set .IBuffer = D3DDevice.CreateIndexBuffer(Len(.I(0)) * .TotI, 0, _ D3DFMT_INDEX16, D3DPOOL_DEFAULT) D3DIndexBuffer8SetData .IBuffer, 0, Len(.I(0)) * .TotI, 0, .I(0) Set .VBuffer = D3DDevice.CreateVertexBuffer(Len(.V(0)) * .TotV, 0, _ D3DFVF_XYZ Or D3DFVF_NORMAL Or D3DFVF_TEX1, D3DPOOL_DEFAULT) D3DVertexBuffer8SetData .VBuffer, 0, Len(.V(0)) * .TotV, 0, .V(0) End With ' Passa alla shape successiva LastSceneObj = LastSceneObj + 1 Next U Input #1, TNInScene For U = 0 To TNInScene - 1 Input #1, TNName Input #1, ShName ShNum = FindShape(ShName) If ShNum = -1 Then MsgBox "Shape not found: " & ShName End End If CurTN = CreateTransformNode(ShNum, TNName) Input #1, TrnNds(CurTN).tX, TrnNds(CurTN).tY, TrnNds(CurTN).tZ Input #1, TrnNds(CurTN).rX, TrnNds(CurTN).rY, TrnNds(CurTN).rZ Input #1, TrnNds(CurTN).sX, TrnNds(CurTN).sY, TrnNds(CurTN).sZ Next U Close #1 End Sub ' Programma vero e prorpio! Private Sub Form_Load() ' Inizializzazione della libreria ''''''''''''''''''''''''''''''''' ' Dichiarazioni variabili per le DirectX Dim Dx As DirectX8 Dim D3D As Direct3D8 ' Dim D3DDevice As Direct3DDevice8 ' // E' stato portato via Dim DispMode As D3DDISPLAYMODE Dim D3DWindow As D3DPRESENT_PARAMETERS ' Dichiarazioni variabili per l'applicazione Dim Light As D3DLIGHT8 ' Dim Material As D3DMATERIAL8 ' Il materiale e' stato spostato nell'oggetto ' Dichiarazioni variabili per il ciclo di rendering Dim matView As D3DMATRIX Dim matProj As D3DMATRIX Dim matWorld As D3DMATRIX Dim matTemp As D3DMATRIX ' Si collega con le DirectX Set Dx = New DirectX8 Set D3D = Dx.Direct3DCreate() ' Imposta la modalita' video in finsetra D3D.GetAdapterDisplayMode D3DADAPTER_DEFAULT, DispMode D3DWindow.Windowed = 1 D3DWindow.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC D3DWindow.BackBufferFormat = DispMode.Format ' Imposta lo Z-Buffere D3DWindow.AutoDepthStencilFormat = D3DFMT_D16 D3DWindow.EnableAutoDepthStencil = 1 ' Crea l'applicazione Set D3DDevice = D3D.CreateDevice(D3DADAPTER_DEFAULT, _ D3DDEVTYPE_HAL, hWnd, _ D3DCREATE_SOFTWARE_VERTEXPROCESSING, _ D3DWindow) ' Definisce il tipo di vertici utilizzati D3DDevice.SetVertexShader D3DFVF_XYZ Or D3DFVF_NORMAL Or _ D3DFVF_TEX1 ' Abilita l'illuminazione D3DDevice.SetRenderState D3DRS_LIGHTING, True D3DDevice.SetRenderState D3DRS_SPECULARENABLE, True ' Abilita lo Z-Buffer D3DDevice.SetRenderState D3DRS_ZENABLE, True ' Inizializzazione dell'applicazione '''''''''''''''''''''''''''''''''''' ' Mostra la finestra Me.Show ' Imposta la luce Light.Type = D3DLIGHT_DIRECTIONAL Light.Direction = MakeVector(9, -5, 9) Light.diffuse.r = 1 Light.diffuse.g = 1 Light.diffuse.b = 1 D3DDevice.SetLight 0, Light D3DDevice.LightEnable 0, 1 Light.Type = D3DLIGHT_DIRECTIONAL Light.Direction = MakeVector(-9, -5, -9) Light.diffuse.r = 0.35 Light.diffuse.g = 0.4 Light.diffuse.b = 0.4 D3DDevice.SetLight 1, Light D3DDevice.LightEnable 1, 1 Set D3DX = New D3DX8 CamTx = 0: CamTy = 0.05: CamTz = 0 CamPx = 0: CamPy = 0.1: CamPz = -0.25 ' Crea la geometria LoadScene ("city.scn") ' Inizializza la variabile di permanenza nel ciclo di rendering bRunning = True ' Ciclo di rendering '''''''''''''''''''' ' Ripete fino a quando bRunning vale falso Do While bRunning ' Cancella lo schermo D3DDevice.Clear 0, ByVal 0, _ D3DCLEAR_TARGET Or D3DCLEAR_ZBUFFER, _ &H0, 1#, 0 ' Imposta la cinepresa D3DXMatrixLookAtLH matView, MakeVector(CamPx, CamPy, CamPz), _ MakeVector(CamTx, CamTy, CamTz), MakeVector(0, 1, 0) D3DDevice.SetTransform D3DTS_VIEW, matView D3DXMatrixPerspectiveFovLH matProj, 3.1416 / 4, 1, 0.01, 500 D3DDevice.SetTransform D3DTS_PROJECTION, matProj ' Inizia a disegnare su video D3DDevice.BeginScene D3DDevice.SetTextureStageState 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR D3DDevice.SetTextureStageState 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR For I = 0 To LastTrnNd - 1 With TrnNds(I) ' Imposta le trasformazioni dell'oggetto D3DXMatrixIdentity matWorld D3DXMatrixScaling matTemp, .sX, .sY, .sZ D3DXMatrixMultiply matWorld, matWorld, matTemp If .sX * .sY * .sZ < 0 Then D3DDevice.SetRenderState D3DRS_CULLMODE, D3DCULL_CW Else D3DDevice.SetRenderState D3DRS_CULLMODE, D3DCULL_CCW End If D3DXMatrixRotationX matTemp, .rX * (3.1416 / 180) D3DXMatrixMultiply matWorld, matWorld, matTemp D3DXMatrixRotationY matTemp, .rY * (3.1416 / 180) D3DXMatrixMultiply matWorld, matWorld, matTemp D3DXMatrixRotationZ matTemp, .rZ * (3.1416 / 180) D3DXMatrixMultiply matWorld, matWorld, matTemp D3DXMatrixTranslation matTemp, .tX, .tY, .tZ D3DXMatrixMultiply matWorld, matWorld, matTemp D3DDevice.SetTransform D3DTS_WORLD, matWorld End With With SceneObjs(TrnNds(I).ScObj) D3DDevice.SetMaterial .Material ' Imposta la texture D3DDevice.SetTexture 0, .te ' Disegna l'oggetto D3DDevice.SetStreamSource 0, .VBuffer, _ Len(.V(0)) D3DDevice.SetIndices .IBuffer, 0 D3DDevice.DrawIndexedPrimitive D3DPT_TRIANGLELIST, 0, _ .TotV, 0, .TotI / 3 End With Next ' Finisce la fase di disegno D3DDevice.EndScene ' Trasferisce il contenuto del Doppio Buffer sullo schermo D3DDevice.Present ByVal 0, ByVal 0, 0, ByVal 0 ' Restituisce il controllo a Windows per dargli la possibilita' di gestire altri eventi DoEvents Loop ' Rilascio delle risorse '''''''''''''''''''''''' Set D3DDevice = Nothing Set D3D = Nothing Set Dx = Nothing ' Chiude l'applicazione Unload Me End Sub Private Sub Timer1_Timer() Dim AutoTn As Integer AutoTn = FindTn("Auto_pCube1") TrnNds(AutoTn).tX = TrnNds(AutoTn).tX + VelAuto * Sin(DirAuto * 3.1416 / 180) TrnNds(AutoTn).tZ = TrnNds(AutoTn).tZ + VelAuto * Cos(DirAuto * 3.1416 / 180) TrnNds(AutoTn).rY = DirAuto CamTx = TrnNds(AutoTn).tX CamTy = 0.05 CamTz = TrnNds(AutoTn).tZ CamPx = CamPx * 0.9 + 0.1 * (TrnNds(AutoTn).tX - 0.15 * Sin(DirAuto * 3.1416 / 180)) CamPy = 0.1 CamPz = CamPz * 0.9 + 0.1 * (TrnNds(AutoTn).tZ - 0.15 * Cos(DirAuto * 3.1416 / 180)) End Sub Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) Dim AutoTn As Integer AutoTn = FindTn("Auto_pCube1") If KeyCode = 37 Then 'sinistra DirAuto = DirAuto - 5 End If If KeyCode = 39 Then 'destra DirAuto = DirAuto + 5 End If If KeyCode = 38 Then 'su If VelAuto < 0.05 Then VelAuto = VelAuto + 0.005 End If End If If KeyCode = 40 Then ' giu If VelAuto > 0# Then VelAuto = VelAuto - 0.005 End If End If End Sub