psychicsoftware
August 22, 2012
Dead By Dawn, Techie

GUI Texture Atlases in Shiva

August 22, 2012
Dead By Dawn, Techie

As you probably know, it’s important to use Texture Atlases for efficiency reasons on mobile devices. The idea is that you pack lots of textures into one big one, and then use UV offsets to define which region of this large texture to display in your HUD components. This means that only one texture has to be referenced by the graphics hardware. But it can be a bit fiddly calculating the UVs, especially if you want to add new textures to it later.

I have put together a nice workflow for this, so I thought it might be useful for other people too..

Step 1: Create your texture atlas. I use a program called Texture Packer for this, which combines your textures into a single PNG and also exports an XML description of it (which we’ll need later; we could of course manually write the XML but it’s a bit more work that way..)

Texture Packer

Step 2: Write or export your XML. My Shiva code a bit later will assume the following format, which is what Texture Packer gives us. It simply encodes the names of the images (sprites), along with their positions and sizes in the atlas.

<TextureAtlas imagePath="ZS_icons.png" width="512" height="512">
<sprite n="backpack" x="204" y="2" w="160" h="186"/>
<sprite n="rotate_left" x="366" y="51" w="48" h="47"/>
<sprite n="rotate_right" x="416" y="2" w="48" h="47"/>
<sprite n="search" x="366" y="2" w="48" h="47"/>
<sprite n="shotgun" x="2" y="2" w="200" h="86"/>
</TextureAtlas>


Step 3:
Import the xml file and texture atlas in to Shiva

Step 4: Create your HUD. Anywhere you want a texture out of the atlas, just set that HUD component to the Atlas texture (it looks a bit weird at design-time..)

HUD at design time

Step 5: Add an XML variable to an AI, and set it initialised from the imported xml. (I call my xml variable xmlZS_icons, and hard-code that in the code below)

Step 6: Add the following function to your AI:

--------------------------------------------------------------------------------
function MyAI.SetUvsFromTextureAtlas ( sComp,sIcon )
--------------------------------------------------------------------------------

local r = xml.getRootElement ( this.xmlZS_icons ( ) )

local imgWid = string.toNumber ( xml.getAttributeValue ( xml.getElementAttributeWithName ( r, "width" ) ) )
local imgHgt = string.toNumber ( xml.getAttributeValue ( xml.getElementAttributeWithName ( r, "height" ) ) )

local c = xml.getElementChildCount ( r )

for i=0, c-1 do


local e = xml.getElementChildAt ( r,i )
if ( sIcon==xml.getAttributeValue ( xml.getElementAttributeWithName ( e, "n" ) ) ) then


local uscale = string.toNumber ( xml.getAttributeValue ( xml.getElementAttributeWithName ( e, "w" ) ) ) / imgWid
local vscale = string.toNumber ( xml.getAttributeValue ( xml.getElementAttributeWithName ( e, "h" ) ) ) / imgHgt
local u = string.toNumber ( xml.getAttributeValue ( xml.getElementAttributeWithName ( e, "x" ) ) ) / imgWid
local v = 1-( string.toNumber ( xml.getAttributeValue ( xml.getElementAttributeWithName ( e, "y" ) ) ) / imgHgt )-vscale
local comp = hud.getComponent ( application.getCurrentUser ( ),sComp )
hud.setComponentBackgroundImageUVOffset ( comp, u, v )
hud.setComponentBackgroundImageUVScale ( comp, uscale, vscale )
return


end

end

log.message ( "Unable to find icon '"..sIcon.."' in texture atlas!" )

 

 

--------------------------------------------------------------------------------
end
--------------------------------------------------------------------------------

 

Step 7: And finally, whenever you instantiate your HUD, call the following for each HUD component that’s included in the texture atlas:

this.SetUvsFromTextureAtlas ( "MyHUD.MyComponent", "sprite_name" )

 

final result

Tweet
Dead County – work in progress
Dead By Dawn

Newsletter

Your email address will not be shared with any 3rd parties, and will only be used for occasional newletters about Psychic Software's games.
 
[Our Privacy Policy]

Presskit

  • Press Kit here

Games in Development

  • The Necromancer's Tale
  • Newby Chinese

Games Released

  • Darkwind: War on Wheels
  • Let's Break Stuff!
  • Musclecar Online
  • Goblins & Gottos
  • Orbs.it
  • Mars Defender
  • Demon Pit
  • Afterburn 2150
  • Block Rockin'
  • More on Gooogle Play
  • More on iOS Appstore

Unfinished Projects “On Hiatus”

  • Zed's Dead
  • Ping Pong Planets
  • Godkin

Archives

  • June 2022
  • April 2022
  • May 2021
  • December 2020
  • November 2020
  • October 2020
  • August 2020
  • May 2020
  • March 2020
  • October 2019
  • October 2018
  • August 2018
  • July 2018
  • January 2018
  • September 2017
  • August 2017
  • May 2017
  • July 2016
  • May 2016
  • April 2016
  • December 2015
  • November 2015
  • September 2015
  • July 2015
  • May 2015
  • April 2015
  • February 2015
  • January 2015
  • December 2014
  • October 2014
  • August 2014
  • January 2014
  • December 2013
  • September 2013
  • July 2013
  • May 2013
  • April 2013
  • March 2013
  • December 2012
  • October 2012
  • August 2012
  • June 2012
  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
  • February 2011
  • January 2011
  • March 2006
  • February 2006
  • January 2006
  • November 2005
  • October 2005
  • September 2005
  • August 2005
  • July 2005
  • December 1995

Categories

  • Afterburn 2150
  • Block Rockin'
  • Conferences & Events
  • Darkwind
  • Dead By Dawn
  • Demon Pit
  • Game Musings
  • Goblins & Grottos
  • Godkin
  • Guest Posts
  • Let's Break Stuff!
  • Mars Defender
  • Monster Melee
  • Musclecar Online
  • Newby Chinese
  • Orbs.it
  • PC Gamer
  • Rock Paper Shotgun
  • Techie
  • The Necromancer
  • Uncategorized
  • Zed's Dead

CyberChimps WordPress Themes

PSYCHICSOFTWARE | Psychic Games Ltd.
Sam Redfern indie games developer and university academic