# terrain grid rendering problem

I'm using DirectX 9 and attempting to write a simple terrain generation object.

I'm running into trouble with the rendering - I'm hoping that this is a common problem, and someone could spot the problem by the output:

I've generated vertices, indices and I'm attempting to render a triangle strip (as it's supposed to be the most efficent way to do a grid.

It looks like I've made some kind of error in vertex or index generation, although I can't see what. I've posted my terrain class here. Can someone have a look and suggest what I've done wrong?

• Added the image for you.. – Keeper Mar 17 '12 at 1:11

Don't bother with the triangle strip - it's going to be much harder to reason about than a triangle list and the graphics driver can perform the conversion automatically anyway. It looks to me like your indices are off, at least- every triangle is drawn connected to vertex 0.

What you should mainly consider is that you don't actually have X many triangles- you have the same triangle repeated X times. Generate one triangle or two triangles, then transform it using the D3DX mathematical library into the positions that you want. Here's some example code.

void GenTriGrid(int numVertRows, int numVertCols,
float dx, float dz,
const D3DXVECTOR3& center,
std::vector<D3DXVECTOR3>& verts,
std::vector<DWORD>& indices)
{
int numVertices = numVertRows*numVertCols;
int numCellRows = numVertRows-1;
int numCellCols = numVertCols-1;

int numTris = numCellRows*numCellCols*2;

float width = (float)numCellCols * dx;
float depth = (float)numCellRows * dz;

//===========================================
// Build vertices.

// We first build the grid geometry centered about the origin
// and on the xz-plane, row by row and in a top-down fashion.
// We then translate the grid vertices so that they are
// centered about the specified parameter 'center'.

verts.resize( numVertices );

// Offsets to translate grid from quadrant 4 to center of
// coordinate system.
float xOffset = -width * 0.5f;
float zOffset =  depth * 0.5f;

int k = 0;
for(float i = 0; i < numVertRows; ++i) {

for(float j = 0; j < numVertCols; ++j)
{
// Negate the depth coordinate to put in
// coordinate system.
verts[k].x =  j * dx + xOffset;
verts[k].z = -i * dz + zOffset;
verts[k].y =  0.0f;
// Translate so that the center of the grid is at the
// specified 'center' parameter.
D3DXMATRIX T;
D3DXMatrixTranslation(&T,
center.x,
center.y,
center.z);
D3DXVec3TransformCoord(&verts[k], &verts[k], &T);
++k; // Next vertex
}
}
indices.resize(numTris * 3);

// Generate indices for each quad.
int k = 0;
for(DWORD i = 0; i < (DWORD)numCellRows; ++i)
{
for(DWORD j = 0; j < (DWORD)numCellCols; ++j)
{
indices[k]     =   i   * numVertCols + j;
indices[k + 1] =   i   * numVertCols + j + 1;
indices[k + 2] = (i+l) * numVertCols + j;

indices[k + 3] = (i+l) * numVertCols + j;
indices[k + 4] =   i   * numVertCols + j + 1;
indices[k + 5] = (i+l) * numVertCols + j + 1;

k += 6;
}
}
}


On an only somewhat tangental note, I haven't understood your code- it's totally illegible. It's a fairly incredible feat that you can read it.

No way can I decode 400 lines of redundant error checking (never heard of resource-managing classes?), HRESULTs, references to non-posted classes, variables declared about six million billion miles away from where they're used, global variables and fixed function pipeline, horrific Hungarian notation, some really crazy indentation, etc.

I'd suggest that you learn some more about coding. Here's an unfortunate lesson- the Windows API, DirectX, etc are all C APIs, designed 20 years ago (or more!) for inter-process communication and do not reflect at all good practice for in-application use.As such, it's actually really a bad idea to learn from their example. You should not return error codes- you should throw exceptions, and if you must return an error code, grab an enumeration for it- do not use a weak error code like HRESULT. Hungarian Notation is quite worthless in modern C++- the compiler will tell you the type and scope of any variable, at any time. CString is so bad, it's implementation is mandated to be illegal for the C++ Standard string class- which should always be preferred. You should not use new/delete directly, but rather favour the use of std::vector for dynamically allocated arrays- it's vastly safer and no less performant. These Initialize functions? That's what a constructor is for, buddy.

Also, fixed-function pipeline (that is, FVF and stuff) is deader than a dodo- even phones have shaders these days.

• DirectX isn't a C API though :) – TravisG Jun 12 '11 at 17:14
• @heishe: It's COM, which is the same thing, effectively. – DeadMG Jun 12 '11 at 20:37
• Hungarian notation can be useful in those few cases, but usually you find those cases are bad design, and so its a good indicator to refactor. – deceleratedcaviar Jun 13 '11 at 3:03
• Sorry for coming from a COM background. The indentation looks fine in my IDE, I just dumped it into pastebin, if it was so offensive to read, skip onto the next question. It's only a prototype, I didn't expect that the response would be centred around moaning about coding style. The code supplied in DeadMGs response was straight out of Frank D Luna. Yeah, I've seen that algorithm, my purpose for this was to learn about mesh generation, although that was missed by DeadMG. Grow up MG ;) – jtsPimp Jun 13 '11 at 19:51
• @jtsPimp: Never said it was mine, I only said it was an example. – DeadMG Jun 13 '11 at 21:49