Multiple image files or just one?

Is there an advantage either way to having multiple image files, or one
image strip?

For example, is there a performance/memory advanage to putting a deck of
cards all in one image file (and one SDL_Surface), and then using
x-offset versus a seperate image (and SDL_Surface) for each card?

Thanks,
Buck

Surely if you had just one long strip of images and you were “cutting them
out” as they were needed, then this would cause a performance hit. Imagine a
game where you could have around 50+ moving objects. That’s over 50 times
you would be copying from one surface onto another.

What you could do is store all the images onto one bitmap and then, on
program start up, copy them all into individual surfaces…?> -----Original Message-----

From: Wesley (Buck) Lemke [SMTP:buck at bucklemke.com]
Sent: Tuesday, January 22, 2002 2:24 AM
To: sdl at libsdl.org
Subject: [SDL] Multiple image files or just one?

Is there an advantage either way to having multiple image files, or one
image strip?

For example, is there a performance/memory advanage to putting a deck of
cards all in one image file (and one SDL_Surface), and then using
x-offset versus a seperate image (and SDL_Surface) for each card?

Thanks,
Buck


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Surely if you had just one long strip of images and you were “cutting them
out” as they were needed, then this would cause a performance hit. Imagine a
game where you could have around 50+ moving objects. That’s over 50 times
you would be copying from one surface onto another.

surely, in either case you’d load the image once creating an SDL surface
then just blit from that straight to the screen, regardless of whether you
do the whole image or just a portion of it, it is still just a single
blit…

I’m unsure of the internal SDL_surface overheads, but certainly if you
have say 500 sprite frames on disk, each in a file of it’s own, thats 500
files of a minimum of your system block size, so for a 500byte image
on a system tih a 2k blocksize, thats 1500 bytes of wasted disk spce every
frame.

Plus, some OS’s still have “number of files” limits…

Either way, it’s not a big optimization thing, certainly not in the 20% of
the code that you want to be spending 80% of your time in :slight_smile:

Yours,
Andy GordonOn Tue, 22 Jan 2002, Sweeney, Steven (FNB) wrote:


QueriX UK
36A London Road		http://www.querix.co.uk
Southampton		
Tel: +44 23 8023 2345	andy at querix.co.uk
Fax: +44 23 8039 9685

Andy Gordon wrote:> On Tue, 22 Jan 2002, Sweeney, Steven (FNB) wrote:

Surely if you had just one long strip of images and you were “cutting them
out” as they were needed, then this would cause a performance hit. Imagine a
game where you could have around 50+ moving objects. That’s over 50 times
you would be copying from one surface onto another.

The only thing that can affect performace here is the orientation of your ‘strip’.
I think there’ll be extra overhead if it’s horizontal, as then skipping x bytes
will be needed when blitting each line, and each small image won’t be in a signle
chunk of memory, which can be memmove-ed otherwise in single call.

I always use vertical stripes of images of uniform width, though had never
measured actual performace-wise benefit.

/lxnt

Surely if you had just one long strip of images and you were “cutting them
out” as they were needed, then this would cause a performance hit. Imagine a
game where you could have around 50+ moving objects. That’s over 50 times
you would be copying from one surface onto another.

surely, in either case you’d load the image once creating an SDL surface
then just blit from that straight to the screen, regardless of whether you
do the whole image or just a portion of it, it is still just a single
blit…
SDL_BlitSurface only uses the srcrect to determine size, no? You can’t
blit a smaller section of a larger surface like you’re suggesting. At
least not with BlitSurface.On Tue, 2002-01-22 at 06:09, Andy Gordon wrote:
On Tue, 22 Jan 2002, Sweeney, Steven (FNB) wrote:

I’m unsure of the internal SDL_surface overheads, but certainly if you
have say 500 sprite frames on disk, each in a file of it’s own, thats 500
files of a minimum of your system block size, so for a 500byte image
on a system tih a 2k blocksize, thats 1500 bytes of wasted disk spce every
frame.

Plus, some OS’s still have “number of files” limits…

Either way, it’s not a big optimization thing, certainly not in the 20% of
the code that you want to be spending 80% of your time in :slight_smile:

Yours,
Andy Gordon


QueriX UK
36A London Road http://www.querix.co.uk
Southampton
Tel: +44 23 8023 2345 andy at querix.co.uk
Fax: +44 23 8039 9685


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

End of Rant.

Jimmy
JimmysWorld.org
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 232 bytes
Desc: This is a digitally signed message part
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20020122/78d5a8f3/attachment.pgp

How about this, do it as one file and write routines to hide how you
actually read, and blit the images. Then, if it should turn out that
what you did is horrible, it most likely is just fine, then you can
rewrite those routines to do it some other way. That way you can get
past the problem today, and if for some reason you want to change it
later you can change it without affecting any of your other code. If you
are using an object oriented language such as C++ bury all the details
in a class. Don’t sweat the details until they cause real pain.

Bob P.

Alexander Sabourenkov wrote:>

Andy Gordon wrote:

On Tue, 22 Jan 2002, Sweeney, Steven (FNB) wrote:

Surely if you had just one long strip of images and you were “cutting them
out” as they were needed, then this would cause a performance hit. Imagine a
game where you could have around 50+ moving objects. That’s over 50 times
you would be copying from one surface onto another.

The only thing that can affect performace here is the orientation of your ‘strip’.
I think there’ll be extra overhead if it’s horizontal, as then skipping x bytes
will be needed when blitting each line, and each small image won’t be in a signle
chunk of memory, which can be memmove-ed otherwise in single call.

I always use vertical stripes of images of uniform width, though had never
measured actual performace-wise benefit.

/lxnt


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


±-----------------------------------+

  • Bob Pendleton is seeking contract +
  • and consulting work. Find out more +
  • at http://www.jump.net/~bobp +
    ±-----------------------------------+

Surely if you had just one long strip of images and you were “cutting
them out” as they were needed, then this would cause a performance hit.
Imagine a game where you could have around 50+ moving objects. That’s
over 50 times you would be copying from one surface onto another.

Actually, Kobo Deluxe uses a slightly modified version of SoFont (C++
version of SFont), which does exactly that - or rather, each character is
blitted directly from the font surface to the screen. (In the OpenGL
mode, it’s done the same way, although glSDL chops the font surface up
into handy pieces and throws them into a texture.)

Anyway, in normal SDL “2D mode”, it does cause a performance hit, as
the RLE blitter has to mess with the runs of the source surfaces all the
time. (Normally, it only does when actually clipping to the destination
clip rect.)

In glSDL OpenGL mode however, it’s actually faster to do it this way,
as keeping the whole font in a single texture reduces the number of
texture changes while rendering. (Note that glSDL is not a part of SDL -
at least not yet - so it doesn’t apply unless you’re actually playing
around with glSDL, or with OpenGL directly.)

Either way, packing images vertically instead of horizontally might be
faster - but Mattias Engdeg?rd will have to verify that, as I don’t know
if RLE surfaces have some kind of row LUTs or something.

What you could do is store all the images onto one bitmap and then, on
program start up, copy them all into individual surfaces…?

That’s what Kobo Deluxe does with tiles and sprites.

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Tuesday 22 January 2002 10:55, Sweeney, Steven (FNB) wrote:

On the contrary, that’s exactly what SFont and similar libraries are
doing. And the parallax examples as well, BTW…

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Tuesday 22 January 2002 17:44, Jimmy wrote:

On Tue, 2002-01-22 at 06:09, Andy Gordon wrote:

On Tue, 22 Jan 2002, Sweeney, Steven (FNB) wrote:

