diff --git a/tools/texturepacker.c b/tools/texturepacker.c index 94aef4c..9594858 100644 --- a/tools/texturepacker.c +++ b/tools/texturepacker.c @@ -15,26 +15,27 @@ #include "../libs/libcyaml/include/cyaml/cyaml.h" -typedef struct image_t { +typedef struct Image { char* filename; - unsigned char* image_data; + unsigned char* imageData; int id, width, height, channels; -} image_t; +} Image; -typedef struct tex_rect_t { - image_t* img; +typedef struct TexRect { + Image* img; int x,y,w,h; -} tex_rect_t; +} TexRect; -image_t* read_image_infos(int argc, char* argv[], int* image_count) { - image_t* images = calloc(argc - 1, sizeof(image_t)); +typedef struct { Image* images; int imageCount; } ParseImages; +ParseImages parseImages(int argc, char* argv[]) { + Image* images = calloc(argc - 1, sizeof(Image)); if (images == NULL) { fprintf(stderr, "Failed to alloc image data array"); exit(-1); } - *image_count = argc - 1; - for (int i = 0; i < *image_count; i++) { - image_t* img = &images[i]; + int imageCount = argc - 1; + for (int i = 0; i < imageCount; i++) { + Image* img = &images[i]; img->filename = argv[i+1]; int result = stbi_info(img->filename, &img->width, &img->height, &img->channels); @@ -44,40 +45,35 @@ image_t* read_image_infos(int argc, char* argv[], int* image_count) { exit(-1); } } - return images; + return (ParseImages) { images , imageCount }; } -int pack_textures(image_t images[], - tex_rect_t tex_rects[], - int image_count, - int* size, - int* totalh, - int* maxw) { - if (tex_rects == NULL) { return -1; } - *totalh = 0, *maxw = 0; - for (int i = 0; i < image_count; i++) { - tex_rects[i] = (tex_rect_t){ +typedef struct { int size; int totalHeight; int maxWidth; } PackTextures; +PackTextures packTextures(Image images[], TexRect texRects[], int imageCount) { + int totalh = 0, maxw = 0; + for (int i = 0; i < imageCount; i++) { + texRects[i] = (TexRect){ &images[i], 0, // Put them all on the 1st column for now - *totalh, + totalh, images[i].width, images[i].height, }; - *totalh += images[i].height; - if (images[i].width > *maxw) { - *maxw = images[i].width; + totalh += images[i].height; + if (images[i].width > maxw) { + maxw = images[i].width; } } - int max = *totalh > *maxw ? *totalh : *maxw; + int max = totalh > maxw ? totalh : maxw; int exp = (int)log2(max) + 1; - *size = (int)pow(2, exp); - return max; + int size = (int)pow(2, exp); + return (PackTextures) { size , totalh , maxw }; } -int load_texture(image_t* img) { +int loadTexture(Image* img) { int w,h,c; - img->image_data = (unsigned char*)stbi_load(img->filename, &w, &h, &c, 4); - if (img->image_data == NULL) { + img->imageData = (unsigned char*)stbi_load(img->filename, &w, &h, &c, 4); + if (img->imageData == NULL) { char *errorMsg = "Could not load data for image '%s': %s"; fprintf(stderr, errorMsg, img->filename, stbi_failure_reason()); // QUESTION: Should we clean up here? Return -1 instead so parent can clean up @@ -86,15 +82,15 @@ int load_texture(image_t* img) { return 0; } -void write_to_atlas(image_t images[], - int image_count, - tex_rect_t tex_rects[], - unsigned char* buf, - int maxw) +void writeToAtlas(Image images[], + int image_count, + TexRect tex_rects[], + unsigned char* buf, + int maxw) { int channels = images[0].channels; for (int i = 0; i < image_count; i++) { - tex_rect_t rect = tex_rects[i]; + TexRect rect = tex_rects[i]; int buf_row = rect.y; int buf_col = rect.x; int img_row = 0; @@ -103,8 +99,8 @@ void write_to_atlas(image_t images[], int buf_idx = (buf_row * maxw + buf_col) * channels; int img_idx = (img_row * rect.w + img_col) * channels; for (int j = 0; j < channels; j++) { - if (images[i].image_data[img_idx + 3] != 0) { - buf[buf_idx + j] = images[i].image_data[img_idx + j]; + if (images[i].imageData[img_idx + 3] != 0) { + buf[buf_idx + j] = images[i].imageData[img_idx + j]; } else { buf[buf_idx + 3] = 0xFF; } @@ -118,7 +114,7 @@ void write_to_atlas(image_t images[], } } -int sdl_test(image_t* images, int image_count, tex_rect_t* tex_rects) { +int sdlTest(Image* images, int image_count, TexRect* tex_rects) { SDL_Window* window = NULL; if (SDL_Init(SDL_INIT_EVERYTHING) < 0) { @@ -126,7 +122,7 @@ int sdl_test(image_t* images, int image_count, tex_rect_t* tex_rects) { return 1; } - window = SDL_CreateWindow( "SDL Tutorial", + window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1024, @@ -138,8 +134,10 @@ int sdl_test(image_t* images, int image_count, tex_rect_t* tex_rects) { } SDL_Renderer* renderer = SDL_CreateRenderer(window, 0, SDL_RENDERER_ACCELERATED); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); - SDL_Texture* texture = - SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, 512, 512); + SDL_Texture* texture = SDL_CreateTexture(renderer, + SDL_PIXELFORMAT_RGBA8888, + SDL_TEXTUREACCESS_STREAMING, + 512, 512); SDL_Event e; bool quit = false; unsigned int* pixels = calloc(512 * 512, sizeof(unsigned int)); @@ -158,13 +156,13 @@ int sdl_test(image_t* images, int image_count, tex_rect_t* tex_rects) { SDL_RenderClear(renderer); if (i < image_count) { for (int s = 0; s < 8; s++) { - tex_rect_t rect = tex_rects[i]; - unsigned char* img = images[i].image_data; + TexRect rect = tex_rects[i]; + unsigned char* img = images[i].imageData; int img_idx = (img_row * rect.w + img_col) * channels; int color = ((unsigned int)img[img_idx + 0]) << 24 - | ((unsigned int)img[img_idx + 1]) << 16 - | ((unsigned int)img[img_idx + 2]) << 8 - | ((unsigned int)img[img_idx + 3]); + | ((unsigned int)img[img_idx + 1]) << 16 + | ((unsigned int)img[img_idx + 2]) << 8 + | ((unsigned int)img[img_idx + 3]); pixels[buf_row * 512 + img_col] = color; img_col++; if (img_col >= rect.w) { @@ -209,20 +207,22 @@ int main(int argc, char* argv[]) { exit(-1); } - int image_count; //------------------------------------- // First get the image info, make sure the file is an image and it exists //------------------------------------- - image_t* images = read_image_infos(argc, argv, &image_count); + ParseImages pi = parseImages(argc, argv); + Image* images = pi.images; + int imageCount = pi.imageCount; + //------------------------------------- // Now run the packing algorithm. This is super inefficient // texture packing but I just want to get it working first //------------------------------------- - tex_rect_t* tex_rects = calloc(image_count, sizeof(tex_rect_t)); - int size, totalh, maxw; + TexRect* texRects = calloc(imageCount, sizeof(TexRect)); // int max = pack_textures(images, tex_rects, image_count, &size, &totalh, &maxw); - pack_textures(images, tex_rects, image_count, &size, &totalh, &maxw); + PackTextures pt = packTextures(images, texRects, imageCount); + int size = pt.size; //------------------------------------- // Now load the data into memory, for now, let's just load all images in one go, @@ -230,8 +230,8 @@ int main(int argc, char* argv[]) { // better yet in parallel so that we can write to the different parts of the // texture atlas concurrently //------------------------------------- - for (int i = 0; i < image_count; i++) { - int result = load_texture(&images[i]); + for (int i = 0; i < imageCount; i++) { + int result = loadTexture(&images[i]); if (result != 0) { // It's going to exit() inside the load_texture function for now printf("Something went wrong\n"); @@ -241,20 +241,20 @@ int main(int argc, char* argv[]) { //------------------------------------- // For each texture rect, draw the corresponding pixels on the atlas //------------------------------------- - // unsigned char* buf = calloc(size*size*4, sizeof(char)); - // write_to_atlas(images, image_count, tex_rects, buf, maxw); + unsigned char* buf = calloc(size*size*4, sizeof(char)); + writeToAtlas(images, imageCount, texRects, buf, size); - // stbi_write_png("test.png", max, max, 4, buf, maxw * 4); + stbi_write_png("test.png", size, size, 4, buf, size * 4); - sdl_test(images, image_count, tex_rects); + // sdlTest(images, imageCount, texRects); //------------------------------------- // Free them all, but eventually we would free after we finished writing them individually //------------------------------------- - for (int i = 0; i < image_count; i++) { - stbi_image_free(images[i].image_data); + for (int i = 0; i < imageCount; i++) { + stbi_image_free(images[i].imageData); } free(images); - free(tex_rects); + free(texRects); return 0; }