egg-palettize simply won't do what I want it to do..

Hi,

I hit some problems with egg-palettize that I can’t figure out myself.
Basically, this is what I want to achieve:

I have a number of gui elements, which are textures that I turned into texture-cards. Most, if not all, of these textures have a non-power-of-two size and are pretty small, e.g. 11x11 pixels, 1x11 pixels, 11x1 pixels, etc. the biggest element so far is 47x47 pixels. (Hmm, the artist seems to like prime numbers… :wink:
Furthermore, all elements are .png files and all should have an alpha-channel. But to be sure I force-rgba them in the textures.txa to make it possible to place all textures into a single texture

So basically I thought I’d use egg-palettize to group them all together into a single texture.

Here’s my textures.txa:

:palette 512 512
:group misc dir textures
:imagetype .png
:shadowtype .png

Slot.egg : misc
WindowBagFrame.egg : misc
Window/FillBot.egg : misc
Window/FillLeftBot.egg : misc
Window/FillRightBot.egg : misc
Window/FillTop.egg : misc
Window/FillLeftTop.egg : misc
Window/FillRightTop.egg : misc
Window/FillLeft.egg : misc
Window/FillRight.egg : misc
Window/FillMid.egg : misc
Window/FrameBot.egg : misc
Window/FrameLeftBot.egg : misc
Window/FrameRightBot.egg : misc
Window/FrameTop.egg : misc
Window/FrameLeftTop.egg : misc
Window/FrameRightTop.egg : misc
Window/FrameLeft.egg : misc
Window/FrameRight.egg : misc

*.png : 100%
*.png : nearest
*.png : force-rgba

I then call egg-palettize as follows:

egg-palettize -inplace -opt Slot.egg WindowBagFrame.egg Window/FillBot.egg Window/FillLeftBot.egg Window/FillRightBot.egg Window/FillTop.egg Window/FillLeftTop.egg Window/FillRightTop.egg Window/FillLeft.egg Window/FillRight.egg Window/FillMid.egg Window/FrameBot.egg Window/FrameLeftBot.egg Window/FrameRightBot.egg Window/FrameTop.egg Window/FrameLeftTop.egg Window/FrameRightTop.egg Window/FrameLeft.egg Window/FrameRight.egg

and egg-palettize gives the following output:

textures.boo does not exist; starting palettization from scratch.
Reading Window/FillBot.png
Reading Window/FillLeft.png
Reading Window/FillLeftBot.png
Reading Window/FillLeftTop.png
Reading Window/FillMid.png
Reading Window/FillRight.png
Reading Window/FillRightBot.png
Reading Window/FillRightTop.png
Reading Window/FillTop.png
Reading Window/FrameBot.png
Reading Window/FrameLeft.png
Reading Window/FrameLeftBot.png
Reading Window/FrameLeftTop.png
Reading Window/FrameRight.png
Reading Window/FrameRightBot.png
Reading Window/FrameRightTop.png
Reading Window/FrameTop.png
Reading Slot.png
Reading WindowBagFrame.png
Resizing textures_palette_2tllc_1.png to 64 64
Generating new textures_palette_2tllc_1.png
Reading Window/FillLeftBot.png
Reading Window/FillLeftTop.png
Reading Window/FillRightBot.png
Reading Window/FillRightTop.png
Reading Window/FrameLeftBot.png
Reading Window/FrameLeftTop.png
Reading Window/FrameRightBot.png
Reading Window/FrameRightTop.png
Reading Window/FillBot.png
Reading Window/FrameTop.png
Reading Window/FillTop.png
Reading Window/FrameBot.png
Reading Window/FillLeft.png
Reading Window/FillRight.png
Reading Window/FrameLeft.png
Reading Window/FrameRight.png
Writing textures_palette_2tllc_1.png
Writing shadow/textures_palette_2tllc_1.png
Reading Window/FillMid.png
Writing FillMid.png
Reading Slot.png
Writing textures/Slot.png
Reading WindowBagFrame.png
Writing textures/WindowBagFrame.png
Writing Window/FillBot.egg
Writing Window/FillLeft.egg
Writing Window/FillLeftBot.egg
Writing Window/FillLeftTop.egg
Writing Window/FillMid.egg
Writing Window/FillRight.egg
Writing Window/FillRightBot.egg
Writing Window/FillRightTop.egg
Writing Window/FillTop.egg
Writing Window/FrameBot.egg
Writing Window/FrameLeft.egg
Writing Window/FrameLeftBot.egg
Writing Window/FrameLeftTop.egg
Writing Window/FrameRight.egg
Writing Window/FrameRightBot.egg
Writing Window/FrameRightTop.egg
Writing Window/FrameTop.egg
Writing Slot.egg
Writing WindowBagFrame.egg

So basically what happens is:

  1. I get one combined image (textures_palette_2tllc_1.png)
  2. Two textures are written to the textures folder: textures/WindowBagFrame.png and Writing textures/Slot.png
  3. All .egg files are modified to reference the new textures.

So now for my problems and oddities:

a) I do not understand why slot.png and WindowBagFrame.png are not combined with the other textures. That’s what I ultimately want to achieve.
WindowBagFrame.png is 47x47 pixels and thus the version in the install dir is 32x32. Similar for slot.png. It gets resized from 44x44 to 32x32.
But as I said, I’d like to have these textures (without resizing) in the palette image. That was one of the reasons why I want to used egg-palettize in the first place: to be able to combine non-power-of-two textures in a single power of two texture…

