Your texture data is located at a pointer in C.
Pass that pointer to Java (a long primitive).
Then hack the fields of a direct ByteBuffer…
private static Map<ByteBuffer, Long> buf2oldBase = new HashMap<ByteBuffer, Long>();
public static synchronized ByteBuffer createByteBufferAt(long pointer, int capacity)
{
ByteBuffer bb = ByteBuffer.allocateDirect(1).order(ByteOrder.nativeOrder());
if(buf2oldBase.get(bb) != null)
throw new IllegalStateException("should never happen, but is here for security");
Field baseField = bb.getClass().getDeclaredField("base");
baseField.setAccessible(true);
Long oldBase = (Long)baseField.get(bb);
baseField.set(bb, pointer);
Field capacityField = bb.getClass().getDeclaredField("capacity");
capacityField.setAccessible(true);
capacityField.set(bb, capacity);
bb.limit(bb.capacity());
// when the reference to 'bb' is not kept, the base
// pointer of 'bb' can get freed by the VM, very nasty!
// so we have to restore the ByteBuffer at some point
buf2oldBase.put(bb, oldBase);
return bb;
}
public static synchronized ByteBuffer restore(ByteBuffer bb)
{
Long oldBase = buf2oldBase.remove(bb);
if(oldBase == null)
throw new IllegalArgumentException("buf was not created here, or already restored");
Field baseField = bb.getClass().getDeclaredField("base");
baseField.setAccessible(true);
baseField.set(bb, oldBase.longValue());
Field capacityField = bb.getClass().getDeclaredField("capacity");
capacityField.setAccessible(true);
capacityField.set(bb, 1);
bb.limit(bb.capacity());
// now the VM can safely free the ByteBuffer
// and the backing base pointer
return bb;
}
sourcecode NOT TESTED and typed… so expect some typo’s
Then use JOGL to upload the data at the pointer to the GPU with some OpenGL calls, in the proper Thread… something that’s rather hard to ensure when uploading directly in C.