diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..6282b93 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "src/aseprite"] + path = src/aseprite + url = https://github.com/bersK/odin-aseprite.git diff --git a/.vscode/tasks.json b/.vscode/tasks.json index d4d47ba..b1eca51 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,60 +1,80 @@ { - "version": "2.0.0", - "command": "", - "args": [], - "tasks": [ - { - "label": "Build Debug", - "type": "shell", - "windows": { - "command": "${workspaceFolder}/scripts/build_debug.bat", - }, - "linux": { - "command": "${workspaceFolder}/scripts/build_debug.sh", - }, - "osx": { - "command": "${workspaceFolder}/scripts/build_debug.sh", - }, - "group": "build" - }, - { - "label": "Build Release", - "type": "shell", - "windows": { - "command": "${workspaceFolder}/scripts/build_release.bat", - }, - "linux": { - "command": "${workspaceFolder}/scripts/build_release.sh", - }, - "osx": { - "command": "${workspaceFolder}/scripts/build_release.sh", - }, - "group": "build" - }, - { - "label": "Build Hot Reload", - "type": "shell", - "windows": { - "command": "${workspaceFolder}/scripts/build_hot_reload.bat; start game.exe", - }, - "linux": { - "command": "${workspaceFolder}/scripts/build_hot_reload.sh", - }, - "osx": { - "command": "${workspaceFolder}/scripts/build_hot_reload.sh", - }, - "presentation": { - "echo": true, - "reveal": "always", - "focus": false, - "panel": "shared", - "showReuseMessage": false, - "clear": true - }, - "group": { - "kind": "build", - "isDefault": true - }, - } - ] + "version": "2.0.0", + "command": "", + "args": [], + "tasks": [ + { + "label": "Build Debug", + "type": "shell", + "windows": { + "command": "${workspaceFolder}/scripts/build_debug.bat", + }, + "linux": { + "command": "${workspaceFolder}/scripts/build_debug.sh", + }, + "osx": { + "command": "${workspaceFolder}/scripts/build_debug.sh", + }, + "group": "build" + }, + { + "label": "Build Release", + "type": "shell", + "windows": { + "command": "${workspaceFolder}/scripts/build_release.bat", + }, + "linux": { + "command": "${workspaceFolder}/scripts/build_release.sh", + }, + "osx": { + "command": "${workspaceFolder}/scripts/build_release.sh", + }, + "group": "build" + }, + { + "label": "Build Hot Reload", + "type": "shell", + "windows": { + "command": "${workspaceFolder}/scripts/build_hot_reload.bat; start game.exe", + }, + "linux": { + "command": "${workspaceFolder}/scripts/build_hot_reload.sh", + }, + "osx": { + "command": "${workspaceFolder}/scripts/build_hot_reload.sh", + }, + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "dedicated", + "showReuseMessage": false, + "clear": true + }, + "group": { + "kind": "build", + "isDefault": false + }, + }, + { + "label": "Build&Run Tile Generator Test", + "type": "shell", + "command": "odin run src/aseprite_odin_generator -out:build/aseprite_odin_generator.exe", + "options": { + "cwd": "${workspaceFolder}" + }, + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "dedicated", + "showReuseMessage": false, + "clear": true + }, + "group": { + "kind": "build", + "isDefault": true + }, + } + ] } \ No newline at end of file diff --git a/README.md b/README.md index 6dc89db..a20f4ac 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,6 @@ Yet-Another-Atlas-Packer by Stefan Stefanov Simple atlas packer using `stb_rect_pack` from the `stb` family of header libraries & `raylib` for rendering/ui. +I'm using a custom marshall/unmarshall odin library for reading .aseprite files found [here](https://github.com/blob1807/odin-aseprite) + Project template provided by Karl Zylinski on github [here](https://github.com/karl-zylinski/odin-raylib-hot-reload-game-template). diff --git a/src/aseprite b/src/aseprite new file mode 160000 index 0000000..f21bed8 --- /dev/null +++ b/src/aseprite @@ -0,0 +1 @@ +Subproject commit f21bed838a6d1e6bc1178ea0876596eb14190192 diff --git a/src/aseprite_odin_generator/atlas.png b/src/aseprite_odin_generator/atlas.png new file mode 100644 index 0000000..02082b4 Binary files /dev/null and b/src/aseprite_odin_generator/atlas.png differ diff --git a/src/aseprite_odin_generator/big.aseprite b/src/aseprite_odin_generator/big.aseprite new file mode 100644 index 0000000..bfc55aa Binary files /dev/null and b/src/aseprite_odin_generator/big.aseprite differ diff --git a/src/aseprite_odin_generator/big.png b/src/aseprite_odin_generator/big.png new file mode 100644 index 0000000..b2f4a73 Binary files /dev/null and b/src/aseprite_odin_generator/big.png differ diff --git a/src/aseprite_odin_generator/generator.odin b/src/aseprite_odin_generator/generator.odin new file mode 100644 index 0000000..fd18903 --- /dev/null +++ b/src/aseprite_odin_generator/generator.odin @@ -0,0 +1,82 @@ +package generator + +import ase "../aseprite" +import "core:fmt" +import "core:mem" +import "core:os" +import fp "core:path/filepath" +import "core:slice" +import "core:strings" +import "core:testing" +import rl "vendor:raylib" + +ATLAS_SIZE :: 512 +EXPORT_PATH :: "E:/dev/odin-atlas-packer/src/aseprite_odin_generator/atlas.png" + +main :: proc() { + fmt.println("Hello!") + ase_file, ase_ok := os.read_entire_file( + "E:/dev/odin-atlas-packer/src/aseprite_odin_generator/big.aseprite", + ) + if !ase_ok { + fmt.panicf("Couldn't load file!") + } + + doc: ase.Document + read, um_err := ase.unmarshal_from_slice(ase_file, &doc) + if um_err != nil { + fmt.panicf("Couldn't unmarshall file!") + } else { + fmt.printfln("Read {0} bytes from file", read) + } + + fmt.println("Header:\n\t", doc.header) + // fmt.println("Frames:\n\t", doc.frames) + + images: [dynamic]rl.Image + atlas: rl.Image = rl.GenImageColor(ATLAS_SIZE, ATLAS_SIZE, rl.BLANK) + + for frame in doc.frames { + for chunk in frame.chunks { + cel_chunk, cok := chunk.(ase.Cel_Chunk) + if !cok { + continue + } + + cel_img, ci_ok := cel_chunk.cel.(ase.Com_Image_Cel) + if !ci_ok { + continue + } + append( + &images, + rl.Image { + data = rawptr(&cel_img.pixel[0]), + width = auto_cast cel_img.width, + height = auto_cast cel_img.height, + format = .UNCOMPRESSED_R8G8B8A8, + }, + ) + } + } + curr_x, curr_y: i32 + for img, img_i in images { + fmt.printfln("Image_{0}: {1}", img_i, img) + rl.ImageDraw( + &atlas, + img, + {0, 0, auto_cast img.width, auto_cast img.height}, + {auto_cast curr_x, auto_cast curr_y, auto_cast img.width, auto_cast img.height}, + rl.WHITE, + ) + curr_x += img.width + curr_y += img.height + } + + // todo: pack the rectangles + + // todo: blit them to the atlas + + // todo: generate metadata (json, odin enums) + + rl.ExportImage(atlas, EXPORT_PATH) +} diff --git a/src/game.odin b/src/game.odin index 34cd934..f2f4057 100644 --- a/src/game.odin +++ b/src/game.odin @@ -293,7 +293,7 @@ draw_atlas_settings_and_preview :: proc() { }, "Pack", ) { - g_mem.atlas_render = true + g_mem.atlas_render = true } elements_height += small_offset * 2 @@ -307,7 +307,7 @@ draw_atlas_settings_and_preview :: proc() { }, "Save", ) { - save_output() + save_output() } if rl.GuiButton( { @@ -334,7 +334,7 @@ draw_atlas_settings_and_preview :: proc() { height = short_edge, } rl.GuiDummyRec(preview_rect, "PREVIEW") - preview_rect.x += 10; preview_rect.y += 10; preview_rect.height-=20;preview_rect.width-=20 + preview_rect.x += 10;preview_rect.y += 10;preview_rect.height -= 20;preview_rect.width -= 20 texture := &g_mem.atlas_render_texture_target.texture rl.DrawTexturePro( texture^, @@ -394,7 +394,7 @@ open_file_dialog_and_store_output_paths :: proc() { } draw_and_handle_source_files_logic :: proc() { - switch g_mem.app_screen { + #partial switch g_mem.app_screen { case .SourceFilesPicker: result := rl.GuiTextInputBox( rl.Rectangle{width = (w / scaling), height = (h / scaling)}, @@ -445,8 +445,6 @@ draw_and_handle_source_files_logic :: proc() { handle_source_file_logic(file_dialg_type) fmt.println("result: ", result) } - case .PackSettingsAndPreview: - draw_packer_and_settings() } }