<p>This looks like a case of 16bit truncation in your indice buffer. For a 257x257 grid you will be addressing more than 65536 vertices so you will need to use a 32bit indice buffer.</p>

<pre><code>gl.drawElements(gl.TRIANGLE_STRIP, buffers.numIndices, gl.UNSIGNED_SHORT, 0);
</code></pre>

<p>change to :</p>

<pre><code>gl.drawElements(gl.TRIANGLE_STRIP, buffers.numIndices, gl.UNSIGNED_INT, 0);
</code></pre>

<p>Also change your buffer allocation code to match this type (Uint16Array -> Uint32Array for Javascript).</p>

CC BY-SA 4.0
2018-09-10T09:19:54.327Z
You might want to mention that in JavaScript/WebGL the array containing the indices has to be a `Uint32Array` instead of `Uint16Array`.
indexoutofbounds
CC BY-SA 4.0
2018-09-11T02:59:21.527Z
Thanks for the suggestion, I've ammended my answer. I wanted to make the answer language agnostic as this can occur on any GL implementation.
PaulHK
CC BY-SA 4.0
2018-09-10T02:11:35.150Z
2018-09-11T02:59:56.690Z
2018-09-11T02:59:56.690Z
PaulHK
<p>I am generating plane vertices where the y values are generated by a heightmap (noise) algorithm. This is how I produce my vertex array:</p>

<pre><code>for (let row = 0; row &lt; noise.length; row++) {
    for (let col = 0; col &lt; noise[0].length; col++) {
        color = noise[row][col];
        positions.push(row, color, col);
    }
}
</code></pre>

<p>After that I generate index values like this (I know that there is a lot of optimization that can be done here):</p>

<pre><code>const height = noise.length + 1;
const width = noise[0].length + 1;

for (let row = 0; row &lt; height - 1; row++) {
    if (row % 2 === 0) {
        if (row === height - 2) break;
        for (let col = 0; col &lt; width - 1; col++) {
            indices.push(col + row * (width));
            indices.push(col - 1 + (row + 1) * (width));
        }
    } else {
        for (let col = width - 2; col &gt;= 0; col--) {
            indices.push(col - 2 + (row + 1) * (width));
            indices.push(col - 2 + row * (width));
        }
    }
}

indices.pop();
</code></pre>

<p>Finally I draw the plane using:</p>

<p><code>gl.drawElements(gl.TRIANGLE_STRIP, buffers.numIndices, gl.UNSIGNED_SHORT, 0);</code></p>

<p>So if I use <code>POINTS</code> as mode, the plane seem to look as it should:</p>

<p><a href="https://i.sstatic.net/JVCye.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/JVCye.png" alt="enter image description here"></a></p>

<p>Whereas if I am using <code>TRINGLE_STRIP</code> the result looks wrong:</p>

<p><a href="https://i.sstatic.net/PbGXw.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/PbGXw.png" alt="enter image description here"></a></p>

<p>First I thought wrong indices might be the reason but then I checked by scaling to a 3x3 grid/plane and the vertex and index output looked as I would have expected:</p>

<p>Vertices:</p>

<pre><code>[-1, -43.89, -1, 
-1,  -82.27,  0, 
-1,  -23.06,  1, 
 0,  -43.43, -1, 
 0,  -54.85,  0, 
 0,  -66.27,  1, 
 1,  -61.89, -1, 
 1,  -27.43,  0, 
 1,  -59.89,  1]
</code></pre>

<p><strong>Note:</strong> </p>

<blockquote>
  <p>The vertices might not exactly correspond to what you would have
  expected from above loop. That is because I am centering the <code>mesh</code>
  around origin after the loop.</p>
</blockquote>

<p>Indices:</p>

<pre><code>[0, 3, 1, 4, 2, 5, 8, 4, 7, 3, 6]
</code></pre>

<p>So my guess is that the problem is that I am pushing my triangles counterclockwise, that is why I tried to enable culling and depth testing but that did not help either:</p>

<pre><code>gl.enable(gl.DEPTH_TEST);
gl.enable(gl.CULL_FACE);
gl.cullFace(gl.FRONT);
</code></pre>

