From: havoc Date: Fri, 25 Nov 2005 08:23:36 +0000 (+0000) Subject: sprites now use skinframe_t instead of their own texture/fogtexture fields X-Git-Tag: xonotic-v0.1.0preview~4449 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=b9d5e6a2abfaad61228b42141f8adfcc650e4288;p=xonotic%2Fdarkplaces.git sprites now use skinframe_t instead of their own texture/fogtexture fields 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 --- diff --git a/image.c b/image.c index 5a151506..549ca9c1 100644 --- 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 a25f2201..944020e6 100644 --- 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 diff --git a/model_alias.c b/model_alias.c index 64258007..f0653b90 100644 --- a/model_alias.c +++ b/model_alias.c @@ -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++; diff --git a/model_brush.c b/model_brush.c index ed7bb4ab..3cbaa5b1 100644 --- a/model_brush.c +++ b/model_brush.c @@ -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) diff --git a/model_shared.c b/model_shared.c index 232b977d..4354ee7e 100644 --- a/model_shared.c +++ b/model_shared.c @@ -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; diff --git a/model_shared.h b/model_shared.h index 4af1f029..60c315fc 100644 --- a/model_shared.h +++ b/model_shared.h @@ -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; diff --git a/model_sprite.c b/model_sprite.c index c44eba5f..0aeb7d04 100644 --- a/model_sprite.c +++ b/model_sprite.c @@ -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); } } diff --git a/model_sprite.h b/model_sprite.h index 35538505..e6df9e48 100644 --- a/model_sprite.h +++ b/model_sprite.h @@ -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 diff --git a/r_sprites.c b/r_sprites.c index ca0d4b67..bd7d0213 100644 --- a/r_sprites.c +++ b/r_sprites.c @@ -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); } } }