sprites now use skinframe_t instead of their own texture/fogtexture fields
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 25 Nov 2005 08:23:36 +0000 (08:23 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 25 Nov 2005 08:23:36 +0000 (08:23 +0000)
cleaned up hlbsp texture loading slightly, now uses Mod_LoadSkinFrame_Internal

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5836 d7cf8633-e32d-0410-b094-e92efae38249

image.c
image.h
model_alias.c
model_brush.c
model_shared.c
model_shared.h
model_sprite.c
model_sprite.h
r_sprites.c

diff --git a/image.c b/image.c
index 5a15150..549ca9c 100644 (file)
--- a/image.c
+++ b/image.c
@@ -1512,7 +1512,7 @@ void Image_HeightmapToNormalmap(const unsigned char *inpixels, unsigned char *ou
        }
 }
 
-int image_loadskin(imageskin_t *s, char *shadername)
+int image_loadskin(imageskin_t *s, const char *shadername)
 {
        int j;
        unsigned char *bumppixels;
diff --git a/image.h b/image.h
index a25f220..944020e 100644 (file)
--- a/image.h
+++ b/image.h
@@ -77,7 +77,7 @@ typedef struct imageskin_s
 }
 imageskin_t;
 
-int image_loadskin(imageskin_t *s, char *name);
+int image_loadskin(imageskin_t *s, const char *name);
 void image_freeskin(imageskin_t *s);
 
 #endif
index 6425800..f0653b9 100644 (file)
@@ -700,7 +700,7 @@ void Mod_IDP0_Load(model_t *mod, void *buffer, void *bufferend)
                                else
                                        sprintf (name, "%s_%i", loadmodel->name, i);
                                if (!Mod_LoadSkinFrame(&tempskinframe, name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP, true, true))
-                                       Mod_LoadSkinFrame_Internal(&tempskinframe, name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP, true, r_fullbrights.integer, (unsigned char *)datapointer, skinwidth, skinheight);
+                                       Mod_LoadSkinFrame_Internal(&tempskinframe, name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_PICMIP, true, r_fullbrights.integer, (unsigned char *)datapointer, skinwidth, skinheight, 8, NULL, NULL);
                                Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures + totalskins * loadmodel->num_surfaces, &tempskinframe);
                                datapointer += skinwidth * skinheight;
                                totalskins++;
index ed7bb4a..3cbaa5b 100644 (file)
@@ -1275,7 +1275,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
                                        if (loadmodel->brush.ishlbsp)
                                        {
                                                // internal texture overrides wad
-                                               unsigned char *pixels, *freepixels, *fogpixels;
+                                               unsigned char *pixels, *freepixels;
                                                pixels = freepixels = NULL;
                                                if (mtdata)
                                                        pixels = W_ConvertWAD3Texture(dmiptex);
@@ -1285,26 +1285,13 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
                                                {
                                                        tx->width = image_width;
                                                        tx->height = image_height;
-                                                       tx->skin.base = tx->skin.merged = R_LoadTexture2D(loadmodel->texturepool, tx->name, image_width, image_height, pixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP, NULL);
-                                                       if (Image_CheckAlpha(pixels, image_width * image_height, true))
-                                                       {
-                                                               fogpixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4);
-                                                               for (j = 0;j < image_width * image_height * 4;j += 4)
-                                                               {
-                                                                       fogpixels[j + 0] = 255;
-                                                                       fogpixels[j + 1] = 255;
-                                                                       fogpixels[j + 2] = 255;
-                                                                       fogpixels[j + 3] = pixels[j + 3];
-                                                               }
-                                                               tx->skin.fog = R_LoadTexture2D(loadmodel->texturepool, tx->name, image_width, image_height, pixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP, NULL);
-                                                               Mem_Free(fogpixels);
-                                                       }
+                                                       Mod_LoadSkinFrame_Internal(&tx->skin, tx->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP, false, false, pixels, image_width, image_height, 32, NULL, NULL);
                                                }
                                                if (freepixels)
                                                        Mem_Free(freepixels);
                                        }
                                        else if (mtdata) // texture included
-                                               Mod_LoadSkinFrame_Internal(&tx->skin, tx->name, TEXF_MIPMAP | TEXF_PRECACHE | TEXF_PICMIP, false, tx->name[0] != '*' && r_fullbrights.integer, mtdata, tx->width, tx->height);
+                                               Mod_LoadSkinFrame_Internal(&tx->skin, tx->name, TEXF_MIPMAP | TEXF_PRECACHE | TEXF_PICMIP, false, tx->name[0] != '*' && r_fullbrights.integer, mtdata, tx->width, tx->height, 8, NULL, NULL);
                                }
                        }
                        if (tx->skin.base == NULL)