b) All the Window*.png graphics are combined in a single image but in a somewhat interesting way: the original images are 11x11 or 11x1 pixels in size and these get padded to 15x15 (!) images in the combined texture.
I’m wondering why egg-palettize wouldn’t simply pad my 47x47 images to 64x64…

c) In the modified .egg files I end up with absolute paths, e.g.:

<CoordinateSystem> { Y-Up }

<Comment> {
  "egg-palettize -inplace -opt Slot.egg WindowBagFrame.egg Window/FillBot.egg Window/FillLeftBot.egg Window/FillRightBot.egg Window/FillTop.egg Window/FillLeftTop.egg Window/FillRightTop.egg Window/FillLeft.egg Window/FillRight.egg Window/FillMid.egg Window/FrameBot.egg Window/FrameLeftBot.egg Window/FrameRightBot.egg Window/FrameTop.egg Window/FrameLeftTop.egg Window/FrameRightTop.egg Window/FrameLeft.egg Window/FrameRight.egg"
}
<Comment> {
  "egg-texture-cards -g 0,1,1,0 -w clamp -p 1,1 -o data/textures/gui/WindowBagFrame.egg data/textures/gui/WindowBagFrame.png"
}
<Texture> WindowBagFrame {
  "/e/TeamVienna/landc/Development/trunk/data/textures/gui/textures/WindowBagFrame.png"
  <Scalar> format { rgba }
  <Scalar> wrap { clamp }
  <Scalar> minfilter { linear }
  <Scalar> magfilter { linear }
  <Scalar> anisotropic-degree { 0 }
  <Scalar> alpha { dual }
}
<Group> {
  <VertexPool> vpool {
    <Vertex> 0 {
      0 0 0
      <UV> { 0 1 }
    }
    <Vertex> 1 {
      0 47 0
      <UV> { 0 0 }
    }
    <Vertex> 2 {
      47 47 0
      <UV> { 1 0 }
    }
    <Vertex> 3 {
      47 0 0
      <UV> { 1 1 }
    }
  }
  <Group> WindowBagFrame {
    <Polygon> {
      <RGBA> { 1 1 1 1 }
      <TRef> { WindowBagFrame }
      <VertexRef> { 0 1 2 3 <Ref> { vpool } }
    }
  }
}

How can I tell egg-palettize to use relative paths…?

Thanks in advance,

Erik

I’m glad to see someone making excellent use of egg-palettize! Lots of good questions, too.

First, let me point out a detail. You should do:

*.png : 100% nearest force-rgba

Instead of:

*.png : 100%
*.png : nearest
*.png : force-rgba

Since only the first matching *.png line applies to a given texture (unless you also use the keyword “cont”).

It is possible that your two textures were omitted because they don’t match the format of the other images, e.g. they don’t have alpha (and the force-rgba wasn’t being seen), or it is possible they were omitted because they don’t fit within the palette. They may also have been omitted because egg-palettize thinks they are repeating textures. It’s possible to ask egg-palettize these questions, though: just do:

egg-palettize -pi

And examine the resulting output; it will read the textures.boo file and tell you all kinds of details about what it thinks it is doing.

