The following warnings occurred:
Warning [2] Undefined array key "avatartype" - Line: 783 - File: global.php PHP 8.0.11 (Linux)
File Line Function
/global.php 783 errorHandler->error
/showthread.php 28 require_once
Warning [2] Undefined array key "avatartype" - Line: 783 - File: global.php PHP 8.0.11 (Linux)
File Line Function
/global.php 783 errorHandler->error
/showthread.php 28 require_once
Warning [2] Undefined variable $awaitingusers - Line: 34 - File: global.php(844) : eval()'d code PHP 8.0.11 (Linux)
File Line Function
/global.php(844) : eval()'d code 34 errorHandler->error
/global.php 844 eval
/showthread.php 28 require_once
Warning [2] Undefined array key "style" - Line: 909 - File: global.php PHP 8.0.11 (Linux)
File Line Function
/global.php 909 errorHandler->error
/showthread.php 28 require_once
Warning [2] Undefined property: MyLanguage::$lang_select_default - Line: 5116 - File: inc/functions.php PHP 8.0.11 (Linux)
File Line Function
/inc/functions.php 5116 errorHandler->error
/global.php 909 build_theme_select
/showthread.php 28 require_once
Warning [2] Undefined array key "additionalgroups" - Line: 7277 - File: inc/functions.php PHP 8.0.11 (Linux)
File Line Function
/inc/functions.php 7277 errorHandler->error
/inc/functions.php 5136 is_member
/global.php 909 build_theme_select
/showthread.php 28 require_once
Warning [2] Undefined array key 1 - Line: 1440 - File: inc/functions.php PHP 8.0.11 (Linux)
File Line Function
/inc/functions.php 1440 errorHandler->error
/inc/functions.php 1405 fetch_forum_permissions
/inc/functions.php 2934 forum_permissions
/showthread.php 645 build_forum_jump
Warning [2] Undefined array key "mybb" - Line: 1977 - File: inc/functions.php PHP 8.0.11 (Linux)
File Line Function
/inc/functions.php 1977 errorHandler->error
/inc/functions_indicators.php 41 my_set_array_cookie
/showthread.php 653 mark_thread_read
Warning [2] Undefined property: MyLanguage::$ratings_update_error - Line: 5 - File: showthread.php(756) : eval()'d code PHP 8.0.11 (Linux)
File Line Function
/showthread.php(756) : eval()'d code 5 errorHandler->error
/showthread.php 756 eval
Warning [2] Undefined array key "additionalgroups" - Line: 7277 - File: inc/functions.php PHP 8.0.11 (Linux)
File Line Function
/inc/functions.php 7277 errorHandler->error
/inc/functions_user.php 844 is_member
/inc/functions_post.php 406 purgespammer_show
/showthread.php 1098 build_postbit
Warning [2] Undefined array key "profilefield" - Line: 6 - File: inc/functions_post.php(474) : eval()'d code PHP 8.0.11 (Linux)
File Line Function
/inc/functions_post.php(474) : eval()'d code 6 errorHandler->error
/inc/functions_post.php 474 eval
/showthread.php 1098 build_postbit
Warning [2] Undefined array key "canonlyreplyownthreads" - Line: 662 - File: inc/functions_post.php PHP 8.0.11 (Linux)
File Line Function
/inc/functions_post.php 662 errorHandler->error
/showthread.php 1098 build_postbit
Warning [2] Undefined array key "showimages" - Line: 743 - File: inc/functions_post.php PHP 8.0.11 (Linux)
File Line Function
/inc/functions_post.php 743 errorHandler->error
/showthread.php 1098 build_postbit
Warning [2] Undefined array key "showvideos" - Line: 748 - File: inc/functions_post.php PHP 8.0.11 (Linux)
File Line Function
/inc/functions_post.php 748 errorHandler->error
/showthread.php 1098 build_postbit
Warning [2] Undefined array key "invisible" - Line: 1534 - File: showthread.php PHP 8.0.11 (Linux)
File Line Function
/showthread.php 1534 errorHandler->error
Warning [2] Undefined variable $threadnotesbox - Line: 30 - File: showthread.php(1561) : eval()'d code PHP 8.0.11 (Linux)
File Line Function
/showthread.php(1561) : eval()'d code 30 errorHandler->error
/showthread.php 1561 eval
Warning [2] Undefined variable $addremovesubscription - Line: 79 - File: showthread.php(1561) : eval()'d code PHP 8.0.11 (Linux)
File Line Function
/showthread.php(1561) : eval()'d code 79 errorHandler->error
/showthread.php 1561 eval




Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
sprite sheet generator
#1
Here's a little tool that is not of much use when you're making games with naalaa.

