Add an experimental shading mode to Polymost for .art tiles, in which extra textures are allocated for each shade level based on the classic mode shade tables. Enable with r_usetileshades 1 (disabled by default). This uses a lot of memory and is still very WIP (a lot of the shading is completely wrong at this point).

Also, further refactor texcache code.

git-svn-id: https://svn.eduke32.com/eduke32@3761 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
terminx 2013-05-15 02:18:27 +00:00
parent 68d49020b1
commit 5a4e7b651b
5 changed files with 148 additions and 134 deletions

View File

@ -57,11 +57,13 @@ extern int32_t shadescale_unbounded;
extern float alphahackarray[MAXTILES];
extern int32_t r_usenewshading;
extern int32_t r_usetileshades;
static inline float getshadefactor(int32_t shade)
{
int32_t shadebound = (shadescale_unbounded || shade>=numshades) ? numshades : numshades-1;
float clamped_shade = min(max(shade*shadescale, 0), shadebound);
if (rendmode == REND_POLYMOST && r_usetileshades) return 1.f;
return ((float)(numshades-clamped_shade))/(float)numshades;
}
@ -71,6 +73,7 @@ typedef struct pthtyp_t
uint32_t glpic;
int16_t picnum;
char palnum;
char shade;
char effects;
char flags; // 1 = clamped (dameth&4), 2 = hightile, 4 = skybox face, 8 = hasalpha, 16 = hasfullbright, 128 = invalidated
char skyface;
@ -81,7 +84,7 @@ typedef struct pthtyp_t
struct pthtyp_t *ofb; // only fullbright
} pthtyp;
extern int32_t gloadtile_art(int32_t,int32_t,int32_t,pthtyp *,int32_t);
extern int32_t gloadtile_art(int32_t,int32_t,int32_t,int32_t,pthtyp *,int32_t);
extern int32_t gloadtile_hi(int32_t,int32_t,int32_t,hicreplctyp *,int32_t,pthtyp *,int32_t,char);
extern int32_t globalnoeffect;

View File

@ -33,11 +33,16 @@ extern void texcache_init(void);
extern void texcache_clearmem(void);
extern int32_t texcache_loadoffsets(void);
extern int32_t texcache_readdata(void *dest, int32_t len);
extern pthtyp *texcache_fetch(int32_t dapicnum, int32_t dapalnum, int32_t dameth);
extern pthtyp *texcache_fetch(int32_t dapicnum, int32_t dapalnum, int32_t dashade, int32_t dameth);
extern int32_t texcache_loadskin(const texcacheheader *head, int32_t *doalloc, GLuint *glpic, int32_t *xsiz, int32_t *ysiz);
extern int32_t texcache_loadtile(const texcacheheader *head, int32_t *doalloc, pthtyp *pth);
extern void texcache_writetex(const char *fn, int32_t len, int32_t dameth, char effect, texcacheheader *head);
extern int32_t texcache_readtexheader(const char *fn, int32_t len, int32_t dameth, char effect, texcacheheader *head, int32_t modelp);
extern void texcache_closefiles(void);
extern void texcache_openfiles(void);
extern void texcache_setupmemcache(void);
extern void texcache_checkgarbage(void);
extern void texcache_setupindex(void);
#endif
#endif

View File

