Closed jeltedeproft closed 8 months ago
Hi, and thanks for the question. Seems like a simple guide on how to load generated atlases is missing for the GDX Texture Packer. Will fix it in the next release.
Overall, manually loading a basis-based atlas should not be any more complicated than loading a regular texture atlas. You just need to do everything that the standard TextureAtlasLoader
do for you.
Before you use the code below, you should have the basisu-wrapper
and basisu-gdx
libraries added to your Gradle modules.
// First off, load the basis texture.
FileHandle textureFile = Gdx.files.internal("path/to/atlas/texture.basis");
TextureData textureData = new BasisuTextureData(textureFile);
Texture texture = new Texture(textureData);
// Load the atlas data.
FileHandle atlasFile = Gdx.files.internal("path/to/atlas/data.atlas");
TextureAtlas.TextureAtlasData atlasData = new TextureAtlas.TextureAtlasData(atlasFile, atlasFile.parent(), false);
// The most important part - manually assign the texture
// to all the pages before initiating the atlas object.
// BEWARE: In case your atlas has multiple pages,
// you should assign the appropriate textures for each page.
// This example works for single-page atlases only.
for (TextureAtlas.TextureAtlasData.Page page : atlasData.getPages()) {
page.texture = texture;
}
// Then simply instantiate the atlas object.
TextureAtlas atlas = new TextureAtlas(atlasData);
That's it. I didn't test the code, but you should get the idea.
PS: You don't need to manually dispose every atlas texture. The textures will be disposed of along with the atlas, when you call atlas.dispose()
I can't get this working, I keep getting classCastExceptions.
I have the following in my assetManager
private static void setLoaders() {
assetManager.setLoader(TextureAtlas.class, ".basis", basisUniversalTextureAtlasLoader);
assetManager.setLoader(Texture.class, ".basis", new BasisuTextureLoader(assetManager.getFileHandleResolver()));
assetManager.setLoader(Texture.class, textureLoader);
assetManager.setLoader(TextureAtlas.class, textureAtlasLoader);
}
my assetLoader has to extend a SynchronousAssetLoader (I think), so it looks like this right now (changed it multiple times)
public class BasisUniversalTextureAtlasLoader extends SynchronousAssetLoader<TextureAtlas, TextureAtlasLoader.TextureAtlasParameter> {
public BasisUniversalTextureAtlasLoader(FileHandleResolver resolver) {
super(resolver);
}
TextureAtlasData data;
@Override
public TextureAtlas load(AssetManager assetManager, String fileName, FileHandle file, TextureAtlasParameter parameter) {
// First off, load the basis texture.
FileHandle textureFile = file.parent().child(fileName + ".basis");
TextureData textureData = new BasisuTextureData(textureFile);
Texture texture = new Texture(textureData);
// Load the atlas data.
TextureAtlas.TextureAtlasData atlasData = new TextureAtlas.TextureAtlasData(file, file.parent(), false);
// The most important part - manually assign the texture
// to all the pages before initiating the atlas object.
// BEWARE: In case your atlas has multiple pages,
// you should assign the appropriate textures for each page.
// This example works for single-page atlases only.
for (TextureAtlas.TextureAtlasData.Page page : atlasData.getPages()) {
page.texture = texture;
}
// Then simply instantiate the atlas object.
TextureAtlas atlas = new TextureAtlas(atlasData);
return atlas;
}
@Override
public Array<AssetDescriptor> getDependencies(String fileName, FileHandle atlasFile, TextureAtlasParameter parameter) {
Array<AssetDescriptor> dependencies = new Array();
return dependencies;
}
static public class BasisuTextureAtlasParameter extends AssetLoaderParameters<TextureAtlas> {
/** whether to flip the texture atlas vertically **/
public boolean flip = false;
public BasisuTextureAtlasParameter() {
}
public BasisuTextureAtlasParameter(boolean flip) {
this.flip = flip;
}
}
}
And I get the following errors
Exception in thread "main" com.badlogic.gdx.utils.GdxRuntimeException: com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load dependencies of asset: sprites/dark.basis
at com.badlogic.gdx.assets.AssetManager.handleTaskError(AssetManager.java:648)
at com.badlogic.gdx.assets.AssetManager.update(AssetManager.java:426)
at com.badlogic.gdx.assets.AssetManager.finishLoadingAsset(AssetManager.java:483)
at jelte.mygame.utility.AssetManagerUtility.loadAsset(AssetManagerUtility.java:150)
at jelte.mygame.utility.AssetManagerUtility.loadTextureAtlas(AssetManagerUtility.java:118)
at jelte.mygame.graphical.GraphicalManagerImpl.<init>(GraphicalManagerImpl.java:65)
at jelte.mygame.StickFighter.create(StickFighter.java:39)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window.initializeListener(Lwjgl3Window.java:416)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window.update(Lwjgl3Window.java:366)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.loop(Lwjgl3Application.java:192)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.<init>(Lwjgl3Application.java:166)
at jelte.mygame.lwjgl3.Lwjgl3Launcher.createApplication(Lwjgl3Launcher.java:15)
at jelte.mygame.lwjgl3.Lwjgl3Launcher.main(Lwjgl3Launcher.java:11)
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load dependencies of asset: sprites/dark.basis
at com.badlogic.gdx.assets.AssetLoadingTask.handleAsyncLoader(AssetLoadingTask.java:119)
at com.badlogic.gdx.assets.AssetLoadingTask.update(AssetLoadingTask.java:91)
at com.badlogic.gdx.assets.AssetManager.updateTask(AssetManager.java:575)
at com.badlogic.gdx.assets.AssetManager.update(AssetManager.java:424)
... 11 more
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: java.lang.ClassCastException: class com.badlogic.gdx.assets.loaders.TextureLoader$TextureParameter cannot be cast to class com.crashinvaders.basisu.gdx.BasisuTextureLoader$BasisuTextureParameter (com.badlogic.gdx.assets.loaders.TextureLoader$TextureParameter and com.crashinvaders.basisu.gdx.BasisuTextureLoader$BasisuTextureParameter are in unnamed module of loader 'app')
at com.badlogic.gdx.utils.async.AsyncResult.get(AsyncResult.java:46)
at com.badlogic.gdx.assets.AssetLoadingTask.handleAsyncLoader(AssetLoadingTask.java:117)
... 14 more
Caused by: java.lang.ClassCastException: class com.badlogic.gdx.assets.loaders.TextureLoader$TextureParameter cannot be cast to class com.crashinvaders.basisu.gdx.BasisuTextureLoader$BasisuTextureParameter (com.badlogic.gdx.assets.loaders.TextureLoader$TextureParameter and com.crashinvaders.basisu.gdx.BasisuTextureLoader$BasisuTextureParameter are in unnamed module of loader 'app')
at com.crashinvaders.basisu.gdx.BasisuTextureLoader.getDependencies(BasisuTextureLoader.java:26)
at com.badlogic.gdx.assets.AssetLoadingTask.call(AssetLoadingTask.java:65)
at com.badlogic.gdx.assets.AssetLoadingTask.call(AssetLoadingTask.java:35)
at com.badlogic.gdx.utils.async.AsyncExecutor$2.call(AsyncExecutor.java:64)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
If you're using AssetManager
, you don't need to write your own loader.
To make the atlas work, you just need to set up the asset manager with BasisuTextureLoader
that comes with the lib.
This is the only line you need:
// Register the texture loader for the ".basis" file extension.
assetManager.setLoader(Texture.class, ".basis", new BasisuTextureLoader(assetManager.getFileHandleResolver()));
Once the asset manager knows how to load .basis
textures, you're good to go.
@jeltedeproft sorry, I made a mistake in the example code link. Please see the updated answer :arrow_up:
Sorry that I come back to this after several weeks, I put this issue aside for a while, but the solution you proposed doesn't seem to work for me.
After adding the loader class like you mentioned
private static void setLoaders() {
assetManager.setLoader(FreeTypeFontGenerator.class, new FreeTypeFontGeneratorLoader(filePathResolver));
assetManager.setLoader(BitmapFont.class, ".ttf", new FreetypeFontLoader(filePathResolver));
assetManager.setLoader(TiledMap.class, tmxMapLoader);
assetManager.setLoader(Texture.class, textureLoader);
assetManager.setLoader(Texture.class, ".basis", new BasisuTextureLoader(assetManager.getFileHandleResolver()));
assetManager.setLoader(TextureAtlas.class, textureAtlasLoader);
assetManager.setLoader(Skin.class, new FreeTypeSkinLoader(assetManager.getFileHandleResolver()));
assetManager.setLoader(ParticleEffect.class, particleEffectLoader);
assetManager.setLoader(Sound.class, soundLoader);
assetManager.setLoader(Music.class, musicLoader);
assetManager.setLoader(SoundBuffer.class, soundBufferLoader);
loadersSet = true;
}
i get the following error
Exception in thread "main" com.badlogic.gdx.utils.GdxRuntimeException: com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load dependencies of asset: sprites/9��;hɹ������
at com.badlogic.gdx.assets.AssetManager.handleTaskError(AssetManager.java:648)
at com.badlogic.gdx.assets.AssetManager.update(AssetManager.java:426)
at com.badlogic.gdx.assets.AssetManager.finishLoadingAsset(AssetManager.java:483)
at jelte.mygame.utility.AssetManagerUtility.loadAsset(AssetManagerUtility.java:150)
at jelte.mygame.utility.AssetManagerUtility.loadTextureAtlas(AssetManagerUtility.java:118)
at jelte.mygame.graphical.GraphicalManagerImpl.<init>(GraphicalManagerImpl.java:66)
at jelte.mygame.StickFighter.create(StickFighter.java:41)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window.initializeListener(Lwjgl3Window.java:416)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window.update(Lwjgl3Window.java:366)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.loop(Lwjgl3Application.java:192)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.<init>(Lwjgl3Application.java:166)
at jelte.mygame.lwjgl3.Lwjgl3Launcher.createApplication(Lwjgl3Launcher.java:15)
at jelte.mygame.lwjgl3.Lwjgl3Launcher.main(Lwjgl3Launcher.java:11)
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load dependencies of asset: sprites/9��;hɹ������
at com.badlogic.gdx.assets.AssetLoadingTask.handleAsyncLoader(AssetLoadingTask.java:119)
at com.badlogic.gdx.assets.AssetLoadingTask.update(AssetLoadingTask.java:91)
at com.badlogic.gdx.assets.AssetManager.updateTask(AssetManager.java:575)
at com.badlogic.gdx.assets.AssetManager.update(AssetManager.java:424)
... 11 more
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load file: sprites/9��;hɹ������
at com.badlogic.gdx.utils.async.AsyncResult.get(AsyncResult.java:46)
at com.badlogic.gdx.assets.AssetLoadingTask.handleAsyncLoader(AssetLoadingTask.java:117)
... 14 more
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load file: sprites/9��;hɹ������
at com.badlogic.gdx.graphics.Pixmap.<init>(Pixmap.java:190)
at com.badlogic.gdx.graphics.TextureData$Factory.loadFromFile(TextureData.java:101)
at com.badlogic.gdx.assets.loaders.TextureLoader.loadAsync(TextureLoader.java:62)
at com.badlogic.gdx.assets.loaders.TextureLoader.loadAsync(TextureLoader.java:35)
at com.badlogic.gdx.assets.AssetLoadingTask.call(AssetLoadingTask.java:71)
at com.badlogic.gdx.assets.AssetLoadingTask.call(AssetLoadingTask.java:35)
at com.badlogic.gdx.utils.async.AsyncExecutor$2.call(AsyncExecutor.java:64)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: File not found: sprites\9��;hɹ������ (Internal)
at com.badlogic.gdx.files.FileHandle.read(FileHandle.java:142)
at com.badlogic.gdx.files.FileHandle.readBytes(FileHandle.java:228)
at com.badlogic.gdx.graphics.Pixmap.<init>(Pixmap.java:187)
... 10 more
Any ideas?
Looking at the error, I don't think it's related to the atlas loader. There might be something wrong with the specific file, whose name appears to be in weird coding:
Couldn't load file: sprites/9��;hɹ�������
Just find the problematic file, and it should be obvious from there that it might be broken or something similar.
On a side note, unless you use your own custom asset loaders, you don't need to add them manually. Just have a look at the AssetManager`s constructor to get an idea of what is supported out of the box.
For Basis textures/atlases to work, you only need this one line:
assetManager.setLoader(Texture.class, ".basis", new BasisuTextureLoader(assetManager.getFileHandleResolver()));
Thanks for the tip! i cleaned up my code a bit with the loaders.
After some debugging I finally understand the issue.
First when the textureAtloas tries to get loaded it uses the TextureAtlasLoader to load the sprites.basis texture atlas. Nothing wrong here.
Then when it starts looking for dependencies (aka the sprites in the atlas) it got the wrong loader for me. It got the TextureLoader.
This was because in the stored loaders it had the following for the Texture key
{.basis=com.crashinvaders.basisu.gdx.BasisuTextureLoader@5e3f861,=com.badlogic.gdx.assets.loaders.TextureLoader@2fb0623e}
It then took the TextureLoader because the filename it finds in the textureAtlas was
sprites/sB
all the sprites in the basis texture atlas have a filename like this, I assume because of the way they are stored? So i think the solution is to remove the basis extension, but then every sprite sheet needs to be in basis format 🤔
Do you have any better solutions?
hmm when I remove the extension it gives me the following error
Exception in thread "main" com.badlogic.gdx.utils.GdxRuntimeException: com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load dependencies of asset: sprites/9��;hɹ������
at com.badlogic.gdx.assets.AssetManager.handleTaskError(AssetManager.java:648)
at com.badlogic.gdx.assets.AssetManager.update(AssetManager.java:426)
at com.badlogic.gdx.assets.AssetManager.finishLoadingAsset(AssetManager.java:483)
at jelte.mygame.utility.AssetManagerUtility.loadAsset(AssetManagerUtility.java:139)
at jelte.mygame.utility.AssetManagerUtility.loadTextureAtlas(AssetManagerUtility.java:107)
at jelte.mygame.graphical.GraphicalManagerImpl.<init>(GraphicalManagerImpl.java:66)
at jelte.mygame.StickFighter.create(StickFighter.java:41)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window.initializeListener(Lwjgl3Window.java:416)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window.update(Lwjgl3Window.java:366)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.loop(Lwjgl3Application.java:192)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.<init>(Lwjgl3Application.java:166)
at jelte.mygame.lwjgl3.Lwjgl3Launcher.createApplication(Lwjgl3Launcher.java:15)
at jelte.mygame.lwjgl3.Lwjgl3Launcher.main(Lwjgl3Launcher.java:11)
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load dependencies of asset: sprites/9��;hɹ������
at com.badlogic.gdx.assets.AssetLoadingTask.handleAsyncLoader(AssetLoadingTask.java:119)
at com.badlogic.gdx.assets.AssetLoadingTask.update(AssetLoadingTask.java:91)
at com.badlogic.gdx.assets.AssetManager.updateTask(AssetManager.java:575)
at com.badlogic.gdx.assets.AssetManager.update(AssetManager.java:424)
... 11 more
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: java.lang.ClassCastException: class com.badlogic.gdx.assets.loaders.TextureLoader$TextureParameter cannot be cast to class com.crashinvaders.basisu.gdx.BasisuTextureLoader$BasisuTextureParameter (com.badlogic.gdx.assets.loaders.TextureLoader$TextureParameter and com.crashinvaders.basisu.gdx.BasisuTextureLoader$BasisuTextureParameter are in unnamed module of loader 'app')
at com.badlogic.gdx.utils.async.AsyncResult.get(AsyncResult.java:46)
at com.badlogic.gdx.assets.AssetLoadingTask.handleAsyncLoader(AssetLoadingTask.java:117)
... 14 more
Caused by: java.lang.ClassCastException: class com.badlogic.gdx.assets.loaders.TextureLoader$TextureParameter cannot be cast to class com.crashinvaders.basisu.gdx.BasisuTextureLoader$BasisuTextureParameter (com.badlogic.gdx.assets.loaders.TextureLoader$TextureParameter and com.crashinvaders.basisu.gdx.BasisuTextureLoader$BasisuTextureParameter are in unnamed module of loader 'app')
at com.crashinvaders.basisu.gdx.BasisuTextureLoader.getDependencies(BasisuTextureLoader.java:26)
at com.badlogic.gdx.assets.AssetLoadingTask.call(AssetLoadingTask.java:65)
at com.badlogic.gdx.assets.AssetLoadingTask.call(AssetLoadingTask.java:35)
at com.badlogic.gdx.utils.async.AsyncExecutor$2.call(AsyncExecutor.java:64)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
The problem is here
The assetDescriptor parameters is of type
com.badlogic.gdx.assets.loaders.TextureLoader$TextureParameter@1c9cdb78
But it expects
com.crashinvaders.basisu.gdx.BasisuTextureLoader$BasisuTextureParameter
it happens here in the TextureAtlasLoader
@Override
public Array<AssetDescriptor> getDependencies (String fileName, FileHandle atlasFile, TextureAtlasParameter parameter) {
FileHandle imgDir = atlasFile.parent();
if (parameter != null)
data = new TextureAtlasData(atlasFile, imgDir, parameter.flip);
else {
data = new TextureAtlasData(atlasFile, imgDir, false);
}
Array<AssetDescriptor> dependencies = new Array();
for (Page page : data.getPages()) {
TextureParameter params = new TextureParameter();
params.format = page.format;
params.genMipMaps = page.useMipMaps;
params.minFilter = page.minFilter;
params.magFilter = page.magFilter;
dependencies.add(new AssetDescriptor(page.textureFile, Texture.class, params));
}
return dependencies;
}
It creates a Textureparameter class, this is why i originally thought i had to make my own TextureAtlasLoader
Oh, my bad. Seems like Basis texture loader for atlases was broken for a while... Thanks for the digging! I'll make a patch for the lib, but it will take some time.
Meanwhile, just use this simplified version of the loader, that is based on the standard TextureParameter
type. Simply place this code to the file named CustomBasisTextureLoader.java
under the com.crashinvadrs.basisu.gdx
package:
package com.crashinvadrs.basisu.gdx;
import com.badlogic.gdx.assets.AssetDescriptor;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.assets.loaders.AsynchronousAssetLoader;
import com.badlogic.gdx.assets.loaders.FileHandleResolver;
import com.badlogic.gdx.assets.loaders.TextureLoader;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.utils.Array;
import com.crashinvaders.basisu.gdx.BasisuGdxUtils;
import com.crashinvaders.basisu.gdx.BasisuTextureData;
public class CustomBasisTextureLoader extends AsynchronousAssetLoader<Texture, TextureLoader.TextureParameter> {
BasisuTextureData textureData;
public CustomBasisTextureLoader(FileHandleResolver resolver) {
super(resolver);
// We need to make sure this one is first time called
// on the main thread and not during async texture loading.
BasisuGdxUtils.initSupportedGlTextureFormats();
}
public void loadAsync(AssetManager manager, String fileName, FileHandle fileHandle, TextureLoader.TextureParameter parameter) {
BasisuTextureData data;
data = new BasisuTextureData(fileHandle);
data.prepare();
textureData = data;
}
public Texture loadSync(AssetManager manager, String fileName, FileHandle fileHandle, TextureLoader.TextureParameter parameter) {
Texture texture = new Texture(this.textureData);
this.textureData = null;
if (parameter != null) {
texture.setFilter(parameter.minFilter, parameter.magFilter);
texture.setWrap(parameter.wrapU, parameter.wrapV);
}
return texture;
}
public Array<AssetDescriptor> getDependencies(String fileName, FileHandle fileHandle, TextureLoader.TextureParameter parameter) {
return null;
}
}
No problem, thanks for sticking with the issue
sorry for coming back to this agai, but I can't get it working with your modified class. I think the problem is that when the gdx-texture-packer outputs the format to basis all the files inside are renamed to gibberish. Then your code tries to use that gibberish name to find the file but doesn't find it
Here is the error I am getting
[Console output redirected to file:C:\Users\Admin\Desktop\darkOutput.txt]
Exception in thread "main" com.badlogic.gdx.utils.GdxRuntimeException: com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load dependencies of asset: sprites/9��;hɹ������
at com.badlogic.gdx.assets.AssetManager.handleTaskError(AssetManager.java:648)
at com.badlogic.gdx.assets.AssetManager.update(AssetManager.java:426)
at com.badlogic.gdx.assets.AssetManager.finishLoadingAsset(AssetManager.java:483)
at jelte.mygame.utility.AssetManagerUtility.loadAsset(AssetManagerUtility.java:138)
at jelte.mygame.utility.AssetManagerUtility.loadTextureAtlas(AssetManagerUtility.java:106)
at jelte.mygame.graphical.GraphicalManagerImpl.<init>(GraphicalManagerImpl.java:66)
at jelte.mygame.StickFighter.create(StickFighter.java:41)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window.initializeListener(Lwjgl3Window.java:416)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window.update(Lwjgl3Window.java:366)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.loop(Lwjgl3Application.java:192)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.<init>(Lwjgl3Application.java:166)
at jelte.mygame.lwjgl3.Lwjgl3Launcher.createApplication(Lwjgl3Launcher.java:15)
at jelte.mygame.lwjgl3.Lwjgl3Launcher.main(Lwjgl3Launcher.java:11)
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load dependencies of asset: sprites/9��;hɹ������
at com.badlogic.gdx.assets.AssetLoadingTask.handleAsyncLoader(AssetLoadingTask.java:119)
at com.badlogic.gdx.assets.AssetLoadingTask.update(AssetLoadingTask.java:91)
at com.badlogic.gdx.assets.AssetManager.updateTask(AssetManager.java:575)
at com.badlogic.gdx.assets.AssetManager.update(AssetManager.java:424)
... 11 more
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: com.crashinvaders.basisu.gdx.BasisuGdxException: Couldn't load file 'sprites/9��;hɹ������'
at com.badlogic.gdx.utils.async.AsyncResult.get(AsyncResult.java:46)
at com.badlogic.gdx.assets.AssetLoadingTask.handleAsyncLoader(AssetLoadingTask.java:117)
... 14 more
Caused by: com.crashinvaders.basisu.gdx.BasisuGdxException: Couldn't load file 'sprites/9��;hɹ������'
at com.crashinvaders.basisu.gdx.BasisuData.readFileIntoBuffer(BasisuData.java:149)
at com.crashinvaders.basisu.gdx.BasisuData.<init>(BasisuData.java:36)
at com.crashinvaders.basisu.gdx.BasisuTextureData.prepare(BasisuTextureData.java:148)
at jelte.mygame.utility.CustomBasisTextureLoader.loadAsync(CustomBasisTextureLoader.java:39)
at jelte.mygame.utility.CustomBasisTextureLoader.loadAsync(CustomBasisTextureLoader.java:1)
at com.badlogic.gdx.assets.AssetLoadingTask.call(AssetLoadingTask.java:71)
at com.badlogic.gdx.assets.AssetLoadingTask.call(AssetLoadingTask.java:35)
at com.badlogic.gdx.utils.async.AsyncExecutor$2.call(AsyncExecutor.java:64)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: File not found: sprites\9��;hɹ������ (Internal)
at com.badlogic.gdx.files.FileHandle.read(FileHandle.java:142)
at com.crashinvaders.basisu.gdx.BasisuData.readFileIntoBuffer(BasisuData.java:129)
... 11 more
Hm, so the atlas page files on the file system have proper names after the texture packer export, right?
Could you please also check if the names are malformed inside of the text of the .atlas
file.
yeah the .atlas file has normal names This zip has the atlas in it dark.zip
Ok, what about the actual files, do they have the same names as in the atlas file, or are they gibberish straight out of gdx-texture-packer? Or do the names get read wrong at runtime, when the atlas tries to load them? I want to understand at what point the names get broken.
If the gdx-texture-packer outputs them that way, I would ask you about the minimalistic gdx-texture-packer project so I can reproduce the issue on my end. Like get a random image or two, create an atlas for them and save the .gdxtp
project file. Please send me the images and the .gdxtp
file. It's important to check if that setup produces the same issue for you.
ok, so the output of the gdx-texture-packer is an atlas file with normal names, all my files have the same normal name. The dark.basis file i can't read, if I open it with notepad++ it has a bunch of weird symbols in it.
The gdx-texture-packer project seems totally fine and the output files are fully valid.
I tested the files in a blank project using this code:
AssetManager assetManager = new AssetManager();
assetManager.setLoader(Texture.class, ".basis", new BasisuTextureLoader(assetManager.getFileHandleResolver()));
assetManager.load("test.atlas", TextureAtlas.class);
assetManager.finishLoading();
TextureRegion region = assetManager.get("test.atlas", TextureAtlas.class).findRegion("alchemist-CLIMBING1-left", 1)
It loads atlas and yields an absolutely normal texture region that I can render on the screen.
At this point, I'd assume that the naming issue you're having is OS/system configuration related. Looks more like something is broken with text encoding. And it doesn't seems like it has anything to do with gdx-texture-packer or basis textures directly. But I wonder if you have similar issues when you change the atlas texture format to PNG? What OS are you on?
Also, it'd help a lot to understand at what stage the names get broken at runtime. If you could jump into debugging and see how the loaded TextureAtlasData
looks like inside of TextureAtlasLoader#getDependencies()
.
I've used PNG for quite a while and it always worked normally, it was only once i switched to basis that i had this problem. I am on a Windows
Edition Windows 11 Pro Version 22H2 Installed on 2/11/2022 OS build 22621.2134 Experience Windows Feature Experience Pack 1000.22659.1000.0
I'll try the debugging next
Gotcha, thanks. I will try to reproduce it on my Win10 machine.
Just to clarify, do you have the same issue with the test atlas you've sent (cannot load on runtime)?
This is the debugging output, if I look at whats inside the TextureAtlasData variable, it has an array of pagefiles and the names of those pages is gibberish
It also has regions and those names are also gibberish
omg I am a complete idiot, I'm so sorry. My atlas constant was pointing to my .basis file in stead of the atlas
Working now! thanks for all the help
Haha, it's good it wasn't another rare system-related bug that takes an eternity to locate...
Anyway, I hope it's gonna work fine for you from here. One note, something I found myself soon after implementing the texture compression lib, Basis doesn't suit pixel art and low-res images well. There are a lot of noticeable artifacts on the compressed textures, it totally destroys the pixel art page images and produces different kinds of unexpected image distortion on different platforms (based on the transcoded format). At least when ETC1S (low-quality compression) is used. You might try UASTC (high-quality compression) which is less size-efficient but should give a more predictable and clean output.
ok, thanks for the tip, I'll use the UASTC compression and I'll do a check to see if the quality is still good.
how do I load a basis universal sprite sheet created gdx-texture-packer into libgdx?