Search code examples
javaopengllwjgl

Switched byte order in result of glGetActiveAttrib in LWJGL


I tried to compare output of glGetActiveAttrib (values type & size) against OpenGL constants and didn't get reasonable results. After some experiments I noticed that the byte order is switched, so this code:

    ByteBuffer auxType = ByteBuffer.allocateDirect(4);
    IntBuffer type = auxType.asIntBuffer();
    ByteBuffer auxSize = ByteBuffer.allocateDirect(4);
    IntBuffer size = auxSize.asIntBuffer();
    String name = glGetActiveAttrib(shader.program, 1, size, type);
    System.out.println(type.get(0));

outputs 1384841216. After re-ordering bytes I get 35666 (GL_FLOAT_VEC4) - that is correct. Same problem with size value. Is there any little-big endian switch in LWJGL or could it be issue with graphic card driver? I'm using LWJGL 3.1.1, graphics card is NVIDIA GTX 1060.


Solution

  • Is there any little-big endian switch in LWJGL or could it be issue with graphic card driver?

    It's actually all about the ByteBuffer itself. It has a byte order. So instead of creating the type ByteBuffer like this:

    IntBuffer type = ByteBuffer.allocateDirect(4)
                               .asIntBuffer();
    

    You create it and tell it the byte order:

    IntBuffer type = ByteBuffer.allocateDirect(Integer.BYTES)
                               .order(ByteOrder.nativeOrder())
                               .asIntBuffer();
    

    Also since you're using LWJGL, you can also use the static helper class org.lwjgl.BufferUtils and instead just do:

    IntBuffer type = BufferUtils.createIntBuffer(1);
    

    Now type.get(0) should correctly yield 35666 instead of 1384841216. If you apply the same to size, then that should equally yield the assumed value.

    Since you didn't supply a shader, I tested it with:

    ...
    layout(location = 1) in vec3 position;
    ...
    

    Then when calling glGetActiveAttrib it correctly yielded:

    String name = glGetActiveAttrib(shader.program, 1, size, type);
    System.out.println(name); // prints "position"
    System.out.println(type.get(0)); // prints "35665"
    System.out.println(size.get(0)); // prints "1"
    

    Remember that size is just the element count of the array, so since we aren't dealing with an array it yields 1.