Allow arbitrary power of 2 sizes for tga texture loads, reduce memory footprint needed to load rgb tgas. Speed load of non-RLE tgas.

Some slight code sanity improvements.
This commit is contained in:
Ragnvald Maartmann-Moe IV 2001-12-21 01:41:19 +00:00
parent aaf9b953a4
commit 010ca032a5
4 changed files with 78 additions and 40 deletions

View file

@ -34,10 +34,15 @@
// could not use texture_t as that is used for models. // could not use texture_t as that is used for models.
typedef struct tex_s { typedef struct tex_s {
int width; int width;
int height; int height;
unsigned char *palette; // 0 = 32 bit, otherise 8 int format;
unsigned char data[4]; // variable length unsigned char *palette; // 0 = 32 bit, otherwise 8
unsigned char data[4]; // variable length
} tex_t; } tex_t;
#define tex_palette 0;
#define tex_rgb 3;
#define tex_rgba 4;
#endif // __texture_h #endif // __texture_h

View file

@ -69,7 +69,7 @@ typedef struct _TargaHeader {
# endif # endif
#endif #endif
byte *LoadTGA (VFile *fin); struct tex_s *LoadTGA (VFile *fin);
void WriteTGAfile (const char *tganame, byte *data, int width, int height); void WriteTGAfile (const char *tganame, byte *data, int width, int height);
#endif // __tga_h #endif // __tga_h

View file

@ -41,9 +41,12 @@ static const char rcsid[] =
#include "QF/qendian.h" #include "QF/qendian.h"
#include "QF/sys.h" #include "QF/sys.h"
#include "QF/texture.h"
#include "QF/tga.h" #include "QF/tga.h"
#include "QF/vfs.h" #include "QF/vfs.h"
#include "compat.h"
static int static int
fgetLittleShort (VFile *f) fgetLittleShort (VFile *f)
@ -71,15 +74,15 @@ fgetLittleLong (VFile *f)
} }
*/ */
byte * struct tex_s *
LoadTGA (VFile *fin) LoadTGA (VFile *fin)
{ {
byte *pixbuf; byte *pixbuf;
unsigned char red = 0, green = 0, blue = 0, alphabyte = 0; byte red = 0, green = 0, blue = 0, alphabyte = 0;
int column, row, columns, rows, numPixels; int column, row, columns, rows, numPixels;
TargaHeader targa_header; TargaHeader targa_header;
byte *targa_rgba; tex_t *targa_data;
targa_header.id_length = Qgetc (fin); targa_header.id_length = Qgetc (fin);
targa_header.colormap_type = Qgetc (fin); targa_header.colormap_type = Qgetc (fin);
@ -107,30 +110,53 @@ LoadTGA (VFile *fin)
rows = targa_header.height; rows = targa_header.height;
numPixels = columns * rows; numPixels = columns * rows;
targa_rgba = malloc (numPixels * 4); switch (targa_header.pixel_size) {
if (!targa_rgba) case 24:
Sys_Error ("LoadTGA: Memory Allocation Failure\n"); targa_data = malloc
(field_offset (tex_t, data[numPixels * 3]));
if (!targa_data)
Sys_Error ("LoadTGA: Memory Allocation Failure\n");
targa_data->format = tex_rgb;
break;
default:
case 32:
targa_data = malloc
(field_offset (tex_t, data[numPixels * 4]));
if (!targa_data)
Sys_Error ("LoadTGA: Memory Allocation Failure\n");
targa_data->format = tex_rgba;
break;
}
targa_data->width = columns;
targa_data->height = rows;
targa_data->palette = 0;
if (targa_header.id_length != 0) if (targa_header.id_length != 0)
Qseek (fin, targa_header.id_length, SEEK_CUR); // skip TARGA image Qseek (fin, targa_header.id_length, SEEK_CUR); // skip TARGA image
// comment // comment
if (targa_header.image_type == 2) { // Uncompressed, RGB images if (targa_header.image_type == 2) { // Uncompressed image
for (row = rows - 1; row >= 0; row--) { switch (targa_header.pixel_size) {
pixbuf = targa_rgba + row * columns * 4; case 24:
for (column = 0; column < columns; column++) { for (row = rows - 1; row >= 0; row--) {
switch (targa_header.pixel_size) { pixbuf = targa_data->data + row * columns *
case 24: targa_data->format;
for (column = 0; column < columns; column++) {
blue = Qgetc (fin); blue = Qgetc (fin);
green = Qgetc (fin); green = Qgetc (fin);
red = Qgetc (fin); red = Qgetc (fin);
*pixbuf++ = red; *pixbuf++ = red;
*pixbuf++ = green; *pixbuf++ = green;
*pixbuf++ = blue; *pixbuf++ = blue;
*pixbuf++ = 255; }
break; }
case 32: break;
case 32:
for (row = rows - 1; row >= 0; row--) {
pixbuf = targa_data->data + row * columns *
targa_data->format;
for (column = 0; column < columns; column++) {
blue = Qgetc (fin); blue = Qgetc (fin);
green = Qgetc (fin); green = Qgetc (fin);
red = Qgetc (fin); red = Qgetc (fin);
@ -139,16 +165,15 @@ LoadTGA (VFile *fin)
*pixbuf++ = green; *pixbuf++ = green;
*pixbuf++ = blue; *pixbuf++ = blue;
*pixbuf++ = alphabyte; *pixbuf++ = alphabyte;
break; }
} }
} break;
} }
} else if (targa_header.image_type == 10) { // Runlength encoded RGB } else if (targa_header.image_type == 10) { // RLE compressed image
// images
unsigned char packetHeader, packetSize, j; unsigned char packetHeader, packetSize, j;
for (row = rows - 1; row >= 0; row--) { for (row = rows - 1; row >= 0; row--) {
pixbuf = targa_rgba + row * columns * 4; pixbuf = targa_data->data + row * columns * targa_data->format;
for (column = 0; column < columns;) { for (column = 0; column < columns;) {
packetHeader = Qgetc (fin); packetHeader = Qgetc (fin);
packetSize = 1 + (packetHeader & 0x7f); packetSize = 1 + (packetHeader & 0x7f);
@ -158,7 +183,6 @@ LoadTGA (VFile *fin)
blue = Qgetc (fin); blue = Qgetc (fin);
green = Qgetc (fin); green = Qgetc (fin);
red = Qgetc (fin); red = Qgetc (fin);
alphabyte = 255;
break; break;
case 32: case 32:
blue = Qgetc (fin); blue = Qgetc (fin);
@ -172,7 +196,8 @@ LoadTGA (VFile *fin)
*pixbuf++ = red; *pixbuf++ = red;
*pixbuf++ = green; *pixbuf++ = green;
*pixbuf++ = blue; *pixbuf++ = blue;
*pixbuf++ = alphabyte; if (targa_header.pixel_size > 24)
*pixbuf++ = alphabyte;
column++; column++;
if (column == columns) { // run spans across rows if (column == columns) { // run spans across rows
column = 0; column = 0;
@ -180,7 +205,8 @@ LoadTGA (VFile *fin)
row--; row--;
else else
goto breakOut; goto breakOut;
pixbuf = targa_rgba + row * columns * 4; pixbuf = targa_data->data + row * columns *
targa_data->format;
} }
} }
} else { // non run-length packet } else { // non run-length packet
@ -193,7 +219,6 @@ LoadTGA (VFile *fin)
*pixbuf++ = red; *pixbuf++ = red;
*pixbuf++ = green; *pixbuf++ = green;
*pixbuf++ = blue; *pixbuf++ = blue;
*pixbuf++ = 255;
break; break;
case 32: case 32:
blue = Qgetc (fin); blue = Qgetc (fin);
@ -207,24 +232,25 @@ LoadTGA (VFile *fin)
break; break;
} }
column++; column++;
if (column == columns) { // pixel packet run spans if (column == columns) { // pixel packet run spans
// across rows // across rows
column = 0; column = 0;
if (row > 0) if (row > 0)
row--; row--;
else else
goto breakOut; goto breakOut;
pixbuf = targa_rgba + row * columns * 4; pixbuf = targa_data->data + row * columns *
targa_data->format;
} }
} }
} }
} }
breakOut:; breakOut:;
} }
} }
Qclose (fin); Qclose (fin);
return targa_rgba; return targa_data;
} }
void void

