for (i = 0;i < r_refdef.numentities;i++)
{
ent = r_refdef.entities[i];
- if (ent->model && !strcmp(ent->model->name, "progs/missile.mdl"))
+ if (ent->model)
R_TestAndDrawShadowVolume(ent, wl->origin, cullradius, lightradius, wl->mins, wl->maxs, clipmins, clipmaxs);
}
}
m.blendfunc1 = GL_ONE;
m.blendfunc2 = GL_ZERO;
}
- m.tex[0] = R_GetTexture(texture->texture);
+ m.tex[0] = R_GetTexture(texture->skin.base);
colorscale = r_colorscale;
if (gl_combine.integer)
{
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE;
- m.tex[0] = R_GetTexture(texture->fogtexture);
+ m.tex[0] = R_GetTexture(texture->skin.fog);
R_Mesh_State(&m);
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
m.blendfunc1 = GL_ONE;
m.blendfunc2 = GL_ZERO;
}
- m.tex[0] = R_GetTexture(texture->texture);
+ m.tex[0] = R_GetTexture(texture->skin.base);
colorscale = r_colorscale;
if (gl_combine.integer)
{
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE;
- m.tex[0] = R_GetTexture(texture->glowtexture);
+ m.tex[0] = R_GetTexture(texture->skin.glow);
R_Mesh_State(&m);
GL_UseColorArray();
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE;
- m.tex[0] = R_GetTexture(texture->fogtexture);
+ m.tex[0] = R_GetTexture(texture->skin.fog);
R_Mesh_State(&m);
GL_UseColorArray();
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_ONE;
m.blendfunc2 = GL_ZERO;
- m.tex[0] = R_GetTexture(texture->texture);
+ m.tex[0] = R_GetTexture(texture->skin.base);
m.tex[1] = R_GetTexture((**surfchain).lightmaptexture);
- m.tex[2] = R_GetTexture(texture->detailtexture);
+ m.tex[2] = R_GetTexture(texture->skin.detail);
m.texrgbscale[0] = 1;
m.texrgbscale[1] = 4;
m.texrgbscale[2] = 2;
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_ONE;
m.blendfunc2 = GL_ZERO;
- m.tex[0] = R_GetTexture(texture->texture);
+ m.tex[0] = R_GetTexture(texture->skin.base);
m.tex[1] = R_GetTexture((**surfchain).lightmaptexture);
if (gl_combine.integer)
m.texrgbscale[1] = 4;
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_ONE;
m.blendfunc2 = GL_ZERO;
- m.tex[0] = R_GetTexture(texture->texture);
+ m.tex[0] = R_GetTexture(texture->skin.base);
R_Mesh_State(&m);
GL_Color(1, 1, 1, 1);
while((surf = *surfchain++) != NULL)
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE;
- m.tex[0] = R_GetTexture(texture->texture);
+ m.tex[0] = R_GetTexture(texture->skin.base);
colorscale = r_colorscale;
if (gl_combine.integer)
{
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_DST_COLOR;
m.blendfunc2 = GL_SRC_COLOR;
- m.tex[0] = R_GetTexture(texture->detailtexture);
+ m.tex[0] = R_GetTexture(texture->skin.detail);
R_Mesh_State(&m);
GL_Color(1, 1, 1, 1);
while((surf = *surfchain++) != NULL)
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE;
- m.tex[0] = R_GetTexture(texture->glowtexture);
+ m.tex[0] = R_GetTexture(texture->skin.glow);
R_Mesh_State(&m);
GL_Color(r_colorscale, r_colorscale, r_colorscale, 1);
while((surf = *surfchain++) != NULL)
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ZERO;
- m.tex[0] = R_GetTexture(texture->glowtexture);
+ m.tex[0] = R_GetTexture(texture->skin.glow);
R_Mesh_State(&m);
if (m.tex[0])
GL_Color(r_colorscale, r_colorscale, r_colorscale, 1);
currentalpha *= r_wateralpha.value;
if (ent->effects & EF_ADDITIVE)
rendertype = SURFRENDER_ADD;
- else if (currentalpha < 1 || texture->fogtexture != NULL)
+ else if (currentalpha < 1 || texture->skin.fog != NULL)
rendertype = SURFRENDER_ALPHA;
else
rendertype = SURFRENDER_OPAQUE;
RSurfShader_Wall_Pass_BaseVertex(ent, surf, texture, rendertype, currentalpha);
- if (texture->glowtexture)
+ if (texture->skin.glow)
RSurfShader_Wall_Pass_Glow(ent, surf, texture, rendertype, currentalpha);
if (fogenabled)
RSurfShader_Wall_Pass_Fog(ent, surf, texture, rendertype, currentalpha);
for (chain = surfchain;(surf = *chain) != NULL;chain++)
if (surf->visframe == r_framecount)
RSurfShader_Wall_Pass_BaseVertex(ent, surf, texture, texture->rendertype, texture->currentalpha);
- if (texture->glowtexture)
+ if (texture->skin.glow)
for (chain = surfchain;(surf = *chain) != NULL;chain++)
if (surf->visframe == r_framecount)
RSurfShader_Wall_Pass_Glow(ent, surf, texture, texture->rendertype, texture->currentalpha);
}
if (!r_dlightmap.integer && !(ent->effects & EF_FULLBRIGHT))
RSurfShader_OpaqueWall_Pass_Light(ent, texture, surfchain);
- if (texture->glowtexture)
+ if (texture->skin.glow)
RSurfShader_OpaqueWall_Pass_Glow(ent, texture, surfchain);
if (fogenabled)
RSurfShader_OpaqueWall_Pass_Fog(ent, texture, surfchain);
t->currentalpha *= r_wateralpha.value;
if (ent->effects & EF_ADDITIVE)
t->rendertype = SURFRENDER_ADD;
- else if (t->currentalpha < 1 || t->fogtexture != NULL)
+ else if (t->currentalpha < 1 || t->skin.fog != NULL)
t->rendertype = SURFRENDER_ALPHA;
else
t->rendertype = SURFRENDER_OPAQUE;
{
R_Mesh_ResizeCheck(mesh->numverts);
memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, lightradius, lightcolor, t->texture, t->nmaptexture, NULL);
- R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, t->glosstexture, t->nmaptexture, NULL);
+ R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, lightradius, lightcolor, t->skin.base, t->skin.nmap, NULL);
+ R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, t->skin.gloss, t->skin.nmap, NULL);
}
}
}
{
R_Mesh_ResizeCheck(mesh->numverts);
memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, lightradius, lightcolor, t->texture, t->nmaptexture, NULL);
- R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, t->glosstexture, t->nmaptexture, NULL);
+ R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, lightradius, lightcolor, t->skin.base, t->skin.nmap, NULL);
+ R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, t->skin.gloss, t->skin.nmap, NULL);
}
}
}
{
R_Mesh_ResizeCheck(mesh->numverts);
memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, lightradius, lightcolor, t->texture, t->nmaptexture, NULL);
- R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, t->glosstexture, t->nmaptexture, NULL);
+ R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, lightradius, lightcolor, t->skin.base, t->skin.nmap, NULL);
+ R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, t->skin.gloss, t->skin.nmap, NULL);
}
}
}
#include "quakedef.h"
#include "image.h"
#include "jpeg.h"
+#include "r_shadow.h"
int image_width;
int image_height;
}
}
-extern cvar_t r_shadow_bumpscale;
void Image_HeightmapToNormalmap(const unsigned char *inpixels, unsigned char *outpixels, int width, int height, int clamp, float bumpscale)
{
int x, y;
float iwidth, iheight, ibumpscale, n[3];
iwidth = 1.0f / width;
iheight = 1.0f / height;
- ibumpscale = (255.0f * 3.0f) / (bumpscale * r_shadow_bumpscale.value);
+ ibumpscale = (255.0f * 3.0f) / bumpscale;
out = outpixels;
for (y = 0;y < height;y++)
{
}
}
}
+
+int image_loadskin(imageskin_t *s, char *name)
+{
+ int j;
+ qbyte *bumppixels;
+ int bumppixels_width, bumppixels_height;
+ memset(s, 0, sizeof(*s));
+ s->basepixels = loadimagepixels(name, false, 0, 0);
+ if (s->basepixels == NULL)
+ return false;
+
+ bumppixels = NULL;bumppixels_width = 0;bumppixels_height = 0;
+ for (j = 3;j < s->basepixels_width * s->basepixels_height * 4;j += 4)
+ if (s->basepixels[j] < 255)
+ break;
+ if (j < s->basepixels_width * s->basepixels_height * 4)
+ {
+ s->maskpixels = Mem_Alloc(loadmodel->mempool, s->basepixels_width * s->basepixels_height * 4);
+ s->maskpixels_width = s->basepixels_width;
+ s->maskpixels_height = s->basepixels_height;
+ memcpy(s->maskpixels, s->basepixels, s->maskpixels_width * s->maskpixels_height * 4);
+ for (j = 0;j < s->basepixels_width * s->basepixels_height * 4;j += 4)
+ {
+ s->maskpixels[j+0] = 255;
+ s->maskpixels[j+1] = 255;
+ s->maskpixels[j+2] = 255;
+ }
+ }
+
+ // _luma is supported for tenebrae compatibility
+ // (I think it's a very stupid name, but oh well)
+ if ((s->glowpixels = loadimagepixels(va("%s_glow", name), false, 0, 0)) != NULL
+ || (s->glowpixels = loadimagepixels(va("%s_luma", name), false, 0, 0)) != NULL)
+ {
+ s->glowpixels_width = image_width;
+ s->glowpixels_height = image_height;
+ }
+ // _norm is the name used by tenebrae
+ // (I don't like the name much)
+ if ((s->nmappixels = loadimagepixels(va("%s_norm", name), false, 0, 0)) != NULL)
+ {
+ s->nmappixels_width = image_width;
+ s->nmappixels_height = image_height;
+ }
+ else if ((bumppixels = loadimagepixels(va("%s_bump", name), false, 0, 0)) != NULL)
+ {
+ bumppixels_width = image_width;
+ bumppixels_height = image_height;
+ }
+ if ((s->glosspixels = loadimagepixels(va("%s_gloss", name), false, 0, 0)) != NULL)
+ {
+ s->glosspixels_width = image_width;
+ s->glosspixels_height = image_height;
+ }
+ if ((s->pantspixels = loadimagepixels(va("%s_pants", name), false, 0, 0)) != NULL)
+ {
+ s->pantspixels_width = image_width;
+ s->pantspixels_height = image_height;
+ }
+ if ((s->shirtpixels = loadimagepixels(va("%s_shirt", name), false, 0, 0)) != NULL)
+ {
+ s->shirtpixels_width = image_width;
+ s->shirtpixels_height = image_height;
+ }
+
+ if (s->nmappixels == NULL)
+ {
+ if (bumppixels != NULL)
+ {
+ if (r_shadow_bumpscale_bumpmap.value > 0)
+ {
+ s->nmappixels = Mem_Alloc(loadmodel->mempool, bumppixels_width * bumppixels_height * 4);
+ s->nmappixels_width = bumppixels_width;
+ s->nmappixels_height = bumppixels_height;
+ Image_HeightmapToNormalmap(bumppixels, s->nmappixels, s->nmappixels_width, s->nmappixels_height, false, r_shadow_bumpscale_bumpmap.value);
+ }
+ }
+ else
+ {
+ if (r_shadow_bumpscale_basetexture.value > 0)
+ {
+ s->nmappixels = Mem_Alloc(loadmodel->mempool, s->basepixels_width * s->basepixels_height * 4);
+ s->nmappixels_width = s->basepixels_width;
+ s->nmappixels_height = s->basepixels_height;
+ Image_HeightmapToNormalmap(s->basepixels, s->nmappixels, s->nmappixels_width, s->nmappixels_height, false, r_shadow_bumpscale_basetexture.value);
+ }
+ }
+ }
+ if (bumppixels != NULL)
+ Mem_Free(bumppixels);
+ return true;
+}
+
+void image_freeskin(imageskin_t *s)
+{
+ if (s->basepixels)
+ Mem_Free(s->basepixels);
+ if (s->nmappixels)
+ Mem_Free(s->nmappixels);
+ if (s->glowpixels)
+ Mem_Free(s->glowpixels);
+ if (s->glosspixels)
+ Mem_Free(s->glosspixels);
+ if (s->pantspixels)
+ Mem_Free(s->pantspixels);
+ if (s->shirtpixels)
+ Mem_Free(s->shirtpixels);
+ memset(s, 0, sizeof(*s));
+}
+
void Image_HeightmapToNormalmap(const unsigned char *inpixels, unsigned char *outpixels, int width, int height, int clamp, float bumpscale);
+typedef struct imageskin_s
+{
+ qbyte *basepixels;int basepixels_width;int basepixels_height;
+ qbyte *nmappixels;int nmappixels_width;int nmappixels_height;
+ qbyte *glowpixels;int glowpixels_width;int glowpixels_height;
+ qbyte *glosspixels;int glosspixels_width;int glosspixels_height;
+ qbyte *pantspixels;int pantspixels_width;int pantspixels_height;
+ qbyte *shirtpixels;int shirtpixels_width;int shirtpixels_height;
+ qbyte *maskpixels;int maskpixels_width;int maskpixels_height;
+}
+imageskin_t;
+
+int image_loadskin(imageskin_t *s, char *name);
+void image_freeskin(imageskin_t *s);
+
#endif
#include "quakedef.h"
#include "image.h"
+#include "r_shadow.h"
static cvar_t r_mipskins = {CVAR_SAVE, "r_mipskins", "0"};
Mem_Free(vertexbuffer);
}
-static rtexture_t *GL_TextureForSkinLayer(const qbyte *in, int width, int height, const char *name, const unsigned int *palette, int precache)
-{
- int i;
- for (i = 0;i < width*height;i++)
- if (((qbyte *)&palette[in[i]])[3] > 0)
- return R_LoadTexture2D (loadmodel->texturepool, name, width, height, in, TEXTYPE_PALETTE, (r_mipskins.integer ? TEXF_MIPMAP : 0) | (precache ? TEXF_PRECACHE : 0), palette);
- return NULL;
-}
-
-static int Mod_LoadExternalSkin (char *basename, skinframe_t *skinframe, int precache)
-{
- skinframe->nmap = loadtextureimage(loadmodel->texturepool, va("%s_nmap" , basename), 0, 0, false, (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0));
- if (skinframe->nmap == NULL)
- skinframe->nmap = loadtextureimagebumpasnmap(loadmodel->texturepool, va("%s_bump" , basename), 0, 0, false, (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0), 1);
- if (skinframe->nmap != NULL)
- {
- skinframe->base = loadtextureimagewithmask(loadmodel->texturepool, va("%s_normal", basename), 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0));
- if (skinframe->base == NULL)
- skinframe->base = loadtextureimagewithmask(loadmodel->texturepool, basename, 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0));
- skinframe->fog = image_masktex;
- }
- else
- {
- skinframe->base = loadtextureimagewithmaskandnmap(loadmodel->texturepool, va("%s_normal", basename), 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0), 1);
- if (skinframe->base == NULL)
- skinframe->base = loadtextureimagewithmaskandnmap(loadmodel->texturepool, basename, 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0), 1);
- skinframe->fog = image_masktex;
- skinframe->nmap = image_nmaptex;
- }
- skinframe->gloss = loadtextureimage(loadmodel->texturepool, va("%s_gloss" , basename), 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0));
- skinframe->pants = loadtextureimage(loadmodel->texturepool, va("%s_pants" , basename), 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0));
- skinframe->shirt = loadtextureimage(loadmodel->texturepool, va("%s_shirt" , basename), 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0));
- skinframe->glow = loadtextureimage(loadmodel->texturepool, va("%s_glow" , basename), 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0));
- if (skinframe->glow == NULL)
- skinframe->glow = loadtextureimage(loadmodel->texturepool, va("%s_luma" , basename), 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0));
- skinframe->merged = skinframe->base;
- return skinframe->base != NULL || skinframe->pants != NULL || skinframe->shirt != NULL || skinframe->glow != NULL;
-}
-
-static int Mod_LoadInternalSkin (char *basename, qbyte *skindata, int width, int height, skinframe_t *skinframe, int precache)
-{
- qbyte *temp1, *temp2;
- if (!skindata)
- return false;
- temp1 = 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, 1);
- skinframe->nmap = R_LoadTexture2D(loadmodel->texturepool, va("%s_nmap", basename), width, height, temp2, TEXTYPE_RGBA, (r_mipskins.integer ? TEXF_MIPMAP : 0) | (precache ? TEXF_PRECACHE : 0), NULL);
- Mem_Free(temp1);
- skinframe->gloss = NULL;
- skinframe->pants = GL_TextureForSkinLayer(skindata, width, height, va("%s_pants", basename), palette_pantsaswhite, false); // pants
- skinframe->shirt = GL_TextureForSkinLayer(skindata, width, height, va("%s_shirt", basename), palette_shirtaswhite, false); // shirt
- skinframe->glow = GL_TextureForSkinLayer(skindata, width, height, va("%s_glow", basename), palette_onlyfullbrights, precache); // glow
- if (skinframe->pants || skinframe->shirt)
- {
- skinframe->base = GL_TextureForSkinLayer(skindata, width, height, va("%s_normal", basename), palette_nocolormapnofullbrights, false); // normal (no special colors)
- skinframe->merged = GL_TextureForSkinLayer(skindata, width, height, va("%s_body", basename), palette_nofullbrights, precache); // body (normal + pants + shirt, but not glow)
- }
- else
- skinframe->base = GL_TextureForSkinLayer(skindata, width, height, va("%s_base", basename), palette_nofullbrights, precache); // no special colors
- // quake model skins don't have alpha
- skinframe->fog = NULL;
- return true;
-}
-
void Mod_BuildAliasSkinFromSkinFrame(aliasskin_t *skin, skinframe_t *skinframe)
{
aliaslayer_t *layer;
sprintf (name, "%s_%i_%i", loadmodel->name, i, j);
else
sprintf (name, "%s_%i", loadmodel->name, i);
- if (!Mod_LoadExternalSkin(name, loadmodel->skinframes + totalskins, i == 0))
- Mod_LoadInternalSkin(name, (qbyte *)datapointer, skinwidth, skinheight, loadmodel->skinframes + totalskins, i == 0);
+ if (!Mod_LoadSkinFrame(loadmodel->skinframes + totalskins, name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA, true, false, true))
+ Mod_LoadSkinFrame_Internal(loadmodel->skinframes + totalskins, name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA, true, false, true, (qbyte *)datapointer, skinwidth, skinheight);
datapointer += skinwidth * skinheight;
totalskins++;
}
for (;;)
{
sprintf (name, "%s_%i", loadmodel->name, loadmodel->numskins);
- if (Mod_LoadExternalSkin(name, &tempskinframe, loadmodel->numskins == 0))
+ if (Mod_LoadSkinFrame (&tempskinframe, name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA, true, false, true))
{
// expand the arrays to make room
tempskinscenes = loadmodel->skinscenes;
loadmodel->skinscenes[i].framecount = 1;
loadmodel->skinscenes[i].loop = true;
loadmodel->skinscenes[i].framerate = 10;
- Mod_LoadExternalSkin (inskin, loadmodel->skinframes + i, true);
+ Mod_LoadSkinFrame (loadmodel->skinframes + i, inskin, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PRECACHE, true, false, true);
inskin += MD2MAX_SKINNAME;
}
}
memset(&tempskinframe, 0, sizeof(tempskinframe));
if (LittleLong(pinmesh->num_shaders) >= 1 && ((md3shader_t *)((qbyte *) pinmesh + pinmesh->lump_shaders))->name[0])
- Mod_LoadExternalSkin (((md3shader_t *)((qbyte *) pinmesh + pinmesh->lump_shaders))->name, &tempskinframe, true);
+ Mod_LoadSkinFrame (&tempskinframe, ((md3shader_t *)((qbyte *) pinmesh + pinmesh->lump_shaders))->name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PRECACHE, true, false, true);
Mod_ValidateElements(mesh->data_elements, mesh->num_triangles, mesh->num_vertices, __FILE__, __LINE__);
Mod_BuildTriangleNeighbors(mesh->data_neighbors, mesh->data_elements, mesh->num_triangles);
Mod_BuildAliasSkinFromSkinFrame(mesh->data_skins, &tempskinframe);
loadmodel->skinscenes[0].loop = true;
loadmodel->skinscenes[0].framerate = 10;
loadmodel->skinframes = (void *)(loadmodel->skinscenes + 1);
- loadmodel->skinframes->base = NULL;
- loadmodel->skinframes->fog = NULL;
- loadmodel->skinframes->pants = NULL;
- loadmodel->skinframes->shirt = NULL;
- loadmodel->skinframes->glow = NULL;
- loadmodel->skinframes->merged = NULL;
loadmodel->numskins = 1;
}
#include "quakedef.h"
#include "image.h"
+#include "r_shadow.h"
// note: model_shared.c sets up r_notexture, and r_surf_notexture
cvar_t r_nosurftextures = {0, "r_nosurftextures", "0"};
cvar_t r_sortsurfaces = {0, "r_sortsurfaces", "0"};
-#define NUM_DETAILTEXTURES 1
-static rtexture_t *detailtextures[NUM_DETAILTEXTURES];
-static rtexturepool_t *detailtexturepool;
-
/*
===============
Mod_BrushInit
memset(mod_novis, 0xff, sizeof(mod_novis));
}
-void Mod_BrushStartup (void)
-{
- int i, x, y, light;
- float vc[3], vx[3], vy[3], vn[3], lightdir[3];
-#define DETAILRESOLUTION 256
- qbyte data[DETAILRESOLUTION][DETAILRESOLUTION][4], noise[DETAILRESOLUTION][DETAILRESOLUTION];
- detailtexturepool = R_AllocTexturePool();
- lightdir[0] = 0.5;
- lightdir[1] = 1;
- lightdir[2] = -0.25;
- VectorNormalize(lightdir);
- for (i = 0;i < NUM_DETAILTEXTURES;i++)
- {
- fractalnoise(&noise[0][0], DETAILRESOLUTION, DETAILRESOLUTION >> 4);
- for (y = 0;y < DETAILRESOLUTION;y++)
- {
- for (x = 0;x < DETAILRESOLUTION;x++)
- {
- vc[0] = x;
- vc[1] = y;
- vc[2] = noise[y][x] * (1.0f / 32.0f);
- vx[0] = x + 1;
- vx[1] = y;
- vx[2] = noise[y][(x + 1) % DETAILRESOLUTION] * (1.0f / 32.0f);
- vy[0] = x;
- vy[1] = y + 1;
- vy[2] = noise[(y + 1) % DETAILRESOLUTION][x] * (1.0f / 32.0f);
- VectorSubtract(vx, vc, vx);
- VectorSubtract(vy, vc, vy);
- CrossProduct(vx, vy, vn);
- VectorNormalize(vn);
- light = 128 - DotProduct(vn, lightdir) * 128;
- light = bound(0, light, 255);
- data[y][x][0] = data[y][x][1] = data[y][x][2] = light;
- data[y][x][3] = 255;
- }
- }
- detailtextures[i] = R_LoadTexture2D(detailtexturepool, va("detailtexture%i", i), DETAILRESOLUTION, DETAILRESOLUTION, &data[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_PRECACHE, NULL);
- }
-}
-
-void Mod_BrushShutdown (void)
-{
- int i;
- for (i = 0;i < NUM_DETAILTEXTURES;i++)
- R_FreeTexture(detailtextures[i]);
- R_FreeTexturePool(&detailtexturepool);
-}
-
/*
===============
Mod_PointInLeaf
dmiptexlump_t *m;
qbyte *data, *mtdata;
char name[256];
- qbyte *basepixels, *bumppixels, *nmappixels, *glosspixels, *glowpixels, *maskpixels;
- int basepixels_width, basepixels_height, bumppixels_width, bumppixels_height;
- int nmappixels_width, nmappixels_height, glosspixels_width, glosspixels_height;
- int glowpixels_width, glowpixels_height, maskpixels_width, maskpixels_height;
- rtexture_t *detailtexture;
loadmodel->textures = NULL;
for (i = 0, tx = loadmodel->textures;i < loadmodel->numtextures;i++, tx++)
{
tx->number = i;
+ strcpy(tx->name, "NO TEXTURE FOUND");
tx->width = 16;
tx->height = 16;
- tx->texture = r_notexture;
+ tx->skin.base = r_notexture;
tx->shader = &Cshader_wall_lightmap;
if (i == loadmodel->numtextures - 1)
{
Con_Printf("warning: unnamed texture in %s, renaming to %s\n", loadmodel->name, tx->name);
}
- basepixels = NULL;basepixels_width = 0;basepixels_height = 0;
- bumppixels = NULL;bumppixels_width = 0;bumppixels_height = 0;
- nmappixels = NULL;nmappixels_width = 0;nmappixels_height = 0;
- glosspixels = NULL;glosspixels_width = 0;glosspixels_height = 0;
- glowpixels = NULL;glowpixels_width = 0;glowpixels_height = 0;
- maskpixels = NULL;maskpixels_width = 0;maskpixels_height = 0;
- detailtexture = NULL;
-
// LordHavoc: HL sky textures are entirely different than quake
if (!loadmodel->ishlbsp && !strncmp(tx->name, "sky", 3) && mtwidth == 256 && mtheight == 128)
{
}
else
{
- if ((basepixels = loadimagepixels(tx->name, false, 0, 0)) != NULL)
- {
- basepixels_width = image_width;
- basepixels_height = image_height;
- }
- // _luma is supported for tenebrae compatibility
- // (I think it's a very stupid name, but oh well)
- if ((glowpixels = loadimagepixels(va("%s_glow", tx->name), false, 0, 0)) != NULL
- || (glowpixels = loadimagepixels(va("%s_luma", tx->name), false, 0, 0)) != NULL)
- {
- glowpixels_width = image_width;
- glowpixels_height = image_height;
- }
- if ((bumppixels = loadimagepixels(va("%s_bump", tx->name), false, 0, 0)) != NULL)
- {
- bumppixels_width = image_width;
- bumppixels_height = image_height;
- }
- if ((glosspixels = loadimagepixels(va("%s_gloss", tx->name), false, 0, 0)) != NULL)
- {
- glosspixels_width = image_width;
- glosspixels_height = image_height;
- }
- if (!basepixels)
+ if (!Mod_LoadSkinFrame(&tx->skin, tx->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, false, true, true))
{
+ // did not find external texture, load it from the bsp or wad3
if (loadmodel->ishlbsp)
{
// internal texture overrides wad
- if (mtdata && (basepixels = W_ConvertWAD3Texture(dmiptex)) != NULL)
- {
- basepixels_width = image_width;
- basepixels_height = image_height;
- }
- else if ((basepixels = W_GetTexture(tx->name)) != NULL)
- {
- // get the size from the wad texture
- tx->width = basepixels_width = image_width;
- tx->height = basepixels_height = image_height;
- }
- }
- else
- {
- if (mtdata) // texture included
+ qbyte *pixels, *freepixels;
+ pixels = freepixels = NULL;
+ if (mtdata)
+ pixels = W_ConvertWAD3Texture(dmiptex);
+ if (pixels == NULL)
+ pixels = freepixels = W_GetTexture(tx->name);
+ if (pixels != NULL)
{
- if (r_fullbrights.integer && tx->name[0] != '*')
- {
- basepixels_width = tx->width;
- basepixels_height = tx->height;
- basepixels = Mem_Alloc(loadmodel->mempool, basepixels_width * basepixels_height * 4);
- Image_Copy8bitRGBA(mtdata, basepixels, basepixels_width * basepixels_height, palette_nofullbrights);
- if (!glowpixels)
- {
- for (j = 0;j < (int)(tx->width*tx->height);j++)
- if (((qbyte *)&palette_onlyfullbrights[mtdata[j]])[3] > 0) // fullbright
- break;
- if (j < (int)(tx->width * tx->height))
- {
- glowpixels_width = tx->width;
- glowpixels_height = tx->height;
- glowpixels = Mem_Alloc(loadmodel->mempool, glowpixels_width * glowpixels_height * 4);
- Image_Copy8bitRGBA(mtdata, glowpixels, glowpixels_width * glowpixels_height, palette_onlyfullbrights);
- }
- }
- }
- else
- {
- basepixels_width = tx->width;
- basepixels_height = tx->height;
- basepixels = Mem_Alloc(loadmodel->mempool, basepixels_width * basepixels_height * 4);
- Image_Copy8bitRGBA(mtdata, basepixels, tx->width * tx->height, palette_complete);
- }
+ 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, NULL);
}
+ if (freepixels)
+ Mem_Free(freepixels);
}
+ else if (mtdata) // texture included
+ Mod_LoadSkinFrame_Internal(&tx->skin, tx->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, false, true, tx->name[0] != '*' && r_fullbrights.integer, mtdata, tx->width, tx->height);
}
}
-
- if (basepixels)
- {
- for (j = 3;j < basepixels_width * basepixels_height * 4;j += 4)
- if (basepixels[j] < 255)
- break;
- if (j < basepixels_width * basepixels_height * 4)
- {
- maskpixels = Mem_Alloc(loadmodel->mempool, basepixels_width * basepixels_height * 4);
- maskpixels_width = basepixels_width;
- maskpixels_height = basepixels_height;
- for (j = 0;j < basepixels_width * basepixels_height * 4;j += 4)
- {
- maskpixels[j+0] = 255;
- maskpixels[j+1] = 255;
- maskpixels[j+2] = 255;
- maskpixels[j+3] = basepixels[j+3];
- }
- }
-
- if (!bumppixels)
- {
- bumppixels = Mem_Alloc(loadmodel->mempool, basepixels_width * basepixels_height * 4);
- bumppixels_width = basepixels_width;
- bumppixels_height = basepixels_height;
- memcpy(bumppixels, basepixels, bumppixels_width * bumppixels_height * 4);
- }
-
- if (!nmappixels && bumppixels)
- {
- nmappixels = Mem_Alloc(loadmodel->mempool, bumppixels_width * bumppixels_height * 4);
- nmappixels_width = bumppixels_width;
- nmappixels_height = bumppixels_height;
- Image_HeightmapToNormalmap(bumppixels, nmappixels, nmappixels_width, nmappixels_height, false, 1);
- }
- }
-
- if (!detailtexture)
- detailtexture = detailtextures[i % NUM_DETAILTEXTURES];
-
- if (basepixels)
- {
- tx->texture = R_LoadTexture2D (loadmodel->texturepool, tx->name, basepixels_width, basepixels_height, basepixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
- if (nmappixels)
- tx->nmaptexture = R_LoadTexture2D (loadmodel->texturepool, va("%s_nmap", tx->name), basepixels_width, basepixels_height, nmappixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
- if (glosspixels)
- tx->glosstexture = R_LoadTexture2D (loadmodel->texturepool, va("%s_gloss", tx->name), glosspixels_width, glosspixels_height, glosspixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
- if (glowpixels)
- tx->glowtexture = R_LoadTexture2D (loadmodel->texturepool, va("%s_glow", tx->name), glowpixels_width, glowpixels_height, glowpixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
- if (maskpixels)
- tx->fogtexture = R_LoadTexture2D (loadmodel->texturepool, va("%s_mask", tx->name), maskpixels_width, maskpixels_height, maskpixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
- tx->detailtexture = detailtexture;
- }
- else
+ if (tx->skin.base == NULL)
{
// no texture found
tx->width = 16;
tx->height = 16;
- tx->texture = r_notexture;
- tx->nmaptexture = NULL;
- tx->glosstexture = NULL;
- tx->glowtexture = NULL;
- tx->fogtexture = NULL;
- tx->detailtexture = NULL;
- }
-
- if (basepixels)
- Mem_Free(basepixels);
- if (bumppixels)
- Mem_Free(bumppixels);
- if (nmappixels)
- Mem_Free(nmappixels);
- if (glosspixels)
- Mem_Free(glosspixels);
- if (glowpixels)
- Mem_Free(glowpixels);
- if (maskpixels)
- Mem_Free(maskpixels);
+ tx->skin.base = r_notexture;
+ }
if (tx->name[0] == '*')
{
else
{
tx->flags |= SURF_LIGHTMAP;
- if (!tx->fogtexture)
+ if (!tx->skin.fog)
tx->flags |= SURF_SHADOWCAST | SURF_SHADOWLIGHT;
tx->shader = &Cshader_wall_lightmap;
}
// type of rendering (SURFRENDER_ value)
int rendertype;
- // base texture without fullbrights, never NULL
- rtexture_t *texture;
- // fullbrights texture, NULL if no fullbrights used
- rtexture_t *glowtexture;
- // alpha texture (used for fogging), NULL if opaque
- rtexture_t *fogtexture;
- // detail texture (usually not used if transparent)
- rtexture_t *detailtexture;
- // normalmap for bumpmap shading
- rtexture_t *nmaptexture;
- // color filtering for glossy surfaces
- rtexture_t *glosstexture;
+ // loaded the same as model skins
+ skinframe_t skin;
// shader to use for this texture
Cshader_t *shader;
// on the same machine.
#include "quakedef.h"
+#include "image.h"
+#include "r_shadow.h"
model_t *loadmodel;
#define MAX_MOD_KNOWN 2048
static model_t mod_known[MAX_MOD_KNOWN];
+rtexturepool_t *mod_shared_texturepool;
rtexture_t *r_notexture;
-rtexturepool_t *r_notexturepool;
+rtexture_t *mod_shared_detailtextures[NUM_DETAILTEXTURES];
+
+void Mod_BuildDetailTextures (void)
+{
+ int i, x, y, light;
+ float vc[3], vx[3], vy[3], vn[3], lightdir[3];
+#define DETAILRESOLUTION 256
+ qbyte data[DETAILRESOLUTION][DETAILRESOLUTION][4], noise[DETAILRESOLUTION][DETAILRESOLUTION];
+ lightdir[0] = 0.5;
+ lightdir[1] = 1;
+ lightdir[2] = -0.25;
+ VectorNormalize(lightdir);
+ for (i = 0;i < NUM_DETAILTEXTURES;i++)
+ {
+ fractalnoise(&noise[0][0], DETAILRESOLUTION, DETAILRESOLUTION >> 4);
+ for (y = 0;y < DETAILRESOLUTION;y++)
+ {
+ for (x = 0;x < DETAILRESOLUTION;x++)
+ {
+ vc[0] = x;
+ vc[1] = y;
+ vc[2] = noise[y][x] * (1.0f / 32.0f);
+ vx[0] = x + 1;
+ vx[1] = y;
+ vx[2] = noise[y][(x + 1) % DETAILRESOLUTION] * (1.0f / 32.0f);
+ vy[0] = x;
+ vy[1] = y + 1;
+ vy[2] = noise[(y + 1) % DETAILRESOLUTION][x] * (1.0f / 32.0f);
+ VectorSubtract(vx, vc, vx);
+ VectorSubtract(vy, vc, vy);
+ CrossProduct(vx, vy, vn);
+ VectorNormalize(vn);
+ light = 128 - DotProduct(vn, lightdir) * 128;
+ light = bound(0, light, 255);
+ data[y][x][0] = data[y][x][1] = data[y][x][2] = light;
+ data[y][x][3] = 255;
+ }
+ }
+ mod_shared_detailtextures[i] = R_LoadTexture2D(mod_shared_texturepool, va("detailtexture%i", i), DETAILRESOLUTION, DETAILRESOLUTION, &data[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_PRECACHE, NULL);
+ }
+}
texture_t r_surf_notexture;
}
}
- r_notexturepool = R_AllocTexturePool();
- r_notexture = R_LoadTexture2D(r_notexturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP, NULL);
+ r_notexture = R_LoadTexture2D(mod_shared_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP, NULL);
}
-extern void Mod_BrushStartup (void);
-extern void Mod_BrushShutdown (void);
-
static void mod_start(void)
{
int i;
Mod_UnloadModel(&mod_known[i]);
Mod_LoadModels();
+ mod_shared_texturepool = R_AllocTexturePool();
Mod_SetupNoTexture();
- Mod_BrushStartup();
+ Mod_BuildDetailTextures();
}
static void mod_shutdown(void)
if (mod_known[i].name[0])
Mod_UnloadModel(&mod_known[i]);
- R_FreeTexturePool(&r_notexturepool);
- Mod_BrushShutdown();
+ R_FreeTexturePool(&mod_shared_texturepool);
}
static void mod_newmap(void)
Mem_Free(mesh);
}
}
+
+static rtexture_t *GL_TextureForSkinLayer(const qbyte *in, int width, int height, const char *name, const unsigned int *palette, int textureflags)
+{
+ int i;
+ for (i = 0;i < width*height;i++)
+ if (((qbyte *)&palette[in[i]])[3] > 0)
+ return R_LoadTexture2D (loadmodel->texturepool, name, width, height, in, TEXTYPE_PALETTE, textureflags, palette);
+ return NULL;
+}
+
+static int detailtexturecycle = 0;
+int Mod_LoadSkinFrame (skinframe_t *skinframe, char *basename, int textureflags, int loadpantsandshirt, int usedetailtexture, int loadglowtexture)
+{
+ imageskin_t s;
+ memset(skinframe, 0, sizeof(*skinframe));
+ if (!image_loadskin(&s, basename))
+ return false;
+ if (usedetailtexture)
+ skinframe->detail = mod_shared_detailtextures[(detailtexturecycle++) % NUM_DETAILTEXTURES];
+ skinframe->base = R_LoadTexture2D (loadmodel->texturepool, basename, s.basepixels_width, s.basepixels_height, s.basepixels, TEXTYPE_RGBA, textureflags, NULL);
+ if (s.nmappixels != NULL)
+ skinframe->nmap = R_LoadTexture2D (loadmodel->texturepool, va("%s_nmap", basename), s.basepixels_width, s.basepixels_height, s.nmappixels, TEXTYPE_RGBA, textureflags, NULL);
+ if (s.glosspixels != NULL)
+ skinframe->gloss = R_LoadTexture2D (loadmodel->texturepool, va("%s_gloss", basename), s.glosspixels_width, s.glosspixels_height, s.glosspixels, TEXTYPE_RGBA, textureflags, NULL);
+ if (s.glowpixels != NULL && loadglowtexture)
+ skinframe->glow = R_LoadTexture2D (loadmodel->texturepool, va("%s_glow", basename), s.glowpixels_width, s.glowpixels_height, s.glowpixels, TEXTYPE_RGBA, textureflags, NULL);
+ if (s.maskpixels != NULL)
+ skinframe->fog = R_LoadTexture2D (loadmodel->texturepool, va("%s_mask", basename), s.maskpixels_width, s.maskpixels_height, s.maskpixels, TEXTYPE_RGBA, textureflags, NULL);
+ if (loadpantsandshirt)
+ {
+ if (s.pantspixels != NULL)
+ skinframe->pants = R_LoadTexture2D (loadmodel->texturepool, va("%s_pants", basename), s.pantspixels_width, s.pantspixels_height, s.pantspixels, TEXTYPE_RGBA, textureflags, NULL);
+ if (s.shirtpixels != NULL)
+ skinframe->shirt = R_LoadTexture2D (loadmodel->texturepool, va("%s_shirt", basename), s.shirtpixels_width, s.shirtpixels_height, s.shirtpixels, TEXTYPE_RGBA, textureflags, NULL);
+ }
+ image_freeskin(&s);
+ return true;
+}
+
+int Mod_LoadSkinFrame_Internal (skinframe_t *skinframe, char *basename, int textureflags, int loadpantsandshirt, int usedetailtexture, int loadglowtexture, qbyte *skindata, int width, int height)
+{
+ qbyte *temp1, *temp2;
+ memset(skinframe, 0, sizeof(*skinframe));
+ if (!skindata)
+ return false;
+ if (usedetailtexture)
+ skinframe->detail = mod_shared_detailtextures[(detailtexturecycle++) % NUM_DETAILTEXTURES];
+ if (r_shadow_bumpscale_basetexture.value > 0)
+ {
+ temp1 = 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)
+ {
+ 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->base = skinframe->merged = GL_TextureForSkinLayer(skindata, width, height, va("%s_merged", basename), palette_complete, 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_nocolormap, textureflags); // no pants or shirt
+ }
+ }
+ return true;
+}
typedef struct skinframe_s
{
- rtexture_t *base; // original texture minus pants/shirt/glow
+ rtexture_t *base; // original texture without pants/shirt/glow
rtexture_t *pants; // pants only (in greyscale)
rtexture_t *shirt; // shirt only (in greyscale)
- rtexture_t *glow; // glow only
- rtexture_t *merged; // original texture minus glow
- rtexture_t *fog; // white texture with alpha of the base texture, NULL if not transparent
+ rtexture_t *glow; // glow only (fullbrights)
+ rtexture_t *merged; // original texture without glow
+ rtexture_t *fog; // alpha of the base texture (if not opaque)
rtexture_t *nmap; // normalmap (bumpmap for dot3)
rtexture_t *gloss; // glossmap (for dot3)
+ rtexture_t *detail; // detail texture (silly bumps for non-dot3)
}
skinframe_t;
// this can be used for anything without a valid texture
extern rtexture_t *r_notexture;
+#define NUM_DETAILTEXTURES 1
+extern rtexture_t *mod_shared_detailtextures[NUM_DETAILTEXTURES];
// every texture must be in a pool...
-extern rtexturepool_t *r_notexturepool;
+extern rtexturepool_t *mod_shared_texturepool;
// model loading
extern model_t *loadmodel;
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 usedetailtexture, int loadglowtexture);
+int Mod_LoadSkinFrame_Internal (skinframe_t *skinframe, char *basename, int textureflags, int loadpantsandshirt, int usedetailtexture, int loadglowtexture, qbyte *skindata, int width, int height);
+
#endif // __MODEL__
unsigned int palette_nofullbrights[256];
unsigned int palette_onlyfullbrights[256];
unsigned int palette_nocolormapnofullbrights[256];
+unsigned int palette_nocolormap[256];
unsigned int palette_pantsaswhite[256];
unsigned int palette_shirtaswhite[256];
unsigned int palette_alpha[256];
palette_nocolormapnofullbrights[i] = palette_complete[0];
palette_nocolormapnofullbrights[255] = 0;
+ for (i = 0;i < 256;i++)
+ palette_nocolormap[i] = palette_complete[i];
+ for (i = pants_start;i < pants_end;i++)
+ palette_nocolormap[i] = palette_complete[0];
+ for (i = shirt_start;i < shirt_end;i++)
+ palette_nocolormap[i] = palette_complete[0];
+ palette_nocolormap[255] = 0;
+
for (i = 0;i < 256;i++)
palette_pantsaswhite[i] = palette_complete[0];
for (i = pants_start;i < pants_end;i++)
extern unsigned int palette_nofullbrights[256];
extern unsigned int palette_onlyfullbrights[256];
extern unsigned int palette_nocolormapnofullbrights[256];
+extern unsigned int palette_nocolormap[256];
extern unsigned int palette_pantsaswhite[256];
extern unsigned int palette_shirtaswhite[256];
extern unsigned int palette_alpha[256];
rtexture_t *r_shadow_blankglosstexture;
rtexture_t *r_shadow_blankwhitetexture;
+cvar_t r_shadow_lightattenuationpower = {0, "r_shadow_lightattenuationpower", "2"};
cvar_t r_shadow_lightattenuationscale = {0, "r_shadow_lightattenuationscale", "2"};
cvar_t r_shadow_lightintensityscale = {0, "r_shadow_lightintensityscale", "1"};
cvar_t r_shadow_realtime = {0, "r_shadow_realtime", "0"};
cvar_t r_shadow_gloss = {0, "r_shadow_gloss", "1"};
cvar_t r_shadow_debuglight = {0, "r_shadow_debuglight", "-1"};
cvar_t r_shadow_scissor = {0, "r_shadow_scissor", "1"};
-cvar_t r_shadow_bumpscale = {0, "r_shadow_bumpscale", "4"};
+cvar_t r_shadow_bumpscale_bumpmap = {0, "r_shadow_bumpscale_bumpmap", "4"};
+cvar_t r_shadow_bumpscale_basetexture = {0, "r_shadow_bumpscale_basetexture", "4"};
cvar_t r_shadow_shadownudge = {0, "r_shadow_shadownudge", "1"};
void R_Shadow_ClearWorldLights(void);
void R_Shadow_Init(void)
{
+ Cvar_RegisterVariable(&r_shadow_lightattenuationpower);
Cvar_RegisterVariable(&r_shadow_lightattenuationscale);
Cvar_RegisterVariable(&r_shadow_lightintensityscale);
Cvar_RegisterVariable(&r_shadow_realtime);
Cvar_RegisterVariable(&r_shadow_gloss);
Cvar_RegisterVariable(&r_shadow_debuglight);
Cvar_RegisterVariable(&r_shadow_scissor);
- Cvar_RegisterVariable(&r_shadow_bumpscale);
+ Cvar_RegisterVariable(&r_shadow_bumpscale_bumpmap);
+ Cvar_RegisterVariable(&r_shadow_bumpscale_basetexture);
Cvar_RegisterVariable(&r_shadow_shadownudge);
R_Shadow_EditLights_Init();
R_RegisterModule("R_Shadow", r_shadow_start, r_shadow_shutdown, r_shadow_newmap);
}
}
-float r_shadow_atten1;
+float r_shadow_attenpower, r_shadow_attenscale;
static void R_Shadow_MakeTextures(void)
{
int x, y, d, side;
qbyte *data;
R_FreeTexturePool(&r_shadow_texturepool);
r_shadow_texturepool = R_AllocTexturePool();
- r_shadow_atten1 = r_shadow_lightattenuationscale.value;
+ r_shadow_attenpower = r_shadow_lightattenuationpower.value;
+ r_shadow_attenscale = r_shadow_lightattenuationscale.value;
data = Mem_Alloc(tempmempool, 6*128*128*4);
data[0] = 128;
data[1] = 128;
v[2] = 0;
intensity = 1.0f - sqrt(DotProduct(v, v));
if (intensity > 0)
- intensity *= intensity;
- intensity = bound(0, intensity * r_shadow_atten1 * 256.0f, 255.0f);
+ intensity = pow(intensity, r_shadow_attenpower);
+ intensity = bound(0, intensity * r_shadow_attenscale * 256.0f, 255.0f);
d = bound(0, intensity, 255);
data[((0*128+y)*128+x)*4+0] = d;
data[((0*128+y)*128+x)*4+1] = d;
//cl.worldmodel->numlights = min(cl.worldmodel->numlights, 1);
if (!r_shadow_attenuation2dtexture
- || r_shadow_lightattenuationscale.value != r_shadow_atten1)
+ || r_shadow_lightattenuationpower.value != r_shadow_attenpower
+ || r_shadow_lightattenuationscale.value != r_shadow_attenscale)
R_Shadow_MakeTextures();
if (r_shadow_reloadlights && cl.worldmodel)
{
extern cvar_t r_shadow_realtime;
extern cvar_t r_shadow_gloss;
extern cvar_t r_shadow_debuglight;
+extern cvar_t r_shadow_bumpscale_bumpmap;
+extern cvar_t r_shadow_bumpscale_basetexture;
void R_Shadow_Init(void);
void R_Shadow_Volume(int numverts, int numtris, int *elements, int *neighbors, vec3_t relativelightorigin, float lightradius, float projectdistance);