mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 03:00:46 +00:00
Highpalookup support is more or less ready, also checked in sample script to
generate the highpalookup maps offline (only with a few incomplete pals right now). New DEF token: highpalookup [pal] [filename] New cvar: r_pr_highpalookups git-svn-id: https://svn.eduke32.com/eduke32@1748 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
b3231e5c9b
commit
3d2bcbfba8
5 changed files with 236 additions and 59 deletions
|
@ -52,6 +52,7 @@ extern float pr_parallaxbias;
|
|||
extern int32_t pr_overridespecular;
|
||||
extern float pr_specularpower;
|
||||
extern float pr_specularfactor;
|
||||
extern int32_t pr_highpalookups;
|
||||
extern int32_t pr_ati_fboworkaround;
|
||||
extern int32_t pr_ati_nodepthoffset;
|
||||
#ifdef __APPLE__
|
||||
|
@ -156,6 +157,11 @@ typedef struct s_prrograminfo {
|
|||
} _prprograminfo;
|
||||
|
||||
#define PR_INFO_LOG_BUFFER_SIZE 8192
|
||||
#define PR_HIGHPALOOKUP_BIT_DEPTH 7
|
||||
#define PR_HIGHPALOOKUP_DIM (1 << PR_HIGHPALOOKUP_BIT_DEPTH)
|
||||
#define PR_HIGHPALOOKUP_DATA_SIZE (4 * PR_HIGHPALOOKUP_DIM * \
|
||||
PR_HIGHPALOOKUP_DIM * \
|
||||
PR_HIGHPALOOKUP_DIM)
|
||||
|
||||
typedef struct s_prprogrambit {
|
||||
int32_t bit;
|
||||
|
@ -259,6 +265,11 @@ typedef struct s_prmirror {
|
|||
int16_t wallnum;
|
||||
} _prmirror;
|
||||
|
||||
typedef struct s_prhighpalookup {
|
||||
char *data;
|
||||
GLuint map;
|
||||
} _prhighpalookup;
|
||||
|
||||
typedef void (*animatespritesptr)(int32_t, int32_t, int32_t, int32_t);
|
||||
|
||||
typedef struct s_pranimatespritesinfo {
|
||||
|
@ -283,6 +294,7 @@ int16_t polymer_addlight(_prlight* light);
|
|||
void polymer_deletelight(int16_t lighti);
|
||||
void polymer_invalidatelights(void);
|
||||
void polymer_texinvalidate(void);
|
||||
void polymer_definehighpalookup(char palnum, char *fn);
|
||||
|
||||
# ifdef POLYMER_C
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ enum scripttoken_t
|
|||
T_VOXEL,
|
||||
T_SKYBOX,
|
||||
T_FRONT,T_RIGHT,T_BACK,T_LEFT,T_TOP,T_BOTTOM,
|
||||
T_HIGHPALOOKUP,
|
||||
T_TINT,T_RED,T_GREEN,T_BLUE,
|
||||
T_TEXTURE,T_ALPHACUT,T_XSCALE,T_YSCALE,T_SPECPOWER,T_SPECFACTOR,T_NOCOMPRESS,T_NODOWNSIZE,
|
||||
T_UNDEFMODEL,T_UNDEFMODELRANGE,T_UNDEFMODELOF,T_UNDEFTEXTURE,T_UNDEFTEXTURERANGE,
|
||||
|
@ -140,6 +141,7 @@ static int32_t defsparser(scriptfile *script)
|
|||
{ "model", T_MODEL },
|
||||
{ "voxel", T_VOXEL },
|
||||
{ "skybox", T_SKYBOX },
|
||||
{ "highpalookup", T_HIGHPALOOKUP },
|
||||
{ "tint", T_TINT },
|
||||
{ "texture", T_TEXTURE },
|
||||
{ "tile", T_TEXTURE },
|
||||
|
@ -1427,6 +1429,88 @@ static int32_t defsparser(scriptfile *script)
|
|||
hicsetskybox(tile,pal,fn);
|
||||
}
|
||||
break;
|
||||
case T_HIGHPALOOKUP:
|
||||
{
|
||||
char *highpaltokptr = script->ltextptr;
|
||||
int32_t pal=-1, oldpathsearchmode, fd, datasize, dataread;
|
||||
char *fn = NULL, *tfn = NULL;
|
||||
char *highpalend;
|
||||
char *highpaldata;
|
||||
|
||||
static const tokenlist highpaltokens[] =
|
||||
{
|
||||
{ "pal", T_PAL },
|
||||
{ "file", T_FILE }
|
||||
};
|
||||
|
||||
if (scriptfile_getbraces(script,&highpalend)) break;
|
||||
while (script->textptr < highpalend)
|
||||
{
|
||||
switch (getatoken(script,highpaltokens,sizeof(highpaltokens)/sizeof(tokenlist)))
|
||||
{
|
||||
case T_PAL:
|
||||
scriptfile_getsymbol(script,&pal); break;
|
||||
case T_FILE:
|
||||
scriptfile_getstring(script,&fn); break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((unsigned)pal >= ((unsigned)MAXPALOOKUPS - RESERVEDPALS))
|
||||
{
|
||||
initprintf("Error: missing or invalid 'palette number' for highpalookup definition near "
|
||||
"line %s:%d\n", script->filename, scriptfile_getlinum(script,highpaltokptr));
|
||||
break;
|
||||
}
|
||||
if (!fn)
|
||||
{
|
||||
initprintf("Error: missing 'file name' for highpalookup definition near line %s:%d\n",
|
||||
script->filename, scriptfile_getlinum(script,highpaltokptr));
|
||||
break;
|
||||
}
|
||||
|
||||
oldpathsearchmode = pathsearchmode;
|
||||
pathsearchmode = 1;
|
||||
if (findfrompath(fn,&tfn) < 0)
|
||||
{
|
||||
char buf[BMAX_PATH];
|
||||
|
||||
Bstrcpy(buf,fn);
|
||||
kzfindfilestart(buf);
|
||||
if (!kzfindfile(buf))
|
||||
{
|
||||
initprintf("Error: file '%s' does not exist\n",fn);
|
||||
pathsearchmode = oldpathsearchmode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else Bfree(tfn);
|
||||
pathsearchmode = oldpathsearchmode;
|
||||
|
||||
// load the highpalookup and send it to polymer
|
||||
datasize = PR_HIGHPALOOKUP_DATA_SIZE;
|
||||
|
||||
highpaldata = Bmalloc(datasize);
|
||||
|
||||
fd = kopen4load(fn, 0);
|
||||
// skip the TGA header
|
||||
klseek(fd, 18, SEEK_SET);
|
||||
|
||||
dataread = 0;
|
||||
|
||||
while (1) {
|
||||
dataread += kread(fd, highpaldata + dataread, datasize - dataread);
|
||||
if (dataread == datasize)
|
||||
break;
|
||||
}
|
||||
|
||||
// ignore whatever image editors might have put after the interesting stuff
|
||||
kclose(fd);
|
||||
|
||||
polymer_definehighpalookup(pal, highpaldata);
|
||||
|
||||
Bfree(highpaldata);
|
||||
}
|
||||
break;
|
||||
case T_TINT:
|
||||
{
|
||||
char *tinttokptr = script->ltextptr;
|
||||
|
|
|
@ -30,6 +30,7 @@ float pr_parallaxbias = 0.0f;
|
|||
int32_t pr_overridespecular = 0;
|
||||
float pr_specularpower = 15.0f;
|
||||
float pr_specularfactor = 1.0f;
|
||||
int32_t pr_highpalookups = 1;
|
||||
int32_t pr_ati_fboworkaround = 0;
|
||||
int32_t pr_ati_nodepthoffset = 0;
|
||||
|
||||
|
@ -43,6 +44,7 @@ _prsector *prsectors[MAXSECTORS];
|
|||
_prwall *prwalls[MAXWALLS];
|
||||
_prsprite *prsprites[MAXSPRITES];
|
||||
_prmaterial mdspritematerial;
|
||||
_prhighpalookup prhighpalookups[MAXPALOOKUPS];
|
||||
|
||||
static const GLfloat vertsprite[4 * 5] =
|
||||
{
|
||||
|
@ -578,9 +580,6 @@ int32_t globaloldoverridematerial;
|
|||
// RENDER TARGETS
|
||||
_prrt *prrts;
|
||||
|
||||
// HIGHPALOOKUP MAP NAMES
|
||||
GLuint globalhighpalookupmap;
|
||||
|
||||
// CONTROL
|
||||
GLfloat spritemodelview[16];
|
||||
GLfloat mdspritespace[4][4];
|
||||
|
@ -673,59 +672,33 @@ int32_t polymer_init(void)
|
|||
|
||||
polymer_initrendertargets(pr_shadowcount + 1);
|
||||
|
||||
// test highpalookup
|
||||
int32_t j, k;
|
||||
int32_t xbits = 6, ybits = 6, zbits = 6; // depth
|
||||
int32_t x = 1 << xbits, y = 1 << ybits, z = 1 << zbits; // dimensions
|
||||
int32_t bitdiff;
|
||||
coltype *highpalookup;
|
||||
|
||||
highpalookup = malloc(x*y*z*sizeof(coltype));
|
||||
|
||||
k = 0;
|
||||
while (k < z) {
|
||||
j = 0;
|
||||
while (j < y) {
|
||||
// Prime highpalookup maps
|
||||
i = 0;
|
||||
while (i < x) {
|
||||
bitdiff = 8 - xbits;
|
||||
highpalookup[k * z * y + j * y + i].r = (i << bitdiff) | (i & ((1 << bitdiff) - 1));
|
||||
|
||||
bitdiff = 8 - ybits;
|
||||
highpalookup[k * z * y + j * y + i].g = (j << bitdiff) | (j & ((1 << bitdiff) - 1));
|
||||
|
||||
bitdiff = 8 - zbits;
|
||||
highpalookup[k * z * y + j * y + i].b = (k << bitdiff) | (k & ((1 << bitdiff) - 1));
|
||||
|
||||
// unneeded padding, will make the texture upload faster
|
||||
highpalookup[k * z * y + j * y + i].a = 0;
|
||||
i++;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
|
||||
bglGenTextures(1, &globalhighpalookupmap);
|
||||
bglBindTexture(GL_TEXTURE_3D, globalhighpalookupmap);
|
||||
while (i < MAXPALOOKUPS)
|
||||
{
|
||||
if (prhighpalookups[i].data)
|
||||
{
|
||||
bglGenTextures(1, &prhighpalookups[i].map);
|
||||
bglBindTexture(GL_TEXTURE_3D, prhighpalookups[i].map);
|
||||
bglTexImage3D(GL_TEXTURE_3D, // target
|
||||
0, // mip level
|
||||
GL_RGBA, // internalFormat
|
||||
x, // width
|
||||
y, // height
|
||||
z, // depth
|
||||
PR_HIGHPALOOKUP_DIM, // width
|
||||
PR_HIGHPALOOKUP_DIM, // height
|
||||
PR_HIGHPALOOKUP_DIM, // depth
|
||||
0, // border
|
||||
GL_RGBA, // upload format
|
||||
GL_BGRA, // upload format
|
||||
GL_UNSIGNED_BYTE, // upload component type
|
||||
highpalookup); // data pointer
|
||||
prhighpalookups[i].data); // data pointer
|
||||
bglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
bglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
bglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, glinfo.clamptoedge?GL_CLAMP_TO_EDGE:GL_CLAMP);
|
||||
bglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, glinfo.clamptoedge?GL_CLAMP_TO_EDGE:GL_CLAMP);
|
||||
bglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, glinfo.clamptoedge?GL_CLAMP_TO_EDGE:GL_CLAMP);
|
||||
bglBindTexture(GL_TEXTURE_3D, 0);
|
||||
|
||||
free(highpalookup);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (pr_verbosity >= 1) OSD_Printf("PR : Initialization complete.\n");
|
||||
|
||||
|
@ -734,7 +707,23 @@ int32_t polymer_init(void)
|
|||
|
||||
void polymer_uninit(void)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
polymer_freeboard();
|
||||
|
||||
i = 0;
|
||||
while (i < MAXPALOOKUPS)
|
||||
{
|
||||
if (prhighpalookups[i].data) {
|
||||
Bfree(prhighpalookups[i].data);
|
||||
prhighpalookups[i].data = NULL;
|
||||
}
|
||||
if (prhighpalookups[i].map) {
|
||||
bglDeleteTextures(1, &prhighpalookups[i].map);
|
||||
prhighpalookups[i].map = 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void polymer_glinit(void)
|
||||
|
@ -1669,6 +1658,13 @@ void polymer_texinvalidate(void)
|
|||
while (i >= 0);
|
||||
}
|
||||
|
||||
void polymer_definehighpalookup(char palnum, char *data)
|
||||
{
|
||||
prhighpalookups[palnum].data = Bmalloc(PR_HIGHPALOOKUP_DATA_SIZE);
|
||||
|
||||
Bmemcpy(prhighpalookups[palnum].data, data, PR_HIGHPALOOKUP_DATA_SIZE);
|
||||
}
|
||||
|
||||
// CORE
|
||||
static void polymer_displayrooms(int16_t dacursectnum)
|
||||
{
|
||||
|
@ -4150,6 +4146,14 @@ static void polymer_getbuildmaterial(_prmaterial* material, int16_t tile
|
|||
if (!waloff[tilenum])
|
||||
loadtile(tilenum);
|
||||
|
||||
// PR_BIT_HIGHPALOOKUP_MAP
|
||||
if (pal > 0 && pr_highpalookups && prhighpalookups[pal].map &&
|
||||
hicfindsubst(tilenum, 0, 0) && (hicfindsubst(tilenum, pal, 0)->palnum != pal))
|
||||
{
|
||||
material->highpalookupmap = prhighpalookups[pal].map;
|
||||
pal = 0;
|
||||
}
|
||||
|
||||
if ((pth = gltexcache(tilenum, pal, cmeth)))
|
||||
{
|
||||
material->diffusemap = pth->glpic;
|
||||
|
@ -4233,11 +4237,6 @@ static int32_t polymer_bindmaterial(_prmaterial material, int16_t* lights,
|
|||
|
||||
// --------- bit validation
|
||||
|
||||
// hack to dynamically insert highpalookup
|
||||
if (debug1) {
|
||||
material.highpalookupmap = globalhighpalookupmap;
|
||||
}
|
||||
|
||||
// PR_BIT_ANIM_INTERPOLATION
|
||||
if (material.nextframedata)
|
||||
programbits |= prprogrambits[PR_BIT_ANIM_INTERPOLATION].bit;
|
||||
|
|
|
@ -6199,6 +6199,7 @@ void polymost_initosdfuncs(void)
|
|||
{ "r_pr_overridespecular", "r_pr_overridespecular: overrides specular material power and factor values with values from the pr_specularpower and pr_specularfactor cvars; use it to fine-tune DEF tokens", (void*)&pr_overridespecular, CVAR_BOOL | CVAR_NOSAVE, 0, 1 },
|
||||
{ "r_pr_specularpower", "r_pr_specularpower: overriden specular material power", (void*)&pr_specularpower, CVAR_FLOAT | CVAR_NOSAVE, -10, 1000 },
|
||||
{ "r_pr_specularfactor", "r_pr_specularfactor: overriden specular material factor", (void*)&pr_specularfactor, CVAR_FLOAT | CVAR_NOSAVE, -10, 1000 },
|
||||
{ "r_pr_highpalookups", "r_pr_highpalookups: enable/disable highpalookups", (void*)&pr_highpalookups, CVAR_BOOL, 0, 1 },
|
||||
{ "r_pr_ati_fboworkaround", "r_pr_ati_fboworkaround: enable this to workaround an ATI driver bug that causes sprite shadows to be square - you need to restart the renderer for it to take effect", (void*)&pr_ati_fboworkaround, CVAR_BOOL | CVAR_NOSAVE, 0, 1 },
|
||||
{ "r_pr_ati_nodepthoffset", "r_pr_ati_nodepthoffset: enable this to workaround an ATI driver bug that causes sprite drawing to freeze the game on Radeon X1x00 hardware - you need to restart the renderer for it to take effect", (void*)&pr_ati_nodepthoffset, CVAR_BOOL | CVAR_NOSAVE, 0, 1 },
|
||||
#endif
|
||||
|
|
81
polymer/highpalookupmaker.py
Normal file
81
polymer/highpalookupmaker.py
Normal file
|
@ -0,0 +1,81 @@
|
|||
def makehighpalookuppixel(pal, rgb):
|
||||
hsv = list(colorsys.rgb_to_hsv(*rgb))
|
||||
if pal == 0:
|
||||
# no-op, pass through
|
||||
return rgb
|
||||
# frozen, blue light
|
||||
elif pal == 1:
|
||||
# make everything blueish
|
||||
hsv[0] = 0.66
|
||||
return list(colorsys.hsv_to_rgb(*hsv))
|
||||
# nightvision
|
||||
elif pal == 6:
|
||||
# make everything green and reverse brightness
|
||||
hsv[0] = 0.33
|
||||
hsv[2] = 1.0 - hsv[2]
|
||||
#hsv[1] = 0.5
|
||||
return list(colorsys.hsv_to_rgb(*hsv))
|
||||
# pal 20
|
||||
elif pal == 20:
|
||||
# blue to gray by removing all saturation
|
||||
if (hsv[0] > 0.6 and hsv[0] < 0.7):
|
||||
hsv[1] = 0
|
||||
# orange and brown to blue
|
||||
if (hsv[0] > 0.04 and hsv[0] < 0.13):
|
||||
hsv[0] = 0.66
|
||||
# purple and reddish to blue
|
||||
if (hsv[0] > 0.7 and hsv[0] < 0.9):
|
||||
hsv[0] = 0.66
|
||||
# green to blue
|
||||
if (hsv[0] > 0.30 and hsv[0] < 0.36):
|
||||
hsv[0] = 0.66
|
||||
return list(colorsys.hsv_to_rgb(*hsv))
|
||||
else:
|
||||
print "unknown pal!"
|
||||
sys.exit()
|
||||
|
||||
import colorsys
|
||||
import sys
|
||||
import struct
|
||||
|
||||
if (len(sys.argv) != 3):
|
||||
print "Usage: python highpalookupmaker.py palnum outfile"
|
||||
sys.exit()
|
||||
|
||||
# bit depth per dimension
|
||||
xbits = 7
|
||||
ybits = 7
|
||||
zbits = 7
|
||||
|
||||
xdim = 1 << xbits
|
||||
ydim = 1 << ybits
|
||||
zdim = 1 << zbits
|
||||
|
||||
palnum = int(sys.argv[1])
|
||||
|
||||
pixels = []
|
||||
pixelcount = xdim * ydim * zdim
|
||||
curpix = 0.0
|
||||
|
||||
fo = open(sys.argv[2], "w")
|
||||
|
||||
# throw in a TGA header in there, this way they'll be able to directly edit it if they feel like it
|
||||
fo.write(struct.pack("=BBBHHBHHHHBB", 0, 0, 2, 0, 0, 0, 0, 0, 16384, 128, 32, 0))
|
||||
|
||||
print "Creating highpalookup map %s for palette %d with depth %d:%d:%d..." % (sys.argv[2], palnum, xbits, ybits, zbits)
|
||||
|
||||
for k in range(zdim):
|
||||
for j in range(ydim):
|
||||
for i in range(xdim):
|
||||
rgb = [float(i) / (xdim - 1), float(j) / (ydim - 1), float(k) / (zdim - 1)]
|
||||
rgb = makehighpalookuppixel(palnum, rgb)
|
||||
# save as BGRA as that's what TGA uses
|
||||
pixels.append(struct.pack('BBBB', int(rgb[2] * 255), int(rgb[1] * 255), int(rgb[0] * 255), 255))
|
||||
curpix += 1
|
||||
if (curpix % 128 == 0):
|
||||
print "\r%f%% done." % (curpix * 100 / pixelcount),
|
||||
|
||||
fo.writelines(pixels)
|
||||
fo.close()
|
||||
|
||||
print "\n"
|
Loading…
Reference in a new issue