VBO Triangle Strip issue with height-map program

Started by Ziath, May 29, 2013, 12:42:11

Previous topic - Next topic

Ziath

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);
	}	
}

Fool Running

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.
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

Ziath

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..  ???

quew8

Surely you aren't using shorts anymore so the offset should be bigger. 1600*x for ints example.

Ziath