简体   繁体   中英

LWJGL drawing large mesh

I am attepmting to load a .ply file into a vbo, and draw it in lwjgl + java. The file loads correctly and all the data is parsed correctly, the only problem is thatit is a model with A LOT of indices (faces). The indices are stored in a byte[] array. In java (and probably everywhere else), bytes can only go up to 128, but the indices required to draw the mesh well surpass 128 in value, so I get this error.

Exception in thread "main" java.lang.NumberFormatException: Value out of range. Value:"128" Radix:10
at java.lang.Byte.parseByte(Byte.java:151)  at java.lang.Byte.parseByte(Byte.java:151)
at game_3d.ModelLoader.loadGeometry(ModelLoader.java:333)
at game_3d.Game_3D.setupGeometry(Game_3D.java:399)
at game_3d.Game_3D.<init>(Game_3D.java:81)
at game_3d.Game_3D.main(Game_3D.java:70)

When I tried to use an int[] array, the model didn't draw correctly. I don't know how or if you even can increase the max value of a byte in a byte[] array, I already tried experimenting with the radix, but the minimum was 10 (which gets me 128).

Well, a byte is a byte. It can only have 256 different values. There is a slight oddity related to the index range when using Java OpenGL bindings. Since Java does not have unsigned data types, the maximum supported value may seem to be 127. But since the arrays of byte values will be passed through to native code, which will treat them as unsigned values, the maximum number of vertices you can address with byte indices is in fact 255.

For example, say you have a value of 160 as an int , and cast it to a byte value for storage in a byte[] array. If you look at the byte value in Java, it will appear to have changed to -96 (160 - 256). But once native code sees the value, and interprets it as an unsigned byte, it will in fact be 160.

See this question for more details about casting int to byte in Java: How are integers cast to bytes in Java? .

Now, if you need more than 256 vertices, you will have to use an index type that supports a larger range. That will work just fine as long as you're consistent:

  • Using short as the type of your index array in Java, you can address 65,536 vertices. The matching type argument of the glDrawElements() call is GL_UNSIGNED_SHORT .
  • Using int as the type of your index array in Java, you can address... a lot of vertices (2 ^ 32, which is more than 4 billion). The matching type argument of the glDrawElements() call is GL_UNSIGNED_INT .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM