EDIT: Updated code and questions on post #6.
Hi,
I want to try to make a simple game just for fun and began with basic rendering, etc; and have now started working on Heightmaps. I’ve written up some code to render a Heightmap using opengl, java, Triangle strips, vbos, and ibos.
I tried my best to gather an understanding and the following is what I produced. When used, it does semi draw a Heightmap however as you can tell the results are a little rough. I end up with 250fps and the terrain is only 200 x 200 on top of a few of the Triangle strips rendering in odd positions.
I’m not sure but it would seem that a few vertices are creating “bridges” to the opposite side of the map. (Also I haven’t added in normals yet, so the Heightmap is just black for now)
Here is two screen shots with the results:
Anyone have any ideas on improving the performance and fixing the “bridging” issue? It would seem as if it could be an issue with the last triangle strip. The backside of the heightmap, at the last vertex is where it starts the “bridges”. I have no idea what went wrong. Any help with this is very much appreciated!
Edit: Just noticed, the last triangle is stretching to the very first triangle and the first triangle isn’t rendering. Very odd.
Here’s the code:
package com.base.engine;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
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 javax.imageio.ImageIO;
import org.lwjgl.BufferUtils;
public class TerrainTest2 {
private static int width;
private static int height;
private static int verticies;
private static int indicies;
private static FloatBuffer vBuffer;
private static IntBuffer iBuffer;
private static float[][] data;
private static int vbo;
private static int ibo;
public TerrainTest2 (String fileName) {
glPushMatrix();
glScalef(0.6f, 0.6f, 0.6f);
glTranslatef(-70.0f, -62.0f, -100.0f);
initHeightmap();
loadHeightImage(fileName);
loadHeightVerticies();
drawHeightmap();
glPopMatrix();
}
//Set buffer handles
public static void initHeightmap() {
vbo = glGenBuffers();
ibo = glGenBuffers();
}
//Load heightmap and get heights from values 0-255
public static void loadHeightImage(String fileName) {
try {
BufferedImage heightmapImage = ImageIO.read(new File("./res/heightmap/" + fileName));
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();
}
}
height = heightmapImage.getHeight();
width = heightmapImage.getWidth();
verticies = (3*(2*height)*width);
indicies = ((height*2)*width);
vBuffer = BufferUtils.createFloatBuffer(verticies);
iBuffer = BufferUtils.createIntBuffer(indicies);
} catch (IOException e){
e.printStackTrace();
}
}
//Add verticies and indicies into there buffers
public static void loadHeightVerticies() {
for (int z = 0; z < data.length - 1; z++) {
for (int x = 0; x < data[z].length; x++) {
vBuffer.put(x).put(data[z][x]).put(z);
vBuffer.put(x).put(data[z + 1][x]).put(z + 1);
}
}
vBuffer.flip();
for (int n = 0; n < indicies; n++) {
iBuffer.put((int) n);
}
iBuffer.flip();
}
//Draw using vbo and ibo using triangle strips
public static void drawHeightmap() {
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vBuffer, GL_STATIC_DRAW);
glVertexPointer(3, GL_FLOAT, 0, 0L);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, iBuffer, GL_STATIC_DRAW);
glDrawElements(GL_TRIANGLE_STRIP, indicies, GL_UNSIGNED_INT, 0);
glDisableClientState(GL_VERTEX_ARRAY);
// cleanup VBO handles
vBuffer.put(0, vbo);
iBuffer.put(0, ibo);
glDeleteBuffers(vbo);
glDeleteBuffers(ibo);
}
}