Issues drawing object from VBO

Hey guys, I’m currently trying to port this tutorial (http://www.arcsynthesis.org/gltut/Positioning/Tut06%20Fun%20with%20Matrices.html) to lwjgl, but I’m having some issues when it comes to actually drawing the object, and instead of looking like this:

http://www.arcsynthesis.org/gltut/Positioning/Robot%20Arm.png

It looks like this:

I think the issue might have something to do with the way the index data is being buffered/read, but I really have no idea. Any help would be greatly appreciated.

import org.lwjgl.opengl.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.ARBVertexBufferObject.*;
import static org.lwjgl.opengl.ARBVertexArrayObject.*;

import org.lwjgl.util.vector.*;
import org.lwjgl.BufferUtils;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;


public class DrawRobot {
	private Matrix4f cameraToClipMatrix;
	private int program, positionAttrib, colorAttrib, modelToCameraMatrixUnif, cameraToClipMatrixUnif, vertexBuffObj, indexBuffObj, vao;
	private float fFrustumScale;
	private final int numberOfVerticies = 24;
	IntBuffer indexDatBuff;
	
	private final float[] RED_COLOR = { 1.0f, 0.0f, 0.0f, 1.0f };
	private final float[] GREEN_COLOR = { 0.0f, 1.0f, 0.0f, 1.0f };
	private final float[] BLUE_COLOR = { 0.0f, 0.0f, 1.0f, 1.0f };
	private final float[] YELLOW_COLOR = { 1.0f, 1.0f, 0.0f, 1.0f };
	private final float[] CYAN_COLOR = { 0.0f, 1.0f, 1.0f, 1.0f };
	private final float[] MAGENTA_COLOR = { 1.0f, 0.0f, 1.0f, 1.0f };
	
	private final float[] vertexData = {
			//Front
			+1.0f, +1.0f, +1.0f,
			+1.0f, -1.0f, +1.0f,
			-1.0f, -1.0f, +1.0f,
			-1.0f, +1.0f, +1.0f,

			//Top
			+1.0f, +1.0f, +1.0f,
			-1.0f, +1.0f, +1.0f,
			-1.0f, +1.0f, -1.0f,
			+1.0f, +1.0f, -1.0f,

			//Left
			+1.0f, +1.0f, +1.0f,
			+1.0f, +1.0f, -1.0f,
			+1.0f, -1.0f, -1.0f,
			+1.0f, -1.0f, +1.0f,

			//Back
			+1.0f, +1.0f, -1.0f,
			-1.0f, +1.0f, -1.0f,
			-1.0f, -1.0f, -1.0f,
			+1.0f, -1.0f, -1.0f,

			//Bottom
			+1.0f, -1.0f, +1.0f,
			+1.0f, -1.0f, -1.0f,
			-1.0f, -1.0f, -1.0f,
			-1.0f, -1.0f, +1.0f,

			//Right
			-1.0f, +1.0f, +1.0f,
			-1.0f, -1.0f, +1.0f,
			-1.0f, -1.0f, -1.0f,
			-1.0f, +1.0f, -1.0f,


			GREEN_COLOR[0], GREEN_COLOR[1], GREEN_COLOR[2], GREEN_COLOR[3],
			GREEN_COLOR[0], GREEN_COLOR[1], GREEN_COLOR[2], GREEN_COLOR[3],
			GREEN_COLOR[0], GREEN_COLOR[1], GREEN_COLOR[2], GREEN_COLOR[3],
			GREEN_COLOR[0], GREEN_COLOR[1], GREEN_COLOR[2], GREEN_COLOR[3],
			
			BLUE_COLOR[0], BLUE_COLOR[1], BLUE_COLOR[2], BLUE_COLOR[3],
			BLUE_COLOR[0], BLUE_COLOR[1], BLUE_COLOR[2], BLUE_COLOR[3],
			BLUE_COLOR[0], BLUE_COLOR[1], BLUE_COLOR[2], BLUE_COLOR[3],
			BLUE_COLOR[0], BLUE_COLOR[1], BLUE_COLOR[2], BLUE_COLOR[3],
			
			RED_COLOR[0], RED_COLOR[1], RED_COLOR[2], RED_COLOR[3],
			RED_COLOR[0], RED_COLOR[1], RED_COLOR[2], RED_COLOR[3],
			RED_COLOR[0], RED_COLOR[1], RED_COLOR[2], RED_COLOR[3],
			RED_COLOR[0], RED_COLOR[1], RED_COLOR[2], RED_COLOR[3],
			
			YELLOW_COLOR[0], YELLOW_COLOR[1], YELLOW_COLOR[2], YELLOW_COLOR[3],
			YELLOW_COLOR[0], YELLOW_COLOR[1], YELLOW_COLOR[2], YELLOW_COLOR[3],
			YELLOW_COLOR[0], YELLOW_COLOR[1], YELLOW_COLOR[2], YELLOW_COLOR[3],
			YELLOW_COLOR[0], YELLOW_COLOR[1], YELLOW_COLOR[2], YELLOW_COLOR[3],
			
			CYAN_COLOR[0], CYAN_COLOR[1], CYAN_COLOR[2], CYAN_COLOR[3],
			CYAN_COLOR[0], CYAN_COLOR[1], CYAN_COLOR[2], CYAN_COLOR[3],
			CYAN_COLOR[0], CYAN_COLOR[1], CYAN_COLOR[2], CYAN_COLOR[3],
			CYAN_COLOR[0], CYAN_COLOR[1], CYAN_COLOR[2], CYAN_COLOR[3],
			
			MAGENTA_COLOR[0], MAGENTA_COLOR[1], MAGENTA_COLOR[2], MAGENTA_COLOR[3],
			MAGENTA_COLOR[0], MAGENTA_COLOR[1], MAGENTA_COLOR[2], MAGENTA_COLOR[3],
			MAGENTA_COLOR[0], MAGENTA_COLOR[1], MAGENTA_COLOR[2], MAGENTA_COLOR[3],
			MAGENTA_COLOR[0], MAGENTA_COLOR[1], MAGENTA_COLOR[2], MAGENTA_COLOR[3],
	};
	
	private final int indexData[] = {
			0, 1, 2,
			2, 3, 0,

			4, 5, 6,
			6, 7, 4,

			8, 9, 10,
			10, 11, 8,

			12, 13, 14,
			14, 15, 12,

			16, 17, 18,
			18, 19, 16,

			20, 21, 22,
			22, 23, 20,	
	};
	
	DrawRobot(int w, int h)	{
		// Set up opengl environment
		glViewport(0, 0, w, h);
		glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		glClearDepth(1.0f);
		
		glEnable(GL_DEPTH_TEST);
		glDepthMask(true);
		glDepthFunc(GL_LEQUAL);
		glDepthRange(0.0f, 1.0f);
		
		glEnable(GL_CULL_FACE);
		glCullFace(GL_BACK);
		glFrontFace(GL_CW);
		
		programInit();
		VAOInit();
		robot();
	}
	
	private float calcFrustrumscale(float fDegFOV)	{
		final float degToRad = 3.14159f * 2.0f / 360.0f;
		float fRadFOV = fDegFOV * degToRad;
		return (float) Math.atan(fRadFOV);
	}
	
	private void programInit()	{
		ShaderLoader loader = new ShaderLoader("src/shaders/PosColorLocalTransform.vert", "src/shaders/ColorPassthrough.frag");
		if (!loader.getBuildStatus())	{
			System.out.println("Failed to load shaders.  Exiting.");
			Display.destroy();
			System.exit(0);
		}
		program = loader.getProgram();
		positionAttrib = glGetAttribLocation(program, "position");
		colorAttrib = glGetAttribLocation(program, "color");
		
		modelToCameraMatrixUnif = glGetUniformLocation(program, "modelToCameraMatrix");
		cameraToClipMatrixUnif = glGetUniformLocation(program, "cameraToClipMatrix");
		
		// Set up camera to clip space translation matrix
		float fzNear = 1.0f, fzFar = 100.0f;
		fFrustumScale = calcFrustrumscale(45.0f);
		cameraToClipMatrix = new Matrix4f();
		cameraToClipMatrix.m00 = fFrustumScale;
		cameraToClipMatrix.m11 = fFrustumScale;
		cameraToClipMatrix.m22 = (fzFar + fzNear) / (fzNear - fzFar);
		cameraToClipMatrix.m23 = -1.0f;
		cameraToClipMatrix.m32 = (2 * fzFar * fzNear) / (fzNear - fzFar);
		
		FloatBuffer buf = BufferUtils.createFloatBuffer(16);
		cameraToClipMatrix.store(buf);
		buf.flip();
		
		
		glUseProgram(program);
		glUniformMatrix4(cameraToClipMatrixUnif, false, buf);
		glUseProgram(0);
	}
	
	private void VAOInit()	{
		IntBuffer vertBuff = BufferUtils.createIntBuffer(1);
		glGenBuffersARB(vertBuff);
		vertexBuffObj = vertBuff.get(0);
		
		FloatBuffer vertexDatBuff = BufferUtils.createFloatBuffer(vertexData.length);
		vertexDatBuff.put(vertexData);
		vertexDatBuff.flip();
		
		glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertexBuffObj);
		glBufferDataARB(GL_ARRAY_BUFFER_ARB, vertexDatBuff, GL_STATIC_DRAW_ARB);
		glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
		
		IntBuffer indexBuff = BufferUtils.createIntBuffer(1);
		glGenBuffersARB(indexBuff);
		indexBuffObj = indexBuff.get(0);
		
		indexDatBuff = BufferUtils.createIntBuffer(indexData.length);
		indexDatBuff.put(indexData);
		indexDatBuff.flip();
		
		glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indexBuffObj);
		glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indexDatBuff, GL_STATIC_DRAW_ARB);
		glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
		
		IntBuffer vaoBuff = BufferUtils.createIntBuffer(1);
		glGenVertexArrays(vaoBuff);
		vao = vaoBuff.get(0);
		glBindVertexArray(vao);
		
		int colorDataOffset = 4 * 3 * numberOfVerticies; // 4 bytes * 3 points * obvious
		glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertexBuffObj);
		glEnableVertexAttribArray(positionAttrib);
		glEnableVertexAttribArray(colorAttrib);
		glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, false, 0, 0);
		glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, false, 0, colorDataOffset);
		glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indexBuffObj);
		
		glBindVertexArray(0);
	}
	
	private float clamp(float fValue, float fMin, float fMax)	{
		if (fValue < fMin)
			return fMin;
		if (fValue > fMax)
			return fMax;
		
		return fValue;
	}
	
	void reshape (int w, int h)
	{
		cameraToClipMatrix.m00 = fFrustumScale * (h / (float)w);
		cameraToClipMatrix.m11 = fFrustumScale;

		glUseProgram(program);
		FloatBuffer buf = BufferUtils.createFloatBuffer(16);
		cameraToClipMatrix.store(buf);
		buf.flip();
		glUniformMatrix4(cameraToClipMatrixUnif, false, buf);
		glUseProgram(0);

		glViewport(0, 0, w, h);
	}
	
	// Defines block for robot
	
        private final float STANDARD_ANGLE_INCREMENT = 11.25f;
	private final float SMALL_ANGLE_INCREMENT = 9.0f;
	
	Vector3f		posBase;
	float			angBase;

	Vector3f		posBaseLeft, posBaseRight;
	float			scaleBaseZ;

	float			angUpperArm;
	float			sizeUpperArm;

	Vector3f		posLowerArm;
	float			angLowerArm;
	float			lenLowerArm;
	float			widthLowerArm;

	Vector3f		posWrist;
	float			angWristRoll;
	float			angWristPitch;
	float			lenWrist;
	float			widthWrist;

	Vector3f		posLeftFinger, posRightFinger;
	float			angFingerOpen;
	float			lenFinger;
	float			widthFinger;
	float			angLowerFinger;
	// End Defines
	
	private void robot()	{
		posBase = new Vector3f(3.0f, -5.0f, -40.0f);
		angBase = -45.0f;
		posBaseLeft = new Vector3f(2.0f, 0.0f, 0.0f);
		posBaseRight = new Vector3f(-2.0f, 0.0f, 0.0f);
		scaleBaseZ = 3.0f;
		angUpperArm = -33.75f;
		sizeUpperArm = 9.0f;
		posLowerArm = new Vector3f(0.0f, 0.0f, 8.0f);
		angLowerArm = 146.25f;
		lenLowerArm = 5.0f;
		widthLowerArm = 1.5f;
		posWrist = new Vector3f(0.0f, 0.0f, 5.0f);
		angWristRoll = 0.0f;
		angWristPitch = 67.5f;
		lenWrist = 2.0f;
		widthWrist = 2.0f;
		posLeftFinger = new Vector3f(1.0f, 0.0f, 1.0f);
		posRightFinger = new Vector3f(-1.0f, 0.0f, 1.0f);
		angFingerOpen = 180.0f;
		lenFinger = 2.0f;
		widthFinger = 0.5f;
		angLowerFinger = 45.0f;
	}
	
	public void Draw()
	{
		MatrixStack modelToCameraStack = new MatrixStack();

		glUseProgram(program);
		glBindVertexArray(vao);

		modelToCameraStack.translate(posBase);
		modelToCameraStack.rotateY(angBase);

		//Draw left base.
		{
			modelToCameraStack.push();
			modelToCameraStack.translate(posBaseLeft);
			modelToCameraStack.scale(new Vector3f(1.0f, 1.0f, scaleBaseZ));
			glUniformMatrix4(modelToCameraMatrixUnif, false, modelToCameraStack.top());
			glDrawElements(GL_TRIANGLES, indexData.length, GL_UNSIGNED_INT, 0);
			modelToCameraStack.pop();
		}

		//Draw right base.
		{
			modelToCameraStack.push();
			modelToCameraStack.translate(posBaseRight);
			modelToCameraStack.scale(new Vector3f(1.0f, 1.0f, scaleBaseZ));
			glUniformMatrix4(modelToCameraMatrixUnif, false, modelToCameraStack.top());
			glDrawElements(GL_TRIANGLES, indexData.length, GL_UNSIGNED_INT, 0);
			modelToCameraStack.pop();
		}

		//Draw main arm.
		DrawUpperArm(modelToCameraStack);

		glBindVertexArray(0);
		glUseProgram(0);
	}
	
	void DrawFingers(MatrixStack modelToCameraStack)
	{
		//Draw left finger
		modelToCameraStack.push();
		modelToCameraStack.translate(posLeftFinger);
		modelToCameraStack.rotateY(angFingerOpen);

		modelToCameraStack.push();
		modelToCameraStack.translate(new Vector3f(0.0f, 0.0f, lenFinger / 2.0f));
		modelToCameraStack.scale(new Vector3f(widthFinger / 2.0f, widthFinger/ 2.0f, lenFinger / 2.0f));
		glUniformMatrix4(modelToCameraMatrixUnif, false, modelToCameraStack.top());
		glDrawElements(GL_TRIANGLES, indexData.length, GL_UNSIGNED_INT, 0);
		modelToCameraStack.pop();

		{
			//Draw left lower finger
			modelToCameraStack.push();
			modelToCameraStack.translate(new Vector3f(0.0f, 0.0f, lenFinger));
			modelToCameraStack.rotateY(-angLowerFinger);

			modelToCameraStack.push();
			modelToCameraStack.translate(new Vector3f(0.0f, 0.0f, lenFinger / 2.0f));
			modelToCameraStack.scale(new Vector3f(widthFinger / 2.0f, widthFinger/ 2.0f, lenFinger / 2.0f));
			glUniformMatrix4(modelToCameraMatrixUnif, false, modelToCameraStack.top());
			glDrawElements(GL_TRIANGLES, indexData.length, GL_UNSIGNED_INT, 0);
			modelToCameraStack.pop();

			modelToCameraStack.pop();
		}

		modelToCameraStack.pop();

		//Draw right finger
		modelToCameraStack.push();
		modelToCameraStack.translate(posRightFinger);
		modelToCameraStack.rotateY(-angFingerOpen);

		modelToCameraStack.push();
		modelToCameraStack.translate(new Vector3f(0.0f, 0.0f, lenFinger / 2.0f));
		modelToCameraStack.scale(new Vector3f(widthFinger / 2.0f, widthFinger/ 2.0f, lenFinger / 2.0f));
		glUniformMatrix4(modelToCameraMatrixUnif, false, modelToCameraStack.top());
		glDrawElements(GL_TRIANGLES, indexData.length, GL11.GL_UNSIGNED_INT, 0);
		modelToCameraStack.pop();

		{
			//Draw right lower finger
			modelToCameraStack.push();
			modelToCameraStack.translate(new Vector3f(0.0f, 0.0f, lenFinger));
			modelToCameraStack.rotateY(angLowerFinger);

			modelToCameraStack.push();
			modelToCameraStack.translate(new Vector3f(0.0f, 0.0f, lenFinger / 2.0f));
			modelToCameraStack.scale(new Vector3f(widthFinger / 2.0f, widthFinger/ 2.0f, lenFinger / 2.0f));
			glUniformMatrix4(modelToCameraMatrixUnif, false, modelToCameraStack.top());
			glDrawElements(GL_TRIANGLES, indexData.length, GL_UNSIGNED_INT, 0);
			modelToCameraStack.pop();

			modelToCameraStack.pop();
		}

		modelToCameraStack.pop();
	}

	void DrawWrist(MatrixStack modelToCameraStack)
	{
		modelToCameraStack.push();
		modelToCameraStack.translate(posWrist);
		modelToCameraStack.rotateZ(angWristRoll);
		modelToCameraStack.rotateX(angWristPitch);

		modelToCameraStack.push();
		modelToCameraStack.scale(new Vector3f(widthWrist / 2.0f, widthWrist/ 2.0f, lenWrist / 2.0f));
		glUniformMatrix4(modelToCameraMatrixUnif, false, modelToCameraStack.top());
		glDrawElements(GL_TRIANGLES, indexData.length, GL_UNSIGNED_INT, 0);
		modelToCameraStack.pop();

		DrawFingers(modelToCameraStack);

		modelToCameraStack.pop();
	}

	void DrawLowerArm(MatrixStack modelToCameraStack)
	{
		modelToCameraStack.push();
		modelToCameraStack.translate(posLowerArm);
		modelToCameraStack.rotateX(angLowerArm);

		modelToCameraStack.push();
		modelToCameraStack.translate(new Vector3f(0.0f, 0.0f, lenLowerArm / 2.0f));
		modelToCameraStack.scale(new Vector3f(widthLowerArm / 2.0f, widthLowerArm / 2.0f, lenLowerArm / 2.0f));
		glUniformMatrix4(modelToCameraMatrixUnif, false, modelToCameraStack.top());
		glDrawElements(GL_TRIANGLES, indexData.length, GL_UNSIGNED_INT, 0);
		modelToCameraStack.pop();

		DrawWrist(modelToCameraStack);

		modelToCameraStack.pop();
	}

	void DrawUpperArm(MatrixStack modelToCameraStack)
	{
		modelToCameraStack.push();
		modelToCameraStack.rotateX(angUpperArm);

		{
			modelToCameraStack.push();
			modelToCameraStack.translate(new Vector3f(0.0f, 0.0f, (sizeUpperArm / 2.0f) - 1.0f));
			modelToCameraStack.scale(new Vector3f(1.0f, 1.0f, sizeUpperArm / 2.0f));
			glUniformMatrix4(modelToCameraMatrixUnif, false, modelToCameraStack.top());
			glDrawElements(GL_TRIANGLES, indexData.length, GL_UNSIGNED_INT, 0);
			modelToCameraStack.pop();
		}

		DrawLowerArm(modelToCameraStack);

		modelToCameraStack.pop();
	}
	
	void AdjBase(boolean bIncrement)
	{
		angBase += bIncrement ? STANDARD_ANGLE_INCREMENT : -STANDARD_ANGLE_INCREMENT;
		angBase = angBase % 360.0f;
	}

	void AdjUpperArm(boolean bIncrement)
	{
		angUpperArm += bIncrement ? STANDARD_ANGLE_INCREMENT : -STANDARD_ANGLE_INCREMENT;
		angUpperArm = clamp(angUpperArm, -90.0f, 0.0f);
	}

	void AdjLowerArm(boolean bIncrement)
	{
		angLowerArm += bIncrement ? STANDARD_ANGLE_INCREMENT : -STANDARD_ANGLE_INCREMENT;
		angLowerArm = clamp(angLowerArm, 0.0f, 146.25f);
	}

	void AdjWristPitch(boolean bIncrement)
	{
		angWristPitch += bIncrement ? STANDARD_ANGLE_INCREMENT : -STANDARD_ANGLE_INCREMENT;
		angWristPitch = clamp(angWristPitch, 0.0f, 90.0f);
	}

	void AdjWristRoll(boolean bIncrement)
	{
		angWristRoll += bIncrement ? STANDARD_ANGLE_INCREMENT : -STANDARD_ANGLE_INCREMENT;
		angWristRoll = angWristRoll % 360.0f;
	}

	void AdjFingerOpen(boolean bIncrement)
	{
		angFingerOpen += bIncrement ? SMALL_ANGLE_INCREMENT : -SMALL_ANGLE_INCREMENT;
		angFingerOpen = clamp(angFingerOpen, 9.0f, 180.0f);
	}
	
	void display()	{
		glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		glClearDepth(1.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		Draw();
		Display.update();
	}
}

Nevermind, all the OpenGl code was correct, it was a bug in my matrixStack implementation, specifically that it wasn’t pushing copies to the stack, but pointers. Thus, all of my transforms stacked on top of eachother until the model was unrecognizable.