Surely if you had just one long strip of images and you were
"cutting them out" as they were needed, then this would cause a
performance hit. Imagine a game where you could have around 50+
moving objects. That’s over 50 times you would be copying from one
surface onto another.

surely, in either case you’d load the image once creating an SDL
surface then just blit from that straight to the screen, regardless
of whether you do the whole image or just a portion of it, it is
still just a single blit…

SDL_BlitSurface only uses the srcrect to determine size, no? You can’t
blit a smaller section of a larger surface like you’re suggesting. At
least not with BlitSurface.

How about this, do it as one file and write routines to hide how you
actually read, and blit the images.

Just what I did in “sprite.[ch]” in Kobo Deluxe.

Then, if it should turn out that
what you did is horrible, it most likely is just fine, then you can
rewrite those routines to do it some other way. That way you can get
past the problem today, and if for some reason you want to change it
later you can change it without affecting any of your other code. If
you are using an object oriented language such as C++ bury all the
details in a class.

That part of my engine is written in C (and just wrapped by the
gfxengine_t class), and is based on a container/bank/frame hierarchy,
where each bank contains frames that must all be of the same type
(opaque, colorkeyed or with alpha channel) and size.

Loading the background tiles for Kobo Deluxe:

    fn = fmap.get("GFX>>tiles.pcx");
    if(!fn || gengine.loadtiles(B_TILES, 16, 16, fn) < 0)
            return -1;

…where fmap is the portable path manager, and gengine is the global
gfxengine_t instance. ‘B_TILES’ is the bank number of the tiles, '16, 16’
is the tile size and fn is the file name.

The function will grab 16x16 tiles starting in the top-left corner of the
specified image, working on to the right, wrapping to the next row when
it hits the edge. Number of tiles is determined by the size of the image
and the tile size only. Each tile will be stored as a separate
SDL_Surface. Every frame is automatically passed through a configurable
image processing plugin chain, where necessary conversions and
transformations are performed.

Functions for rendering sprites, as well as the motion interpolated
"objects" of the engine, take bank+frame arguments to specify which
surface to use.

