- 수정됨
[libgdx] Changing skeletons on the fly
I need to be able to change Spine characters on the fly. User can select which character to use and the json
and atlas
are updated accordingly.
I figured it would be as simple as to replace the SkeletonData, Atlas and related objects in my ApplicationAdapter
and it almost was, but the result is just black meshes. For some reason the textures are not updated. The shape is there because the meshes are loaded correctly, but it's just filled black.
I did not change or recreate OrthographicCamera
, SkeletonRenderer
or PolygonSpriteBatch
objects. I tried to dispose PolygonSpriteBatch
and create a new one, but I got the following error: java.lang.IllegalArgumentException: Error compiling shader
.
I can't use skins because the skeletons and animations are so different. Is there something that need to be disposed that I didn't? I assume I'm just missing something obvious. What would be the recommended way to do something like this?
EDIT:
Turns out replacing the whole fragment (extends AndroidFragmentApplication
) works.
You should be able to draw any skeleton you want. Eg, instead of drawing skeleton A, draw skeleton B. I'm not sure why your textures would be black.
Here's a sample project demonstrating the issue: https://github.com/Woncler/spine-libgdx-test (press back button to swap skeletons).
Image removed due to the lack of support for HTTPS. | Show Anyway
Currently I'm just recreating the fragment (and the GLSurfaceView
) over and over again, which works but is quite slow especially on older devices. So if swapping only the Skeleton object should work, I would prefer to do it that way.
Maybe you disposed the atlas?
I think I came up with a solution.
Every time I changed the Skeleton object, I loaded a new .atlas
file. For some reason libgdx or OpenGL does not like that and the textures didn't get loaded. I also got the following error:
E/libEGL: call to OpenGL ES API with no current context (logged once per thread)
The trick was to load all the atlases in the create()
-function, before anything gets rendered. I'm storing them in a Map
and getting them when needed.
I'm not sure how efficient that is memorywise in the long run if the atlases get big and plenty, but it'll do for now.
No current context means you are trying to do OpenGL stuff from a thread that is not the OpenGL thread. All OpenGL calls must be made from the OpenGL thread. That is why your textures aren't being loaded.