converting to 231: jogl-relevant Nio advice or tutorial ?

Hi, I’ve used Jogl successfully in the past and am now updating some code to the current 231 version.

In a web search I was not able to find any nio tutorials that seemed particularly relevant, they
all talk about file mapping. Probably that is relevant, but I don’t understand yet.

Some particular questions:

  1. if one uses a floatbuffer .array() and then indexes the array, when do you have to rewind?
 
    float[] fbuf = theFloatbuffer.array();
    for( i=0; ... ) {
       float x = fbuf[i];
       theFloatbuffer.rewind();	// is this needed here ??
    }

  1. How important is it that the buffer be “direct”?

  2. Does a view of another buffer prevent it from being garbage collected?
    E.g.,

    {
      {
        ByteBuffer b = ByteBuffer.allocateDirect(len);	// local scope
	_globalfloatbuf = b.asFloatBuffer();		// bad idea?
      }
    }

Several more related questions, so here’s a new self-contained message (more coherent than adding on I think)

I’ve used Jogl successfully in the past and am now updating some code to the current 231 version.

In a web search I was not able to find any nio tutorials that seemed
particularly relevant, they all talk about file mapping rather than views of
arrays. Probably that is relevant, but I don’t understand yet.

Some particular questions:

  1. if one uses a floatbuffer .array() and then indexes the array, when do you have to rewind?

    float[] fbuf = theFloatbuffer.array();
    for( i=0; ... ) {
       float x = fbuf[i];
       theFloatbuffer.rewind();	// is this needed here ??
    }

1b) do you have to rewind before using array():

    bytebuf.rewind();   // necessary?
    byte[] arr = bytebuf.array();

  1. How important is it that the buffer be “direct”?

  2. Does a view of another buffer prevent it from being garbage collected?
    E.g.,

    {
      {
        ByteBuffer b = ByteBuffer.allocateDirect(len);	// local scope
	_globalfloatbuf = b.asFloatBuffer();		// bad idea?
      }
    }

  1. Overhead of allocateDirect():
    In reading just one pixel from an image (rather than reading the whole
    image), is it better to use a .allocateDirect(), or does allocateDirect
    only pay off when there is a large amount of data to be read or written?

  2. is setting nativeOrder necessary in this case, or only when the
    data will be accessed as floats?


	    ByteBuffer bbrgb = ByteBuffer.allocateDirect(3);
	    bbrgb.ByteOrder.nativeOrder());	// todo Necessary?
	    gl.glReadPixels(isx,isy,1,1, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, bbrgb);

No. The buffer knows nothing about the accesses you do to the array.

No. array() returns the same answer every time regardless of the buffer’s position.

Certain APIs like glVertexPointer require the buffer be direct. The technical reasons are discussed in some of the presentations linked from the JOGL home page. The Javadoc indicates when the buffer must be direct; if no statement is in the Javadoc then the buffer may legally refer to an array.

Yes, it does prevent it from being GCd.

As a matter of fact on some platforms Sun’s implementation of allocateDirect() can allocate a huge amount of memory – basically an entire 4K page even if you only need less than that. While I wouldn’t make this your primary criterion, when you can get away with allocating a small heap-based buffer it is in fact cheaper to do so.

It isn’t strictly necessary but is good practice. If you are allocating direct Buffers I would strongly recommend you use the com.sun.opengl.util.BufferUtil class as it will help avoid accidents where you forget to set the byte order.