VBOs in LWJGL

AAAAAAH! I spent hours looking up tutorials trying to understand vbos, ibos, and textures, and I can’t even display a simple textured vbo! I DID manage to get rendering working in immediate mode, but only because it is infinitely more simplistic.

I should probably tell you what I am trying to make. I am making a class called TexturedMesh that will store a VBO for coordinates, another VBO for texture coordinates, and an IBO for vertex data.

Here is my class:


package render;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import core.Disposable;
import core.Renderable;
import core.Texture;


/**
 * 2-Dimensional Mesh object that can be rendered.  Uses VBOs to render data.
 * @author William Andrew Cahill
 */
public class TexturedMesh2D implements Renderable, Disposable
{
	// Buffered objects
	private Texture tex;			// Texture to use
	private int vbo;				// Verticies to draw
	private int ibo;				// Index buffer to use
	private int tvbo;				// Texture vbo to use
	
	// Vertex buffers
	private FloatBuffer vertices, texCoords;		// Vertex and Texture coordinates
	private IntBuffer indices;						// Indices
	
	
	/**
	 * Constructs the mesh
	 * @param vertices List of vertices to connect to
	 * @param texCoords Texture coordinates for mapping
	 * @param indices Order in which to connect vertices
	 * @param tex Texture to map to Mesh2D
	 */
	public TexturedMesh2D(FloatBuffer vertices, FloatBuffer texCoords, IntBuffer indices, Texture tex)
	{
		create(vertices, texCoords, indices, tex);
	}
	
	
	/**
	 * Constructs a TexturedMesh with the mesh simply wrapping the entire texture.
	 * @param tex Texture to use
	 */
	public TexturedMesh2D(Texture tex)
	{
		// Creates vertices
		FloatBuffer vertices = BufferUtils.createFloatBuffer(8).put(new float[]
		{
			0, 0,
			tex.getWidth(), 0,
			tex.getWidth(), tex.getHeight(),
			0, tex.getHeight()
		});
		
		// Creates texture coordinates
		FloatBuffer texCoords = BufferUtils.createFloatBuffer(8).put(new float[]
		{
			0, 0,
			1, 0,
			1, 1,
			0, 1
		});
		
		// Creates indices
		IntBuffer indices = BufferUtils.createIntBuffer(4).put(new int[]{0, 1, 2, 3});
		
		// Creates mesh
		create(vertices, texCoords, indices, tex);
	}
	
	
	/**
	 * Creates the mesh
	 */
	private void create(FloatBuffer vertices, FloatBuffer texCoords, IntBuffer indices, Texture tex)
	{
		// Checks arguments
		if(vertices == null || texCoords == null || indices == null || tex == null)
			throw new IllegalArgumentException("Arguments cannot be null");
		
		// Stores arguments
		this.vertices = vertices;
		this.texCoords = texCoords;
		this.indices = indices;
		this.tex = tex;
		
		// Creates coordinate vbo
		vbo = GL15.glGenBuffers();
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
		GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertices, GL15.GL_STATIC_DRAW);
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
		
		// Creates texture vbo
		tvbo = GL15.glGenBuffers();
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tvbo);
		GL15.glBufferData(GL15.GL_ARRAY_BUFFER, texCoords, GL15.GL_STATIC_DRAW);
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
		
		// Creates ibo
		ibo = GL15.glGenBuffers();
		GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, ibo);
		GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices, GL15.GL_STATIC_DRAW);
		GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
	}
	
	
	/**
	 * Sets up object pointers before using them
	 */
	private void setupPointers()
	{
		// Points to vertices
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
		GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
		GL11.glVertexPointer(2, GL11.GL_FLOAT, 0, 0);
		
		// Points to texture vertices
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, tvbo);
		GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
		GL11.glVertexPointer(2, GL11.GL_FLOAT, 0, 0);
		
		// Points to indices
		GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, ibo);
	}

	
	@Override
	public void render()
	{
		render(0, 0);
	}

	
	@Override
	public void render(float x, float y)
	{
		// Translates
		GL11.glTranslatef(x,  y,  0);
		
		// Sets up buffer pointers
		setupPointers();
		
		// Binds texture
		tex.bind();
		
		// Draws elements
		GL11.glDrawElements(GL11.GL_TRIANGLE_STRIP, indices.capacity(), GL11.GL_UNSIGNED_INT, 0);
		
		// Disables states
		GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
		GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
		
		// Translates back
		GL11.glTranslatef(-x, -y, 0);
	}
	
	
	@Override
	public boolean isDisposed()
	{
		// Later, later...
		return false;
	}

	
	@Override
	public void dispose()
	{
		// Later, later...
	}
	
	
	/**
	 * Disposes of the TextureMesh2D's underlying resources
	 * @param disposeChildren Flag that determines if underlying resources besides the Texture coordinates
	 * should be disposed of
	 */
	public void dispose(boolean disposeChildren)
	{
		// I'll get to this later...
	}
}

I had to implement a lot of code before I could even think of testing it, so I’m not surprised that nothing shows up on my screen. I don’t even know where to look in order start fixing it, though. Help?

Edit: When testing, I use the constructor in which only the Texture is supplied. I made a Texture class from scratch, and there haven’t been any problems with it yet. Oh, and a shout out to theagentd for helping in this post regarding binding textures: http://www.java-gaming.org/index.php?topic=25516.0 Helped me out a lot.

Edit2: When I call GL11.glGetError(), I get an error code of 1285 which means out of memory. Hrm… It happens after GL11.glDrawElements(GL11.GL_TRIANGLE_STRIP, indices.capacity(), GL11.GL_UNSIGNED_INT, 0);