From c4609f5195807976f4867b86bfaee15d3e4dd497 Mon Sep 17 00:00:00 2001 From: Ragnvald Maartmann-Moe IV Date: Fri, 6 Sep 2002 21:37:22 +0000 Subject: [PATCH] Experimentally allow external texture loading. Also prevent loading RGB textures as RGBA, which wastes a lot of texture memory, and looks ugly on 16bpp boards. --- libs/models/brush/gl_model_brush.c | 34 +++++++--------- libs/util/tga.c | 5 ++- libs/video/renderer/gl/gl_skin.c | 25 +++++------- libs/video/renderer/gl/gl_sky.c | 14 +++---- libs/video/renderer/gl/gl_textures.c | 60 ++++++++++++++-------------- 5 files changed, 62 insertions(+), 76 deletions(-) diff --git a/libs/models/brush/gl_model_brush.c b/libs/models/brush/gl_model_brush.c index dcd564f5e..8a20fe24f 100644 --- a/libs/models/brush/gl_model_brush.c +++ b/libs/models/brush/gl_model_brush.c @@ -46,6 +46,7 @@ static const char rcsid[] = #include "QF/sys.h" #include "QF/texture.h" #include "QF/tga.h" +#include "QF/va.h" #include "QF/GL/qf_textures.h" #include "compat.h" @@ -69,42 +70,35 @@ Mod_ProcessTexture (miptex_t *mt, texture_t *tx) void Mod_LoadExternalTextures (model_t *mod) { - char filename[MAX_QPATH + 8]; - int length, i; + char *filename; + int i; tex_t *targa; texture_t *tx; QFile *f; - for (i = 0; i < mod->numtextures; i++) - { + for (i = 0; i < mod->numtextures; i++) { tx = mod->textures[i]; if (!tx) continue; - length = strlen (tx->name) - 1; // backslash at the end of texture name indicates external texture - if (tx->name[length] != '\\') - continue; +// if (tx->name[length] != '\\') +// continue; // replace special flag characters with underscores - if (tx->name[0] == '+' || tx->name[0] == '*') - snprintf (filename, sizeof (filename), "maps/_%s", tx->name + 1); - else - snprintf (filename, sizeof (filename), "maps/%s", tx->name); - - length += 5; // add "maps/" to the string length calculation - snprintf (filename + length, sizeof (filename) - length, ".tga"); + if (tx->name[0] == '+' || tx->name[0] == '*') { + filename = va ("maps/_%s.tga", tx->name + 1); + } else { + filename = va ("maps/%s.tga", tx->name); + } COM_FOpenFile (filename, &f); if (f) { targa = LoadTGA (f); Qclose (f); - if (targa->format < 4) - tx->gl_texturenum = GL_LoadTexture (tx->name, targa->width, - targa->height, targa->data, true, false, 3); - else - tx->gl_texturenum = GL_LoadTexture (tx->name, targa->width, - targa->height, targa->data, true, true, 4); + tx->gl_texturenum = + GL_LoadTexture (tx->name, targa->width, targa->height, + targa->data, true, false, 3); } } } diff --git a/libs/util/tga.c b/libs/util/tga.c index 4923c6558..f02f7d7b0 100644 --- a/libs/util/tga.c +++ b/libs/util/tga.c @@ -56,6 +56,7 @@ blit_rgb (byte *buf, int count, byte red, byte green, byte blue) *buf++ = red; *buf++ = green; *buf++ = blue; + *buf++ = 255; } return buf; } @@ -147,7 +148,7 @@ LoadTGA (QFile *fin) switch (targa->pixel_size) { case 24: - tex = Hunk_TempAlloc (field_offset (tex_t, data[numPixels * 3])); + tex = Hunk_TempAlloc (field_offset (tex_t, data[numPixels * 4])); tex->format = tex_rgb; break; default: @@ -165,7 +166,7 @@ LoadTGA (QFile *fin) dataByte = (byte *) (targa + 1); dataByte += targa->id_length; - span = columns * tex->format; + span = columns * 4; // tex->format pixrow = tex->data + (rows - 1) * span; if (targa->image_type == 2) { // Uncompressed image diff --git a/libs/video/renderer/gl/gl_skin.c b/libs/video/renderer/gl/gl_skin.c index 5564ed86b..4832ebf40 100644 --- a/libs/video/renderer/gl/gl_skin.c +++ b/libs/video/renderer/gl/gl_skin.c @@ -96,10 +96,7 @@ build_skin_8 (byte * original, int tinwidth, int tinheight, unsigned int scaled_width, unsigned int scaled_height, int inwidth, qboolean alpha) { - /* - any improvements in here should be mirrored in - GL_Resample8BitTexture in gl_textures.c - */ + // Improvements should be mirrored in GL_ResampleTexture in gl_textures.c byte *inrow; byte pixels[512 * 256], *out; int i, j; @@ -126,10 +123,7 @@ build_skin_32 (byte * original, int tinwidth, int tinheight, unsigned int scaled_width, unsigned int scaled_height, int inwidth, qboolean alpha) { - /* - any improvements in here should be mirrored in - GL_ResampleTexture in gl_textures.c - */ + // Improvements should be mirrored in GL_ResampleTexture in gl_textures.c byte *inrow; int i, j; int samples = alpha ? gl_alpha_format : gl_solid_format; @@ -148,9 +142,8 @@ build_skin_32 (byte * original, int tinwidth, int tinheight, } } - qfglTexImage2D (GL_TEXTURE_2D, 0, samples, - scaled_width, scaled_height, 0, GL_RGBA, - GL_UNSIGNED_BYTE, pixels); + qfglTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, pixels); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -175,11 +168,11 @@ build_skin (int texnum, byte *ptexels, int width, int height, scaled_height >>= gl_playermip->int_val; if (VID_Is8bit ()) { // 8bit texture upload - build_skin_8 (ptexels, owidth, oheight, scaled_width, - scaled_height, width, alpha); + build_skin_8 (ptexels, owidth, oheight, scaled_width, scaled_height, + width, alpha); } else { - build_skin_32 (ptexels, owidth, oheight, scaled_width, - scaled_height, width, alpha); + build_skin_32 (ptexels, owidth, oheight, scaled_width, scaled_height, + width, alpha); } } @@ -191,7 +184,7 @@ Skin_Do_Translation (skin_t *player_skin, int slot, skin_t *skin) int texnum = skin->texture; tex_t *skin_texels; - if ((skin_texels = (tex_t*)Skin_Cache (player_skin)) != NULL) { + if ((skin_texels = (tex_t *) Skin_Cache (player_skin)) != NULL) { // skin data width inwidth = 320; inheight = 200; diff --git a/libs/video/renderer/gl/gl_sky.c b/libs/video/renderer/gl/gl_sky.c index 384d9b9eb..0f36ea2b7 100644 --- a/libs/video/renderer/gl/gl_sky.c +++ b/libs/video/renderer/gl/gl_sky.c @@ -86,7 +86,8 @@ R_LoadSkys (const char *skyname) if (!f) { Con_DPrintf ("Couldn't load %s\n", name); // also look in gfx/env, where Darkplaces looks for skies - snprintf (name, sizeof (name), "gfx/env/%s%s.tga", skyname, suf[i]); + snprintf (name, sizeof (name), "gfx/env/%s%s.tga", skyname, + suf[i]); COM_FOpenFile (name, &f); if (!f) { Con_DPrintf ("Couldn't load %s\n", name); @@ -97,14 +98,9 @@ R_LoadSkys (const char *skyname) targa = LoadTGA (f); Qclose (f); - 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); + qfglTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, targa->width, + targa->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + &targa->data); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); diff --git a/libs/video/renderer/gl/gl_textures.c b/libs/video/renderer/gl/gl_textures.c index 985b5d6b7..c944f4514 100644 --- a/libs/video/renderer/gl/gl_textures.c +++ b/libs/video/renderer/gl/gl_textures.c @@ -178,7 +178,6 @@ static glformat_t formats[] = { int gl_alpha_format = 4, gl_lightmap_format = 4, gl_solid_format = 3; - void GL_TextureMode_f (void) { @@ -249,12 +248,9 @@ GL_TextureDepth_f (int format) static void GL_ResampleTexture (unsigned int *in, int inwidth, int inheight, - unsigned int *out, int outwidth, int outheight) + unsigned int *out, int outwidth, int outheight) { - /* - any improvements in here should be mirrored in build_skin_32 in - gl_skin.c - */ + // Improvements here should be mirrored in build_skin_32 in gl_skin.c int i, j; unsigned int frac, fracstep; unsigned int *inrow; @@ -274,12 +270,9 @@ GL_ResampleTexture (unsigned int *in, int inwidth, int inheight, static void GL_Resample8BitTexture (unsigned char *in, int inwidth, int inheight, - unsigned char *out, int outwidth, int outheight) + unsigned char *out, int outwidth, int outheight) { - /* - any improvements in here should be mirrored in build_skin_8 in - gl_skin.c - */ + // Improvements here should be mirrored in build_skin_8 in gl_skin.c unsigned char *inrow; int i, j; unsigned int frac, fracstep; @@ -303,7 +296,7 @@ GL_Resample8BitTexture (unsigned char *in, int inwidth, int inheight, Operates in place, quartering the size of the texture. */ static void -GL_MipMap (byte * in, int width, int height) +GL_MipMap (byte *in, int width, int height) { byte *out; int i, j; @@ -328,7 +321,7 @@ GL_MipMap (byte * in, int width, int height) Mipping for 8 bit textures */ static void -GL_MipMap8Bit (byte * in, int width, int height) +GL_MipMap8Bit (byte *in, int width, int height) { byte *at1, *at2, *at3, *at4, *out; int i, j; @@ -357,7 +350,7 @@ GL_MipMap8Bit (byte * in, int width, int height) static void GL_Upload32 (unsigned int *data, int width, int height, qboolean mipmap, - qboolean alpha) + qboolean alpha) { int scaled_width, scaled_height, intformat; unsigned int *scaled; @@ -386,7 +379,7 @@ GL_Upload32 (unsigned int *data, int width, int height, qboolean mipmap, memcpy (scaled, data, width * height * sizeof (GLuint)); } else { GL_ResampleTexture (data, width, height, scaled, scaled_width, - scaled_height); + scaled_height); } qfglTexImage2D (GL_TEXTURE_2D, 0, intformat, scaled_width, scaled_height, @@ -403,7 +396,8 @@ GL_Upload32 (unsigned int *data, int width, int height, qboolean mipmap, scaled_height = max (scaled_height, 1); miplevel++; qfglTexImage2D (GL_TEXTURE_2D, miplevel, intformat, scaled_width, - scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); + scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + scaled); } } @@ -433,8 +427,8 @@ GL_Upload32 (unsigned int *data, int width, int height, qboolean mipmap, If we don't, this function does nothing. */ void -GL_Upload8_EXT (byte * data, int width, int height, qboolean mipmap, - qboolean alpha) +GL_Upload8_EXT (byte *data, int width, int height, qboolean mipmap, + qboolean alpha) { byte *scaled; int scaled_width, scaled_height; @@ -458,10 +452,11 @@ GL_Upload8_EXT (byte * data, int width, int height, qboolean mipmap, memcpy (scaled, data, width * height); } else { GL_Resample8BitTexture (data, width, height, scaled, scaled_width, - scaled_height); + scaled_height); } qfglTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, - scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled); + scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, + scaled); if (mipmap) { int miplevel; @@ -475,8 +470,8 @@ GL_Upload8_EXT (byte * data, int width, int height, qboolean mipmap, scaled_height = max (scaled_height, 1); miplevel++; qfglTexImage2D (GL_TEXTURE_2D, miplevel, GL_COLOR_INDEX8_EXT, - scaled_width, scaled_height, 0, GL_COLOR_INDEX, - GL_UNSIGNED_BYTE, scaled); + scaled_width, scaled_height, 0, GL_COLOR_INDEX, + GL_UNSIGNED_BYTE, scaled); } } @@ -501,7 +496,7 @@ GL_Upload8_EXT (byte * data, int width, int height, qboolean mipmap, void -GL_Upload8 (byte * data, int width, int height, qboolean mipmap, qboolean alpha) +GL_Upload8 (byte *data, int width, int height, qboolean mipmap, qboolean alpha) { int i, s, p; unsigned int *trans; @@ -538,23 +533,27 @@ GL_Upload8 (byte * data, int width, int height, qboolean mipmap, qboolean alpha) } int -GL_LoadTexture (const char *identifier, int width, int height, byte * data, - qboolean mipmap, qboolean alpha, int bytesperpixel) +GL_LoadTexture (const char *identifier, int width, int height, byte *data, + qboolean mipmap, qboolean alpha, int bytesperpixel) { int crc, i; gltexture_t *glt; // LordHavoc: now just using a standard CRC for texture validation - crc = CRC_Block (data, width * height * bytesperpixel); + if (bytesperpixel == 1) + crc = CRC_Block (data, width * height * bytesperpixel); + else + crc = CRC_Block (data, width * height * 4); // see if the texture is already present if (identifier[0]) { for (i = 0, glt = gltextures; i < numgltextures; i++, glt++) { if (strequal (identifier, glt->identifier)) { if (crc != glt->crc - || width != glt->width + || width != glt->width || height != glt->height - || bytesperpixel != glt->bytesperpixel) goto SetupTexture; + || bytesperpixel != glt->bytesperpixel) + goto SetupTexture; else return gltextures[i].texnum; } @@ -586,12 +585,15 @@ SetupTexture: case 1: GL_Upload8 (data, width, height, mipmap, alpha); break; + case 3: + GL_Upload32 ((GLuint *) data, width, height, mipmap, 0); + break; case 4: GL_Upload32 ((GLuint *) data, width, height, mipmap, alpha); break; default: Sys_Error ("SetupTexture: unknown bytesperpixel %i", - glt->bytesperpixel); + glt->bytesperpixel); } return glt->texnum;