GLBasic forum

Main forum => GLBasic - en => Topic started by: bigtunacan on 2011-Sep-22

Title: TexturePacker importer
Post by: bigtunacan on 2011-Sep-22
This may not be the prettiest thing you've ever seen, but here is what I'm currently using to load from Texture Packer.  The main action is occurring in init_images (loading the texture atlas) and draw_named_sprite (draws from texture atlas data using polyvectors).

@Slydog,
As you can see I re-used your String_KeyValue function; I hope you don't mind.  I re-posted it here and it may turn up somewhere on the website for texture packer.  I have clearly attributed it to you.  If this makes you unhappy let me know and I will gladly re-write that section with something of my own.

I'm planning to add support for drawing with rotation and scaling still.  Also I may add support for loading multiple texture atlases; not sure that's a real high priority for me just yet as my games in progress probably don't have a need for it.

I would love to hear suggestions for improvements from anyone out here.

You can chech out Texture Packer here.  http://www.texturepacker.com/
(http://www.texturepacker.com/)


Code (glbasic) Select

TYPE SPRITE
entity_type
index
width
height
tx1
ty1
tx2
ty2
img$
name$ = ""
ENDTYPE

// Supporting function to always get a unique
FUNCTION get_sprite_index:
LOCAL tmp = SPRITE_COUNT
SPRITE_COUNT = SPRITE_COUNT + 1
RETURN tmp
ENDFUNCTION

FUNCTION init_images: file$
// This loads from Texture Packer.  Make sure to export data in the CEGUI/OGRE DATA format
LOCAL fh
LOCAL line$
LOCAL tags$[]
LOCAL key$
LOCAL value$
LOCAL spr AS SPRITE

fh = GENFILE()
IF OPENFILE(fh, file$, 1) = FALSE // Open SpriteSheet file
DEBUG ">-> Error opening file\n"
RETURN FALSE
ENDIF

WHILE ENDOFFILE(fh) = FALSE
READLINE fh, line$
line$ = TRIM$(line$)
line$ = MID$(line$, 1) // Strip off first '<' character
line$ = LEFT$(line$, LEN(line$) - 1) // Strip off last '>' character
IF RIGHT$(line$, 1) = "/" THEN line$ = LEFT$(line$, LEN(line$) - 1) // Strip off last '/' character if present

SPLITSTR(line$, tags$[], " ", TRUE)
IF LEN(tags$[]) < 1 THEN CONTINUE // Ignore elements with no tags
tags$[0] = TRIM$(UCASE$(tags$[0]))

SELECT tags$[0]
CASE "IMAGESET"
String_KeyValue(tags$[2], key$, value$)
atlas_index = 0 // <= right now I only support a single Texture Atlas being loaded at once.
LOADSPRITE "imgs/" + value$, atlas_index // <= Most users of GLBasic prob need Media/ rather than imgs/
CASE "IMAGE"
String_KeyValue(tags$[1], key$, value$)
spr.name$ = value$
String_KeyValue(tags$[2], key$, value$)
spr.tx1 = INTEGER(value$)
String_KeyValue(tags$[3], key$, value$)
spr.ty1 = INTEGER(value$)
String_KeyValue(tags$[4], key$, value$)
spr.width = INTEGER(value$)
String_KeyValue(tags$[5], key$, value$)
spr.height = INTEGER(value$)
spr.tx2 = spr.tx1 + spr.width
spr.ty2 = spr.ty1 + spr.height
spr.index = get_sprite_index()

// Make sure this is last
DIMPUSH sprite_list[], spr
ENDSELECT
WEND
ENDFUNCTION


// This function created by Slydog
FUNCTION String_KeyValue%: string$, BYREF keyword$, BYREF value$, strip_quotes%=TRUE
LOCAL ix%
ix = INSTR(string$, "=")
IF ix < 0
keyword$ = ""
value$   = ""
ELSE
keyword$ = UCASE$(TRIM$(LEFT$(string$, ix)))
value$   =        TRIM$( MID$(string$, ix+1))
ENDIF
IF strip_quotes
IF LEFT$(value$, 1) = CHR$(34) THEN value$ = MID$(value$, 1)
IF RIGHT$(value$, 1) = CHR$(34) THEN value$ = LEFT$(value$, LEN(value$)-1)
ENDIF
ENDFUNCTION


// Returns a specific sprite from this list based on name
FUNCTION get_named_sprite AS SPRITE: name$
FOR i=0 TO LEN(sprite_list[])-1
IF sprite_list[i].name$ = name$ THEN RETURN sprite_list[i]
NEXT
ENDFUNCTION

CONSTANT MIRROR_NORMAL=1
CONSTANT MIRROR_VERT = 2
CONSTANT MIRROR_HORIZ = 4

// This draws a sprite based on a texture atlas.  Supports vertical and horizontal mirroring
FUNCTION draw_named_sprite: name$, x, y, mirror=MIRROR_NORMAL
LOCAL txt_spr AS SPRITE
txt_spr = get_named_sprite(name$)

IF bAND(MIRROR_NORMAL, mirror)=1
// Normal
STARTPOLY 0,0 // Bitmap = No.0
  POLYVECTOR  x,    y,  txt_spr.tx1,  txt_spr.ty1, RGB(255, 255, 255)
  POLYVECTOR  x, y+txt_spr.height, txt_spr.tx1, txt_spr.ty2, RGB (255, 255, 255)
  POLYVECTOR  x+txt_spr.width, y+txt_spr.height, txt_spr.tx2, txt_spr.ty2, RGB(255, 255, 255)
  POLYVECTOR  x+txt_spr.width, y, txt_spr.tx2, txt_spr.ty1, RGB(255, 255, 255)
ENDPOLY
ELSEIF bAND(bOR(MIRROR_VERT,MIRROR_HORIZ),mirror)=6
//LEFT/RIGHT/UP/DOWN
STARTPOLY 0,0 // Bitmap = No.0
  POLYVECTOR  x,    y,  txt_spr.tx2,  txt_spr.ty2, RGB(255, 255, 255)
  POLYVECTOR  x, y+txt_spr.height, txt_spr.tx2, txt_spr.ty1, RGB (255, 255, 255)
  POLYVECTOR  x+txt_spr.width, y+txt_spr.height, txt_spr.tx1, txt_spr.ty1, RGB(255, 255, 255)
  POLYVECTOR  x+txt_spr.width, y, txt_spr.tx1, txt_spr.ty2, RGB(255, 255, 255)
ENDPOLY
ELSEIF bAND(MIRROR_VERT, mirror)=2
//LEFT/RIGHT
STARTPOLY 0,0 // Bitmap = No.0
  POLYVECTOR  x,    y,  txt_spr.tx2,  txt_spr.ty1, RGB(255, 255, 255)
  POLYVECTOR  x, y+txt_spr.height, txt_spr.tx2, txt_spr.ty2, RGB (255, 255, 255)
  POLYVECTOR  x+txt_spr.width, y+txt_spr.height, txt_spr.tx1, txt_spr.ty2, RGB(255, 255, 255)
  POLYVECTOR  x+txt_spr.width, y, txt_spr.tx1, txt_spr.ty1, RGB(255, 255, 255)
ENDPOLY
ELSEIF bAND(MIRROR_HORIZ, mirror)=4
// UP/DOWN
STARTPOLY 0,0 // Bitmap = No.0
  POLYVECTOR  x,    y,  txt_spr.tx1,  txt_spr.ty2, RGB(255, 255, 255)
  POLYVECTOR  x, y+txt_spr.height, txt_spr.tx1, txt_spr.ty1, RGB (255, 255, 255)
  POLYVECTOR  x+txt_spr.width, y+txt_spr.height, txt_spr.tx2, txt_spr.ty1, RGB(255, 255, 255)
  POLYVECTOR  x+txt_spr.width, y, txt_spr.tx2, txt_spr.ty2, RGB(255, 255, 255)
ENDPOLY
ENDIF
ENDFUNCTION
Title: Re: TexturePacker importer
Post by: Slydog on 2011-Sep-22
Great job!

And no problem about the function. 
If I post any code, I consider it freely usable by anyone for any reason.
Title: Re: TexturePacker importer
Post by: Albert on 2011-Sep-22
Put a link to the Texture Packer into the first post please.
Title: Re: TexturePacker importer
Post by: bigtunacan on 2011-Sep-22
Added link.