Problem with glDrawElements()

I have a problem with glDrawElements(). It worked with arrays and previous versions of jogl but not with buffers and the current.
I’m reading my data with this:

			
vertbuff = BufferUtils.newDoubleBuffer(vertices * 3);

intbuff = BufferUtils.newIntBuffer(indices * 3);

for (int i = 0; i < vertices; i++) {
	st = new StringTokenizer(br.readLine(), " ");
	while (st.hasMoreTokens()) {
		vertbuff.put(Double.parseDouble(st.nextToken()));
	}
}

for (int i = 0; i < indices; i++) {
	st = new StringTokenizer(br.readLine(), " ");
	st.nextToken();
	while (st.hasMoreTokens()) {
		intbuff.put(Integer.parseInt(st.nextToken()));
	}
}

The file is structured like this:


vertices:
-1.24479 0.64876801 0.200864
-1.48926 0.64368999 0.227226
indices:
3 0 1 2 
3 1 3 4 
3 5 6 2 

And then I’m trying to draw the elements with:

		
gl.glColor3f(1.0f, 0.0f, 0.0f);
gl.glVertexPointer(3, GL.GL_DOUBLE, 0, vertbuff);
gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
gl.glDrawElements(GL.GL_TRIANGLES, intbuff.capacity(), GL.GL_UNSIGNED_INT, intbuff);
gl.glDisableClientState(GL.GL_VERTEX_ARRAY);

But I alaway get an error:


#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x691ba460, pid=3040, tid=3300
#
# Java VM: Java HotSpot(TM) Client VM (1.5.0_05-b05 mixed mode)
# Problematic frame:
# C  [atioglxx.dll+0x1ba460]

It works sometimes, when I reduce the size of the buffers (with less vertices and less indices), but not everytime. I already tried to install new drivers but it did not help.

Hi,

I think you have to call rewind() on your buffer…

Yes, the new version of JOGL uses the position and limit of the buffers to determine what part of it will be used. Read more about in the java.nio.Buffer javadoc. This problem deserves a sticky post until most people have got their project ported to the new version. There has recently been several posts about this.

Yeah, it works :slight_smile:
thx!

Thanks and good point. We’re planning to add range checks for the Buffer-related calls but in the meantime I’ve made this topic sticky as suggested.

Given this is a sticky topic, I thought I would summarize the two big things I’ve learned about using Buffers in JSR-231 programs:

  • Use BufferUtils method to make your buffers. This ensures they are:
    [list]

  • The right size (i.e, size of, say, float times array count)

  • Direct Buffers instead of Indirect

  • The right byte order (ByteOrder.naturalOrder())

  • rewind() your Buffers before submitting them to glVertexPointer(), glNormalPointer(), etc.
    [/list]

For me, the incorrect ByteOrder was producing the VM crash that was described in starting this thread.

Keith

Hello,

I am having a similar case with a JVM crash, but when using glMultiDrawElements() and vertex arrays. I checked all the things that Keith mentioned above and all seem to be done right. It is very strange, because the crash occurs on 2 Windows machines and doesn’t occur on the Linux-Mashine. I don’t know if it is some kind of bug, or if my code is incorrect.

The method that is producing the error is here:


    public void renderPrimitives(GL gl)
    {
        // position world
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glPushMatrix();

        // rotate and translate view
        gl.glMultMatrixf(viewMatrix, 0);

        // enable backface culling
        gl.glEnable(GL.GL_CULL_FACE);
        gl.glCullFace(GL.GL_BACK);

        // enable vertex arrays
        gl.glEnableClientState(GL.GL_VERTEX_ARRAY);

        // send vertex data
        float[] varray = new float[vertices.length * 3];
        int k = 0;
        for (Vector3DVO v : vertices)
        {
            varray[k++] = v.x;
            varray[k++] = v.z;
            varray[k++] = -v.y;
        }
        FloatBuffer verticesBuffer = BufferUtil.newFloatBuffer(vertices.length * 3);
        verticesBuffer.put(varray);
        verticesBuffer.rewind();
        gl.glVertexPointer(3, GL.GL_FLOAT, 0, verticesBuffer);

        int[] counts = new int[faces_vertices.length];
        IntBuffer[] indices = new IntBuffer[faces_vertices.length];
        for (int i = 0; i < faces_vertices.length; i++)
        {
            counts[i] = faces_vertices[i].length;
            indices[i] = BufferUtil.newIntBuffer(faces_vertices[i].length);
            indices[i].put(faces_vertices[i]);
            indices[i].rewind();
        }
        // ===== HERE COMES THE CRASH =====
        gl.glMultiDrawElements(GL.GL_POLYGON, counts, 0, GL.GL_UNSIGNED_INT,
                               indices, faces_vertices.length);

        gl.glDisableClientState(GL.GL_VERTEX_ARRAY);

        // restore view
        gl.glPopMatrix();
    }

On the Ubuntu Machine (JDK 1.6, ATI Radeon X1600 with the ATI driver xorg-driver-fglrx 7.1.0-8.34) it runs normally.

On the first Windows Machine (JDK 1.6, ATI Radeon 9600 with the latest drivers 8.401.0.0) it crashes with this message:


#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6936eae5, pid=1460, tid=444
#
# Java VM: Java HotSpot(TM) Client VM (1.6.0_02-b06 mixed mode, sharing)
# Problematic frame:
# C  [atioglxx.dll+0x36eae5]

On the second Windows Machine (JDK 1.6 or JDK 1.5, NVIDIA GeForce 6200SE TurboCache with 6.14.10.9371 drivers) it also crashes with a similar message:


# An unexpected error has been detected by Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x695e320a, pid=3708, tid=2388
#
# Java VM: Java HotSpot(TM) Client VM (1.6.0_01-b06 mixed mode, sharing)
# Problematic frame:
# C  [nvoglnt.dll+0xe320a]

I also noticed, that this is somehow related with intensive IO - it crashes at the start of the application, when a lot of files are being read from the disk (in another thread). When I suspend the rendering thread with a Breakpoint for some seconds, until no more files are being read, the application doesn’t crash. Does anybody have a clue of what is going on?

Best Regards,
Ivan

I suspect this might be a JOGL bug where we should be retaining a persistent reference to your FloatBuffer passed to glVertexPointer to prevent it from being GCd while the C code is accessing it. Do you have a test case for the crash?

Hello,

     That problem may be due to memeory. I had faces same problem in my application before few month. The reason was the memory. After that i had implemented buffers to use same FloatBuffer and ByteBuffer to draw the things. Means, if you have a buffer with enough capacity then you can use same buffer until and unless large size is required.

 You can put code like this

    FloatBuffer buffer1 = null;
private FloatBuffer getFloatBuffer(int size,int bufferNo){
	if(bufferNo==1){
		if(buffer1==null || buffer1.capacity()<size){
			buffer1 = BufferUtil.newFloatBuffer(size); 
		}
		buffer1.rewind();
		return buffer1;
	}

Regards

BufferUtil has been renamed Buffers in JOGL 2.0.

WTF this is over 5 years old!

This thread is now non-sticky in order to focus less attention on outdated information.