0
\$\begingroup\$

I am currently working on a project and usually in C++ I use the function.
ByteBuffer glMapBuffer(int target, int access)

usage:

FloatBuffer buffer = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY).order(
    ByteOrder.nativeOrder()).asFloatBuffer();

But in java (lwjgl 3.0.0) this function returns null, because of this reason it throws a NullPointerException.

Anyone any idea how to use this function in java?

There are several functions:

glMapBuffer(int target, int access)  
glMapBuffer(int target, int access, ByteBuffer old_buffer)  
glMapBuffer(int target, int access, long length, ByteBuffer old_buffer)  

I hope this is specific enough, thank you for your help :D

\$\endgroup\$
2
\$\begingroup\$

Edited Answer

Before writing to a Buffer Object, you must have some space allocated in GPU's memory, you can grow or shrink the Buffer Objects via:

glBufferData(int target, long size, int usage);

When the Buffer Object already have size bytes, you can call glMapBuffer passing the full size, or some smaller number (you dont have to actually shrink the Buffer Object if it will most likely grow again soon)

glMapBuffer(int target, int access)

Returns a brand new ByteBuffer, with the current size of Buffer Object;

glMapBuffer(int target, int access, ByteBuffer old_buffer)

Returns a new ByteBuffer, or reuses the old object (if not null), with the current size of Buffer Object (not the old_buffer object);

glMapBuffer(int target, int access, long length, ByteBuffer old_buffer)

This is like the previous one, but it is faster because it don't have to query for the Buffer Object's size.

When passing an old_buffer, it unmaps it first (and may use some optimization) before mapping it again.

Don't forget to call glUnmapBuffer(int target) at the end of it all. (After that your mapped ByteBuffer will be in an invalid state and you must not read/write to it)

Example

private int id;
private long currentSize;

public void updateBuffer(...) {

    long calculatedSize = ...;
    if (currentSize < calculatedSize) {
        currentSize = calculatedSize;
        glBufferData(GL_ARRAY_BUFFER, currentSize, GL_DYNAMIC_DRAW);
    }
    ByteBuffer bb = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
    try {
        FloatBuffer floatBuffer = ...
        ...
    } finally {
        glUnmapBuffer(GL_ARRAY_BUFFER);
    }
}
\$\endgroup\$
4
  • \$\begingroup\$ I have an initialization method where the buffer gets bound I specify a pre-calculated size. I'm trying to draw the triangles dynamic. After playing around with it, plus using your tip, it still throws a NullPointerException :( Anyways thank you for your help! \$\endgroup\$
    – Tripl3Fac3
    Aug 19 '16 at 14:38
  • \$\begingroup\$ You don't have to pre allocate the buffer (actually you can't), what this method does is (more or less) map a previously allocated GPU memory block so you can access via a ByteBuffer. When you create a (direct) ByteBuffer you are allocating space in the CPU's memory. Store your pre-calculated size only, and a ByteBuffer pointer (private ByteBuffer mappedBuffer = null;) then use mappedBuffer = glBindBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY, preCalcSize, mappedBuffer); after that you can FloatBuffer buf = ..... Hope it helps. \$\endgroup\$
    – Judison
    Aug 19 '16 at 20:42
  • \$\begingroup\$ Sorry, I forget something, you must call glBufferData(int target​, long size​, int usage​); to pre-allocate the memory in GPU before, at initialization, or when the required size grows. \$\endgroup\$
    – Judison
    Aug 19 '16 at 20:52
  • \$\begingroup\$ I did the initialization (glBufferData) but I think there might be just an error in the native code because now it doesn't even allow me to do the same thing I used about 2 hours ago.. I think the native code might have been corrupted \$\endgroup\$
    – Tripl3Fac3
    Aug 19 '16 at 21:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.