LWJGL Forum

Programming => Lightweight Java Gaming Library => Topic started by: Ziath on May 29, 2013, 12:42:11

Title: VBO Triangle Strip issue with height-map program
Post by: Ziath on May 29, 2013, 12:42:11
Hello all. I have seem to encounter a problem in my program for height map rendering. I have looked all over the web for a solution to my issue, and i have found some threads on forums about this same thing, but no solution was provided :/. If anyone could point me in the right direction or help me that would be awesome.

So here is a screen shots of the problem.

http://i.imgur.com/IXfVtgu.png

I am using VBOs and IBOs to render the vertices with TRIANGLE_STRIP. It looks as if once the strip moves over to start a new "strip" it continues the previous strip which causes those lines to jump which i tried to solve by drawing the vertices through an index with glDrawElements. Also, when i set it to draw all the lines, it stops on the last strip about 4/5ths of the way through. (this was boxed in red)

For some odd reason, if i limit the map (which is 200x200), to draw only 160 lines, the issue disappears:

http://i.imgur.com/wBlsxT9.png

Here is my code:

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;

import javax.imageio.ImageIO;

import org.lwjgl.BufferUtils;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;


public class Heightmap {

private int width = 200;
private int height = 200;
private int verticies = (3*(2*height)*width);
private int indicies = ((height*2)*width);
private FloatBuffer vBuffer = BufferUtils.createFloatBuffer(verticies);
private ShortBuffer iBuffer = BufferUtils.createShortBuffer(indicies);
private IntBuffer ib = BufferUtils.createIntBuffer(indicies);
private static float[][] data;

public Heightmap() {

glPushMatrix();
glScalef(0.6f, 0.6f, 0.6f);
glTranslatef(-70.0f, -62.0f, -100.0f);
loadHeightImage();
loadHeightVerticies();
drawHeightMap();
glPopMatrix();

}

public void loadHeightImage() {

try {
BufferedImage heightmapImage = ImageIO.read(new File("src/heightmap.bmp"));
data = new float[heightmapImage.getWidth()][heightmapImage.getHeight()];
Color colour;

for (int x = 0; x < data.length; x++)
{
for (int z = 0; z < data[x].length; z++)
{
colour = new Color(heightmapImage.getRGB(x, z));
data[z][x] = colour.getRed();

}
}
} catch (IOException e){
e.printStackTrace();
}
}

public void loadHeightVerticies() {

for (int z = 0; z < this.data.length - 1; z++) {
for (int x = 0; x < this.data[z].length; x++) {

vBuffer.put(x).put(this.data[z][x]).put(z);
vBuffer.put(x).put(this.data[z + 1][x]).put(z + 1);
}
}

this.vBuffer.flip();

for (int n = 0; n < indicies; n++) {
this.iBuffer.put((short) n);
}

this.iBuffer.flip();
}

public void drawHeightMap() {

glGenBuffers(ib);
   int vHandle = ib.get(0);
   int iHandle = ib.get(1);
   
   glEnableClientState(GL_VERTEX_ARRAY);
   glBindBuffer(GL_ARRAY_BUFFER, vHandle);
   glBufferData(GL_ARRAY_BUFFER, vBuffer, GL_STATIC_DRAW);
   glVertexPointer(3, GL_FLOAT, 0, 0L);
   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iHandle);
   glBufferData(GL_ELEMENT_ARRAY_BUFFER, iBuffer, GL_STATIC_DRAW);
   
   for (int x = 0; x < 160; x++) {
   
    glDrawElements(GL_TRIANGLE_STRIP, 400, GL_UNSIGNED_SHORT, 800*x);
}
   
   glDisableClientState(GL_VERTEX_ARRAY);
   
   // cleanup VBO handles
   ib.put(0, vHandle);
   
   glDeleteBuffers(ib);
}
}
Title: Re: VBO Triangle Strip issue with height-map program
Post by: Fool Running on May 29, 2013, 12:52:55
ShortBuffer iBuffer = BufferUtils.createShortBuffer(indicies);
...
this.iBuffer.put((short) n);

I think this is your problem. You are creating too many vertexes than can be indexed in a short (65536). Try changing to integers instead.
I had a similar problem once. I would have expected to get an overflow exception or something, but it never happened and the mesh was just cut off. The reason is that when you cast an integer to a short, it just takes the first 16 bits of the integer and turns them into a short. There is no checking to see if the integer is too big for a short.
Title: Re: VBO Triangle Strip issue with height-map program
Post by: Ziath on May 29, 2013, 13:14:45
Okay, yeah that does make a lot more sense. I did change it, but its now worse but it did fix the cut off. More lines for some reason.

for (int x = 0; x < 200; x++) {
   
    glDrawElements(GL_TRIANGLE_STRIP, 400, GL_UNSIGNED_INT, 800*x);
}


I think there is something wrong with this. But i can't seem to figure it out..

GL11.glDrawElements(GL11.GL_TRIANGLES, numberIndices, GL11.GL_UNSIGNED_INT, 0);

400 should be the right amount of indicies per strip... And the offset is 800 * current strip..  ???
Title: Re: VBO Triangle Strip issue with height-map program
Post by: quew8 on May 29, 2013, 16:19:22
Surely you aren't using shorts anymore so the offset should be bigger. 1600*x for ints example.
Title: Re: VBO Triangle Strip issue with height-map program
Post by: Ziath on May 29, 2013, 16:54:31
Ahh i see. That fixed it. Thank you guys