Hi,
Ive been writing a little terrain generator and heightmap renderer and came to a stand still performance wise and so decided to try using VBO’s to increase speed. I took my orginal 3Dimensional array and split it into patches of size 16 * 16 and each one storing the another 3 dimensional array of that section. Each patch has its own vertex/colour buffer which is set up after all the patches have been made and each patch is called in sequence to render its section.
The speed has increased alot, allowing all 512 * 512 tiles to be displayed at once but each patch is exactly the same as the last one, there are gaps between each patch ( which is probably me messing up the splitting ) and the the triangles in each patch go all over the place, including what i assume is infinity at some points. At one point the first patch was drawn perfectly with the ones behind getting worse, but I randomy switched a 0 for a 1, crashed my pc and forgot what other things i had changed.
Ive checked the “patching” method over and over and im sure its working fine and ive checked the vertex index layout against many sugesstions online so i think its my buffer generation / drawing section. If anyone has any ideas or knows what ive done wrong help would be welcome.
public class TerrainPatch
{
public static final short TERRAIN_DIMENSIONS = 16; //Size of patches sides
public static final short VERTEX_LIST_COUNT = TERRAIN_DIMENSIONS * TERRAIN_DIMENSIONS * 6;//The number of vertices in the buffer 3 verts + 3 for a colour
//Index data, i wrote it by hand because im silly, though im fairly certain its correct.
private static final short[] INDICES =
{ 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23, 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31, 31, 16,
16, 32, 17, 33, 18, 34, 19, 35, 20, 36, 21, 37, 22, 38, 23, 39, 24, 40, 25, 41, 26, 42, 27, 43, 28, 44, 29, 45, 30, 46, 31, 47, 47, 32,
32, 48, 33, 49, 34, 50, 35, 51, 36, 52, 37, 53, 38, 54, 39, 55, 40, 56, 41, 57, 42, 58, 43, 59, 44, 60, 45, 61, 46, 62, 47, 63, 63, 48,
48, 64, 49, 65, 50, 66, 51, 67, 52, 68, 53, 69, 54, 70, 55, 71, 56, 72, 57, 73, 58, 74, 59, 75, 60, 76, 61, 77, 62, 78, 63, 79, 79, 64,
64, 80, 65, 81, 66, 82, 67, 83, 68, 84, 69, 85, 70, 86, 71, 87, 72, 88, 73, 89, 74, 90, 75, 91, 76, 92, 77, 93, 78, 94, 79, 95, 95, 80,
80, 96, 81, 97, 82, 98, 83, 99, 84, 100, 85, 101, 86, 102, 87, 103, 88, 104, 89, 105, 90, 106, 91, 107, 92, 108, 93, 109, 94, 110, 95, 111, 111, 96,
96, 112, 97, 113, 98, 114, 99, 115, 100, 116, 101, 117, 102, 118, 103, 119, 104, 120, 105, 121, 106, 122, 107, 123, 108, 124, 109, 125, 110, 126, 111, 127, 127, 112,
112, 128, 113, 129, 114, 130, 115, 131, 116, 132, 117, 133, 118, 134, 119, 135, 120, 136, 121, 137, 122, 138, 123, 139, 124, 140, 125, 141, 126, 142, 127, 143, 143, 128,
128, 144, 129, 145, 130, 146, 131, 147, 132, 148, 133, 149, 134, 150, 135, 151, 136, 152, 137, 153, 138, 154, 139, 155, 140, 156, 141, 157, 142, 158, 143, 159, 159, 144,
144, 160, 145, 161, 146, 162, 147, 163, 148, 164, 149, 165, 150, 166, 151, 167, 152, 168, 153, 169, 154, 170, 155, 171, 156, 172, 157, 173, 158, 174, 159, 175, 175, 160,
160, 176, 161, 177, 162, 178, 163, 179, 164, 180, 165, 181, 166, 182, 167, 183, 168, 184, 169, 185, 170, 186, 171, 187, 172, 188, 173, 189, 174, 190, 175, 191, 191, 176,
176, 192, 177, 193, 178, 194, 179, 195, 180, 196, 181, 197, 182, 198, 183, 199, 184, 200, 185, 201, 186, 202, 187, 203, 188, 204, 189, 205, 190, 206, 191, 207, 207, 192,
192, 208, 193, 209, 194, 210, 195, 211, 196, 212, 197, 213, 198, 214, 199, 215, 200, 216, 201, 217, 202, 218, 203, 219, 204, 220, 205, 221, 206, 222, 207, 223, 223, 208,
208, 224, 209, 225, 210, 226, 211, 227, 212, 228, 213, 229, 214, 230, 215, 231, 216, 232, 217, 233, 218, 234, 219, 235, 220, 236, 221, 237, 222, 238, 223, 239, 239, 224,
224, 240, 225, 241, 226, 242, 227, 243, 228, 244, 229, 245, 230, 246, 231, 247, 232, 248, 233, 249, 234, 250, 235, 251, 236, 252, 237, 253, 238, 254, 239, 255, 255, 255 };
private float[][][] terrainData = null; //Base Terrain
private FloatBuffer terrainVertexData = null; //Buffer full of vertex and colour information
private ShortBuffer terrainIndexData = null; //Buffer full of indices to the vertex information
private IntBuffer indicesBufferID= null; //Buffer to the indices buffer ID
private IntBuffer terrainVertexBufferID = null; //Buffer to the vertices buffer ID
private int xStart, zStart; //The offset of a patch ( for translating the patch to the right place)
public TerrainPatch(float[][][] newTerrainData, int xStartIn, int zStartIn)
{
//Copy the base terrain here, set the offset
terrainData = new float[16][16][5];
System.arraycopy(newTerrainData, 0, terrainData, 0, 16);
xStart = xStartIn;
zStart = zStartIn;
}
//Create all of the buffers here
public void initPatch(GL gl)
{
/* This packs the vertex and colour information into a 1 dimensional array Should be in the order x1, y1, z1, r1, g1, b1, x2, y2, z2, r3 ... */
terrainVertexData = genVertexList();
//Create buffers to store buffer IDs
terrainVertexBufferID = BufferUtil.newIntBuffer(1);
indicesBufferID = BufferUtil.newIntBuffer(1);
terrainIndexData = ShortBuffer.wrap(INDICES); //Create a new ShortBuffer containing the index data
//Generate vertex buffer
gl.glGenBuffers(1, terrainVertexBufferID); //Create 1 buffer
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, terrainVertexBufferID.get()); //Bind to the vertexBuffer ( I have no idea if im supposed to be using .get() like that)
gl.glBufferData(GL.GL_ARRAY_BUFFER, terrainVertexData.capacity() * BufferUtil.SIZEOF_FLOAT, terrainVertexData, GL.GL_STATIC_DRAW); //Fill with terrain vertex data
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); //Unbind
//Same as above but with index data
gl.glGenBuffers(1, indicesBufferID);
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, indicesBufferID.get());
gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, terrainIndexData.capacity()* BufferUtil.SIZEOF_SHORT, terrainIndexData, GL.GL_STATIC_DRAW);
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
//rewind ( Nothing was happening untill i added a few of these, then things actually appeared )
terrainVertexBufferID.rewind();
indicesBufferID.rewind();
}
//This draws the patch
public void renderPatch(GL gl)
{
//Enable colours and vertices
gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL.GL_COLOR_ARRAY);
//Bind to the vertex buffer and set pointers to vertices and colours
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, terrainVertexBufferID.get());
gl.glVertexPointer(3, GL.GL_FLOAT, 6 * BufferUtil.SIZEOF_FLOAT, 0);
gl.glColorPointer(3, GL.GL_FLOAT, 6 * BufferUtil.SIZEOF_FLOAT, 3 * BufferUtil.SIZEOF_FLOAT);
//Bind the indices buffer
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, indicesBufferID.get());
gl.glTranslatef(xStart, 0, zStart); //Translate to the start position of this patch
gl.glEnable(GL.GL_DEPTH_TEST); //Enable depth testing
gl.glDrawElements(GL.GL_TRIANGLE_STRIP, terrainIndexData.capacity() * BufferUtil.SIZEOF_SHORT, GL.GL_UNSIGNED_SHORT, 0); //Draw the vertices
gl.glDisable(GL.GL_DEPTH_TEST);
gl.glTranslatef(-xStart, 0, -zStart);
//More rewinds
terrainVertexBufferID.rewind();
indicesBufferID.rewind();
terrainIndexData.rewind();
gl.glDisableClientState(GL.GL_COLOR_ARRAY);
gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
}
//This just converts the 3 dimensional array into a 1 dimensioanly array
private FloatBuffer genVertexList()
{
int count = 0, step = 6;
float[] vertexList = new float[VERTEX_LIST_COUNT];
for(int x = 0;x < TERRAIN_DIMENSIONS;x++)
{
for(int z = 0;z < TERRAIN_DIMENSIONS;z++)
{
vertexList[count + 0] = x;
vertexList[count + 1] = terrainData[x][z][0]; //Y vertex data
vertexList[count + 2] = z;
vertexList[count + 3] = terrainData[x][z][1]; //Red
vertexList[count + 4] = terrainData[x][z][2]; //Green
vertexList[count + 5] = terrainData[x][z][3]; //Blue
count += step;
}
}
return FloatBuffer.wrap(vertexList);
}
}
Here is an example of the problem. I have a feeling its the way i have splitted the image but ive checked it over and over.
http://img101.imageshack.us/img101/2447/example4wv.th.jpg
If anyone thinks it is the way i have split it, i can post the code for that too.
Thanks in advance for any help.