<p><a href="https://i.sstatic.net/IhodK.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/IhodK.png" alt="enter image description here"></a></p>

<p>Any guess what might be the reason for wrong <code>TRIANGLE_STRIP</code> rendering?</p>

<p><strong>Update 1:</strong></p>

<p>According to @PaulHK's recommendation I changed my index creation loop to insert the last index of a single strip twice. </p>

<pre><code>for (let row = 0; row &lt; rows - 1; row++) {
    if (row % 2 === 0) {
        for (let col = 0; col &lt; cols; col++) {
            indices.push(col + row * cols);
            indices.push(col + (row + 1) * cols);
        }
    } else {
        for (let col = cols - 1; col &gt;= 0; col--) {
            indices.push(col + (row) * cols);
            indices.push(col + (row + 1) * cols);
        }
    }
}
</code></pre>

<p>For a 3x3 grid this produces:</p>

<p><strong>Vertices:</strong></p>

<pre><code>[-1, -9.6, -1,
 -1, -64.6, 0,
 -1, -11.1, 1,
 0, -38.8, -1,
 0, -32.8, 0,
 0, -26.8, 1,
 1, -37.0, -1,
 1, -1, 0,
 1, -47.5, 1]
</code></pre>

<p><strong>Indices:</strong></p>

<pre><code>[0, 3, 1, 4, 2, 5, 5, 8, 4, 7, 3, 6]
</code></pre>

<p>Unfortunately the rendered object still looks the same.</p>

<p><strong>Update 2:</strong></p>

<p>I use the Diamond-square algorithm to generate the mesh. This requires a grid of size <code>(2^n) + 1</code>.
I.e.:</p>

<blockquote>
  <p>2, 3, 5, 9, 17, 33, 65, 129, 257, 513 ...</p>
</blockquote>

<p>Maybe it's just a coincidence but it seems to me that the grid can be displayed correctly for sizes <code>3 - 129</code> with the procedure from <strong>Update 1</strong>. For a size of 257 and above the mesh has errors.</p>

<p><strong>3x3 looks fine:</strong>
<a href="https://i.sstatic.net/KQNSfm.gif" rel="nofollow noreferrer"><img src="https://i.sstatic.net/KQNSfm.gif" alt="enter image description here"></a></p>

<p><strong>129x129 looks fine:</strong>
<a href="https://i.sstatic.net/kK8wom.gif" rel="nofollow noreferrer"><img src="https://i.sstatic.net/kK8wom.gif" alt="enter image description here"></a></p>

<p><strong>257x257 seems wrong:</strong>
<a href="https://i.sstatic.net/cRGdom.gif" rel="nofollow noreferrer"><img src="https://i.sstatic.net/cRGdom.gif" alt="enter image description here"></a></p>

CC BY-SA 4.0
2018-08-29T05:09:29.913Z
Are you trying to draw it as a single strip? You should be drawing it as a series of strips. This can still be done in 1 draw call but you will need to insert a degenerate triangle (duplicate the last vertex) at the end of each strip column.
PaulHK
CC BY-SA 4.0
2018-08-29T17:15:48.783Z
@PaulHK For a 3x3 plane that would be `[0, 3, 1, 4, 2, 5, 5, 8, 4, 7, 3, 6]`, right? But it still does not seem to work properly.
チーズパン
CC BY-SA 4.0
2018-08-30T02:13:34.747Z
It should be [Col(n), Col(n)+1, Col(n+1), Col(n+1)+1, Col(n+2), Col(n+2)+1, .... Col(n+8)+1, Col(n+8)+1]  .. So for every pair of indices we take a vertex for the current column and one from its neighbour, this is the same as your strip. At the end we insert a duplicate vertex which will create a degenerate triangle. This will cause the next set of strip indices to start a new strip without any connecting triangles to the last column.
PaulHK
CC BY-SA 4.0
2018-08-30T03:19:36.150Z
https://computergraphics.stackexchange.com/questions/3746/rendering-same-vertex-array-in-different-modes/3794#3794
PaulHK
CC BY-SA 4.0
2018-09-05T08:21:54.773Z
Can you reduce the grid size to say 3x3 points, this will make visualising the problem much easier.
PaulHK
CC BY-SA 4.0
2018-09-06T02:06:18.763Z
Ok, interesting the 3x3 version works and the 257x257 doesn't. Are you using 16bit indices by any chance? Because you can only address up to 256x256 using 16bit indices. For your case you need to use 32bit indices.
PaulHK
CC BY-SA 4.0
2018-09-07T16:48:48.690Z
@PaulHK Yes sir I did use `Uint16Array` and changing it to `Uint32Array` did solve the issue. Please submit an answer and grab the bounty. Ty!
チーズパン
CC BY-SA 4.0
2018-09-10T02:11:58.147Z
Good to know your problem is solved.
PaulHK
<webgl>
Problems rendering a plane via `drawElements`
チーズパン
# Problems rendering a plane via `drawElements`

