VertexCount = 3456 PrT = PrimitiveType.TriangleList VxB = New VertexBuffer(GetType(CustomVertex.PositionNormalTextured), VertexCount, D9, Usage.WriteOnly, CustomVertex.PositionNormalTextured.Format, Pool.Managed) 'That is a LOT of non-trivial parameters. TextureAndMeshSetup() 'Set up our textures. SetVertexBufferData(Vertices, VxB, D9) |
Private Sub SetVertexBufferData(ByRef vs() As CustomVertex.PositionNormalTextured, ByVal vxbf As VertexBuffer, ByVal D9 As Device) Dim LX, LY As Single, Ctr As Integer Const dL As Single = 1.0F 'After that workout, we now have to actually set the vertices. 'We do this by locking the surface out of D9 while we "operate" on it. Dim A As Array = vxbf.Lock(0, LockFlags.None) 'It returns a vanilla array... vs = DirectCast(A, CustomVertex.PositionNormalTextured()) 'So we have to convert it to an array of the appropriate vertices. 'Z = F(X, Y), but this time with texture. 'Our texture should be 0,0 at X,Y = -3,-3 and 1,1 at X,Y = 3,3 'So, we will simply do an interpolation during this process. 'An interpolation is, again, like this: 'Vf = L + Percent * (H - L), where Vf is the texture value, L is the lowest texture value, and H is the highest texture value. 'Percent would also be an interpolation: Percent = (Vo - L) / (H - L) 'where Vo is the loop variable value, L is the lowest loop value, and H is the highest loop value. 'The first formula would be Vf = 0 + Percent * (1 - 0) = Percent. 'The second formula would be Percent = (Vo - -3) / (3 - -3) = (Vo + 3) / 6, 'Therefore, Vf = (Vo + 3) / 6 'with L + dL 'Vf = (Vo + dVo + 3) / 6 For LY = -12.0F To 11.999F Step dL For LX = -12.0F To 11.999F Step dL 'triangle 1: vs(Ctr) = New CustomVertex.PositionNormalTextured(LX, LY, F(LX, LY), 0.0F, 0.0F, 0.0F, (LX + 3.0F) / 6.0F, (LY + 3.0F) / 6.0F) vs(Ctr + 1) = New CustomVertex.PositionNormalTextured(LX + dL, LY, F(LX + 0.25F, LY), 0.0F, 0.0F, 0.0F, (LX + 3.0F + dL) / 6.0F, (LY + 3.0F) / 6.0F) vs(Ctr + 2) = New CustomVertex.PositionNormalTextured(LX, LY + dL, F(LX, LY + 0.25F), 0.0F, 0.0F, 0.0F, (LX + 3.0F) / 6.0F, (LY + 3.0F + dL) / 6.0F) 'triangle 2: vs(Ctr + 3) = New CustomVertex.PositionNormalTextured(LX + dL, LY + dL, F(LX + dL, LY + dL), 0.0F, 0.0F, 0.0F, (LX + 3.0F + dL) / 6.0F, (LY + 3.0F + dL) / 6.0F) vs(Ctr + 4) = vs(Ctr + 2) vs(Ctr + 5) = vs(Ctr + 1) Ctr += 6 Next Next NormalizeTriangles(vs, PrT) 'It's important to unlock the vertex buffer, so that D9 can see what we put in there. vxbf.Unlock() End Sub Private Function F(ByVal X As Single, ByVal Y As Single) As Single 'Try out your own functions of X and Y. 'Return 0.05F * X * X 'Z = 1/4 (X²)... parabolic sheet of paper. 'Return 0.25F * X * Y 'Origami? Looks like the beginning of a paper bird. 'Return 0.25F * X * X + 0.25F * Y * Y 'A hammock with an invisible person sitting in it. 'Return Convert.ToSingle(Math.Sin(X * PiHalf)) 'This looks more sinusoidal at a higher resolution. 'Return 0.25F * X * X - 0.25F * Y * Y 'Saddle paper. 'Return Convert.ToSingle(Math.Cos(X * PiHalf)) * Convert.ToSingle(Math.Sin(Y * PiHalf)) 'Eggshell bed comforter. Return 0.0F 'Plane Z = 0 End Function |
'So, we'd be drawing here. 'To draw a vertex buffer, we set the device to receive from a vertex stream. 'The data is ready to stream out of the vertex buffer into the device and the device should draw it onto the screen. D9.SetStreamSource(0, VxB, 0) 'StreamNumber is usually zero while we only have one vertex buffer that streams vertex data. 'Of course, we also have to tell it which vertex buffer to get vertex data from. 'Offset as 0 just tells the device how many vertices to skip before drawing. D9.VertexFormat = CustomVertex.PositionNormalTextured.Format 'We also need to tell the device what kind of vertices to draw. 'We have not told the device which vertices these are (that was the vertex buffer). 'This could actually come out of the loop, but there will usually be many different types of vertex types 'set within this loop. D9.DrawPrimitives(PrT, 0, GetPrimitiveCount(PrT, VertexCount)) |
D9.Lights(0).Type = LightType.Point 'Regular lightbulb. D9.Lights(0).Position = New Vector3(0.0F, 0.0F, 2.0F) 'Place the bulb here. D9.Lights(0).Range = 48.8F D9.Lights(0).Attenuation0 = 0.0F D9.Lights(0).Attenuation1 = 0.45F D9.Lights(0).Ambient = Color.White |
Camera = New Vector3(3.0F, 3.0F, 1.0F) FocusPt = New Vector3(3.0F, 4.0F, 1.0F) CamNormal = New Vector3(0.0F, 0.0F, 1.0F) |
Dim AnglePl, AngleEv As Double |
FocusPt.X = Camera.X + Convert.ToSingle(Math.Cos(AnglePl) * Math.Cos(AngleEv)) FocusPt.Y = Camera.Y + Convert.ToSingle(Math.Sin(AnglePl) * Math.Cos(AngleEv)) FocusPt.Z = Camera.Z + Convert.ToSingle(Math.Sin(AngleEv)) |
Case Keys.NumPad2 'Down If AngleEv < PiHalf Then AngleEv += (Pi / 30) End If FocusPt.X = Camera.X + Convert.ToSingle(Math.Cos(AnglePl) * Math.Cos(AngleEv)) FocusPt.Y = Camera.Y + Convert.ToSingle(Math.Sin(AnglePl) * Math.Cos(AngleEv)) FocusPt.Z = Camera.Z + Convert.ToSingle(Math.Sin(AngleEv)) |
Case Keys.NumPad8 'Up If AngleEv > -PiHalf Then AngleEv -= (Pi / 30) End If FocusPt.X = Camera.X + Convert.ToSingle(Math.Cos(AnglePl) * Math.Cos(AngleEv)) FocusPt.Y = Camera.Y + Convert.ToSingle(Math.Sin(AnglePl) * Math.Cos(AngleEv)) FocusPt.Z = Camera.Z + Convert.ToSingle(Math.Sin(AngleEv)) |
Case Keys.NumPad6 'Left AnglePl += (Pi / 30) FocusPt.X = Camera.X + Convert.ToSingle(Math.Cos(AnglePl) * Math.Cos(AngleEv)) FocusPt.Y = Camera.Y + Convert.ToSingle(Math.Sin(AnglePl) * Math.Cos(AngleEv)) FocusPt.Z = Camera.Z + Convert.ToSingle(Math.Sin(AngleEv)) |
Case Keys.NumPad4 'Left AnglePl -= (Pi / 30) FocusPt.X = Camera.X + Convert.ToSingle(Math.Cos(AnglePl) * Math.Cos(AngleEv)) FocusPt.Y = Camera.Y + Convert.ToSingle(Math.Sin(AnglePl) * Math.Cos(AngleEv)) FocusPt.Z = Camera.Z + Convert.ToSingle(Math.Sin(AngleEv)) |
Dim dX, dY, dZ As Single |
Case Keys.Up dX = Convert.ToSingle(Math.Cos(AnglePl)) dY = Convert.ToSingle(Math.Sin(AnglePl)) Camera.X += dX Camera.Y += dY FocusPt.X += dX FocusPt.Y += dY |
Case Keys.Down dX = Convert.ToSingle(Math.Cos(AnglePl)) dY = Convert.ToSingle(Math.Sin(AnglePl)) Camera.X -= dX Camera.Y -= dY FocusPt.X -= dX FocusPt.Y -= dY |
Case Keys.Right dX = Convert.ToSingle(Math.Sin(AnglePl)) dY = Convert.ToSingle(Math.Cos(AnglePl)) Camera.X -= dX Camera.Y += dY FocusPt.X -= dX FocusPt.Y += dY |
Case Keys.Left dX = Convert.ToSingle(Math.Sin(AnglePl)) dY = Convert.ToSingle(Math.Cos(AnglePl)) Camera.X += dX Camera.Y -= dY FocusPt.X += dX FocusPt.Y -= dY |
dX = Convert.ToSingle(Math.Cos(AnglePl) * Math.Cos(AngleEv)) dY = Convert.ToSingle(Math.Sin(AnglePl) * Math.Cos(AngleEv)) dZ = Convert.ToSingle(Math.Sin(AngleEv)) Camera.X += dX Camera.Y += dY Camera.Z += dZ FocusPt.X += dX FocusPt.Y += dY FocusPt.Z += dZ |
Case Keys.Down dX = Convert.ToSingle(Math.Cos(AnglePl) * Math.Cos(AngleEv)) dY = Convert.ToSingle(Math.Sin(AnglePl) * Math.Cos(AngleEv)) dZ = Convert.ToSingle(Math.Sin(AngleEv)) Camera.X -= dX Camera.Y -= dY Camera.Z += dZ FocusPt.X -= dX FocusPt.Y -= dY FocusPt.Z -= dZ |