When you make games that use opengl/opengles you know that texture binding can be costy. Therefor you want to squeeze as many images as possible into every texture. There are already nice tools out there that do this for you, such as Texture Packer (costs Money though). But I prefer writing my own tools, so here's a naalaa program that grabs every png image in a directory and packs them in a single image. It also generates a json file (in the same format as Texture Packer and most other programs) that specifies the locations of all sub images in the resulting image.

This program should be run from the command line. The syntax is:

atlasgen <path to images> <texture width> <texture height> [<output filename>]

So if you have a bunch of png files in a folder, c:\hello\images, and you want to generate a texture and json named my_texture.png and my_texture.json, you'd write:

Code:
atlasgen c:\hello\images 1024 1024 my_texture



Code:
' ==============================================================================
' image atlas generator, by marcus.
' ==============================================================================

import "QuickSort.lib"

LENGTH = 1
AREA = 2

if sizeof(args) < 4
   _Error "atlasgen <path to images> <atlas width> <atlas height> [(name)]"
endif

path$ = args[1]
WIDTH = int(args[2])
HEIGHT = int(args[3])

if sizeof(args) > 4
   name$ = args[4]
else
   name$ = "assets"
endif

if not (mid(path, len(path) - 1) = "/" or mid(path, len(path) - 1) = "\")
   path = path + "/"
endif
files$[] = ListFiles(path)

count = 0
for i = 0 to sizeof(files) - 1
   if len(files[i])
       load image count, path + files[i]
       if image(count) then count = count + 1
   endif
next

if count = 0 then end

' area seems to work better
sort = AREA

uns?[count]
org?[count]
rects?[1000]

tmp[count][2]
for i = 0 to sizeof(org) - 1
   ' Add spacing.
   uns[i].w = width(i) + 2
   uns[i].h = height(i) + 2
   uns[i].img = i
   uns[i].fn$ = files[i]
   tmp[i][0] = i
 ' sort based on area
   if sort = AREA
       ' This one wins in all cases.
       tmp[i][1] = uns[i].w*uns[i].h
       tmp[i][1] = tmp[i][1]*min(uns[i].w, uns[i].h)/max(uns[i].w, uns[i].h)
 ' sort based on max of width and height
   elseif sort = LENGTH
       tmp[i][1] = max(uns[i].w, uns[i].h)
   endif
next

' sort by area
_QuickSort2D tmp, 1

for i = 0 to sizeof(uns) - 1
   org[sizeof(org) - 1 - i] = uns[tmp[i][0]]
next

rectCount = 1
rects[0].x = 0
rects[0].y = 0
rects[0].w = WIDTH
rects[0].h = HEIGHT

for i = 0 to sizeof(org) - 1
   smallestIndex = rectCount
   smallestArea = WIDTH*HEIGHT*2
   for j = 0 to rectCount - 1
       if rects[j].w >= org[i].w and rects[j].h >= org[i].h and rects[j].w*rects[j].h < smallestArea
           smallestIndex = j
           smallestArea = rects[j].w*rects[j].h
       endif
   next
   if smallestIndex = rectCount
       set color 0, 0, 0
       draw rect 0, 0, 208, 24, true
       set color 255, 255, 255
       _Error "Images did not fit"
   endif

   j = smallestIndex
   org[i].x = rects[j].x
   org[i].y = rects[j].y
   orgX = rects[j].x
   orgY = rects[j].y
   orgW = rects[j].w
   orgH = rects[j].h

   rects[rectCount].x = orgX + org[i].w
   rects[rectCount].y = orgY
   rects[rectCount].w = orgW - org[i].w
   rects[rectCount].h = orgH
   a1 = rects[rectCount].w*rects[rectCount].h

   rects[rectCount].x = orgX
   rects[rectCount].y = orgY + org[i].h
   rects[rectCount].w = orgW
   rects[rectCount].h = orgH - org[i].h
   a2 = rects[rectCount].w*rects[rectCount].h

   ' This is not right. Checking which split yields one largest rectangle.
 ' It would be better to check which one yields the two 'most square' rectangles.
   if a1 > a2
       rects[j].x = orgX
       rects[j].y = orgY + org[i].h
       rects[j].w = org[i].w
       rects[j].h = orgH - org[i].h

       rects[rectCount].x = orgX + org[i].w
       rects[rectCount].y = orgY
       rects[rectCount].w = orgW - org[i].w
       rects[rectCount].h = orgH
   else
       rects[j].x = orgX + org[i].w
       rects[j].y = orgY
       rects[j].w = orgW - org[i].w
       rects[j].h = org[i].h

       rects[rectCount].x = orgX
       rects[rectCount].y = orgY + org[i].h
       rects[rectCount].w = orgW
       rects[rectCount].h = orgH - org[i].h
   endif

   rectCount = rectCount + 1
next

create image -1, WIDTH, HEIGHT
set image -1
set color 0, 0, 0, 0
for y = 0 to HEIGHT - 1
   for x = 0 to WIDTH - 1
       set pixel x, y
   next
next

for i = 0 to sizeof(org) - 1
   for y = 0 to height(org[i].img) - 1
       for x = 0 to width(org[i].img) - 1
           set image org[i].img
           c[] = pixel(x, y)
           set image -1
           set color c[0], c[1], c[2], c[3]
           set pixel org[i].x + 1 + x, org[i].y + 1 + y
       next
   next
next
save image - 1, name + ".png"

tab$ = chr(9)
create file 0, name + ".json"
wln file 0, "{", quoted("frames"), ": ["
for i = 0 to sizeof(org) - 1
   wln file 0, "{"
   wln file 0, tab, quoted("filename"), ": ", quoted(org[i].fn$), ","
   write file 0, tab, quoted("frame"), ": {"
   write file 0, quoted("x"), ": ", org[i].x + 1, ", "
   write file 0, quoted("y"), ": ", org[i].y + 1, ", "
   write file 0, quoted("w"), ": ", width(org[i].img), ", "
   wln file 0, quoted("h"), ": ", height(org[i].img), "},"
   wln file 0, tab, quoted("rotated"), ": false,"
   wln file 0, tab, quoted("trimmed"), ": false,"
   write file 0, tab, quoted("spriteSourceSize"), ": {"
   write file 0, quoted("x"), ": 0, "
   write file 0, quoted("y"), ": 0, "
   write file 0, quoted("w"), ": ", width(org[i].img), ", "
   wln file 0, quoted("h"), ": ", height(org[i].img), "},"
   write file 0, tab, quoted("sourceSize"), ": {"
   write file 0, quoted("w"), ": ", width(org[i].img), ", "
   wln file 0, quoted("h"), ": ", height(org[i].img), "}"  
   if i < sizeof(org) - 1
       wln file 0, "},"
   else
       wln file 0, "}"
   endif
next
wln file 0, "]}"
free file 0

function quoted$(txt$)
   return chr(34) + txt + chr(34)
endfunc

procedure Error(txt$)
   set color 0, 0, 0
   cls
   set color 255, 255, 255
   set caret 0, 0
   wln txt
   t = time()
   while time() < t + 2000
       redraw
       wait 10
   wend    
   end
endproc

procedure ListFiles$[](dir$)
    shellexecute "open", "cmd", "", "/c cd " + chr(34) + dir + chr(34) + " & dir /b *.png > png_list.txt", true    
    open file 0, dir + "png_list.txt"
    if file(0)
        tmp$ = ""
        while not eof(0)
            tmp = tmp + read$(0) + chr(10)
        wend
        free file 0
        return split(tmp, chr(10))
    else
        bad$[]
        return bad
    endif
endproc


Attached Files
.txt   atlasgen.txt (Size: 5.81 KB / Downloads: 7)
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)