PNG and SDL

I’m interested in the interaction of PNG and SDL.

What I desire, is an architecture like Quake’s, where the engine has
control over many things, and the driver merely provides a portable
"hardware" environment to program to.

However, I wish to raise the level of that driver API just a bit.
Instead of providing a framebuffer, I wish to provide generics graphics
primitives (drawLine, fillRectangle, etc.) as inspired by X Windows.

Specifically, I’d like to provide a sort of XPutImage, but I obviously
can’t use the XImage structure in a generic driver.

So, I’d like to use PNG. I figure PNG is portable, and so can be the
graphics format of my engine. By using libpng, I can freely promote the
image structure to the level of engine, and require that the driver know
how to deal with PNG images. This lets me avoid moving all the image
handling code into the driver, and using void* all through the engine.

Therefore, I might have a putImage function that takes a PNG structure.
An SDL driver would have to handle this PNG image and correctly draw it
to an SDL surface.

Now, I see that SDL_image handles conversion to and from PNG. But my
question is a little more subtle. Obviously, I can’t convert a PNG image
to an SDL surface during each call to putImage. How do I ensure that
everything is fast, within the constraints I have set?

Well, the most unobtrustive method is simply to have the SDL driver
convert a PNG image the first time it is put. Then, it is cached, so
subsequent calls skip the conversion. However unobtrusive this is, it
wastes space, storing each image and its converted representation, even
if it may never be drawn again.

I could make the engine convert the loaded PNG to the proper bit depth
etc. This might make the conversion less painful, but it still has to
occur. Is this going to be too much overhead to do during each putImage
call?

I hope I’m being clear. Basically, I’d like to load PNG images using
libpng directly in the engine, and have the driver (SDL or otherwise)
provide a putImage(png_structp, src_x, src_y, dest_x, dest_y, width,
height) function that draws the image onto the “global” screen surface.

What is the best way of approaching this?–
Marc Lepage
http://www.antimeta.com/
Minion open source game, RTS game programming, etc.

I’m interested in the interaction of PNG and SDL.

What I desire, is an architecture like Quake’s, where the engine has
control over many things, and the driver merely provides a portable
"hardware" environment to program to.

I hope I’m being clear. Basically, I’d like to load PNG images using
libpng directly in the engine, and have the driver (SDL or otherwise)
provide a putImage(png_structp, src_x, src_y, dest_x, dest_y, width,
height) function that draws the image onto the “global” screen surface.

What is the best way of approaching this?

Sounds like you want to implement a simple cacheing system. The following
document is my favourite guide to playing the cacheing game, reprinted from
somewhere or another… and pardon me for spamming the mailing list with
Canadian humour :stuck_out_tongue:

--------8<---------

     THE PAGING GAME

Jeff Berryman, University of British Columbia

      *** RULES ***
  1. Each player gets several million things.
  2. Things are kept in crates that hold 4096 things each. Things in the
    same crate are called crate-mates.
  3. Crates are stored either in the workshop or in the warehouse. The
    workshop is almost always too small to hold all the crates.
  4. There is only one workshop, but there may be several warehouses.
    Everybody shares them.5) Each thing has its own thing number.
  5. What you do with a thing is to zark it. Everybody takes turns
    zarking.
  6. You can only zark your own things, not anybody else’s.
  7. Things may only be zarked when they are in the workshop.
  8. Only the Thing King knows whether a thing is in the workshop or in a
    warehouse.
  9. The longer a thing goes without being zarked, the grubbier it is said
    to become.
  10. The way to get things is to ask the Thing King. He only gives out
    things in crates. This is to keep royal overhead down.
  11. The way to zark a thing is to give its thing number. If you give the
    number of a thing that happens to be in the workshop, it gets zarked
    right away. If it is in a warehouse, the Thing King moves the crate
    containing your thing into the workshop. If there is no room in the
    workshop, he first finds the grubbiest crate in the workshop, whether it
    be yours or somebody else’s, and packs it off with all its crate-mates
    to a warehouse. In its place he puts the crate containing your thing.
    Your thing gets zarked and you never even know that it wasn’t in the
    workshop all along.
  12. Each players stock of things has the same numbers as everybody else’s.
    The Thing King always knows who owns what thing and whose turn it is, so
    you can’t ever accidentally zark somebody else’s thing even if it has
    the same number as one of yours.