(Right, I should shut up and go back to work now… :slight_smile:

Don’t sweat the details until they cause real pain.

Exactly. Get it to work first - that’s enough work already! :slight_smile:

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Tuesday 22 January 2002 20:12, Bob Pendleton wrote:

David Olofson wrote:

How about this, do it as one file and write routines to hide how you
actually read, and blit the images.

Just what I did in “sprite.[ch]” in Kobo Deluxe.

[skip…]

The function will grab 16x16 tiles starting in the top-left corner of the
specified image, working on to the right, wrapping to the next row when
it hits the edge. Number of tiles is determined by the size of the image
and the tile size only. Each tile will be stored as a separate
SDL_Surface. Every frame is automatically passed through a configurable
image processing plugin chain, where necessary conversions and
transformations are performed.

But if they’re are all of uniform size, why not put them all in a vertical
strip? Or you prefer editing whole bank at once in, say, Gimp, and have them
all laid out in a grid and then loading the bank straight from the file?

Even that way, I would’ve written a loader to convert multiple files, say,
each containing related images into one single bank than to withness sheer
inefficiency of skipping lots of data to the start of each line of sprite.
:slight_smile:

/lxnt> On Tuesday 22 January 2002 20:12, Bob Pendleton wrote:

Surely if you had just one long strip of images and you were
"cutting them out" as they were needed, then this would cause a
performance hit. Imagine a game where you could have around 50+
moving objects. That’s over 50 times you would be copying from one
surface onto another.

surely, in either case you’d load the image once creating an SDL
surface then just blit from that straight to the screen, regardless
of whether you do the whole image or just a portion of it, it is
still just a single blit…

SDL_BlitSurface only uses the srcrect to determine size, no? You can’t
blit a smaller section of a larger surface like you’re suggesting. At
least not with BlitSurface.

On the contrary, that’s exactly what SFont and similar libraries are
doing. And the parallax examples as well, BTW…
Ok, I must have been really tired… because I remember this not
working. And was really unhappy about it. We’re talking about cutting
sx!=0,sy!=0,sw,sh to dx,dy here right?

When I tried only the width and height of the source only seemed to work
and the origin x,y were ignored. If I WAS just really tired, this is a
great thing.

Thanks.On Wed, 2002-01-23 at 10:46, David Olofson wrote:

On Tuesday 22 January 2002 17:44, Jimmy wrote:

On Tue, 2002-01-22 at 06:09, Andy Gordon wrote:

On Tue, 22 Jan 2002, Sweeney, Steven (FNB) wrote:

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -’


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

End of Rant.

Jimmy
JimmysWorld.org
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 232 bytes
Desc: This is a digitally signed message part
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20020123/40676132/attachment.pgp

David Olofson wrote:

How about this, do it as one file and write routines to hide how you
actually read, and blit the images.

Just what I did in “sprite.[ch]” in Kobo Deluxe.

[skip…]

The function will grab 16x16 tiles starting in the top-left corner of
the specified image, working on to the right, wrapping to the next
row when it hits the edge. Number of tiles is determined by the size
of the image and the tile size only. Each tile will be stored as a
separate SDL_Surface. Every frame is automatically passed through a
configurable image processing plugin chain, where necessary
conversions and transformations are performed.

But if they’re are all of uniform size, why not put them all in a
vertical strip?

Why?

Or you prefer editing whole bank at once in, say, Gimp,
and have them all laid out in a grid and then loading the bank straight
from the file?

That’s the way the files are arranged currently - but you could give
the engine a vertical or horizontal strip is well; it doesn’t matter. The
engine extracts the tiles and stores them in the way it sees fit anyway.

The reasons why I decided to use one surface per frame:

* It's easy for rendering code to ask the "container" for a
  specific frame without knowning about the internals of
  the container.

* The plugin system becomes nice and clean, as I can just
  pass the bank to each plugin, and have it loop over the
  frames without worrying about any other per-frame
  boundaries than the natural boundaries of each surface.
  (Correct clamping during interpolation is messy enough
  as it is without that...)

* No source rects need to be filled in and passed to
  SDL_BlitSurface().

* SDL doesn't have to do RLE clipping all the time.

Even that way, I would’ve written a loader to convert multiple files,
say, each containing related images into one single bank than to
withness sheer inefficiency of skipping lots of data to the start of
each line of sprite.

:slight_smile:

Well, of course… What’s your point? :slight_smile:

You can load multiple files into the same bank with my engine if you
like. You can also load a whole image as a single frame, and you can
"load" a rectangle from a frame of one bank as a fram of another bank.
(You can even load an SFont as a bank - although that’s currently a bit
of a kludge internally. I’ll ditch SoFont and hack a more carefully
integrated font system some time…)

The only restriction is that all frames of a bank must be of the same
size. Why? Well, the sprite engine must know the size of every sprite in
the system to do wrapping (for wrapping worlds like that in Kobo Deluxe)
and off-screen culling correctly, and it simply asks sprite.[ch] about
it. As I don’t want to mix up graphics coordinates and control system
coordinates (which are incompatible in scaled modes!), I can’t check the
surfaces directly. And as a matter of fact, there may not always be a
surface to check at all! The engine is supposed to work even if the
graphics isn’t loaded, to be usable in dedicated game servers and the
like. (Obviously, if you’re constructing collision detection masks from
the graphics, you’ll have to load at least the sprites anyway.)

Sure, I could allow mixed surface sizes in banks, or eliminate one
dimension of addressing entirely, but the current system is nice and
clean, and more than sufficient for what I’ve done so far. Might change
eventually, but I doubt it. (In native OpenGL mode, that would complicate
things a great deal, as the idea is to keep all frames of a bank in a
minimal number of OpenGL textures, rather than one texture per frame.)

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Wednesday 23 January 2002 18:10, Alexander Sabourenkov wrote:

On Tuesday 22 January 2002 20:12, Bob Pendleton wrote:

[…]

SDL_BlitSurface only uses the srcrect to determine size, no? You
can’t blit a smaller section of a larger surface like you’re
suggesting. At least not with BlitSurface.

On the contrary, that’s exactly what SFont and similar libraries
are doing. And the parallax examples as well, BTW…

Ok, I must have been really tired… because I remember this not
working. And was really unhappy about it. We’re talking about cutting
sx!=0,sy!=0,sw,sh to dx,dy here right?

Yep.

When I tried only the width and height of the source only seemed to
work and the origin x,y were ignored. If I WAS just really tired, this
is a great thing.

Were you perhaps using calculated values for sx, sy? It’s pretty easy to
end up with the wrong sign, which would explain why nothing appeared to
happen… :slight_smile:

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Wednesday 23 January 2002 19:24, Jimmy wrote:

[…]

SDL_BlitSurface only uses the srcrect to determine size, no? You
can’t blit a smaller section of a larger surface like you’re
suggesting. At least not with BlitSurface.

On the contrary, that’s exactly what SFont and similar libraries
are doing. And the parallax examples as well, BTW…

Ok, I must have been really tired… because I remember this not
working. And was really unhappy about it. We’re talking about cutting
sx!=0,sy!=0,sw,sh to dx,dy here right?

Yep.

When I tried only the width and height of the source only seemed to
work and the origin x,y were ignored. If I WAS just really tired, this
is a great thing.

Were you perhaps using calculated values for sx, sy? It’s pretty easy to
end up with the wrong sign, which would explain why nothing appeared to
happen… :slight_smile:
Nope, I’m just a retard. sigh

Bless you good man. You’re my best friend of the day. I just got a
30-40 fps boost thanks to you. On Wed, 2002-01-23 at 13:50, David Olofson wrote:

On Wednesday 23 January 2002 19:24, Jimmy wrote:

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -’


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

End of Rant.

Jimmy
JimmysWorld.org
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 232 bytes
Desc: This is a digitally signed message part
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20020123/fe12beb4/attachment.pgp

Just to speak of my own experience, I am doing exactly the above, using
a script (written in Pike) to combine frame images into a vertical strip.

In the rendering program, it uses both srcrect and clipping to render
each frame from a segment on the strip. I define a custom surface struct
in C and use several functions to create so call “sub-surface” from a
real SDL_Surface, and do blitting and all. I also used reference counting
to free the original SDL_Surface when the last “sub-surface” is freed.

It is very convenient, and works like a charm. I didn’t measure how
much the penalty would be, but I am running 50 “live” characters on one
screen (each with its own animation strip) just fine. Of course the
animation itself isn’t at 100 fps, but I can achieve the overall screen
refreshing rate at 100 fps, which is more than sufficient for your event
loop.

Besides, I almost have everything (including main rendering loop, event
management, whole set of GUI) in a scripting language (Lua). I am sure
there are lots of penalty doing this, but I can still have 100 fps of
my game running on a PIII 450 and ancient video card.

I do believe it is always good to optimize the 20% code to achive 80%
gain in performance, and you should only consider this after you do a
real profiling of your running code. Comparing to my Lua script, the
penalty of doing this “multiple images onto one” is negligible.

Regards,
.Paul.On Wed, Jan 23, 2002 at 08:10:28PM +0300, Alexander Sabourenkov wrote:

But if they’re are all of uniform size, why not put them all in a vertical
strip? Or you prefer editing whole bank at once in, say, Gimp, and have them
all laid out in a grid and then loading the bank straight from the file?

Even that way, I would’ve written a loader to convert multiple files, say,
each containing related images into one single bank than to withness sheer
inefficiency of skipping lots of data to the start of each line of sprite.
:slight_smile: