Loading a TGA for a Quake model...
Moderator: InsideQC Admins
23 posts
• Page 1 of 2 • 1, 2
Loading a TGA for a Quake model...
Hello again, I'm using FitzQuake and would like to know if someone can provide me an example on how to do this. I'd like to basically load and apply a TGA texture to a Quake model. I spent some time doing it myself but I'm obviously doing something wrong
Edit:
Okay I took a closer look at it and seem to have sorted it although the textures are horribly misaligned.
Edit:
Just to lay things down for people that don't bother reading other posts, the model is from the Daikatana pre-alpha. Currently I'm literally just slapping the texture onto the model as there seems to be a problem with this line:
For those that want to look into the format itself there's a link here
http://dl.dropbox.com/u/5324043/OpenKatana/dmodel.rar
The header is DKPO, it's version 7 and overall not much different to a Quake model.
Edit:
Okay I took a closer look at it and seem to have sorted it although the textures are horribly misaligned.
Edit:
Just to lay things down for people that don't bother reading other posts, the model is from the Daikatana pre-alpha. Currently I'm literally just slapping the texture onto the model as there seems to be a problem with this line:
// emit s/t coords into the commands stream
s = stverts[k].s;
t = stverts[k].t;
For those that want to look into the format itself there's a link here
http://dl.dropbox.com/u/5324043/OpenKatana/dmodel.rar
The header is DKPO, it's version 7 and overall not much different to a Quake model.
Last edited by hogsy on Fri Aug 12, 2011 12:19 pm, edited 1 time in total.
-

hogsy - Posts: 198
- Joined: Wed Aug 03, 2011 3:44 pm
- Location: UK
baker might have a clue, hees done a load of work on the fitzquake source.
one thing that springs to mind you say you are using tga's ? might be the old bug where tga's get drawn inside out in that case fitz needs to update his code, its been fixed for years.
i doubt fitz function looks anywhere near mine but if it helps to squash the bug heres the tga code with that particular bug fixed.
one thing that springs to mind you say you are using tga's ? might be the old bug where tga's get drawn inside out in that case fitz needs to update his code, its been fixed for years.
i doubt fitz function looks anywhere near mine but if it helps to squash the bug heres the tga code with that particular bug fixed.
- Code: Select all
/*
=============
TARGA LOADING
=============
*/
#define TGA_MAXCOLORS 16384
/* Definitions for image types. */
#define TGA_Null 0 /* no image data */
#define TGA_Map 1 /* Uncompressed, color-mapped images. */
#define TGA_RGB 2 /* Uncompressed, RGB images. */
#define TGA_Mono 3 /* Uncompressed, black and white images. */
#define TGA_RLEMap 9 /* Runlength encoded color-mapped images. */
#define TGA_RLERGB 10 /* Runlength encoded RGB images. */
#define TGA_RLEMono 11 /* Compressed, black and white images. */
#define TGA_CompMap 32 /* Compressed color-mapped data, using Huffman, Delta, and runlength encoding. */
#define TGA_CompMap4 33 /* Compressed color-mapped data, using Huffman, Delta, and runlength encoding. 4-pass quadtree-type process. */
/* Definitions for interleave flag. */
#define TGA_IL_None 0 /* non-interleaved. */
#define TGA_IL_Two 1 /* two-way (even/odd) interleaving */
#define TGA_IL_Four 2 /* four way interleaving */
#define TGA_IL_Reserved 3 /* reserved */
/* Definitions for origin flag */
#define TGA_O_UPPER 0 /* Origin in lower left-hand corner. */
#define TGA_O_LOWER 1 /* Origin in upper left-hand corner. */
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;
int fgetLittleShort (FILE *f)
{
byte b1, b2;
b1 = fgetc(f);
b2 = fgetc(f);
return (short)(b1 + b2*256);
}
int fgetLittleLong (FILE *f)
{
byte b1, b2, b3, b4;
b1 = fgetc(f);
b2 = fgetc(f);
b3 = fgetc(f);
b4 = fgetc(f);
return b1 + (b2<<8) + (b3<<16) + (b4<<24);
}
/*
=============
LoadTGA
=============
*/
byte *LoadTGA (FILE *fin, char *name)
{
int w, h, x, y, realrow, truerow, baserow, i, temp1, temp2, pixel_size, map_idx;
int RLE_count, RLE_flag, size, interleave, origin;
qboolean mapped, rlencoded;
byte *data, *dst, r, g, b, a, j, k, l, *ColorMap;
TargaHeader header;
/* load file */
if (!fin && COM_FOpenFile(name, &fin)) return NULL;
header.id_length = fgetc (fin);
header.colormap_type = fgetc (fin);
header.image_type = fgetc (fin);
header.colormap_index = fgetLittleShort (fin);
header.colormap_length = fgetLittleShort (fin);
header.colormap_size = fgetc (fin);
header.x_origin = fgetLittleShort (fin);
header.y_origin = fgetLittleShort (fin);
header.width = fgetLittleShort (fin);
header.height = fgetLittleShort (fin);
header.pixel_size = fgetc (fin);
header.attributes = fgetc (fin);
if (header.id_length != 0)
fseek (fin, header.id_length, SEEK_CUR);
/* validate TGA type */
switch (header.image_type)
{
case TGA_Map:
case TGA_RGB:
case TGA_Mono:
case TGA_RLEMap:
case TGA_RLERGB:
case TGA_RLEMono:
break;
default:
Con_Printf ("%s : Only type 1 (map), 2 (RGB), 3 (mono), 9 (RLEmap), 10 (RLERGB), 11 (RLEmono) TGA images supported\n", name);
fclose (fin);
return NULL;
break;
}
/* validate color depth */
switch (header.pixel_size)
{
case 8:
case 15:
case 16:
case 24:
case 32:
break;
default:
Con_Printf ("%s : Only 8, 15, 16, 24 or 32 bit images (with colormaps) supported\n", name);
fclose (fin);
return NULL;
break;
}
r = g = b = a = l = 0;
/* if required, read the color map information. */
ColorMap = NULL;
mapped = (header.image_type == TGA_Map || header.image_type == TGA_RLEMap) && header.colormap_type == 1;
if (mapped)
{
/* validate colormap size */
switch (header.colormap_size)
{
case 8:
case 15:
case 16:
case 32:
case 24:
break;
default:
Con_Printf ("%s : Only 8, 15, 16, 24 or 32 bit colormaps supported\n", name);
fclose (fin);
return NULL;
break;
}
temp1 = header.colormap_index;
temp2 = header.colormap_length;
if ((temp1 + temp2 + 1) >= TGA_MAXCOLORS)
{
fclose (fin);
return NULL;
}
ColorMap = malloc (TGA_MAXCOLORS * 4);
map_idx = 0;
for (i = temp1 ; i < temp1 + temp2 ; ++i, map_idx += 4)
{
/* read appropriate number of bytes, break into rgb & put in map. */
switch (header.colormap_size)
{
case 8: /* grey scale, read and triplicate. */
r = g = b = getc (fin);
a = 255;
break;
case 15: /* 5 bits each of red green and blue. */
/* watch byte order. */
j = getc (fin);
k = getc (fin);
l = ((unsigned int) k << 8) + j;
r = (byte) ( ((k & 0x7C) >> 2) << 3 );
g = (byte) ( (((k & 0x03) << 3) + ((j & 0xE0) >> 5)) << 3 );
b = (byte) ( (j & 0x1F) << 3 );
a = 255;
break;
case 16: /* 5 bits each of red green and blue, 1 alpha bit. */
/* watch byte order. */
j = getc (fin);
k = getc (fin);
l = ((unsigned int) k << 8) + j;
r = (byte) ( ((k & 0x7C) >> 2) << 3 );
g = (byte) ( (((k & 0x03) << 3) + ((j & 0xE0) >> 5)) << 3 );
b = (byte) ( (j & 0x1F) << 3 );
a = (k & 0x80) ? 255 : 0;
break;
case 24: /* 8 bits each of blue, green and red. */
b = getc (fin);
g = getc (fin);
r = getc (fin);
a = 255;
l = 0;
break;
case 32: /* 8 bits each of blue, green, red and alpha. */
b = getc (fin);
g = getc (fin);
r = getc (fin);
a = getc (fin);
l = 0;
break;
}
ColorMap[map_idx+0] = r;
ColorMap[map_idx+1] = g;
ColorMap[map_idx+2] = b;
ColorMap[map_idx+3] = a;
}
}
/* check run-length encoding. */
rlencoded = (header.image_type == TGA_RLEMap || header.image_type == TGA_RLERGB || header.image_type == TGA_RLEMono);
RLE_count = RLE_flag = 0;
image_width = w = header.width;
image_height = h = header.height;
size = w * h * 4;
data = calloc (size, 1);
/* read the Targa file body and convert to portable format. */
pixel_size = header.pixel_size;
origin = (header.attributes & 0x20) >> 5;
interleave = (header.attributes & 0xC0) >> 6;
truerow = 0;
baserow = 0;
for (y=0 ; y<h ; y++)
{
realrow = truerow;
if (origin == TGA_O_UPPER)
{
realrow = h - realrow - 1;
}
dst = data + realrow * w * 4;
for (x=0 ; x<w ; x++)
{
/* check if run length encoded. */
if (rlencoded)
{
if (!RLE_count)
{
/* have to restart run. */
i = getc (fin);
RLE_flag = (i & 0x80);
if (!RLE_flag) // stream of unencoded pixels
{
RLE_count = i + 1;
}
else // single pixel replicated
{
RLE_count = i - 127;
}
/* decrement count & get pixel. */
--RLE_count;
}
else
{
/* have already read count & (at least) first pixel. */
--RLE_count;
if (RLE_flag)
{
/* replicated pixels. */
goto PixEncode;
}
}
}
/* read appropriate number of bytes, break into RGB. */
switch (pixel_size)
{
case 8: /* grey scale, read and triplicate. */
r = g = b = l = getc (fin);
a = 255;
break;
case 15: /* 5 bits each of red green and blue. */
/* watch byte order. */
j = getc (fin);
k = getc (fin);
l = ((unsigned int) k << 8) + j;
r = (byte) ( ((k & 0x7C) >> 2) << 3 );
g = (byte) ( (((k & 0x03) << 3) + ((j & 0xE0) >> 5)) << 3 );
b = (byte) ( (j & 0x1F) << 3 );
a = 255;
break;
case 16: /* 5 bits each of red green and blue, 1 alpha bit. */
/* watch byte order. */
j = getc (fin);
k = getc (fin);
l = ((unsigned int) k << 8) + j;
r = (byte) ( ((k & 0x7C) >> 2) << 3 );
g = (byte) ( (((k & 0x03) << 3) + ((j & 0xE0) >> 5)) << 3 );
b = (byte) ( (j & 0x1F) << 3 );
a = (k & 0x80) ? 255 : 0;
break;
case 24: /* 8 bits each of blue, green and red. */
b = getc (fin);
g = getc (fin);
r = getc (fin);
a = 255;
l = 0;
break;
case 32: /* 8 bits each of blue, green, red and alpha. */
b = getc (fin);
g = getc (fin);
r = getc (fin);
a = getc (fin);
l = 0;
break;
default:
fclose (fin);
Con_Printf ("%s : Illegal pixel_size '%d'\n", name, pixel_size);
if (data)
{
free (data);
}
if (mapped)
{
free (ColorMap);
}
return NULL;
break;
}
PixEncode:
if (mapped)
{
map_idx = l * 4;
*dst++ = ColorMap[map_idx+0];
*dst++ = ColorMap[map_idx+1];
*dst++ = ColorMap[map_idx+2];
*dst++ = ColorMap[map_idx+3];
}
else
{
*dst++ = r;
*dst++ = g;
*dst++ = b;
*dst++ = a;
}
}
if (interleave == TGA_IL_Four)
{
truerow += 4;
}
else if (interleave == TGA_IL_Two)
{
truerow += 2;
}
else
{
truerow++;
}
if (truerow >= h)
{
truerow = ++baserow;
}
}
if (mapped)
{
free (ColorMap);
}
fclose (fin);
return data;
}
-

