Update: Tile maps in 3D
Author Message Update: Tile maps in 3D

I've finally figured out how to set up and render a tile map. I thought I'd
share it with anybody else who's trying to accomplish this. It's rather
lengthy, so if you're not interested, you can stop reading now.

The tile map is defined as an m x n grid of quads. Each quad is defined with
a vertex at each corner of the quad and two triangles with three indexed
vertices each:

down
IndexCount = QuadCount * 6          ' 3 indices per triangle

The indices are 16-bit, so I need to check IndexCount to make sure it's not
more than 64k. With this setup, I can get a square map with a maximum of
SQRT(65536 / 6) or 104 quads across and 104 quads down. If you need more

The map will be rendered as one or more indexed triangle lists. The vertices
for each quad are laid out like this:

0         2
+         +

1         3
+         +

Assigning texture coordinates to the vertices is pretty straightforward:

Vert 0 = (0.0, 0.0)
Vert 1 = (0.0, 1.0)
Vert 2 = (1.0, 0.0)
Vert 3 = (1.0, 1.0)

The vertices are indexed in this order:

u-l    u-r    l-l    u-r    l-r    l-l
0,     2,     1,     2,     3,    1

Here's the code I use to generate my vertex and index data:

Private m_VertCount As Long
Private m_Verts() As MapVertex
Private m_IndexCount As Long
Private m_Indices() As Integer
Private m_PrimCount As Long

'---------------------------------------------------------------------------
--
' Name: CreateMap (m, n, QuadSize)
' Desc: Creates a new Map object

'---------------------------------------------------------------------------
--
Public Sub Create(m As Integer, n As Integer, QuadSize As Single)
Dim QuadCount As Long                      ' Example: 2 x 2 map
m_VertCount = QuadCount * 4             ' = 16 verts
m_IndexCount = QuadCount * 6            ' = 24 indices
m_PrimCount = QuadCount * 2             ' =  8 tris

' Initialize the vertex array
ReDim m_Verts(m_VertCount - 1)

' Initialize the index array
ReDim m_Indices(m_IndexCount - 1)

Dim MapX As Single        ' Used to increment the horizontal
position of the vertices
Dim MapZ As Single        ' Used to increment the vertical position
of the vertices

Dim i, j, c, t As Integer      ' Various counter and increment
variables

' Calculate the initial vertical position of the vertices
MapZ = CSng(n * QuadSize) / 2.0   ' 1.0 assuming QuadSize = 1.0

For i = 1 To n            ' Loop through each row
' Get the initial horizontal position of the vertices
MapX = -CSng(m * QuadSize) / 2.0
For j = 1 To m       ' Loop through each column
With m_Verts(c)
.X = MapX : .Y = 0.0 : .Z = MapZ : .tU = 0.0 : .tV = 0.0
End With

With m_Verts(c + 1)
.X = MapX : .Y = 0.0 : .Z = MapZ - QuadSize : .tU = 0.0
: .tV = 1.0
End With

With m_Verts(c + 2)
.X = MapX + QuadSize : .Y = 0.0 : .Z = MapZ : .tU = 1.0
: .tV = 0.0
End With

With m_Verts(c + 3)
.X = MapX + QuadSize : .Y = 0 : .Z = MapZ - QuadSize :
.tU = 1.0 : .tV = 1.0
End With

' Set the indices: ul, ur, ll, ur, lr, ll
m_Indices(t) = c
m_Indices(t + 1) = c + 2
m_Indices(t + 2) = c + 1
m_Indices(t + 3) = c + 2
m_Indices(t + 4) = c + 3
m_Indices(t + 5) = c + 1

c = c + 4
t = t + 6
Next j
Next i
End Sub

The VB and IB are created with the D3DUSAGE_WRITEONLY flag and placed in the
default memory pool. They're locked with the D3DLOCK_NOSYSLOCK flag.

The quads are rendered with a DIP call like this:

D3DDev.DrawIndexedPrimitive D3DPT_TRIANGLELIST, 0, m_VertCount, 0,
m_PrimCount

So far, so good. Now I'll have figure out how to vary the y-coordinate of
each vertex to give my map some relief. This is gonna be tricky because the
vertices of one quad have to match up with up to eight of it's neighbors.

Anyway, I hope this helps.

Tim

Sun, 03 Oct 2004 03:02:51 GMT  Update: Tile maps in 3D
Oops! I based my calculation of the maximum number of quads on the number of
indices per quad. It should be based on the number of vertices per quad:

SQRT(65536 / 4)

So I can get a square map with up to 127 quads across and 127 quads down.

Sorry 'bout that.

Tim

Quote:
> The indices are 16-bit, so I need to check IndexCount to make sure it's
not
> more than 64k. With this setup, I can get a square map with a maximum of
> SQRT(65536 / 6) or 104 quads across and 104 quads down. If you need more