Forum

textures2quake: Takes high res textures --> Quake/Half-Li

Discuss anything not covered by any of the other categories.

Moderator: InsideQC Admins

Postby Sajt » Fri Jan 22, 2010 2:37 am

A nearest-neighbour reduction using luminosity weighting (wow... a lot of big words makes that sound more than what it is: extremely simple) produces a much more palatable image:

Image

But I'm sure that that fancier algorithm must be good for something. I wonder what sort of image it would do well on.
F. A. Špork, an enlightened nobleman and a great patron of art, had a stately Baroque spa complex built on the banks of the River Labe.
Sajt
 
Posts: 1215
Joined: Sat Oct 16, 2004 3:39 am

Postby Baker » Fri Jan 22, 2010 2:59 am

Works well enough for my purposes. Most textures that would be used in a Quake map aren't really "millions of colors" type textures.

I used what was available in FreeImage.

Quake palette conversion of Nexuiz:

Image

Maybe fun to work on the fixed palette conversions for future versions :D

/Btw ... I can't tell if you are being sarcastic, but if so I'd like to point out that your palette indexes in your sample are wrong.

Image
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby Sajt » Fri Jan 22, 2010 6:10 am

I'm not really sure what I could have been sarcastic about. I would like to see an example of what sort of situations this special algorithm is designed for.

