0

I am trying to patch up an OBJ loading class, as it only supported Short numbers, and I have a large OBJ that goes above the Short number limit.

I had to change the code to use Integer Vectors (instead of Short ones) and a ShortBuffer was changed to an IntBuffer.

Now, the basic OBJ I had (10,000 lines) which used to load in 3 seconds, no longer loads at all and gives me a BufferOverflowException.

Below is the problematic chunk of code:

ByteBuffer fBuf = ByteBuffer.allocateDirect(faces.size() * 2);
fBuf.order(ByteOrder.nativeOrder());
faceBuffer = fBuf.asIntBuffer();
faceBuffer.put(toPrimitiveArrayS(faces)); // this gives the exception
faceBuffer.position(0);

Below is the function toPrimitiveArrayS

private static int[] toPrimitiveArrayS(Vector<Integer> vector){
    int[] s;
    s = new int[vector.size()];
    for (int i=0; i<vector.size(); i++){
        s[i] = vector.get(i);
    }
    return s;
}

Oddly, if I changed the 2 to a 4 in allocateDirect, the model loads, but is rendered incorrectly (previously, it loaded fine with that number as 2, so I only just changed it to see)

Full class code below:

public class TDModelPart {
Vector<Integer> faces;
Vector<Integer> vtPointer;
Vector<Integer> vnPointer;
Material material;
private FloatBuffer normalBuffer;
IntBuffer faceBuffer;

public TDModelPart(Vector<Integer> faces, Vector<Integer> vtPointer, Vector<Integer> vnPointer, Material material, Vector<Float> vn) {
    super();

    this.faces = faces;
    this.vtPointer = vtPointer;
    this.vnPointer = vnPointer;
    this.material = material;

    ByteBuffer byteBuf = ByteBuffer.allocateDirect(vnPointer.size() * 4 * 3);
    byteBuf.order(ByteOrder.nativeOrder());
    normalBuffer = byteBuf.asFloatBuffer();

    for(int i=0; i<vnPointer.size(); i++){
        float x=vn.get(vnPointer.get(i)*3);
        float y=vn.get(vnPointer.get(i)*3+1);
        float z=vn.get(vnPointer.get(i)*3+2);
        normalBuffer.put(x);
        normalBuffer.put(y);
        normalBuffer.put(z);
    }

    normalBuffer.position(0);

    ByteBuffer fBuf = ByteBuffer.allocateDirect(faces.size() * 2);
    fBuf.order(ByteOrder.nativeOrder());
    faceBuffer = fBuf.asIntBuffer();
    faceBuffer.put(toPrimitiveArrayS(faces));
    faceBuffer.position(0);
}

public String toString(){
    String str=new String();
    if(material!=null)
        str+="Material name:"+material.getName();
    else
        str+="Material not defined!";
    str+="\nNumber of faces:"+faces.size();
    str+="\nNumber of vnPointers:"+vnPointer.size();
    str+="\nNumber of vtPointers:"+vtPointer.size();
    return str;
}

public IntBuffer getFaceBuffer(){
    return faceBuffer;
}

public FloatBuffer getNormalBuffer(){
    return normalBuffer;
}

private static int[] toPrimitiveArrayS(Vector<Integer> vector){
    int[] s;
    s = new int[vector.size()];
    for (int i=0; i<vector.size(); i++){
        s[i] = vector.get(i);
    }
    return s;
}

public int getFacesCount(){
    return faces.size();
}

public Material getMaterial(){
    return material;
}
}
Mr Pablo
  • 4,109
  • 8
  • 51
  • 104

1 Answers1

0

You are allocating two bytes (16 bits) per face index, you should be allocating four since you are using one int per index (an int is a 32 bit integer, four bytes), you are trying to allocate the double amount of bytes your faceBuffer can handle

  • So what do I need to fix? I can't use ShortBuffer, but using IntBuffer doesn't work, and I need it to – Mr Pablo Dec 27 '14 at 11:06
  • when you upload your indices to the graphics card are you indicating it that they are now unsigned integers? – Gustavo Ulises Arias Méndez Dec 27 '14 at 20:53
  • Honestly no idea what you mean. I simply changed the ShortBuffer to IntBuffer. Read my question, that's all the info I have. – Mr Pablo Dec 28 '14 at 11:42
  • I thought you were working with OpenGLES, did you try to change your toPrimitiveArrayS from int[] to short[]? – Gustavo Ulises Arias Méndez Dec 28 '14 at 14:54
  • That function was changed from short[] to int[]. Everything that is now int, used to be short. Short was the old way and I need it to be int. And yes, it is opengl es, but I am new to it, and I'm doing this in android sdk. I'm not "uploading" anything to the graphics card – Mr Pablo Dec 28 '14 at 16:27
  • My question even shows the function toPrimitiveArrayS is now int[]. Please read my question carefully – Mr Pablo Dec 28 '14 at 16:29