@ -1019,7 +1019,7 @@ void polymer_drawrooms(int32_t daposx, int32_t daposy, int32_t da
skyhoriz += 360.0f;
drawingskybox = 1;
pth = texcache_fetch(cursky,0,0);
pth = texcache_fetch(cursky,0,0,0);
drawingskybox = 0;
// if it's not a skybox, make the sky parallax
@ -1547,7 +1547,7 @@ int16_t polymer_addlight(_prlight* light)
loadtile(picnum);
pth = NULL;
pth = texcache_fetch(picnum, 0, 0);
pth = texcache_fetch(picnum, 0, 0, 0);
if (pth)
light->lightmap = pth->glpic;
@ -3827,7 +3827,7 @@ static void polymer_drawsky(int16_t tilenum, char palnum, int8_t shade)
bglScalef(1000.0f, 1000.0f, 1000.0f);
drawingskybox = 1;
pth = texcache_fetch(tilenum,0,0);
pth = texcache_fetch(tilenum,0,0,0);
drawingskybox = 0;
if (pth && (pth->flags & 4))
@ -3868,7 +3868,7 @@ static void polymer_drawartsky(int16_t tilenum, char palnum, int8_t shad
DO_TILE_ANIM(picnum, 0);
if (!waloff[picnum])
loadtile(picnum);
pth = texcache_fetch(picnum, palnum, 0);
pth = texcache_fetch(picnum, palnum, 0, 0);
glpics[i] = pth ? pth->glpic : 0;
glcolors[i][0] = glcolors[i][1] = glcolors[i][2] = getshadefactor(shade);
@ -3958,7 +3958,7 @@ static void polymer_drawskybox(int16_t tilenum, char palnum, int8_t shad
while (i < 6)
{
drawingskybox = i + 1;
pth = texcache_fetch(tilenum, palnum, 4);
pth = texcache_fetch(tilenum, palnum, 0, 4);
color[0] = color[1] = color[2] = getshadefactor(shade);
@ -4558,7 +4558,7 @@ static void polymer_getbuildmaterial(_prmaterial* material, int16_t tile
loadtile(tilenum);
// PR_BIT_DIFFUSE_MAP
pth = texcache_fetch(tilenum, pal, cmeth);
pth = texcache_fetch(tilenum, pal, 0, cmeth);
if (pth)
material->diffusemap = pth->glpic;
@ -4719,7 +4719,7 @@ static void polymer_getbuildmaterial(_prmaterial* material, int16_t tile
}
// PR_BIT_DIFFUSE_DETAIL_MAP
if (hicfindsubst(tilenum, DETAILPAL, 0) && (pth = texcache_fetch(tilenum, DETAILPAL, 0)) &&
if (hicfindsubst(tilenum, DETAILPAL, 0) && (pth = texcache_fetch(tilenum, DETAILPAL, 0, 0)) &&
pth->hicr && (pth->hicr->palnum == DETAILPAL))
{
material->detailmap = pth->glpic;
@ -4728,17 +4728,17 @@ static void polymer_getbuildmaterial(_prmaterial* material, int16_t tile
}
// PR_BIT_GLOW_MAP
if (hicfindsubst(tilenum, GLOWPAL, 0) && (pth = texcache_fetch(tilenum, GLOWPAL, 0)) &&
if (hicfindsubst(tilenum, GLOWPAL, 0) && (pth = texcache_fetch(tilenum, GLOWPAL, 0, 0)) &&
pth->hicr && (pth->hicr->palnum == GLOWPAL))
material->glowmap = pth->glpic;
// PR_BIT_SPECULAR_MAP
if (hicfindsubst(tilenum, SPECULARPAL, 0) && (pth = texcache_fetch(tilenum, SPECULARPAL, 0)) &&
if (hicfindsubst(tilenum, SPECULARPAL, 0) && (pth = texcache_fetch(tilenum, SPECULARPAL, 0, 0)) &&
pth->hicr && (pth->hicr->palnum == SPECULARPAL))
material->specmap = pth->glpic;
// PR_BIT_NORMAL_MAP
if (hicfindsubst(tilenum, NORMALPAL, 0) && (pth = texcache_fetch(tilenum, NORMALPAL, 0)) &&
if (hicfindsubst(tilenum, NORMALPAL, 0) && (pth = texcache_fetch(tilenum, NORMALPAL, 0, 0)) &&
pth->hicr && (pth->hicr->palnum == NORMALPAL))
{
material->normalmap = pth->glpic;
@ -5437,7 +5437,7 @@ static void polymer_updatelights(void)
loadtile(picnum);
pth = NULL;
pth = texcache_fetch(picnum, 0, 0);
pth = texcache_fetch(picnum, 0, 0, 0);
if (pth)
light->lightmap = pth->glpic;

View File

@ -110,6 +110,7 @@ float shadescale = 1.0f;
int32_t shadescale_unbounded = 0;
int32_t r_usenewshading = 2;
int32_t r_usetileshades = 0;
static double gviewxrange, ghoriz;
double gyxscale, gxyaspect, ghalfx, grhalfxdown10, grhalfxdown10x;
@ -483,77 +484,11 @@ void polymost_glinit()
bglEnableClientState(GL_TEXTURE_COORD_ARRAY);
texcache_init();
texcache_loadoffsets();
Bstrcpy(ptempbuf,TEXCACHEFILE);
Bstrcat(ptempbuf,".cache");
texcache_indexptr = Bfopen(ptempbuf, "at+");
if (!texcache_indexptr)
{
glusetexcache = 0;
initprintf("Unable to open cache index \"%s\": %s\n", ptempbuf, strerror(errno));
return;
}
fseek(texcache_indexptr, 0, BSEEK_END);
if (!ftell(texcache_indexptr))
{
rewind(texcache_indexptr);
Bfprintf(texcache_indexptr,"// automatically generated by EDuke32, DO NOT MODIFY!\n");
}
else rewind(texcache_indexptr);
texcache_filehandle = Bopen(TEXCACHEFILE, BO_BINARY|BO_CREAT|BO_APPEND|BO_RDWR, BS_IREAD|BS_IWRITE);
if (texcache_filehandle < 0)
{
initprintf("Unable to open cache file \"%s\": %s\n", TEXCACHEFILE, strerror(errno));
glusetexcache = 0;
return;
}
initprintf("Opened \"%s\" as cache file\n", TEXCACHEFILE);
if (glusememcache && !texcache_noalloc)
{
texcache_memsize = filelength(texcache_filehandle);
if (texcache_memsize > 0)
{
texcache_memptr = (uint8_t *)Brealloc(texcache_memptr, texcache_memsize);
if (!texcache_memptr)
{
initprintf("Failed allocating %d bytes for memcache, disabling memcache.\n", texcache_memsize);
texcache_clearmem();
texcache_noalloc = 1;
}
else
{
if (Bread(texcache_filehandle, texcache_memptr, texcache_memsize) != texcache_memsize)
{
initprintf("Failed reading texcache into memcache!\n");
texcache_clearmem();
texcache_noalloc = 1;
}
}
}
}
i = 0;
texcache_currentindex = texcache_firstindex;
while (texcache_currentindex->next)
{
i += texcache_currentindex->len;
texcache_currentindex = texcache_currentindex->next;
}
i = Blseek(texcache_filehandle, 0, BSEEK_END)-i;
if (i)
initprintf("Cache contains %d bytes of garbage data\n",i);
// Blseek(cachefilehandle, 0, BSEEK_SET);
texcache_openfiles();
texcache_setupmemcache();
texcache_checkgarbage();
}
////////// VISIBILITY FOG ROUTINES //////////
@ -925,7 +860,7 @@ static void texture_setup(int32_t dameth)
}
}
int32_t gloadtile_art(int32_t dapic, int32_t dapal, int32_t dameth, pthtyp *pth, int32_t doalloc)
int32_t gloadtile_art(int32_t dapic, int32_t dapal, int32_t dashade, int32_t dameth, pthtyp *pth, int32_t doalloc)
{
coltype *pic;
int32_t xsiz, ysiz;
@ -1010,7 +945,8 @@ int32_t gloadtile_art(int32_t dapic, int32_t dapal, int32_t dameth, pthtyp *pth,
if (dacol != 255)
{
dacol = (uint8_t)palookup[dapal][dacol];
char *p = (char *)(palookup[dapal])+(int32_t)(dashade<<8);
dacol = (uint8_t)p[dacol];
}
else
{
@ -1035,6 +971,7 @@ int32_t gloadtile_art(int32_t dapic, int32_t dapal, int32_t dameth, pthtyp *pth,
pth->picnum = dapic;
pth->palnum = dapal;
pth->shade = dashade;
pth->effects = 0;
pth->flags = ((dameth&4)>>2) | (hasalpha<<3);
pth->hicr = NULL;
@ -1047,7 +984,7 @@ int32_t gloadtile_art(int32_t dapic, int32_t dapal, int32_t dameth, pthtyp *pth,
pth->ofb = (pthtyp *)Bcalloc(1,sizeof(pthtyp));
if (!pth->ofb) return 1;
pth->flags |= (1<<4);
if (gloadtile_art(dapic, dapal, dameth, pth->ofb, 1)) return 1;
if (gloadtile_art(dapic, dapal, 0, dameth, pth->ofb, 1)) return 1;
fullbrightloadingpass = 0;
}
@ -1435,7 +1372,7 @@ void drawpoly(double *dpx, double *dpy, int32_t n, int32_t method)
float hackscx, hackscy;
if (skyclamphack) method |= 4;
pth = texcache_fetch(globalpicnum,globalpal,method&(~3));
pth = texcache_fetch(globalpicnum,globalpal,min(max(globalshade,0),numshades-1),method&(~3));
if (!pth)
{
@ -1482,7 +1419,7 @@ void drawpoly(double *dpx, double *dpy, int32_t n, int32_t method)
detailpth = NULL;
if (r_detailmapping && usehightile && !drawingskybox &&
hicfindsubst(globalpicnum, DETAILPAL, 0))
detailpth = texcache_fetch(globalpicnum, DETAILPAL, method&(~3));
detailpth = texcache_fetch(globalpicnum, DETAILPAL, 0, method&(~3));
if (detailpth && detailpth->hicr && (detailpth->hicr->palnum == DETAILPAL))
{
@ -1528,7 +1465,7 @@ void drawpoly(double *dpx, double *dpy, int32_t n, int32_t method)
glowpth = NULL;
if (r_glowmapping && usehightile && !drawingskybox &&
hicfindsubst(globalpicnum, GLOWPAL, 0))
glowpth = texcache_fetch(globalpicnum, GLOWPAL, method&(~3));
glowpth = texcache_fetch(globalpicnum, GLOWPAL, 0, method&(~3));
if (glowpth && glowpth->hicr && (glowpth->hicr->palnum == GLOWPAL))
{
@ -4917,9 +4854,10 @@ void polymost_fillpolygon(int32_t npoints)
if (gloy1 != -1) setpolymost2dview(); //disables blending, texturing, and depth testing
bglEnable(GL_ALPHA_TEST);
bglEnable(GL_TEXTURE_2D);
pth = texcache_fetch(globalpicnum,globalpal,0);
pth = texcache_fetch(globalpicnum,globalpal,globalshade,0);
bglBindTexture(GL_TEXTURE_2D, pth ? pth->glpic : 0);
/*
f = getshadefactor(globalshade);
switch ((globalorientation>>7)&3)
{
@ -4932,6 +4870,7 @@ void polymost_fillpolygon(int32_t npoints)
a = 0.33f; bglEnable(GL_BLEND); break;
}
bglColor4f(f,f,f,a);
*/
tessectrap((float *)rx1,(float *)ry1,xb1,npoints);
}
@ -4978,7 +4917,7 @@ int32_t polymost_drawtilescreen(int32_t tilex, int32_t tiley, int32_t wallnum, i
{
int32_t ousehightile = usehightile;
usehightile = usehitile && usehightile;
pth = texcache_fetch(wallnum,0,4);
pth = texcache_fetch(wallnum,0,0,4);
if (usehightile)
loadedhitile[wallnum>>3] |= (1<<(wallnum&7));
usehightile = ousehightile;
@ -5305,7 +5244,7 @@ void polymost_initosdfuncs(void)
{ "r_animsmoothing","r_animsmoothing: enable/disable model animation smoothing",(void *) &r_animsmoothing, CVAR_BOOL, 0, 1 },
{ "r_modelocclusionchecking","r_modelocclusionchecking: enable/disable hack to cull \"obstructed\" models",(void *) &r_modelocclusionchecking, CVAR_INT, 0, 2 },
{ "r_detailmapping","r_detailmapping: enable/disable detail mapping",(void *) &r_detailmapping, CVAR_BOOL, 0, 1 },
{ "r_downsize","r_downsize: controls downsizing factor for hires textures",(void *) &r_downsize, CVAR_INT|CVAR_FUNCPTR, 0, 5 },
{ "r_downsize","r_downsize: controls downsizing factor (quality) for hires textures",(void *) &r_downsize, CVAR_INT|CVAR_FUNCPTR, 0, 5 },
{ "r_fullbrights","r_fullbrights: enable/disable fullbright textures",(void *) &r_fullbrights, CVAR_BOOL, 0, 1 },
{ "r_glowmapping","r_glowmapping: enable/disable glow mapping",(void *) &r_glowmapping, CVAR_BOOL, 0, 1 },
/*
@ -5333,6 +5272,7 @@ void polymost_initosdfuncs(void)
{ "r_texturemiplevel","r_texturemiplevel: changes the highest OpenGL mipmap level used",(void *) &gltexmiplevel, CVAR_INT, 0, 6 },
{ "r_texturemode", "r_texturemode: changes the texture filtering settings", (void *) &gltexfiltermode, CVAR_INT|CVAR_FUNCPTR, 0, 5 },
{ "r_usenewshading", "r_usenewshading: visibility code: 0: Polymost, 2: Classic", (void *) &r_usenewshading, CVAR_INT, 0, 2 },
{ "r_usetileshades", "r_usetileshades: enable/disable Polymost tile shade textures", (void *) &r_usetileshades, CVAR_BOOL | CVAR_INVALIDATEART, 0, 1 },
{ "r_vbocount","r_vbocount: sets the number of Vertex Buffer Objects to use when drawing models",(void *) &r_vbocount, CVAR_INT, 1, 256 },
{ "r_vbos","r_vbos: enable/disable using Vertex Buffer Objects when drawing models",(void *) &r_vbos, CVAR_BOOL, 0, 1 },
{ "r_vertexarrays","r_vertexarrays: enable/disable using vertex arrays when drawing models",(void *) &r_vertexarrays, CVAR_BOOL, 0, 1 },
@ -5414,7 +5354,7 @@ void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype)
hicprecaching = 1;
texcache_fetch(dapicnum, dapalnum, (datype & 1) << 2);
texcache_fetch(dapicnum, dapalnum, 0, (datype & 1) << 2);
hicprecaching = 0;
if (datype == 0 || !usemodels) return;

View File

@ -49,13 +49,15 @@ static const char *texcache_loaderrs[5] = {
"bglGetTexLevelParameteriv failed",
};
pthtyp *texcache_fetch(int32_t dapicnum, int32_t dapalnum, int32_t dameth)
pthtyp *texcache_fetch(int32_t dapicnum, int32_t dapalnum, int32_t dashade, int32_t dameth)
{
int32_t i, j;
hicreplctyp *si;
pthtyp *pth, *pth2;
j = (dapicnum&(GLTEXCACHEADSIZ-1));
if (getrendermode() != REND_POLYMOST || !r_usetileshades) dashade = 0;
si = usehightile ? hicfindsubst(dapicnum,dapalnum,drawingskybox) : NULL;
@ -136,14 +138,14 @@ tryart:
// load from art
for (pth=texcache_head[j]; pth; pth=pth->next)
if (pth->picnum == dapicnum && pth->palnum == dapalnum &&
if (pth->picnum == dapicnum && pth->palnum == dapalnum && pth->shade == dashade &&
(pth->flags & (1+2)) == ((dameth&4)>>2)
)
{
if (pth->flags & 128)
{
pth->flags &= ~128;
if (gloadtile_art(dapicnum,dapalnum,dameth,pth,0))
if (gloadtile_art(dapicnum,dapalnum,dashade,dameth,pth,0))
return NULL; //reload tile (for animations)
}
@ -153,7 +155,7 @@ tryart:
pth = (pthtyp *)Bcalloc(1,sizeof(pthtyp));
if (!pth) return NULL;
if (gloadtile_art(dapicnum,dapalnum,dameth,pth,1))
if (gloadtile_art(dapicnum,dapalnum,dashade,dameth,pth,1))
{
Bfree(pth);
return NULL;
@ -254,25 +256,41 @@ void texcache_init(void)
hash_init(&h_texcache);
}
void texcache_invalidate(void)
void texcache_removefiles(void)
{
#ifdef DEBUGGINGAIDS
OSD_Printf("texcache_invalidate()\n");
#endif
r_downsizevar = r_downsize; // update the cvar representation when the menu changes r_downsize
polymost_glreset();
texcache_init();
// LoadCacheOffsets();
Bstrcpy(ptempbuf, TEXCACHEFILE);
unlink(ptempbuf);
Bstrcat(ptempbuf, ".cache");
unlink(ptempbuf);
}
static int32_t texcache_enabled(void)
{
if (!glusetexcompr || !glusetexcache) return 0;
if (!glinfo.texcompr || !bglCompressedTexImage2DARB || !bglGetCompressedTexImageARB)
{
// lacking the necessary extensions to do this
OSD_Printf("Warning: the GL driver lacks necessary functions to use caching\n");
glusetexcache = 0;
return 0;
}
if (!texcache_indexptr || texcache_filehandle < 0)
{
OSD_Printf("Warning: no active cache!\n");
return 0;
}
return 1;
}
void texcache_openfiles(void)
{
Bstrcpy(ptempbuf,TEXCACHEFILE);
Bstrcat(ptempbuf,".cache");
texcache_indexptr = Bfopen(ptempbuf, "at+");
texcache_filehandle = Bopen(TEXCACHEFILE,BO_BINARY|BO_CREAT|BO_TRUNC|BO_APPEND|BO_RDWR,BS_IREAD|BS_IWRITE);
texcache_filehandle = Bopen(TEXCACHEFILE, BO_BINARY|BO_CREAT|BO_APPEND|BO_RDWR, BS_IREAD|BS_IWRITE);
if (!texcache_indexptr || texcache_filehandle < 0)
{
@ -281,10 +299,51 @@ void texcache_invalidate(void)
glusetexcache = 0;
return;
}
else
initprintf("Deleted and reopened \"%s\" as cache file\n", TEXCACHEFILE);
Bfprintf(texcache_indexptr,"// automatically generated by EDuke32, DO NOT MODIFY!\n");
Bfseek(texcache_indexptr, 0, BSEEK_END);
if (!Bftell(texcache_indexptr))
{
Brewind(texcache_indexptr);
Bfprintf(texcache_indexptr,"// automatically generated by EDuke32, DO NOT MODIFY!\n");
}
else Brewind(texcache_indexptr);
initprintf("Opened \"%s\" as cache file\n", TEXCACHEFILE);
}
void texcache_checkgarbage(void)
{
int32_t i = 0;
if (!texcache_enabled())
return;
texcache_currentindex = texcache_firstindex;
while (texcache_currentindex->next)
{
i += texcache_currentindex->len;
texcache_currentindex = texcache_currentindex->next;
}
i = Blseek(texcache_filehandle, 0, BSEEK_END)-i;
if (i)
initprintf("Cache contains %d bytes of garbage data\n",i);
}
void texcache_invalidate(void)
{
#ifdef DEBUGGINGAIDS
OSD_Printf("texcache_invalidate()\n");
#endif
r_downsizevar = r_downsize; // update the cvar representation when the menu changes r_downsize
polymost_glreset();
texcache_init();
texcache_removefiles();
texcache_openfiles();
}
int32_t texcache_loadoffsets(void)
@ -353,28 +412,6 @@ int32_t texcache_readdata(void *dest, int32_t len)
return 0;
}
static int32_t texcache_enabled(void)
{
if (!glusetexcompr || !glusetexcache) return 0;
if (!glinfo.texcompr || !bglCompressedTexImage2DARB || !bglGetCompressedTexImageARB)
{
// lacking the necessary extensions to do this
OSD_Printf("Warning: the GL driver lacks necessary functions to use caching\n");
glusetexcache = 0;
return 0;
}
if (!texcache_indexptr || texcache_filehandle < 0)
{
OSD_Printf("Warning: no active cache!\n");
return 0;
}
return 1;
}
typedef struct { int32_t len, method; char effect, name[BMAX_PATH]; } texcacheid_t;
static const char * texcache_calcid(char *cachefn, const char *fn, const int32_t len, const int32_t dameth, const char effect)
@ -711,3 +748,32 @@ int32_t texcache_loadtile(const texcacheheader *head, int32_t *doalloc, pthtyp *
return 0;
}
void texcache_setupmemcache(void)
{
if (!glusememcache || texcache_noalloc || !texcache_enabled())
return;
texcache_memsize = filelength(texcache_filehandle);
if (texcache_memsize <= 0)
return;
texcache_memptr = (uint8_t *)Brealloc(texcache_memptr, texcache_memsize);
if (!texcache_memptr)
{
initprintf("Failed allocating %d bytes for memcache, disabling memcache.\n", texcache_memsize);
texcache_clearmem();
texcache_noalloc = 1;
return;
}
if (Bread(texcache_filehandle, texcache_memptr, texcache_memsize) != texcache_memsize)
{
initprintf("Failed reading texcache into memcache!\n");
texcache_clearmem();
texcache_noalloc = 1;
}
}