*** NOTES ***

  1. Traditionally, the Thing King sits at a large, segmented table and is
    attended by pages (the so-called “table pages”) whose jobs it is to help
    the king remember where all the things are and to whom they belong.
  2. One consequence of Rule 13 is that everybody’s thing numbers will be
    similar from game to game, regardless of the number of players.
  3. The Thing King has a few things of his own, some of which move back and
    forth between workshop and warehouse just like anybody else’s, but some
    of which are just too heavy to move out of the workshop.
  4. With the given set of rules, oft-zarked things tend to get kept mostly
    in
    the workshop, while little-zarked things stay mostly in a warehouse.
  5. Sometimes even the warehouses get full. The Thing King then has to
    start
    piling things on the dump out back. This makes the game slow because it
    takes a long time to get things off the dump when they are needed in the
    workshop. A forthcoming change in the rules will allow the Thing King
    to select the grubbiest things in the warehouses and send them to dump
    in his spare time, thus keeping the warehouses from getting too full.
    This means that the most infrequently-zarked things will end up in the
    dump so the Thing King won’t have to get things from the dump so often.
    This should speed up the game when there are a lot of players and the
    warehouses are getting full.

LONG LIVE THE THING KING!

--------8<--------

How you actually implement your cacheing system is entirely up to you. (in
other words, the criteria as to whether or not we put what in the
warehouses) Is that basically what you’re talking about?


Marc Lepage
http://www.antimeta.com/
Minion open source game, RTS game programming, etc.

Nicholas

----- Original Message -----
From: mlepage@antimeta.com (Marc A. Lepage)
To: sdl at lokigames.com
Date: Sunday, January 23, 2000 1:52 PM
Subject: [SDL] PNG and SDL

Marc Lepage wrote:

Now, I see that SDL_image handles conversion to and from PNG. But my
question is a little more subtle. Obviously, I can’t convert a PNG image
to an SDL surface during each call to putImage. How do I ensure that
everything is fast, within the constraints I have set?

The thing is that the XImage structure and the PNG format are not at all
at the same level. PNG is purely a storage format, while XImage is
purely an in-memory format. XImage maps to an SDL surface in the SDL
system.

Well, the most unobtrustive method is simply to have the SDL driver
convert a PNG image the first time it is put. Then, it is cached, so
subsequent calls skip the conversion. However unobtrusive this is, it
wastes space, storing each image and its converted representation, even
if it may never be drawn again.

It isn’t wasted space. An XImage is a fully uncompressed, ready to be
transferred format, the same thing as an SDL surface. Loading a PNG from
a file each time is wasted time. If you load the whole PNG in memory
and convert from there, it’s now wasted time and space (as
uncompressing the PNG will take time, and you’ll have both the PNG and
uncompressed SDL surface in memory).

This is exactly why designing engines or games is not so easy. You have
to manage the memory, make your own decisions regarding whether an SDL
surface is still useful or not, to keep it or to free it, etc…

I would suggest making your engine API so that a clear distinction is
made between an image ressource (in storage format, PNG if you wish to)
and a drawable surface (in the framebuffer native format).

Note that you do not have to use void* in your putImage function, but
something like SDL_surface* (or maybe a typedef you use to hide the
actual SDL machinery).–
Pierre Phaneuf
Ludus Design, http://ludusdesign.com/

Nicholas Vining wrote:

How you actually implement your cacheing system is entirely up to you. (in
other words, the criteria as to whether or not we put what in the
warehouses) Is that basically what you’re talking about?

I think Pierre’s answer was more what I was talking about. :slight_smile:

I think I’ll use PNG as an image resource format, with resource loading
code in the engine. The driver will typedef or wrap a surface. The
engine will manipulate that typedef or surface as an opaque
pointer/handle. The driver will provide resource->surface conversion
code.

So, engine loads PNG. Engine asks driver to create a DriverSurface from
it. Engine dumps PNG. Engine asks driver to render DriverSurface. etc.–
Marc A. Lepage
Software Developer
Molecular Mining Corporation
http://www.molecularmining.com/

on Mon, 24 Jan 2000 Marc A. Lepage wrote:

Nicholas Vining wrote:

How you actually implement your cacheing system is entirely up to you. (in
other words, the criteria as to whether or not we put what in the
warehouses) Is that basically what you’re talking about?

I think Pierre’s answer was more what I was talking about. :slight_smile:

