Add async texture loading
This commit is contained in:
+17
-3
@@ -180,11 +180,11 @@ errorret_t assetUpdate(void) {
|
||||
// If an error occured these things need to be true, basically just
|
||||
// ensuring the sync loader is setting the error correctly.
|
||||
if(errorIsNotOk(ret)) {
|
||||
errorCatch(errorPrint(ret));
|
||||
assertTrue(
|
||||
loading->entry->state == ASSET_ENTRY_STATE_ERROR,
|
||||
"Loader did not set entry state to error on failed load."
|
||||
);
|
||||
errorCatch(errorPrint(ret));
|
||||
}
|
||||
|
||||
threadMutexUnlock(&loading->mutex);
|
||||
@@ -236,8 +236,22 @@ void assetUpdateAsync(thread_t *thread) {
|
||||
switch(loading->entry->state) {
|
||||
case ASSET_ENTRY_STATE_PENDING_ASYNC:
|
||||
loading->entry->state = ASSET_ENTRY_STATE_LOADING_ASYNC;
|
||||
printf("Simulated async load\n");
|
||||
sleep(1);
|
||||
assertNotNull(
|
||||
ASSET_LOADER_CALLBACKS[loading->type].loadAsync,
|
||||
"Loader does not support async loading."
|
||||
);
|
||||
errorret_t ret = (
|
||||
ASSET_LOADER_CALLBACKS[loading->type].loadAsync(loading)
|
||||
);
|
||||
|
||||
if(errorIsNotOk(ret)) {
|
||||
errorCatch(errorPrint(ret));
|
||||
assertTrue(
|
||||
loading->entry->state == ASSET_ENTRY_STATE_ERROR,
|
||||
"Loader did not set entry state to error on failed load."
|
||||
);
|
||||
}
|
||||
|
||||
threadMutexUnlock(&loading->mutex);
|
||||
loading++;
|
||||
break;
|
||||
|
||||
@@ -12,26 +12,31 @@ assetloadercallbacks_t ASSET_LOADER_CALLBACKS[ASSET_LOADER_TYPE_COUNT] = {
|
||||
|
||||
[ASSET_LOADER_TYPE_MESH] = {
|
||||
.loadSync = assetMeshLoaderSync,
|
||||
.loadAsync = NULL,
|
||||
.dispose = assetMeshDispose
|
||||
},
|
||||
|
||||
[ASSET_LOADER_TYPE_TEXTURE] = {
|
||||
.loadSync = assetTextureLoaderSync,
|
||||
.loadAsync = assetTextureLoaderAsync,
|
||||
.dispose = assetTextureDispose
|
||||
},
|
||||
|
||||
[ASSET_LOADER_TYPE_TILESET] = {
|
||||
.loadSync = assetTilesetLoaderSync,
|
||||
.loadAsync = NULL,
|
||||
.dispose = assetTilesetDispose
|
||||
},
|
||||
|
||||
[ASSET_LOADER_TYPE_LOCALE] = {
|
||||
.loadSync = assetLocaleLoaderSync,
|
||||
.loadAsync = NULL,
|
||||
.dispose = assetLocaleDispose
|
||||
},
|
||||
|
||||
[ASSET_LOADER_TYPE_JSON] = {
|
||||
.loadSync = assetJsonLoaderSync,
|
||||
.loadAsync = NULL,
|
||||
.dispose = assetJsonDispose
|
||||
},
|
||||
};
|
||||
|
||||
@@ -52,10 +52,12 @@ typedef struct assetloading_s assetloading_t;
|
||||
typedef struct assetentry_s assetentry_t;
|
||||
|
||||
typedef errorret_t (assetloadersynccallback_t)(assetloading_t *loading);
|
||||
typedef errorret_t (assetloaderasynccallback_t)(assetloading_t *loading);
|
||||
typedef errorret_t (assetloaderdisposecallback_t)(assetentry_t *entry);
|
||||
|
||||
typedef struct {
|
||||
assetloadersynccallback_t *loadSync;
|
||||
assetloaderasynccallback_t *loadAsync;
|
||||
assetloaderdisposecallback_t *dispose;
|
||||
} assetloadercallbacks_t;
|
||||
|
||||
|
||||
@@ -52,10 +52,19 @@ int assetTextureEOF(void *user) {
|
||||
return file->position >= file->size;
|
||||
}
|
||||
|
||||
errorret_t assetTextureLoaderSync(assetloading_t *loading) {
|
||||
errorret_t assetTextureLoaderAsync(assetloading_t *loading) {
|
||||
assertNotNull(loading, "Loading cannot be NULL");
|
||||
|
||||
// Only care about loading pixels.
|
||||
if(loading->loading.texture.state != ASSET_TEXTURE_LOADING_STATE_LOAD_PIXELS){
|
||||
errorOk();
|
||||
}
|
||||
|
||||
// Init the file
|
||||
assertNull(
|
||||
loading->loading.texture.data, "Pixels already defined?"
|
||||
);
|
||||
|
||||
assetfile_t *file = &loading->loading.texture.file;
|
||||
assetLoaderErrorChain(loading, assetFileInit(
|
||||
file,
|
||||
@@ -77,13 +86,12 @@ errorret_t assetTextureLoaderSync(assetloading_t *loading) {
|
||||
}
|
||||
|
||||
// Load image pixels.
|
||||
int width, height, channels;
|
||||
loading->loading.texture.data = stbi_load_from_callbacks(
|
||||
&ASSET_TEXTURE_STB_CALLBACKS,
|
||||
file,
|
||||
&width,
|
||||
&height,
|
||||
&channels,
|
||||
&loading->loading.texture.width,
|
||||
&loading->loading.texture.height,
|
||||
&loading->loading.texture.channels,
|
||||
channelsDesired
|
||||
);
|
||||
|
||||
@@ -101,14 +109,43 @@ errorret_t assetTextureLoaderSync(assetloading_t *loading) {
|
||||
if(!isHostLittleEndian()) {
|
||||
stbi__vertical_flip(
|
||||
loading->loading.texture.data,
|
||||
width, height, channelsDesired
|
||||
loading->loading.texture.width,
|
||||
loading->loading.texture.height,
|
||||
loading->loading.texture.channels
|
||||
);
|
||||
}
|
||||
|
||||
loading->loading.texture.state = ASSET_TEXTURE_LOADING_STATE_CREATE_TEXTURE;
|
||||
loading->entry->state = ASSET_ENTRY_STATE_PENDING_SYNC;
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t assetTextureLoaderSync(assetloading_t *loading) {
|
||||
assertNotNull(loading, "Loading cannot be NULL");
|
||||
|
||||
switch(loading->loading.texture.state) {
|
||||
case ASSET_TEXTURE_LOADING_STATE_INITIAL:
|
||||
loading->loading.texture.state = ASSET_TEXTURE_LOADING_STATE_LOAD_PIXELS;
|
||||
loading->entry->state = ASSET_ENTRY_STATE_PENDING_ASYNC;
|
||||
errorOk();
|
||||
break;
|
||||
|
||||
case ASSET_TEXTURE_LOADING_STATE_CREATE_TEXTURE:
|
||||
break;
|
||||
|
||||
default:
|
||||
errorOk();
|
||||
}
|
||||
|
||||
// Create the texture.
|
||||
assertNotNull(
|
||||
loading->loading.texture.data, "Pixels should have been loaded by now."
|
||||
);
|
||||
|
||||
assetLoaderErrorChain(loading, textureInit(
|
||||
(texture_t*)&loading->entry->data.texture,
|
||||
(int32_t)width, (int32_t)height,
|
||||
loading->loading.texture.width,
|
||||
loading->loading.texture.height,
|
||||
loading->entry->input->texture,
|
||||
(texturedata_t){
|
||||
.rgbaColors = (color_t*)loading->loading.texture.data
|
||||
|
||||
@@ -13,8 +13,18 @@ typedef struct assetloading_s assetloading_t;
|
||||
typedef struct assetentry_s assetentry_t;
|
||||
typedef textureformat_t assettextureloaderinput_t;
|
||||
|
||||
typedef enum {
|
||||
ASSET_TEXTURE_LOADING_STATE_INITIAL,
|
||||
ASSET_TEXTURE_LOADING_STATE_LOAD_PIXELS,
|
||||
ASSET_TEXTURE_LOADING_STATE_CREATE_TEXTURE,
|
||||
ASSET_TEXTURE_LOADING_STATE_DONE
|
||||
} assettextureloadingstate_t;
|
||||
|
||||
typedef struct {
|
||||
assetfile_t file;
|
||||
assettextureloadingstate_t state;
|
||||
|
||||
int channels, width, height;
|
||||
uint8_t *data;
|
||||
} assettextureloaderloading_t;
|
||||
|
||||
@@ -46,6 +56,14 @@ void assetTextureSkipper(void *user, int n);
|
||||
*/
|
||||
int assetTextureEOF(void *user);
|
||||
|
||||
/**
|
||||
* Synchronous loader for texture assets.
|
||||
*
|
||||
* @param loading Loading information for the asset being loaded.
|
||||
* @return Error code indicating success or failure of the load operation.
|
||||
*/
|
||||
errorret_t assetTextureLoaderAsync(assetloading_t *loading);
|
||||
|
||||
/**
|
||||
* Synchronous loader for texture assets.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user