revelator - Posts: 2567
- Joined: Thu Jan 24, 2008 12:04 pm
- Location: inside tha debugger
I've uploaded a copy of the model and a TGA version of its texture here: http://dl.dropbox.com/u/5324043/OpenKatana/dmodel.rar
-

hogsy - Posts: 198
- Joined: Wed Aug 03, 2011 3:44 pm
- Location: UK
Also, fitzquake already fixed the upside-down tga bug.
One guess is, if you're working with a modified fitzquake with this feature added, there may be UV mapping issues due to the way fitzquake deals with non-power-of-two images. The UVs were probably generated with the original 8-bit texture in mind; if the replacement texture isn't the same size as the original (or a power of two multiple of the original size) the modded fitzquake might not be smart enough to fix the UVs for that case.
One guess is, if you're working with a modified fitzquake with this feature added, there may be UV mapping issues due to the way fitzquake deals with non-power-of-two images. The UVs were probably generated with the original 8-bit texture in mind; if the replacement texture isn't the same size as the original (or a power of two multiple of the original size) the modded fitzquake might not be smart enough to fix the UVs for that case.
- metlslime
- Posts: 316
- Joined: Tue Feb 05, 2008 11:03 pm
Sorry, I had assumed you meant TGA support. This is a feature I'm working on implementing myself (which I thought was quite obvious from my first post
). The texture scale for all "dkpo" models is 640x480.
There is no original texture stored in the models as the textures are required to be loaded externally for this model format.
There is no original texture stored in the models as the textures are required to be loaded externally for this model format.
-

hogsy - Posts: 198
- Joined: Wed Aug 03, 2011 3:44 pm
- Location: UK
hmm not sure its gonna work without some modification then since quakes texture manager rescales sizes according to the models builtin texture mip's (which in this case wont work).
would probably need something like a shader i reckon ?.
one place to look could be quake2 it does things a little different than quake since its models also rely on external data.
would probably need something like a shader i reckon ?.
one place to look could be quake2 it does things a little different than quake since its models also rely on external data.
-

revelator - Posts: 2567
- Joined: Thu Jan 24, 2008 12:04 pm
- Location: inside tha debugger
23 posts
• Page 1 of 2 • 1, 2
Who is online
Users browsing this forum: No registered users and 1 guest