index 232b977..4354ee7 100644 (file)
@@ -918,7 +918,7 @@ static rtexture_t *GL_TextureForSkinLayer(const unsigned char *in, int width, in
        return NULL;
 }
 
-int Mod_LoadSkinFrame(skinframe_t *skinframe, char *basename, int textureflags, int loadpantsandshirt, int loadglowtexture)
+int Mod_LoadSkinFrame(skinframe_t *skinframe, const char *basename, int textureflags, int loadpantsandshirt, int loadglowtexture)
 {
        imageskin_t s;
        memset(skinframe, 0, sizeof(*skinframe));
@@ -950,46 +950,99 @@ int Mod_LoadSkinFrame(skinframe_t *skinframe, char *basename, int textureflags,
        return true;
 }
 
-int Mod_LoadSkinFrame_Internal(skinframe_t *skinframe, char *basename, int textureflags, int loadpantsandshirt, int loadglowtexture, unsigned char *skindata, int width, int height)
+int Mod_LoadSkinFrame_Internal(skinframe_t *skinframe, const char *basename, int textureflags, int loadpantsandshirt, int loadglowtexture, const unsigned char *skindata, int width, int height, int bitsperpixel, const unsigned int *palette, const unsigned int *alphapalette)
 {
+       int i;
        unsigned char *temp1, *temp2;
        memset(skinframe, 0, sizeof(*skinframe));
        if (cls.state == ca_dedicated)
                return false;
        if (!skindata)
                return false;
-       if (r_shadow_bumpscale_basetexture.value > 0)
-       {
-               temp1 = (unsigned char *)Mem_Alloc(loadmodel->mempool, width * height * 8);
-               temp2 = temp1 + width * height * 4;
-               Image_Copy8bitRGBA(skindata, temp1, width * height, palette_nofullbrights);
-               Image_HeightmapToNormalmap(temp1, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
-               skinframe->nmap = R_LoadTexture2D(loadmodel->texturepool, va("%s_nmap", basename), width, height, temp2, TEXTYPE_RGBA, textureflags, NULL);
-               Mem_Free(temp1);
-       }
-       if (loadglowtexture)
+       if (bitsperpixel == 32)
        {
-               skinframe->glow = GL_TextureForSkinLayer(skindata, width, height, va("%s_glow", basename), palette_onlyfullbrights, textureflags); // glow
-               skinframe->base = skinframe->merged = GL_TextureForSkinLayer(skindata, width, height, va("%s_merged", basename), palette_nofullbrights, textureflags); // all but fullbrights
-               if (loadpantsandshirt)
+               if (r_shadow_bumpscale_basetexture.value > 0)
                {
-                       skinframe->pants = GL_TextureForSkinLayer(skindata, width, height, va("%s_pants", basename), palette_pantsaswhite, textureflags); // pants
-                       skinframe->shirt = GL_TextureForSkinLayer(skindata, width, height, va("%s_shirt", basename), palette_shirtaswhite, textureflags); // shirt
-                       if (skinframe->pants || skinframe->shirt)
-                               skinframe->base = GL_TextureForSkinLayer(skindata, width, height, va("%s_nospecial", basename), palette_nocolormapnofullbrights, textureflags); // no special colors
+                       temp1 = (unsigned char *)Mem_Alloc(loadmodel->mempool, width * height * 8);
+                       temp2 = temp1 + width * height * 4;
+                       Image_HeightmapToNormalmap(skindata, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
+                       skinframe->nmap = R_LoadTexture2D(loadmodel->texturepool, va("%s_nmap", basename), width, height, temp2, TEXTYPE_RGBA, textureflags | TEXF_ALPHA, NULL);
+                       Mem_Free(temp1);
+               }
+               skinframe->base = skinframe->merged = R_LoadTexture2D(loadmodel->texturepool, basename, width, height, skindata, TEXTYPE_RGBA, textureflags, NULL);
+               if (textureflags & TEXF_ALPHA)
+               {
+                       for (i = 3;i < width * height * 4;i += 4)
+                               if (skindata[i] < 255)
+                                       break;
+                       if (i < width * height * 4)
+                       {
+                               unsigned char *fogpixels = Mem_Alloc(loadmodel->mempool, width * height * 4);
+                               memcpy(fogpixels, skindata, width * height * 4);
+                               for (i = 0;i < width * height * 4;i += 4)
+                                       fogpixels[i] = fogpixels[i+1] = fogpixels[i+2] = 255;
+                               skinframe->fog = R_LoadTexture2D(loadmodel->texturepool, va("%s_fog", basename), width, height, fogpixels, TEXTYPE_RGBA, textureflags, NULL);
+                               Mem_Free(fogpixels);
+                       }
                }
        }
-       else
+       else if (bitsperpixel == 8)
        {
-               skinframe->base = skinframe->merged = GL_TextureForSkinLayer(skindata, width, height, va("%s_merged", basename), palette_complete, textureflags); // all
-               if (loadpantsandshirt)
+               if (r_shadow_bumpscale_basetexture.value > 0)
+               {
+                       temp1 = (unsigned char *)Mem_Alloc(loadmodel->mempool, width * height * 8);
+                       temp2 = temp1 + width * height * 4;
+                       if (bitsperpixel == 32)
+                               Image_HeightmapToNormalmap(skindata, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
+                       else
+                       {
+                               // use either a custom palette or the quake palette
+                               Image_Copy8bitRGBA(skindata, temp1, width * height, palette ? palette : palette_complete);
+                               Image_HeightmapToNormalmap(temp1, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
+                       }
+                       skinframe->nmap = R_LoadTexture2D(loadmodel->texturepool, va("%s_nmap", basename), width, height, temp2, TEXTYPE_RGBA, textureflags | TEXF_ALPHA, NULL);
+                       Mem_Free(temp1);
+               }
+               // use either a custom palette, or the quake palette
+               if (palette)
+                       skinframe->base = skinframe->merged = GL_TextureForSkinLayer(skindata, width, height, va("%s_merged", basename), palette, textureflags); // all
+               else if (loadglowtexture)
+               {
+                       skinframe->glow = GL_TextureForSkinLayer(skindata, width, height, va("%s_glow", basename), palette_onlyfullbrights, textureflags); // glow
+                       skinframe->base = skinframe->merged = GL_TextureForSkinLayer(skindata, width, height, va("%s_merged", basename), palette_nofullbrights, textureflags); // all but fullbrights
+                       if (loadpantsandshirt)
+                       {
+                               skinframe->pants = GL_TextureForSkinLayer(skindata, width, height, va("%s_pants", basename), palette_pantsaswhite, textureflags); // pants
+                               skinframe->shirt = GL_TextureForSkinLayer(skindata, width, height, va("%s_shirt", basename), palette_shirtaswhite, textureflags); // shirt
+                               if (skinframe->pants || skinframe->shirt)
+                                       skinframe->base = GL_TextureForSkinLayer(skindata, width, height, va("%s_nospecial", basename), palette_nocolormapnofullbrights, textureflags); // no special colors
+                       }
+               }
+               else
                {
-                       skinframe->pants = GL_TextureForSkinLayer(skindata, width, height, va("%s_pants", basename), palette_pantsaswhite, textureflags); // pants
-                       skinframe->shirt = GL_TextureForSkinLayer(skindata, width, height, va("%s_shirt", basename), palette_shirtaswhite, textureflags); // shirt
-                       if (skinframe->pants || skinframe->shirt)
-                               skinframe->base = GL_TextureForSkinLayer(skindata, width, height, va("%s_nospecial", basename), palette_nocolormap, textureflags); // no pants or shirt
+                       skinframe->base = skinframe->merged = GL_TextureForSkinLayer(skindata, width, height, va("%s_merged", basename), palette_complete, textureflags); // all
+                       if (loadpantsandshirt)
+                       {
+                               skinframe->pants = GL_TextureForSkinLayer(skindata, width, height, va("%s_pants", basename), palette_pantsaswhite, textureflags); // pants
+                               skinframe->shirt = GL_TextureForSkinLayer(skindata, width, height, va("%s_shirt", basename), palette_shirtaswhite, textureflags); // shirt
+                               if (skinframe->pants || skinframe->shirt)
+                                       skinframe->base = GL_TextureForSkinLayer(skindata, width, height, va("%s_nospecial", basename), palette_nocolormap, textureflags); // no pants or shirt
+                       }
+               }
+               if (textureflags & TEXF_ALPHA)
+               {
+                       // if not using a custom alphapalette, use the quake one
+                       if (!alphapalette)
+                               alphapalette = palette_alpha;
+                       for (i = 0;i < width * height;i++)
+                               if (((unsigned char *)alphapalette)[skindata[i]*4+3] < 255)
+                                       break;
+                       if (i < width * height)
+                               skinframe->fog = GL_TextureForSkinLayer(skindata, width, height, va("%s_fog", basename), alphapalette, textureflags); // fog mask
                }
        }
+       else
+               return false;
        if (!skinframe->nmap)
                skinframe->nmap = r_texture_blanknormalmap;
        return true;
index 4af1f02..60c315f 100644 (file)
@@ -615,8 +615,8 @@ shadowmesh_t *Mod_ShadowMesh_Finish(mempool_t *mempool, shadowmesh_t *firstmesh,
 void Mod_ShadowMesh_CalcBBox(shadowmesh_t *firstmesh, vec3_t mins, vec3_t maxs, vec3_t center, float *radius);
 void Mod_ShadowMesh_Free(shadowmesh_t *mesh);
 
-int Mod_LoadSkinFrame(skinframe_t *skinframe, char *basename, int textureflags, int loadpantsandshirt, int loadglowtexture);
-int Mod_LoadSkinFrame_Internal(skinframe_t *skinframe, char *basename, int textureflags, int loadpantsandshirt, int loadglowtexture, unsigned char *skindata, int width, int height);
+int Mod_LoadSkinFrame(skinframe_t *skinframe, const char *basename, int textureflags, int loadpantsandshirt, int loadglowtexture);
+int Mod_LoadSkinFrame_Internal(skinframe_t *skinframe, const char *basename, int textureflags, int loadpantsandshirt, int loadglowtexture, const unsigned char *skindata, int width, int height, int bitsperpixel, const unsigned int *palette, const unsigned int *alphapalette);
 
 extern cvar_t r_mipskins;
 
index c44eba5..0aeb7d0 100644 (file)
@@ -37,7 +37,6 @@ void Mod_SpriteInit (void)
        Cvar_RegisterVariable(&r_mipsprites);
 }
 
-static int alphaonlytable[4] = {255 | 0x80000000, 255 | 0x80000000, 255 | 0x80000000, 3};
 static void Mod_Sprite_SharedSetup(const unsigned char *datapointer, int version, const unsigned int *palette, const unsigned int *alphapalette)
 {
        int                                     i, j, groupframes, realframes, x, y, origin[2], width, height;
@@ -47,7 +46,6 @@ static void Mod_Sprite_SharedSetup(const unsigned char *datapointer, int version
        dspriteinterval_t       *pinintervals;
        float                           modelradius, interval;
        char                            name[MAX_QPATH], fogname[MAX_QPATH];
-       unsigned char                           *pixbuf;
        const void                      *startframes;
        modelradius = 0;
 
@@ -159,29 +157,18 @@ static void Mod_Sprite_SharedSetup(const unsigned char *datapointer, int version
                                        sprintf (name, "%s_%i_%i", loadmodel->name, i, j);
                                else
                                        sprintf (name, "%s_%i", loadmodel->name, i);
-                               loadmodel->sprite.sprdata_frames[realframes].texture = loadtextureimagewithmask(loadmodel->texturepool, name, 0, 0, false, (r_mipsprites.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_CLAMP | TEXF_PRECACHE | TEXF_PICMIP);
-                               loadmodel->sprite.sprdata_frames[realframes].fogtexture = image_masktex;
+                               Mod_LoadSkinFrame(&loadmodel->sprite.sprdata_frames[realframes].skin, name, (r_mipsprites.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_CLAMP | TEXF_PRECACHE | TEXF_PICMIP, false, false);
 
-                               if (!loadmodel->sprite.sprdata_frames[realframes].texture)
+                               if (!loadmodel->sprite.sprdata_frames[realframes].skin.base)
                                {
                                        if (groupframes > 1)
                                                sprintf (fogname, "%s_%i_%ifog", loadmodel->name, i, j);
                                        else
                                                sprintf (fogname, "%s_%ifog", loadmodel->name, i);
                                        if (version == SPRITE32_VERSION)
-                                       {
-                                               loadmodel->sprite.sprdata_frames[realframes].texture = R_LoadTexture2D(loadmodel->texturepool, name, width, height, datapointer, TEXTYPE_RGBA, TEXF_ALPHA | (r_mipsprites.integer ? TEXF_MIPMAP : 0) | TEXF_CLAMP | TEXF_PRECACHE | TEXF_PICMIP, NULL);
-                                               // make fog version (just alpha)
-                                               pixbuf = (unsigned char *)Mem_Alloc(tempmempool, width*height*4);
-                                               Image_CopyMux(pixbuf, datapointer, width, height, false, false, false, 4, 4, alphaonlytable);
-                                               loadmodel->sprite.sprdata_frames[realframes].fogtexture = R_LoadTexture2D(loadmodel->texturepool, fogname, width, height, pixbuf, TEXTYPE_RGBA, TEXF_ALPHA | (r_mipsprites.integer ? TEXF_MIPMAP : 0) | TEXF_CLAMP | TEXF_PRECACHE | TEXF_PICMIP, NULL);
-                                               Mem_Free(pixbuf);
-                                       }
+                                               Mod_LoadSkinFrame_Internal(&loadmodel->sprite.sprdata_frames[realframes].skin, name, (r_mipsprites.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_CLAMP | TEXF_PRECACHE | TEXF_PICMIP, false, false, datapointer, width, height, 32, NULL, NULL);
                                        else //if (version == SPRITE_VERSION || version == SPRITEHL_VERSION)
-                                       {
-                                               loadmodel->sprite.sprdata_frames[realframes].texture = R_LoadTexture2D(loadmodel->texturepool, name, width, height, datapointer, TEXTYPE_PALETTE, TEXF_ALPHA | (r_mipsprites.integer ? TEXF_MIPMAP : 0) | TEXF_CLAMP | TEXF_PRECACHE | TEXF_PICMIP, palette);
-                                               loadmodel->sprite.sprdata_frames[realframes].fogtexture = R_LoadTexture2D(loadmodel->texturepool, fogname, width, height, datapointer, TEXTYPE_PALETTE, TEXF_ALPHA | (r_mipsprites.integer ? TEXF_MIPMAP : 0) | TEXF_CLAMP | TEXF_PRECACHE | TEXF_PICMIP, alphapalette);
-                                       }
+                                               Mod_LoadSkinFrame_Internal(&loadmodel->sprite.sprdata_frames[realframes].skin, name, (r_mipsprites.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_CLAMP | TEXF_PRECACHE | TEXF_PICMIP, false, false, datapointer, width, height, 8, palette, alphapalette);
                                }
                        }
 
@@ -392,11 +379,9 @@ void Mod_IDS2_Load(model_t *mod, void *buffer, void *bufferend)
 
                if (width > 0 && height > 0 && cls.state != ca_dedicated)
                {
-                       sprframe->texture = loadtextureimagewithmask(loadmodel->texturepool, pinframe->name, 0, 0, false, (r_mipsprites.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_CLAMP | TEXF_PRECACHE | TEXF_PICMIP);
-                       sprframe->fogtexture = image_masktex;
-
+                       Mod_LoadSkinFrame(&sprframe->skin, pinframe->name, (r_mipsprites.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_CLAMP | TEXF_PRECACHE | TEXF_PICMIP, false, false);
                        // TODO: use a default texture if we can't load it?
-                       if (sprframe->texture == NULL)
+                       if (sprframe->skin.base == NULL)
                                Host_Error("Mod_IDS2_Load: failed to load %s", pinframe->name);
                }
        }
index 3553850..e6df9e4 100644 (file)
@@ -35,7 +35,7 @@ SPRITE MODELS
 typedef struct mspriteframe_s
 {
        float   up, down, left, right;
-       rtexture_t *texture, *fogtexture;
+       skinframe_t skin;
 } mspriteframe_t;
 
 #endif
index ca0d4b6..bd7d021 100644 (file)
@@ -93,7 +93,7 @@ void R_DrawSpriteModelCallback(const void *calldata1, int calldata2)
                {
                        frame = ent->model->sprite.sprdata_frames + ent->frameblend[i].frame;
                        // FIXME: negate left and right in loader
-                       R_DrawSprite(GL_SRC_ALPHA, (ent->effects & EF_ADDITIVE) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, frame->texture, frame->fogtexture, (ent->effects & EF_NODEPTHTEST), org, left, up, frame->left, frame->right, frame->down, frame->up, color[0], color[1], color[2], ent->alpha * ent->frameblend[i].lerp);
+                       R_DrawSprite(GL_SRC_ALPHA, (ent->effects & EF_ADDITIVE) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, frame->skin.base, frame->skin.fog, (ent->effects & EF_NODEPTHTEST), org, left, up, frame->left, frame->right, frame->down, frame->up, color[0], color[1], color[2], ent->alpha * ent->frameblend[i].lerp);
                }
        }
 }