As for the palette, my program exported a PCX and I used PSP to convert it to a PNG so I could upload it. Paint Shop Pro rearranges the palette (or "optimizes" it?) when it saves a PNG. They still are the same Quake colours, though, just in a different order. (It's not like anyone in their right mind would use PNG for game textures, anyway.)

Looks like PSP has an option to disable that palette "optimization". I'll use that next time...
F. A. Špork, an enlightened nobleman and a great patron of art, had a stately Baroque spa complex built on the banks of the River Labe.
Sajt
 
Posts: 1215
Joined: Sat Oct 16, 2004 3:39 am

Postby Baker » Fri Jan 22, 2010 1:38 pm

Sajt wrote:I'm not really sure what I could have been sarcastic about. I would like to see an example of what sort of situations this special algorithm is designed for.


Could be a speed thing ...

My general research activities are in visual/multimedia computing and communications. I have published numerous algorithms for computer graphics and image processing (image coding in particular), some of which are being used by practitioners, such as a fast optimal color quantizer, and a Context-based Adaptive Lossless Image Codec (CALIC) which was developed jointly with Nasir Memon as a candidate algorithm for the new JPEG lossless standard.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby Teiman » Fri Jan 22, 2010 1:52 pm

Sajt wrote:... (It's not like anyone in their right mind would use PNG for game textures, anyway.)...


Oooops... hehehe.
Teiman
 
Posts: 309
Joined: Sun Jun 03, 2007 9:39 am

Postby Baker » Fri Jan 22, 2010 1:59 pm

Teiman wrote:
Sajt wrote:... (It's not like anyone in their right mind would use PNG for game textures, anyway.)...


Oooops... hehehe.


It is a shame that TGA can't be used on the internet like PNG can. It is also a shame that TGA cannot easily be browsed with the thumbnail view in Windows.

Back when I was a fan of PNG textures in the past, that was what I liked about them: make them once, display them anywhere.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby c0burn » Fri Jan 22, 2010 2:30 pm

I use FastStone MaxView as my image viewer, and when installed the shell extension shows TGA thumbnails, which is nice.
c0burn
 
Posts: 208
Joined: Fri Nov 05, 2004 12:48 pm
Location: Liverpool, England

Postby Teiman » Fri Jan 22, 2010 4:21 pm

I was trying to avoid it, but here goes:

Why? Why is a bad idea to use PNG?

Is not like JPG, it don't destroy the quality of the image. and it supports a alpha channel, two styles (1 bit alfa and 8 bits alfa )...

Why is not that good? do it randomize the palette in 8 bits mode or something?
Teiman
 
Posts: 309
Joined: Sun Jun 03, 2007 9:39 am

Postby Spike » Fri Jan 22, 2010 4:58 pm

Tei:
png and zip use the same compression algorithm, but applied differently.
In png, its applied on a per-plane basis. In zip+tga its applied over the entire byte stream.
Compressing a tga in a zip means that you compress each pixel individually while png compresses each pixel 3/4 times. Repeating patterns and windows and stuff mean that tga has a smaller chance for repetition, but when there is some, there are a third less references in the window.

Basically the outcome is that you can block-decompress+decode a tga faster than you can decode+combine the multiple planes of a png.
And its a bit smaller too.

.rar+.tga or .tar.gz+.tga gives solid archives, which allows the reuse of compression windows over multiple similar files.

If the engine supports zips/pk3s, use tgas.
If the engine doesn't support zips/pk3s, you get even better compression from tgas inside a pak anyway, and the extra size weighed against the lack of compression doesn't hinder load times, but it does mean faster download speeds. However it does use more disk space. Disk space is rarely a concern nowadays.

pngs are nice and all... but... mneh.
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Postby Baker » Fri Jan 22, 2010 6:03 pm

Teiman wrote:I was trying to avoid it, but here goes:

Why? Why is a bad idea to use PNG?


Another reason: TGA loading in the engine can just use the engine code. If you have some non-traditional platform, supporting TGA loading is as easy as any other platform. You don't need .dll files to load a TGA.

Case in point, FitzQuake and Enhanced GL/WinQuake support external TGA textures but need no external dlls.

Code: Select all
/*
=========================================================

TARGA LOADING

=========================================================
*/

#pragma pack(1)
typedef struct _TargaHeader {
   unsigned char    id_length, colormap_type, image_type;
   unsigned short   colormap_index, colormap_length;
   unsigned char   colormap_size;
   unsigned short   x_origin, y_origin, width, height;
   unsigned char   pixel_size, attributes;
} TargaHeader;
#pragma pack()

/*
=============
LoadTGA
=============
*/
static byte *LoadTGA (char *name, int *width, int *height, qboolean alphablend)
{
   TargaHeader *targa_header;
   FILE       *f;
   int       columns, rows, numPixels;
   byte       *pixbuf, *buf;
   byte       *targa_rgba;
   int       row, realrow, column;
   qboolean    upside_down, alpha, blend;
   char       filename[MAX_OSPATH];

   sprintf (filename, "%s.tga", name);
   COM_FOpenFile (filename, &f);

   if (!f)
      return NULL;

   if (com_filesize < sizeof(TargaHeader))
      Sys_Error ("LoadTGA: can't read header in %s", filename);

   targa_header = malloc (com_filesize);

   if (!targa_header)
      Sys_Error ("LoadTGA1: error allocating %d bytes for %s", com_filesize, filename);

   if (fread (targa_header, 1, com_filesize, f) != com_filesize)
      Sys_Error ("LoadTGA: error reading %s", filename);

   fclose (f);

   targa_header->width = SwapShort (&targa_header->width);
   targa_header->height = SwapShort (&targa_header->height);

   if (targa_header->image_type!=2
      && targa_header->image_type!=10)
      Sys_Error ("LoadTGA: %s: only type 2 and 10 targa RGB images supported, not %d", filename, targa_header->image_type);

   if (targa_header->colormap_type !=0
      || (targa_header->pixel_size!=32 && targa_header->pixel_size!=24))
      Sys_Error ("LoadTGA: %s: only 24 and 32 bit images supported (no colormaps, type=%d, bpp=%d)", filename, targa_header->colormap_type, targa_header->pixel_size);

   columns = targa_header->width;
   rows = targa_header->height;
   numPixels = columns * rows;
   upside_down = !(targa_header->attributes & 0x20); // true => picture is stored bottom to top

   targa_rgba = malloc (numPixels*4);

   if (!targa_rgba)
      Sys_Error ("LoadTGA2: error allocating %d bytes for %s", numPixels*4, filename);

   blend = alphablend && gl_alphablend.value;
   alpha = targa_header->pixel_size == 32;

   buf = (byte *)(targa_header + 1);

   if (targa_header->id_length != 0)
      buf += targa_header->id_length; // skip TARGA image comment

   if (targa_header->image_type==2) {  // Uncompressed, RGB images
      for(row=rows-1; row>=0; row--) {
         realrow = upside_down ? row : rows - 1 - row;
         pixbuf = targa_rgba + realrow*columns*4;

         ChkBounds ("LoadTGA1", buf - (byte *)targa_header + columns * targa_header->pixel_size / 8, com_filesize, filename);
         ChkBounds ("LoadTGA2", pixbuf - targa_rgba + columns * 4, numPixels * 4, filename);

         for(column=0; column<columns; column++) {
            unsigned char red,green,blue,alphabyte;
            blue = *buf++;
            green = *buf++;
            red = *buf++;
            *pixbuf++ = red;
            *pixbuf++ = green;
            *pixbuf++ = blue;
            *pixbuf++ = alpha ? *buf++ : (blend ? (red + green + blue) / 3 : 255); // Better way?;
         }
      }
   }
   else if (targa_header->image_type==10) {   // Runlength encoded RGB images
      unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
      for(row=rows-1; row>=0; row--) {
         realrow = upside_down ? row : rows - 1 - row;
         pixbuf = targa_rgba + realrow*columns*4;
         for(column=0; column<columns; ) {
            packetHeader = *buf++;
            packetSize = 1 + (packetHeader & 0x7f);

            ChkBounds ("LoadTGA3", pixbuf - targa_rgba + packetSize * 4, numPixels * 4, filename);

            if (packetHeader & 0x80) {        // run-length packet
               ChkBounds ("LoadTGA4", buf - (byte *)targa_header + targa_header->pixel_size / 8, com_filesize, filename);
               blue = *buf++;
               green = *buf++;
               red = *buf++;
               alphabyte = alpha ? *buf++ : (blend ? (red + green + blue) / 3 : 255); // Better way?;

               for(j=0;j<packetSize;j++) {
                  *pixbuf++ = red;
                  *pixbuf++ = green;
                  *pixbuf++ = blue;
                  *pixbuf++ = alphabyte;
                  column++;
                  if (column==columns) { // run spans across rows
                     column=0;
                     if (row>0)
                        row--;
                     else
                        goto breakOut;
                     realrow = upside_down ? row : rows - 1 - row;
                     pixbuf = targa_rgba + realrow*columns*4;
                  }
               }
            }
            else {                            // non run-length packet
               ChkBounds ("LoadTGA5", buf - (byte *)targa_header + packetSize * targa_header->pixel_size / 8, com_filesize, filename);
               for(j=0;j<packetSize;j++) {
                  blue = *buf++;
                  green = *buf++;
                  red = *buf++;
                  *pixbuf++ = red;
                  *pixbuf++ = green;
                  *pixbuf++ = blue;
                  *pixbuf++ = alpha ? *buf++ : (blend ? (red + green + blue) / 3 : 255); // Better way?;
                  column++;
                  if (column==columns) { // pixel packet run spans across rows
                     column=0;
                     if (row>0)
                        row--;
                     else
                        goto breakOut;
                     realrow = upside_down ? row : rows - 1 - row;
                     pixbuf = targa_rgba + realrow*columns*4;
                  }
               }
            }
         }
         breakOut:;
      }
   }

   *width = targa_header->width;
   *height = targa_header->height;

   free (targa_header);

   return targa_rgba;
}
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby Sajt » Fri Jan 22, 2010 7:55 pm

Also, the LibPNG loader is notoriously slow.

Of course, much better than either PNG or zipped TGA is the mysterious "dmip" format... but that's another story.
F. A. Špork, an enlightened nobleman and a great patron of art, had a stately Baroque spa complex built on the banks of the River Labe.
Sajt
 
Posts: 1215
Joined: Sat Oct 16, 2004 3:39 am

Postby Teiman » Fri Jan 22, 2010 9:59 pm

Uh.. ok, thanks guys ( Sajt, Baker, Spike).

Now.. I remember the libpng library as a memory-hungry and unstable one.

The tga in a zip thing is very interesting.
Teiman
 
Posts: 309
Joined: Sun Jun 03, 2007 9:39 am

Postby ceriux » Sat Jan 23, 2010 7:01 am

made a news post about it on my moddb group

http://www.moddb.com/groups/quakedb/new ... rsion-tool
User avatar
ceriux
 
Posts: 2223
Joined: Sat Sep 06, 2008 3:30 pm
Location: Indiana, USA

Postby negke » Sun Jan 24, 2010 2:21 pm

Good job.
Especially the 50% reduction will make batch conversion much more convenient in many cases.
negke
 
Posts: 150
Joined: Wed Apr 16, 2008 5:53 pm

Postby Baker » Wed Feb 17, 2010 6:11 pm

Some things that this could do better ...

Take the #water #lava textures and for the Quake portion of the process, turn them into *water and *lava, etc.

Apparently a 16 pixels is the minimum Quake texture dimension, not 8. Reference: http://www.celephais.net/stuff/texturefaq.htm

And apparently liquids and clip should be 64x64 for software renderers.

And sky textures 256x128. Although since Quake 3 and no other game uses Quake sky textures, such a conversion enforcement is a little "unneeded".
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

PreviousNext

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 2 guests