Search code examples
javalibgdxindexoutofboundsexception

OutOfBoundsException when converting Java.awt.Polygon to a LibGDX polygon


Introduction

I have been attempting to draw filled polygons using LibGDX's ShapeRenderer by converting Java.awt.Polygon into float arrays, then passing these into the ShapeRenderer's polygon(float[]) method. I have noticed that for polygons with a large amount of npoints (in this case 4370), I keep getting an IndexOutOfBoundsException. This does not occur with smaller sized polygons.

Here I iterate over my Province objects which have their own Polygons, from these I gather the x, y and npoints and create a float array.

for (Province p : map.getProvinces()) { shapeRenderer.setColor(p.getColor());
    // Convert the Polygon's vertices to a float array
    int[] xpoints = p.getPolygon().xpoints;
    int[] ypoints = p.getPolygon().ypoints;
    float[] verticesArray = new float[p.getPolygon().npoints * 2];
    
    for (int i = 0; i < p.getPolygon().npoints; i++) {
        verticesArray[i * 2] = xpoints[i];
        verticesArray[i * 2 + 1] = ypoints[i];
    }
    
    shapeRenderer.polygon(verticesArray); //IndexOutOfBoundsException: tried accessing index 20003 but bound is 20000
}

What I've tried

I have been using print statements to see what i was exactly passing into the polygon method:

Npoints: 550
Xpoints: [3042, 3043, 3044, 3045, 3046, 3047, 3048, 3049, 3050,... etc]
Ypoints: [1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068,... etc]
id: 1
rgb: -32769

Npoints: 449
Xpoints:[...etc]
Ypoints:[...etc]
id: 2
rgb: -49153

Npoints: 515
Xpoints:[...etc]
Ypoints:[...etc]
id: 3
rgb: -16385

Npoints: 4370
Xpoints:[...etc]
Ypoints:[...etc]
id: 4
rgb: -1

// Exception 

As mentioned earlier the only noticeable thing here (for me at least) was the last polygon's large number of Npoints, leading to my description in the introduction. I'm not actually sure if this is the cause of the issue or if it's completely unrelated.

I decided to dig a bit deeper and looked at the Callstack.

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 20003 out of bounds for length 20000
    at com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer20.color(ImmediateModeRenderer20.java:121)
    at com.badlogic.gdx.graphics.glutils.ShapeRenderer.polygon(ShapeRenderer.java:1132)
    at com.badlogic.gdx.graphics.glutils.ShapeRenderer.polygon(ShapeRenderer.java:1141)
    at com.mygdx.game.Actor.draw(Actor.java:66)

I then decided to look at line 121 of ImmediateModeRenderer20.java, where i found:

public void color (float colorBits) {
     vertices[vertexIdx + colorOffset] = colorBits;
}

I then modified this source code by removing the "+ colorOffset", since I thought perhaps this value was 3 (20000 + 3). Nope, same error.

I guess a more general question would be, how does one convert java polygons so they can be drawn with LibGDX, since perhaps I am approaching this problem incorrectly.


Solution

  • Turns out, there was no problem with the float array I was passing. The Shaperenderer initializes a ImmediateModeRenderer20 instance with a default vertices value of 5000. By this point I noticed there were alternative consturctors for Shaperenderer with an argument to manually set the limit. I just did

    Shaperenderer sr = new Shaperenderer(10000000) 
    

    And this solved the issue.