View file

@ -40,6 +40,7 @@ static const char rcsid[] =
#include "QF/console.h" #include "QF/console.h"
#include "QF/cvar.h" #include "QF/cvar.h"
#include "QF/render.h" #include "QF/render.h"
#include "QF/texture.h"
#include "QF/tga.h" #include "QF/tga.h"
#include "QF/vfs.h" #include "QF/vfs.h"
#include "QF/vid.h" #include "QF/vid.h"
@ -78,7 +79,7 @@ R_LoadSkys (const char *skyname)
skyloaded = true; skyloaded = true;
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
byte *targa_rgba; tex_t *targa;
qfglBindTexture (GL_TEXTURE_2D, SKY_TEX + i); qfglBindTexture (GL_TEXTURE_2D, SKY_TEX + i);
snprintf (name, sizeof (name), "env/%s%s.tga", skyname, suf[i]); snprintf (name, sizeof (name), "env/%s%s.tga", skyname, suf[i]);
@ -88,12 +89,18 @@ R_LoadSkys (const char *skyname)
skyloaded = false; skyloaded = false;
continue; continue;
} }
targa_rgba = LoadTGA (f); targa = LoadTGA (f);
qfglTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, if (targa->format < 4)
GL_RGBA, GL_UNSIGNED_BYTE, targa_rgba); qfglTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, targa->width,
targa->height, 0, GL_RGB, GL_UNSIGNED_BYTE,
&targa->data);
else
qfglTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, targa->width,
targa->height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
&targa->data);
free (targa_rgba); free (targa);
qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);