I think I’ll use PNG as an image resource format, with resource loading
code in the engine. The driver will typedef or wrap a surface. The
engine will manipulate that typedef or surface as an opaque
pointer/handle. The driver will provide resource->surface conversion
code.

So, engine loads PNG. Engine asks driver to create a DriverSurface from
it. Engine dumps PNG. Engine asks driver to render DriverSurface. etc.

Hi,

In my eyes PNG is more a image-FILEformat, it does not make sense, to use it as
an image resource, as it even provides weird image formats. (I think everything
form 1bit to 64bits per pixel at all available endian modes …)

I prefer to use PNG as fileformat and convert the images at loadtime, to my
desired format - which is the pixelformat my game currently runs at -
Doing the conversion at runtime is a bad idea, since it may take a long time.

just my two pence,–
Karsten-O. Laux (@Karsten_Laux)

Karsten-Olaf Laux wrote:

I think I’ll use PNG as an image resource format, with resource loading
code in the engine. The driver will typedef or wrap a surface. The
engine will manipulate that typedef or surface as an opaque
pointer/handle. The driver will provide resource->surface conversion
code.

So, engine loads PNG. Engine asks driver to create a DriverSurface from
it. Engine dumps PNG. Engine asks driver to render DriverSurface. etc.

In my eyes PNG is more a image-FILEformat, it does not make sense, to use
it as an image resource, as it even provides weird image formats. (I think
everything form 1bit to 64bits per pixel at all available endian modes
…)

I prefer to use PNG as fileformat and convert the images at loadtime, to my
desired format - which is the pixelformat my game currently runs at -
Doing the conversion at runtime is a bad idea, since it may take a long
time.

For you, what is the difference between loadtime and runtime? I "load"
my files at “runtime”, when the program is running, that is. A file is
one way to contain a resource.

When he says that his engine loads the PNG, creates a DriverSurface from
it and then dumps the PNG, he means just that, loading the file, doing
the conversion, then dropping the PNG and using the pre-converted image
in the native pixel format of the game.

As I see this, you meant exactly the same thing that he said, but I am
wondering whether I missed something? (like for example, do you mean
that “resource” is something like a “WAD file”, and that he should
convert the image before packing it into that “WAD file”?)–
Pierre Phaneuf
Ludus Design, http://ludusdesign.com/

If no one minds me stepping into a thread… Is there anything published on
using pnglib or something similar with SDL? I’d like a little handholding
wiring them together, and it sounds like it’s already working for some of
you. I’m developing dual-platform, NT4 and Linux.

  • Scott>-----Original Message-----

From: owner-sdl at lokigames.com [mailto:owner-sdl at lokigames.com]On Behalf
Of Karsten-Olaf Laux
Sent: Wednesday, January 26, 2000 11:30 AM
To: sdl at lokigames.com
Subject: Re: [SDL] PNG and SDL

on Mon, 24 Jan 2000 Marc A. Lepage wrote:

Nicholas Vining wrote:

How you actually implement your cacheing system is entirely up
to you. (in

other words, the criteria as to whether or not we put what in the
warehouses) Is that basically what you’re talking about?

I think Pierre’s answer was more what I was talking about. :slight_smile:

I think I’ll use PNG as an image resource format, with resource loading
code in the engine. The driver will typedef or wrap a surface. The
engine will manipulate that typedef or surface as an opaque
pointer/handle. The driver will provide resource->surface conversion
code.

So, engine loads PNG. Engine asks driver to create a DriverSurface from
it. Engine dumps PNG. Engine asks driver to render DriverSurface. etc.

Hi,

In my eyes PNG is more a image-FILEformat, it does not make sense,
to use it as
an image resource, as it even provides weird image formats. (I
think everything
form 1bit to 64bits per pixel at all available endian modes …)

I prefer to use PNG as fileformat and convert the images at loadtime, to my
desired format - which is the pixelformat my game currently runs at -
Doing the conversion at runtime is a bad idea, since it may take a
long time.

just my two pence,


Karsten-O. Laux (klaux at rhrk.uni-kl.de)

Scott Russell schrieb am 27 Jan 2000:

If no one minds me stepping into a thread… Is there anything published on
using pnglib or something similar with SDL? I’d like a little handholding
wiring them together, and it sounds like it’s already working for some of
you. I’m developing dual-platform, NT4 and Linux.

I don’t know what’s going on unter NT, but under Linux your program
automatically links with libpng if you link with SDL_image.

Then just use IMG_Load(filename) and you have the Image in a SDL_Surface.