(Asked by: username_0 on 2018-08-28)

I am generating plane vertices where the y values are generated by a heightmap (noise) algorithm. This is how I produce my vertex array:

```
for (let row = 0; row < noise.length; row++) {
    for (let col = 0; col < noise[0].length; col++) {
        color = noise[row][col];
        positions.push(row, color, col);
    }
}

```

After that I generate index values like this (I know that there is a lot of optimization that can be done here):

```
const height = noise.length + 1;
const width = noise[0].length + 1;

for (let row = 0; row < height - 1; row++) {
    if (row % 2 === 0) {
        if (row === height - 2) break;
        for (let col = 0; col < width - 1; col++) {
            indices.push(col + row * (width));
            indices.push(col - 1 + (row + 1) * (width));
        }
    } else {
        for (let col = width - 2; col >= 0; col--) {
            indices.push(col - 2 + (row + 1) * (width));
            indices.push(col - 2 + row * (width));
        }
    }
}

indices.pop();

```

Finally I draw the plane using:

`gl.drawElements(gl.TRIANGLE_STRIP, buffers.numIndices, gl.UNSIGNED_SHORT, 0);`

So if I use `POINTS` as mode, the plane seem to look as it should:

[![enter image description here](https://i.sstatic.net/JVCye.png)](https://i.sstatic.net/JVCye.png)

Whereas if I am using `TRINGLE_STRIP` the result looks wrong:

[![enter image description here](https://i.sstatic.net/PbGXw.png)](https://i.sstatic.net/PbGXw.png)

First I thought wrong indices might be the reason but then I checked by scaling to a 3x3 grid/plane and the vertex and index output looked as I would have expected:

Vertices:

```
[-1, -43.89, -1, 
-1,  -82.27,  0, 
-1,  -23.06,  1, 
 0,  -43.43, -1, 
 0,  -54.85,  0, 
 0,  -66.27,  1, 
 1,  -61.89, -1, 
 1,  -27.43,  0, 
 1,  -59.89,  1]

```

**Note:**

> The vertices might not exactly correspond to what you would have
> expected from above loop. That is because I am centering the `mesh`
> around origin after the loop.

Indices:

```
[0, 3, 1, 4, 2, 5, 8, 4, 7, 3, 6]

```

So my guess is that the problem is that I am pushing my triangles counterclockwise, that is why I tried to enable culling and depth testing but that did not help either:

```
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.CULL_FACE);
gl.cullFace(gl.FRONT);

```

[![enter image description here](https://i.sstatic.net/IhodK.png)](https://i.sstatic.net/IhodK.png)

Any guess what might be the reason for wrong `TRIANGLE_STRIP` rendering?

**Update 1:**

According to @username_1's recommendation I changed my index creation loop to insert the last index of a single strip twice.

```
for (let row = 0; row < rows - 1; row++) {
    if (row % 2 === 0) {
        for (let col = 0; col < cols; col++) {
            indices.push(col + row * cols);
            indices.push(col + (row + 1) * cols);
        }
    } else {
        for (let col = cols - 1; col >= 0; col--) {
            indices.push(col + (row) * cols);
            indices.push(col + (row + 1) * cols);
        }
    }
}

```

For a 3x3 grid this produces:

**Vertices:**

```
[-1, -9.6, -1,
 -1, -64.6, 0,
 -1, -11.1, 1,
 0, -38.8, -1,
 0, -32.8, 0,
 0, -26.8, 1,
 1, -37.0, -1,
 1, -1, 0,
 1, -47.5, 1]

```

**Indices:**

```
[0, 3, 1, 4, 2, 5, 5, 8, 4, 7, 3, 6]

```

Unfortunately the rendered object still looks the same.

**Update 2:**

I use the Diamond-square algorithm to generate the mesh. This requires a grid of size `(2^n) + 1`.
I.e.:

> 2, 3, 5, 9, 17, 33, 65, 129, 257, 513 ...

Maybe it's just a coincidence but it seems to me that the grid can be displayed correctly for sizes `3 - 129` with the procedure from **Update 1**. For a size of 257 and above the mesh has errors.

**3x3 looks fine:**
[![enter image description here](https://i.sstatic.net/KQNSfm.gif)](https://i.sstatic.net/KQNSfm.gif)

**129x129 looks fine:**
[![enter image description here](https://i.sstatic.net/kK8wom.gif)](https://i.sstatic.net/kK8wom.gif)

**257x257 seems wrong:**
[![enter image description here](https://i.sstatic.net/cRGdom.gif)](https://i.sstatic.net/cRGdom.gif)

**Tags:** webgl

> **Comments:**
> **username_1**: Are you trying to draw it as a single strip? You should be drawing it as a series of strips. This can still be done in 1 draw call but you will need to insert a degenerate triangle (duplicate the last vertex) at the end of each strip column.  
> **username_0**: @username_1 For a 3x3 plane that would be `[0, 3, 1, 4, 2, 5, 5, 8, 4, 7, 3, 6]`, right? But it still does not seem to work properly.  
> **username_1**: It should be [Col(n), Col(n)+1, Col(n+1), Col(n+1)+1, Col(n+2), Col(n+2)+1, .... Col(n+8)+1, Col(n+8)+1]  .. So for every pair of indices we take a vertex for the current column and one from its neighbour, this is the same as your strip. At the end we insert a duplicate vertex which will create a degenerate triangle. This will cause the next set of strip indices to start a new strip without any connecting triangles to the last column.  
> **username_1**: https://computergraphics.stackexchange.com/questions/3746/rendering-same-vertex-array-in-different-modes/3794#3794  
> **username_1**: Can you reduce the grid size to say 3x3 points, this will make visualising the problem much easier.  
> **username_1**: Ok, interesting the 3x3 version works and the 257x257 doesn't. Are you using 16bit indices by any chance? Because you can only address up to 256x256 using 16bit indices. For your case you need to use 32bit indices.  
> **username_0**: @username_1 Yes sir I did use `Uint16Array` and changing it to `Uint32Array` did solve the issue. Please submit an answer and grab the bounty. Ty!  
> **username_1**: Good to know your problem is solved.  

---

## 1 answers

### Answer by username_1 on 2018-09-10. Score: 3 | Accepted answer

This looks like a case of 16bit truncation in your indice buffer. For a 257x257 grid you will be addressing more than 65536 vertices so you will need to use a 32bit indice buffer.

```
gl.drawElements(gl.TRIANGLE_STRIP, buffers.numIndices, gl.UNSIGNED_SHORT, 0);

```

change to :

```
gl.drawElements(gl.TRIANGLE_STRIP, buffers.numIndices, gl.UNSIGNED_INT, 0);

```

Also change your buffer allocation code to match this type (Uint16Array -> Uint32Array for Javascript).

> **Comments:**
> **username_2**: You might want to mention that in JavaScript/WebGL the array containing the indices has to be a `Uint32Array` instead of `Uint16Array`.  
> **username_1**: Thanks for the suggestion, I've ammended my answer. I wanted to make the answer language agnostic as this can occur on any GL implementation.  

---