I see from the filename convention (textures_palette_2tllc_1.png) that most of your textures are grayscale-alpha. The “2” means you have 2 channels, “t” also means two-channel, “l” and “l” indicate linear minfilter and magfilter, and “c” means it is a combined color and alpha image (as opposed to separate color and alpha images).

Textures that don’t end up within the palette are rounded down to a power of two, which is why these two textures were rounded down (though you can change this behavior). Textures that do end up within the palette don’t have to be made a power of two, but they do get a margin around them. The default margin is two pixels on each side, which is why your 11x11 pixel images became 15x15. The 11x1 should have become 15x5, though, not 15x15.

The reason that textures are given a margin within the palette is to minimize bleedover from neighboring images when the texture is reduced and neighboring pixels are sampled. Since you (presumably) plan to render these with minfilter = nearest, though, you don’t really need the margin, so you can turn it off with:

:margin 0

in your textures.txa.

You can use the -dr parameter to egg-palettize to make the generated texture filenames relative.

David

Hi David,

Thanks for your excellent comments, I now have everything working, but I still found something that feels like a bug to me:

I have this 47x47 texture that egg-palettize really wanted to resize. Even when it placed the image into the palette, it still shrunk it slightly.
I have a hunch that it tried to keep the image plus the border inside the original dimensions of 47x47.
When I removed the border spec as you suggested, no resizing at all happened. But this behaviour stll feels fishy to me.

And eventually, I’d like to be able to specify a border as well, because if someone insists on playing the game at a lower res than the target resolution, I’d like to enable filtering (& mipmapping?) for the gui textures again.
If you want to investigate this some more I could provide you with my sourcedata… just let me know

Anyway for the record and maybe the benefit of others here’s my combination of texture.txa and command line that did the trick for me:

textures.txa:

:palette 512 512
:group misc dir data/textures/gui/textures
:imagetype .png
:shadowtype .png
:powertwo 0
:margin 0

data/textures/gui/Slot.egg : misc
data/textures/gui/WindowBagFrame.egg : misc
data/textures/gui/Window/FillBot.egg : misc
data/textures/gui/Window/FillLeftBot.egg : misc
data/textures/gui/Window/FillRightBot.egg : misc
data/textures/gui/Window/FillTop.egg : misc
data/textures/gui/Window/FillLeftTop.egg : misc
data/textures/gui/Window/FillRightTop.egg : misc
data/textures/gui/Window/FillLeft.egg : misc
data/textures/gui/Window/FillRight.egg : misc
data/textures/gui/Window/FillMid.egg : misc
data/textures/gui/Window/FrameBot.egg : misc
data/textures/gui/Window/FrameLeftBot.egg : misc
data/textures/gui/Window/FrameRightBot.egg : misc
data/textures/gui/Window/FrameTop.egg : misc
data/textures/gui/Window/FrameLeftTop.egg : misc
data/textures/gui/Window/FrameRightTop.egg : misc
data/textures/gui/Window/FrameLeft.egg : misc
data/textures/gui/Window/FrameRight.egg : misc

*.png : 100% nearest force-rgba blend

And the commandline:

egg-palettize -inplace -opt -dr . -dm data/textures/gui/textures/ -ds data/textures/gui/shadow/ data/textures/gui/Slot.egg data/textures/gui/WindowBagFrame.egg [...many more files...]data/textures/gui/Window/FrameRight.egg

Cheers,

Erik

Actually, this is part of the designed behavior of egg-palettize. If the texture image is small–no more than 10x the margin size–it will create exterior margins: it inflates the total number of pixels by the margin size in all directions. If the texture image is larger than this, it instead creates interior margins: it scales the image smaller to make room for the margins within the original image size.

The reason it creates interior margins is to help packing. The reasoning is that texture images are likely to be painted in standard sizes, and it is likely that different texture images will be integer multiples of some common factor in size. It’s also quite common that textures are painted in power-of-two sizes.

These sizes are ideal for optimal packing within the palette. They’re likely to fit snug up within the size of the palette image with very little waste. However, if you start packing images of lots of different random sizes, you might end up with larger parts of your palette image unused.

Of course, in your case this reasoning doesn’t apply, since you appear to be creating nonstandard texture images anyway. So you might as well have exterior margins. Furthermore, you’re concerned about maintaining strict pixel accuracy, so you don’t want to have any inadvertent scaling.

There’s not presently an option to disable this “feature” right now, but I’ll put one in for the future.

David