Reputation: 49
I have two ByteBuffers, they are completely identical but somehow behave differently when used in the GL11.glTexImage2D();
method.
My code:
IntBuffer width = BufferUtils.createIntBuffer(1);
IntBuffer height = BufferUtils.createIntBuffer(1);
IntBuffer comp = BufferUtils.createIntBuffer(1);
ByteBuffer data = STBImage.stbi_load("dsc8x12.bmp", width, height, comp, 4);
byte[] bytes = new byte[data.limit()];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = data.get(i);
}
ByteBuffer data2 = ByteBuffer.wrap(bytes);
System.out.println(data.equals(data2));
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, 1024, 12, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, data);
The console output is true
Here is how the window looks when the final argument in the GL11.glTexImage2D();
is either data
or data2
When data
is used:
When data2
is used:
Upvotes: 2
Views: 166
Reputation: 5806
The reason why you get two different results with the two different ByteBuffers is that LWJGL only works with direct NIO Buffers, that is, ByteBuffers that are not backed by arrays.
The reason for this particular output that you are getting is two-fold:
the non-direct ByteBuffer you supply (the one being created by .wrap(array)
) has an internal address field value of 0
. This is what LWJGL looks at when it actually calls the native OpenGL function. It reads that address field value and expects this to be the virtual memory address of the client memory to upload to the texture.
Now, there are some OpenGL functions that will just SEGFAULT when given an invalid pointer, such as zero. However, in this case, the glTexImage2D
function is actually semantically overloaded, as when it receives the zero address as the last argument, it will only allocate texture memory of the requested size (here the remaining
size of the ByteBuffer) and not move any client memory to the server (i.e. the GPU).
The ByteBuffer returned by STBImage.stbi_load
is direct, and hence, the correct texture memory from the client's virtual memory address space is uploaded to OpenGL.
So, in essence: When you use LWJGL, you must always only use direct NIO Buffers, not ones that are wrappers of arrays!
Upvotes: 3