The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
Android Asset Management with SDL2
scanner_darkly


Joined: 23 Aug 2015
Posts: 16
I'm interested to know the best way possible for me to manage my assets with my Android SDL2 program. I have the program set up on desktop (not using Android of course, just SDL2 and OpenGL 3.3) to load assets from a directory like this "./resources/shaders/shader.vert.glsl". This works well with C++ streams and such but it does not work with Android. I have an assets directory (called "assets") in the top level of my Android Studio project (adjacent to jni directory and the AndroidManifest.xml file).

I've done some research on the web and I've found several different solutions, some involving an android library within the NDK, and then SDL's solution using RWops library. Furthermore, I have 3 main types of assets that I'm dealing with: images (both png and jpeg), Wavefront object files (also really just ASCII text files), and then shader files (text files). On my desktop I handle the images with STB library like this:

Code:
   
std::string filename = "./resources/textures/image.png";
int width, height, comp;
unsigned char* imageData = stbi_load(filename.c_str(), &width, &height, &comp, STBI_rgb_alpha);


I know that using RWops I can parse the files using a technique like so:

Code:
   
    std::string vertString;

    SDL_RWops* sdlIO = SDL_RWFromFile(vertFile.c_str(), "r");
    if (sdlIO != NULL)
    {
        char data[1];
        std::size_t amountRead;
        while ((amountRead = SDL_RWread(sdlIO, data, sizeof(char), 1)) > 0)
        {
            vertString += data;
        }

        SDL_RWclose(sdlIO);
    }


My question would be how would I pass the filepath to STB image library? And is there any suggestions, ideas, or potential issues I might have when using RWops for this task? I ran into an issue last night with the shader parsing because the strings weren't null terminated, so I'm hoping for some ideas along those lines if possible.

I'm not too worried about sprite-batching or texture atlasing yet, and that's something I can deal with separately.

Thanks.
AntTheAlchemist


Joined: 13 Feb 2015
Posts: 60
Location: UK
RWops is the way to go. Everything is cross-platform, so my Android code is identical to the PC.I have sub-directories "images", "sound", "levels", etc. I copy all these directories into the android assets directory and they're picked up the same way on both platforms. So, basically, "assets" is the Android root directory.
scanner_darkly


Joined: 23 Aug 2015
Posts: 16
How do you handle the images? Maybe I'm just rusty with C parsing, but I can't seem to get a handle on how to send the filename to STB image. Could you post an example of one of your parses for your level or images if possible?

Thanks for the feedback.
scanner_darkly


Joined: 23 Aug 2015
Posts: 16
I fixed the image loading issue by just using SDL Image (not sure why I didn't consider this earlier).

But I have stumbled into another predicament (the last one I think), and that's FreeType. I could use SDL_ttf but I don't want to rewrite all my text rendering if I can avoid it.

Is there a way I can load my .ttf file from assets using SDL_RWops and then pass the file path into FT_New_Face(ftLibrary, filepath, 0, &face)?
AntTheAlchemist


Joined: 13 Feb 2015
Posts: 60
Location: UK
Does FreeType have a FT_New_Face_From_Memory(), or something? A good library shouldn't restrict you to only using file names as parameters. It should offer loading from a stream, or from memory.

I opted to go with LodePNG for images. I load the file into memory using SDL_RWops and there's a lodepng_decode32() which takes a pointer to memory as source. You can override PNG's internal memory handlers to make it conform to any internal garbage collection, too, since image decoding can be memory intensive.
scanner_darkly


Joined: 23 Aug 2015
Posts: 16
AntTheAlchemist wrote:
Does FreeType have a FT_New_Face_From_Memory(), or something? A good library shouldn't restrict you to only using file names as parameters. It should offer loading from a stream, or from memory.

I opted to go with LodePNG for images. I load the file into memory using SDL_RWops and there's a lodepng_decode32() which takes a pointer to memory as source. You can override PNG's internal memory handlers to make it conform to any internal garbage collection, too, since image decoding can be memory intensive.


Ah, it appears so! Here's a code snippet from http://www.freetype.org/freetype2/docs/tutorial/step1.html:

Code:
error = FT_New_Memory_Face( library,
                            buffer,    /* first byte in memory */
                            size,      /* size in bytes        */
                            0,         /* face_index           */
                            &face );


I'm at work right now so I can't test this, but can I just use this method to parse the TTF file and then pass the char buffer into FT_New_Memory_Face?

Here's the parsing code from https://wiki.libsdl.org/SDL_RWread :

Code:
char* file_read(const char* filename) {
        SDL_RWops *rw = SDL_RWFromFile(filename, "rb");
        if (rw == NULL) return NULL;
       
        Sint64 res_size = SDL_RWsize(rw);
        char* res = (char*)malloc(res_size + 1);

        Sint64 nb_read_total = 0, nb_read = 1;
        char* buf = res;
        while (nb_read_total < res_size && nb_read != 0) {
                nb_read = SDL_RWread(rw, buf, 1, (res_size - nb_read_total));
                nb_read_total += nb_read;
                buf += nb_read;
        }
        SDL_RWclose(rw);
        if (nb_read_total != res_size) {
                free(res);
                return NULL;
        }
       
        res[nb_read_total] = '\0';
        return res;
}


Where filename is the TTF file I want to parse and res would be the buffer I pass into FT_New_Memory_Face.
Android Asset Management with SDL2
SiPlus


Joined: 06 Feb 2015
Posts: 13
There is FT_New_Memory_Face, you need to keep the file contents in
memory until you don't need the font anymore.

On 26-Aug-15 16:10, AntTheAlchemist wrote:
Quote:
Does FreeType have a FT_New_Face_From_Memory(), or something? A good
library shouldn't restrict you to only using file names as parameters.
It should offer loading from a stream, or from memory.

I opted to go with LodePNG for images. I load the file into memory
using SDL_RWops and there's a lodepng_decode32() which takes a pointer
to memory as source. You can override PNG's internal memory handlers
to make it conform to any internal garbage collection, too, since
image decoding can be memory intensive.
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org