# How to create a regular grid of triangles correctly?

I am trying to create an terrain using opentk/opengl.

I have a problem with the VBO/IBO. I think a picture of the problem is the best way to show it:

I dont understand why the last triangle of a row connects to the first vertices of the row.

Here is the code:

int mapSize = 7;
void CreateVertexBuffer()
{
Vector3[] vertices = new Vector3[(mapSize + 1) * (mapSize + 1)];
short[] indices = new short[ ((mapSize)*(mapSize)) * 6];

for (int x = 0; x < mapSize + 1 ; x++)
{
for (int y = 0; y < mapSize + 1 ; y++)
{
int li_offset = x * (mapSize + 1) + y;
vertices[li_offset] = new Vector3(x / 4.0f, 0 , y / 4.0f);
}
}
int index = 0;
for (int x = 0; x < mapSize ; x++)
{
for (int y = 0; y < mapSize ; y++)
{
indices[index + 0] = (short)( x * (mapSize + 1) + y);
indices[index + 1] = (short)(indices[index + 0] + mapSize + 2);
indices[index + 2] = (short)(indices[index + 0] + mapSize + 1);

indices[index + 3] = (short)(indices[index + 0]);
indices[index + 4] = (short)(indices[index + 0] + 1);
indices[index + 5] = (short)(indices[index + 0] + 2);

index += 6;
}
}
GL.GenBuffers(1, out vbo);
GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,
new IntPtr(vertices.Length * Vector3.SizeInBytes),
vertices, BufferUsageHint.StaticDraw);
GL.GenBuffers(1, out ibo);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo);
GL.BufferData<short>(BufferTarget.ElementArrayBuffer,
new IntPtr(indices.Length * sizeof(short) ),
indices, BufferUsageHint.StaticDraw);
}


How can I make the last row of triangles properly formed like all the others?

• This is just a wild guess, but if it's using triangle strips for rendering you might need to use a degenerate triangle at the end of each row, and zig-zag down. So if you numbered your quads in a 4xN it would go like 0,1,2,3, 7,6,5,4... – jzx Jun 20 '14 at 20:24

Okay, after bug-searching for a while i came up with this, which works just fine.

 void CreateVertexBuffer()
{
Vector3[] vertices = new Vector3[mapSize*mapSize];

short[] indices;

for (int x = 0; x < mapSize; x++)
{
for (int z = 0; z < mapSize; z++)
{
vertices[x * mapSize + z] = new Vector3(x/10.0f,1.0f,z/10.0f);
}
}

indices = new short[mapSize * mapSize * 6];
int index = 0;

for (int x = 0; x < mapSize ; x++)
{
for (int z = 0; z < mapSize-1; z++)
{
int offset = x * mapSize + z;
indices[index] = (short)(offset + 0);
indices[index + 1] = (short)(offset + 1);
indices[index + 2] = (short)(offset + mapSize);
indices[index + 3] = (short)(offset + 1);
indices[index + 4] = (short)(offset + mapSize + 1);
indices[index + 5] = (short)(offset + mapSize);
index += 6;
}
}

GL.GenBuffers(1, out vbo);
GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,
new IntPtr(vertices.Length * Vector3.SizeInBytes),
vertices, BufferUsageHint.StaticDraw);
GL.GenBuffers(1, out ibo);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo);
GL.BufferData<short>(BufferTarget.ElementArrayBuffer,
new IntPtr(indices.Length * sizeof(short) ),
indices, BufferUsageHint.StaticDraw);
}