diff --git a/include/QF/texture.h b/include/QF/texture.h index 29dc36286..e0d777f5e 100644 --- a/include/QF/texture.h +++ b/include/QF/texture.h @@ -34,10 +34,15 @@ // could not use texture_t as that is used for models. typedef struct tex_s { - int width; - int height; - unsigned char *palette; // 0 = 32 bit, otherise 8 - unsigned char data[4]; // variable length + int width; + int height; + int format; + unsigned char *palette; // 0 = 32 bit, otherwise 8 + unsigned char data[4]; // variable length } tex_t; +#define tex_palette 0; +#define tex_rgb 3; +#define tex_rgba 4; + #endif // __texture_h diff --git a/include/QF/tga.h b/include/QF/tga.h index 4e309044a..36e9db7af 100644 --- a/include/QF/tga.h +++ b/include/QF/tga.h @@ -69,7 +69,7 @@ typedef struct _TargaHeader { # endif #endif -byte *LoadTGA (VFile *fin); +struct tex_s *LoadTGA (VFile *fin); void WriteTGAfile (const char *tganame, byte *data, int width, int height); #endif // __tga_h diff --git a/libs/util/tga.c b/libs/util/tga.c index 2e16b5d20..142f78901 100644 --- a/libs/util/tga.c +++ b/libs/util/tga.c @@ -41,9 +41,12 @@ static const char rcsid[] = #include "QF/qendian.h" #include "QF/sys.h" +#include "QF/texture.h" #include "QF/tga.h" #include "QF/vfs.h" +#include "compat.h" + static int fgetLittleShort (VFile *f) @@ -71,15 +74,15 @@ fgetLittleLong (VFile *f) } */ -byte * +struct tex_s * LoadTGA (VFile *fin) { 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; - TargaHeader targa_header; - byte *targa_rgba; + TargaHeader targa_header; + tex_t *targa_data; targa_header.id_length = Qgetc (fin); targa_header.colormap_type = Qgetc (fin); @@ -107,30 +110,53 @@ LoadTGA (VFile *fin) rows = targa_header.height; numPixels = columns * rows; - targa_rgba = malloc (numPixels * 4); - if (!targa_rgba) - Sys_Error ("LoadTGA: Memory Allocation Failure\n"); + switch (targa_header.pixel_size) { + case 24: + 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) Qseek (fin, targa_header.id_length, SEEK_CUR); // skip TARGA image // comment - if (targa_header.image_type == 2) { // Uncompressed, RGB images - for (row = rows - 1; row >= 0; row--) { - pixbuf = targa_rgba + row * columns * 4; - for (column = 0; column < columns; column++) { - switch (targa_header.pixel_size) { - case 24: - + if (targa_header.image_type == 2) { // Uncompressed image + switch (targa_header.pixel_size) { + case 24: + 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); green = Qgetc (fin); red = Qgetc (fin); *pixbuf++ = red; *pixbuf++ = green; *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); green = Qgetc (fin); red = Qgetc (fin); @@ -139,16 +165,15 @@ LoadTGA (VFile *fin) *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = alphabyte; - break; + } } - } + break; } - } else if (targa_header.image_type == 10) { // Runlength encoded RGB - // images + } else if (targa_header.image_type == 10) { // RLE compressed image unsigned char packetHeader, packetSize, j; 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;) { packetHeader = Qgetc (fin); packetSize = 1 + (packetHeader & 0x7f); @@ -158,7 +183,6 @@ LoadTGA (VFile *fin) blue = Qgetc (fin); green = Qgetc (fin); red = Qgetc (fin); - alphabyte = 255; break; case 32: blue = Qgetc (fin); @@ -172,7 +196,8 @@ LoadTGA (VFile *fin) *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; - *pixbuf++ = alphabyte; + if (targa_header.pixel_size > 24) + *pixbuf++ = alphabyte; column++; if (column == columns) { // run spans across rows column = 0; @@ -180,7 +205,8 @@ LoadTGA (VFile *fin) row--; else goto breakOut; - pixbuf = targa_rgba + row * columns * 4; + pixbuf = targa_data->data + row * columns * + targa_data->format; } } } else { // non run-length packet @@ -193,7 +219,6 @@ LoadTGA (VFile *fin) *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; - *pixbuf++ = 255; break; case 32: blue = Qgetc (fin); @@ -207,24 +232,25 @@ LoadTGA (VFile *fin) break; } column++; - if (column == columns) { // pixel packet run spans + if (column == columns) { // pixel packet run spans // across rows column = 0; if (row > 0) row--; else goto breakOut; - pixbuf = targa_rgba + row * columns * 4; + pixbuf = targa_data->data + row * columns * + targa_data->format; } } } } - breakOut:; + breakOut:; } } Qclose (fin); - return targa_rgba; + return targa_data; } void diff --git a/libs/video/renderer/gl/gl_sky.c b/libs/video/renderer/gl/gl_sky.c index 8221570e6..91bbc81ea 100644 --- a/libs/video/renderer/gl/gl_sky.c +++ b/libs/video/renderer/gl/gl_sky.c @@ -40,6 +40,7 @@ static const char rcsid[] = #include "QF/console.h" #include "QF/cvar.h" #include "QF/render.h" +#include "QF/texture.h" #include "QF/tga.h" #include "QF/vfs.h" #include "QF/vid.h" @@ -78,7 +79,7 @@ R_LoadSkys (const char *skyname) skyloaded = true; for (i = 0; i < 6; i++) { - byte *targa_rgba; + tex_t *targa; qfglBindTexture (GL_TEXTURE_2D, SKY_TEX + i); snprintf (name, sizeof (name), "env/%s%s.tga", skyname, suf[i]); @@ -88,12 +89,18 @@ R_LoadSkys (const char *skyname) skyloaded = false; continue; } - targa_rgba = LoadTGA (f); + targa = LoadTGA (f); - qfglTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, - GL_RGBA, GL_UNSIGNED_BYTE, targa_rgba); + if (targa->format < 4) + 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_MAG_FILTER, GL_LINEAR);