BZ2 Texture Converter Readme.txt
Nathan Mates
Last Updated 2009/04/17


   NOTE: this is for BZ2 modders only. The generated texture
files, .dxtbz2 files, require 1.3pb3 or later.

   NOTE: If you get an error that says roughly 'the application
parameter is incorrect' on double-clicking the DXTGen.exe, then you
MUST install 'vcredist_x86.exe', which can be downloaded from
http://www.microsoft.com/downloads/details.aspx?familyid=A5C84275-3B97-4AB7-A40D-3802B2AF5FC2&displaylang=en
[Note: this is a different version than the vcredist_x86.exe used by
v1-15 of BX2DXTGen and/or BZ2 1.3pb4/pb4a - the older versions used
the VS2005SP1 version. . The 2008SP1 version of vcredist is now
needed.  Simply run the downloaded vcredist_x86.exe to install the
system DLLs used by this. 1.3TechAlpha5 (when released) will
auto-install these DLLs for you.


   This is an offline processing tool that allows you to convert
various texture files usable by BZ2 into a a more efficient format.
Textures are compressed via the 'DXT' texture compression algorithms,
which is a much more efficient file format, storing data in a format
easily readable by modern graphics cards, and all of the mipmaps for
that picture are generated up front for both speed and quality.

   DXT compression is a slightly lossy process. Thus, modders will
want to keep their original files (.tga, .pic, .png, .bmp, .jpg/.jpeg,
.tif/.tiff, or .gif) around, and convert to .dxtbz2 as a last
step. Mods can then omit the original files, which will usually
provide some good size savings.  Also, by use of a cfg file, modders
can tune how their textures are compressed/mipped/etc.

   Included with this distribution is the cfg file used to compress
BZ2's textures. This should provide a good starting point to work with
the process. Everything is run by the program DXTGen.exe. You can
double-click on the exe, and start playing with the GUI. Most of the
options ought to be self-explanatory. Or, you can also run it from the
commandline, which takes the following commandline arguments:

DXTGen.exe InputDirectory Tuning.cfg OutputDirectory

   Note that the input and output must be directories. Reading/writing
.pak files is NOT supported. But, all modders know how to deal with
those files, right? You can also use the ConvertStockAssets.bat, which
shows how to this app, assuming that you've got your directory
structure set up like I do.

   This exe looks for texture files with the following extensions, and
tries to convert them, unless overridden in BZ2DXTOptions.cfg (see below)

.bmp 
.dds
.gif (single frame only; animated GIFs should only convert first frame)
.jpe
.jpg
.jp2 (i.e. jpeg 2000)
.pic
.png
.tga
.tif
.jpeg
.tiff

   Modders should look at the BZ2DXTOptions.cfg included in the same
directory as this README to get an idea of what options are available
for the tuning cfg. There are three types of textures that need
special attention:

1) 640x480 shell backdrops. Anything matching this size will now be
autoconverted to 1024x1024, with 3 mips total (e.g. also 512x512 and
256x256). 1.3TechAlpha5 doesn't support 640x480 textures anymore, and
needs square power-of-two textures.

2) Textures that are to be drawn as 2D icons onscreen (search for
"cmnd_attack" for a sample). These shold have "NumMips = 1" in their
section. This prevents DXTGen from generating unused mips for that
texture. However, (see more below), those icons should have a texture
size as close to 1:1 with their onscreen size. You can either tweak
texture sizes in something like Photoshop/Paint Shop Pro/etc, or use
DXTGen's PreScaleX/Y to scale them.

3) Textures referenced in a draw_planar odf chunk (search for "ring"
for a sample). These should have "PlanarAlphaBorder = 2" in their
chunk, otherwise garbage will tend to appear onscreen when certain ATI
cards/drivers are used. This change shouldn't make any noticeable
difference to the texture on any card.


----

   A bit more on the # mipmaps issue, from a forum post I made:

   As to settings on # mips, anything that's supposed to be 2D, such
as the wireframes and icons, should have #mips = 1. That prevents the
graphics card from using a lower resolution if it's shown at a size
smaller than 1 pixel :: 1 texel (i.e. much fewer pixels onscreen than
are in the texture). However, you should still try and match up the
pixel::texel ratio to be as close as possible to 1::1.

   As an extreme example, take a wireframe icon for a unit, that's
being displayed as 32x32 pixels. If the source .tga for that is
256x256, DirectX's initial inclination is to try and find a 32x32 mip
of that .tga, and use that instead. It's certainly a LOT more
efficient for the graphics card to read a 32x32 to display into a
32x32 region, versus reading 256x256 (memory hit) and shrink it down
to 32x32 (speed hit). It's far better for the modder to create a 32x32
texture and work from there. However, if you must override DirectX's
auto-mip-selections, setting #mips to 1 will prevent it from picking a
smaller mip.

   For 3D textures, it's usually to leave #mips at the default,
32. That will generate mips of the texture down to 4x4, and leave it
up to the graphics card to figure out which mip should be used to get
a 1::1 pixel::texel range. [The vid.render.mipbias introduced recently
gives a hint as to which mips should be used.]

   However, you shouldn't try and shove HUGE textures into a small
space. For example, I believe that's what's happening in [forum post
link deleted, referring to blurry textures on a unit's preview model
in the pregame MP "choose vehicle" dialog]. If you try and shove a
256x256 or 512x512 texture into a small space in the pregame UI, such
as for a unit's preview model in MP, it will tend to pick a smaller
mip. First off, the new offline converter should help shrink things
without getting as chunky. However, it'll make a LOT of sense to try
and get everything lined up so that your textures (use a different XSI
if needed in mpvehicles.txt) are as close to 1:1 with their displayed
size. That'll prevent graphics cards from picking a shrunk one to try
and counteract the modder's mistakes.

   Also, the #mipmaps setting in GamePrefs.ini is ignored with DXT
textures. This is because it's figured that the modder did the right
thing when they converted it -- they can review the results and
reconvert if they don't like things.

----

   Technical notes: this exe is statically linked against the nVidia
DXT compression libraries from DDS_Utilities_8.31.0225.1745.exe from
http://developer.nvidia.com/page/tools.html . The UI is done with WTL
8.0, from
http://www.microsoft.com/downloads/details.aspx?familyid=E5BA5BA4-6E6B-462A-B24C-61115E846F0C&displaylang=en
, available under Microsoft Permissive License. It is also dynamically
linked (via DLLs) against the following libraries:


- Independent JPEG Group's JPEG source version 6b, from http://www.ijg.org/
- JasPer version 1.900.1, from http://www.ece.uvic.ca/~mdadams/jasper/
  (Note: this lib is statically linked into the OpenIL DLL, as the JasPer
  libs are not set up to be built as a separate DLL.)
- libpng version 1.2.35 from http://www.libpng.org/
- libtiff 3.8.2 from http://www.libtiff.org/
- libmng 1.0.10 from http://gjuyn.xs4all.nl/libmng/
- Little CMS library, v1.18 from http://www.littlecms.com/
- OpenIL v1.7.8, from http://openil.sourceforge.net/ , which uses
  all of the above libraries. (Some .vcproj modifications to default
  install were made to compile under VS.NET 2008, and aggressively
  optimize; copy of changed files is included in a .7z file
- PCRE 7.9, from http://www.pcre.org/ , is used for pattern matching.
- zlib v1.2.3, from http://www.gzip.org/zlib/


   OpenIL provided Microsoft Visual Studio project (.vcproj) and
solution (.sln) files for itself and the other DLLs. I've changed them
slightly, in order to have a much more consistent build directory,
more security, and stronger optimizations. In my possibly
overaggressive reading of the OpenIL license, I need to distribute my
changes. Those changed files (and only those files) are included in a
.7z file in this distribution.

   For really advanced modders, the file format of a .dxtbz2 file looks
like this. It starts with this header:

struct DXTBZ2Header
{
	int m_Sig; // = = 'GSH!';
	int m_DXTLevel; // 1..5

	// "Representative" color, used by terrain. This is essentially
	// the color the bitmap would be if mipped down to 1x1.
	unsigned char m_1x1Red;
	unsigned char m_1x1Green;
	unsigned char m_1x1Blue;
	unsigned char m_1x1Alpha; // not used initially, set to 255

	int m_NumMips; // 1..n
	int m_BaseHeight; // of first mip
	int m_BaseWidth; // of first mip
};

   That is followed by a number of chunks

struct DXTBZ2Chunk
{
    int m_ChunkSize;
    unsigned char m_Data[m_ChunkSize]; // Variable-sized, see above for true size
};

   In the above, assume that int is 32 bits, and unsigned char is 8 bits.