mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-29 20:20:43 +00:00
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:
parent
aaf9b953a4
commit
010ca032a5
4 changed files with 78 additions and 40 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue