IllegalArgumentException in LWJGLRenderer.predrawGeometry

I created a FloatBuffer for several vertices, a FloatBuffer for texture coords and an IntBuffer for indices. The texture coords are more than the indices used in the TriMesh I create from that. Consequently the number of texture coords is the same as the number of indices but lower that the number of vertices in the buffer.

It looks like TriMesh does not like that as I get the following exception:


java.lang.IllegalArgumentException
        at java.nio.Buffer.limit(Buffer.java:249)
        at com.jme.renderer.lwjgl.LWJGLRenderer.predrawGeometry(LWJGLRenderer.java:1309)
        at com.jme.renderer.lwjgl.LWJGLRenderer.draw(LWJGLRenderer.java:855)
        at com.jme.scene.TriMesh.draw(TriMesh.java:273)
        at com.jme.scene.Spatial.onDraw(Spatial.java:324)
        at com.jme.scene.Node.draw(Node.java:426)
        at com.jme.scene.Spatial.onDraw(Spatial.java:324)
        at com.jme.scene.Node.draw(Node.java:426)
        at com.jme.scene.Spatial.onDraw(Spatial.java:324)
        at com.jme.scene.Node.draw(Node.java:426)
        at com.jme.scene.Spatial.onDraw(Spatial.java:324)
        at com.jme.scene.Node.draw(Node.java:426)
        at com.jme.scene.Spatial.onDraw(Spatial.java:324)
        at com.jme.renderer.lwjgl.LWJGLRenderer.draw(LWJGLRenderer.java:1105)
        at com.jme.app.SimpleGame.render(SimpleGame.java:92)
        at com.jme.app.BaseGame.start(BaseGame.java:77)
        at de.worldofmystery.client.ModelTest.main(ModelTest.java:42)



The line in LWJGLRenderer is:


                    textures.limit(t.getVertQuantity() * 2);



As far as I can see it wants to set the limit to the number of vertices not to the number of indices or texture coords.

You realise that if you pick an index from the vertexbuffer, to give that index in the vertexbuffer a texture coordinate, it will look at the position in the vertexbuffer -not the indexbuffer-  for determining the texture coordinates.



So while we could theoretically support having a texturebuffer smaller than the vertexbuffer, every vertex over the texturebuffer limit will not have texture coordinates. Do you still need this?

The size of the indexbuffer matches the size of the vertexbuffer and the reason for the bigger floatbuffer for vertices is that it is shared over several meshes. So as long as everything runs well, the additional vertices will not be used.

This concept was not my idea btw., I try to write a FormatConverter for AC3D files.



I'll give an example just to see if I understood you well:

There is an object with eight vertices and they are put into a floatbuffer. This object consists of six surfaces with four used vertices so there are four indices and four texture coords.

Drawing the geometry will fetch the vertces by index and then take their index position in the vertex buffer to find the texture coords? So for the first index pointing to vertex #2 it will fetch the texture coord #2?

Then I have to change the concept of shared vertices in the loader as it won't work correctly.

I think there is another problem: TriMesh determines the number of triangles by deviding the number of vertices by three so the count will be wrong even if it would accept a smaller texture coords buffer.

My problem here is the way AC3D stores its data:

It defines an object and a bunch of vertices, materials and rotation/translation. Each object consists of several surfaces which can be textured independantly by giving a list of vertex indices and texture coords. I thought I could use TriMesh for the surfaces but then I would have to define only the vertices used in the surface and create a vertex buffer for each surface.

The only alternative I see would be a new Geometry class for a surface but I wonder if this is worth while the effort and would be used outside the AC3D loader.

Well, I

Or, like I said you can slice() the vertexbuffer and set the length values manually (setVertexCount, setTriangleCount). This way nothing is copied, and you still use more or less the same memory.



That is, if you're using ranges and not random points.

Well, the amount of vertices should still be the same as the amount of texture coordinates if I understand correctly. Just sometimes, your vertices start in the middle of some buffer… which you currently can't set right now, other than by slicing the buffer, and setting the length manually. However, you (or the format) probably instead uses a custom  indexbuffer to point to somewhere in the "middle" of the vertexbuffer. Correct? (does it pick a range or "random" point?)



AFAIK, if you use indexbuffers, the indices given also apply to the texture buffer. So even if predraw would set the right length, OpenGL would then try to look for texture coordinates beyond that of the size of your buffer. Or I could be missing something here…


It's more or less random. AC3D just stores all vertices of an object and then defines each surface. It would be foreseeable for simple shapes but totally random for more complex ones.