element vertex_buffer_object must be enabled?

I’m getting this error …

Exception in thread “AWT-EventQueue-0” javax.media.opengl.GLException: element v
ertex_buffer_object must be enabled to call this method
at com.sun.opengl.impl.GLImpl.checkBufferObject(GLImpl.java:27718)
at com.sun.opengl.impl.GLImpl.checkElementVBOEnabled(GLImpl.java:27785)
at com.sun.opengl.impl.GLImpl.glDrawElements(GLImpl.java:3542)

… and as far as I can tell, I have GL_VERTEX_ARRAY enabled, or am I not understanding what a vertex buffer object is?

Any help much appreciated.


	gl.glEnableClientState(GL.GL_VERTEX_ARRAY);

	if (options != null && options.getCullFace()) {
		gl.glEnable(GL.GL_CULL_FACE);
		gl.glCullFace(GL.GL_BACK);
	}
		
	int i = 0;
	
	vElementsBuffer[region].rewind();
	gl.glVertexPointer(3, GL.GL_FLOAT, 0, vElementsBuffer[region]);

	indBuffers[region].rewind();
		
	while (indBuffers[region].position() < indBuffers[region].capacity()) {
		gl.glLoadName(i++);
		gl.glDrawElements(GL.GL_TRIANGLES, indBuffers[region].capacity(),
		GL.GL_UNSIGNED_INT, indBuffers[region].get());
	}

	if (options != null && options.getCullFace()) {
		gl.glDisable(GL.GL_CULL_FACE);
	}

	gl.glDisableClientState(GL.GL_VERTEX_ARRAY);

This is the LWJGL version of what your trying to do:

You have to bind the VBO your doing; any array other than indices are “GL_ARRAY_BUFFER_ARB” whereas the inddex buffer is “GL_ELEMENT_ARRAY_BUFFER_ARB”. Hope this helps

DP

Honestly, none of that made sense as I’m not familiar with ARB or LWJGL or binding even. The ArbVertexBufferObject I think confused me most, but I’ll look into enabling other arrays if that’s what it means.

Actually, I was trying to follow along this example I found …
http://www.java-gaming.org/forums/index.php?topic=11044.0

ARBVertexBufferObject is just an encapsulation of the extension; for JOGL, i think you just call GL. without the ARB at the end…

DP

Wow, really at a loss about what I’m doing here. Mainly because I dont’ know why this is needed and the redbook says nothing about doing this in it’s examples of using glDrawElements() and of course jogl docs are few.

  1. Do I just make this call before each glVertexPointer() call for my vertex arrays (that what was meant by normal arrays) using GL_ARRAY_BUFFER_ARB?
  2. And call this also before each call to glDrawElements where I use int buffers with the arg GL_ELEMENT_ARRAY_BUFFER_ARB?
  3. What does the id do and how does that work? ugh, what’s an ARB.

What I now have is …


		gl.glEnableClientState(GL.GL_VERTEX_ARRAY);

		int i = 0;
		
		vElementsBuffer[region].rewind();

		IntBuffer ids = BufferUtils.newIntBuffer(2);
		
		gl.glGenBuffersARB(2, ids);
		
		ids.rewind();
		
		gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, ids.get(0));
		gl.glVertexPointer(3, GL.GL_FLOAT, 0, vElementsBuffer[region]);
		
		indBuffers[region].rewind();
		
		gl.glBindBufferARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, ids.get(1));		
		
		while (indBuffers[region].position() < indBuffers[region].capacity()) {
			gl.glLoadName(i++);
			gl.glDrawElements(GL.GL_TRIANGLES, indBuffers[region].capacity(), GL.GL_UNSIGNED_INT, indBuffers[region].get());
		}

		gl.glDisableClientState(GL.GL_VERTEX_ARRAY);

Forget VBOs for now. You started with plain-old vertex-arrays and that’s much more important to understand. Once you’re there, you can look at VBOs. Further, VBOs wouldn’t even be faster in your code.

Everything below will be about your first post, not the one with VBO-code.

The problem is that you are using glDrawElements wrong in your second invocation (in the loop)

The first:
glDrawElements(int, int int, buffer);
In loop:
glDrawElements(int, int int, int); // note that you are calling buffer.get() -> so it’s an int!

the (int, int, int, int) method is reserved for VBOs, so you probably made a mistake. From what I can see from the code you’re trying to render triangle-per-triangle. So we need to pass a (range of the) buffer to the glDrawElements method that draws only 1 triangle (3 indices).


IntBuffer indices = indBuffers[region];
int triangles = indices.remaining() / 3;

for(int i=0; i<triangles; i++)
{
   gl.glLoadName(i++);

   // select the next 3 indices of the buffer
   indices.limit( indices.position() + 3);

   gl.glDrawElements(GL.GL_TRIANGLES, 3, GL.GL_UNSIGNED_INT, indices);

   // set the position to where we left, and make sure the limit=capacity
   indices.position( indices.position() + 3 );
   indices.limit( indices.capacity() );
}

Note that this approach is highly inefficient, try color-coding (1 color per triangle - reading pixel back from farmebuffer) it might be 100-1000x faster (i might be off a bit :))

This is very helpful and makes much more sense to me. Once I understand this, I’ll certainly work towards color coding, but the only problem I have w/ that is that, it won’t make any sense to the user to have triangles of all different colors (1000’s of colors) because the color sections of a model have meaning in my app. Anyways …

I’m close, but don’t think I quite understand the last arg to glDrawElements.

Is indices supposed to be the index into the vertexArray (given by glVertexPointer before drawing each element w/ glDrawElement) containing the starting offsets of each new triangle within the vertex array?,So it just contains the index offset? I’m sure I’m not populating this correctly now. But at least my app doesn’t crash anymore.


	int i = 0;

	while (...) {
		// region holds a list of all triangle edges.
		int triangles = region.size() / 3;

		indBuffers[i] = BufferUtils.newIntBuffer(triangles);

	
		// I think something here is wrong, I don't know what
		// indices really contains, so I have them as an id for each triangle.
		for (int j = 0; j < triangles; j += 3) {
			indBuffers[i].put(j);
		}				
	
		i++;
	}
	...

public void drawTriangles(int region) {
	gl.glEnableClientState(GL.GL_VERTEX_ARRAY);

	indBuffers[region].rewind();

	// elementsBuffer contains all triangle vertices.
	gl.glVertexPointer(3, GL.GL_FLOAT, 0, elementsBuffer[region]);
	
	for (int i = 0; i < indBuffers[region].position() < indBuffers[region].limit(); i++) {
		gl.glLoadName(i);

		// select next 3 indices in buffer.
		indBuffers[region].limit(indBuffers[region].position() + 3);
		gl.glDrawElements(GL.GL_TRIANGLES, 3, GL.GL_UNSIGNED_INT, indBuffers[region]);
	
		// set the position to where we left off and make sure limit
		// equals capacity.	
		indBuffers[region].position(indBuffers[region].position() + 3);
		indBuffers[region].limit(indBuffers[region].capacity());
	}

	gl.glDisableClientState(GL.GL_VERTEX_ARRAY);

Well, i already explained the color-coding in another thread to you, but basicly the view will_not_see_it, as you’re clearing the color-buffer the very same frame, and render your true textures/whatever on top of it.

so, each frame:

  1. clear color+depth buffer
  2. render color-coded
  3. read-back pixel
  4. clear color+depth buffer
  5. render normally

the user will only see what happened after step 4

Ah, ok, I didn’t get that part, that the view would not see it, now I understand what you meant.