So far, all of our textures are simple shapes with simple colors lit up by lights. We can alter the textures of our figures to make them look like something else - perhaps a carpet, sandstone, grassy field, denim, or maybe concrete. First, we must declare a texture that we will use:
    Dim Tx As Texture
    'The single-texture that our project is using (soon, there will be more textures)
Our textures can be initialized in their own subroutine:
    Private Sub TextureSetup()
        Tx = TextureLoader.FromFile(D9, Application.StartupPath & "\sandwave.jpg")
        'This loads the texture from the file.
        'Ironically, the other four procedures take over 10 nontrivial arguments.
        D9.SetTexture(0, Tx)
        'Sets the active texture.  The 0 is up for discussion.

    End Sub
The TextureSetup function can be called easily before we even set up our vertex buffer data.
            TextureSetup()
            'Set up our textures.
Now, of course, if you haven't already figured this out yourself, we need to use a vertex that supports textures - so, instead of using PositionNormal, we use PositionNormalTextured. First in the declaration:
    Dim Vertices() As CustomVertex.PositionNormalTextured
    'Three dimensional plot - each vertex has a normal direction - texture coordinates to fit the texture this vertex holds.
Second in the initialization for the vertex types.
            'Next, our vertex buffer.
            'I don't use overload #1 or #3 because I don't know how big a TransformedColored vertex is.
            VertexCount = 36
            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.

            TextureSetup()
            'Set up our textures.
Third in the SetVertexBufferData subroutine (note the texture coordinates are already coded into the constructors. Texture coordinates of 0,0 correspond to the upper left corner of the picture in the texture file. 1,1 is the bottom right corner of the texture, 0,1 is the bottom left, 1,0 is the top right. Intermediate values, such as 0.5, 0.5 correspond to to other points within the texture - 0.5, 0.5 is the center of the texture. 0.25, 0.25 is in between the center and the upper left, 25% of the distance to the right end, and 25% of the distance to the bottom.
    Private Sub SetVertexBufferData(ByRef vs() As CustomVertex.PositionNormalTextured, ByVal vxbf As VertexBuffer, ByVal D9 As Device)
        Dim LX, LY As Single, Ctr As Integer

        '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 = 0, 0,0,0
        vs(0) = New CustomVertex.PositionNormalTextured(0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F)
        vs(1) = New CustomVertex.PositionNormalTextured(0.0F, 2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F)
        vs(2) = New CustomVertex.PositionNormalTextured(2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F)
        'z = 0, 2,2,0
        vs(3) = New CustomVertex.PositionNormalTextured(2.0F, 2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 1.0F)
        vs(4) = New CustomVertex.PositionNormalTextured(2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F)
        vs(5) = New CustomVertex.PositionNormalTextured(0.0F, 2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F)
        'x = 0, 0,0,0
        vs(6) = New CustomVertex.PositionNormalTextured(0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F)
        vs(7) = New CustomVertex.PositionNormalTextured(0.0F, 0.0F, 2.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F)
        vs(8) = New CustomVertex.PositionNormalTextured(0.0F, 2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F)
        'x = 0, 0,2,2
        vs(9) = New CustomVertex.PositionNormalTextured(0.0F, 2.0F, 2.0F, 0.0F, 0.0F, 0.0F, 1.0F, 1.0F)
        vs(10) = New CustomVertex.PositionNormalTextured(0.0F, 2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F)
        vs(11) = New CustomVertex.PositionNormalTextured(0.0F, 0.0F, 2.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F)
        'y = 0, 0,0,0
        vs(12) = New CustomVertex.PositionNormalTextured(0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F)
        vs(13) = New CustomVertex.PositionNormalTextured(2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F)
        vs(14) = New CustomVertex.PositionNormalTextured(0.0F, 0.0F, 2.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F)
        'y = 0, 2,0,2
        vs(15) = New CustomVertex.PositionNormalTextured(2.0F, 0.0F, 2.0F, 0.0F, 0.0F, 0.0F, 1.0F, 1.0F)
        vs(16) = New CustomVertex.PositionNormalTextured(0.0F, 0.0F, 2.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F)
        vs(17) = New CustomVertex.PositionNormalTextured(2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F)
        'z = 2, 0,0,2
        vs(18) = New CustomVertex.PositionNormalTextured(0.0F, 0.0F, 2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F)
        vs(19) = New CustomVertex.PositionNormalTextured(2.0F, 0.0F, 2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F)
        vs(20) = New CustomVertex.PositionNormalTextured(0.0F, 2.0F, 2.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F)
        'z = 2, 2,2,2
        vs(21) = New CustomVertex.PositionNormalTextured(2.0F, 2.0F, 2.0F, 0.0F, 0.0F, 0.0F, 1.0F, 1.0F)
        vs(22) = New CustomVertex.PositionNormalTextured(0.0F, 2.0F, 2.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F)
        vs(23) = New CustomVertex.PositionNormalTextured(2.0F, 0.0F, 2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F)
        'y = 2, 0,2,0
        vs(24) = New CustomVertex.PositionNormalTextured(0.0F, 2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F)
        vs(25) = New CustomVertex.PositionNormalTextured(0.0F, 2.0F, 2.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F)
        vs(26) = New CustomVertex.PositionNormalTextured(2.0F, 2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F)
        'y = 2, 2,2,2
        vs(27) = New CustomVertex.PositionNormalTextured(2.0F, 2.0F, 2.0F, 0.0F, 0.0F, 0.0F, 1.0F, 1.0F)
        vs(28) = New CustomVertex.PositionNormalTextured(2.0F, 2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F)
        vs(29) = New CustomVertex.PositionNormalTextured(0.0F, 2.0F, 2.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F)
        'x = 2, 2,0,0
        vs(30) = New CustomVertex.PositionNormalTextured(2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F)
        vs(31) = New CustomVertex.PositionNormalTextured(2.0F, 2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F)
        vs(32) = New CustomVertex.PositionNormalTextured(2.0F, 0.0F, 2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F)
        'x = 2, 2,2,2
        vs(33) = New CustomVertex.PositionNormalTextured(2.0F, 2.0F, 2.0F, 0.0F, 0.0F, 0.0F, 1.0F, 1.0F)
        vs(34) = New CustomVertex.PositionNormalTextured(2.0F, 0.0F, 2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F)
        vs(35) = New CustomVertex.PositionNormalTextured(2.0F, 2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F)

        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
Fourth, in the triangle normal calculator:
    Private Sub NormalizeTriangles(ByRef vs() As CustomVertex.PositionNormalTextured, ByVal PrT As PrimitiveType)
        Dim N As Vector3, LV As Integer
        If PrT = PrimitiveType.TriangleList Then
            For LV = 2 To vs.GetUpperBound(0) Step 3
                N = GetNormal(vs(LV - 2).Position, vs(LV - 1).Position, vs(LV).Position)
                N.Normalize()
                vs(LV - 2).Normal = N
                vs(LV - 1).Normal = N
                vs(LV).Normal = N
            Next
        End If
    End Sub
And lastly, in the Render subroutine to tell the device what kind of vertices to draw:
        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.
We need to have adequate lighting, as well:
        D9.Lights(0).Position = New Vector3(3.0F, 0.0F, 5.0F) 'Place the bulb here.
        D9.Lights(0).Range = 7.2F
        D9.Lights(0).Attenuation0 = 0.0F
        D9.Lights(0).Attenuation1 = 0.55F

.vb file