GL .blend support.

Consult me if you are interested in this feature.

TODO: Polymer.

git-svn-id: https://svn.eduke32.com/eduke32@5888 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
hendricks266 2016-10-09 07:55:23 +00:00
parent 2025aab189
commit 8a1f1f2ede
8 changed files with 267 additions and 11 deletions

View file

@ -71,6 +71,37 @@ static inline void bricolor(palette_t *wpptr, int32_t dacol)
wpptr->b = britable[curbrightness][curpalette[dacol].b];
}
}
enum
{
BLENDFACTOR_ZERO = 0,
BLENDFACTOR_ONE,
BLENDFACTOR_SRC_COLOR,
BLENDFACTOR_ONE_MINUS_SRC_COLOR,
BLENDFACTOR_SRC_ALPHA,
BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
BLENDFACTOR_DST_ALPHA,
BLENDFACTOR_ONE_MINUS_DST_ALPHA,
BLENDFACTOR_DST_COLOR,
BLENDFACTOR_ONE_MINUS_DST_COLOR,
NUMBLENDFACTORS,
};
typedef struct glblenddef_
{
float alpha;
uint8_t src, dst, flags;
} glblenddef_t;
typedef struct glblend_
{
glblenddef_t def[2];
} glblend_t;
extern glblend_t const nullglblend, defaultglblend;
extern glblend_t glblend[MAXBLENDTABS];
extern void handle_blend(uint8_t enable, uint8_t blend, uint8_t def);
#endif
#ifdef __cplusplus

View file

@ -33,7 +33,7 @@ void uploadtexture(int32_t doalloc, vec2_t siz, int32_t texfmt, coltype *pic, ve
void polymost_drawsprite(int32_t snum);
void polymost_drawmaskwall(int32_t damaskwallcnt);
void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
int8_t dashade, char dapalnum, int32_t dastat, uint8_t daalpha, int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, int32_t uniqid);
int8_t dashade, char dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend, int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, int32_t uniqid);
void polymost_fillpolygon(int32_t npoints);
void polymost_initosdfuncs(void);
void polymost_drawrooms(void);

View file

@ -112,6 +112,12 @@ enum scripttoken_t
T_NUMALPHATABS,
T_UNDEF,
T_UNDEFBASEPALETTERANGE, T_UNDEFPALOOKUPRANGE, T_UNDEFBLENDTABLERANGE,
T_GLBLEND, T_FORWARD, T_REVERSE, T_BOTH, T_SRC, T_DST, T_ALPHA,
T_ZERO, T_ONE,
T_SRC_COLOR, T_ONE_MINUS_SRC_COLOR,
T_SRC_ALPHA, T_ONE_MINUS_SRC_ALPHA,
T_DST_ALPHA, T_ONE_MINUS_DST_ALPHA,
T_DST_COLOR, T_ONE_MINUS_DST_COLOR,
};
static int32_t lastmodelid = -1, lastvoxid = -1, modelskin = -1, lastmodelskin = -1, seenframe = 0;
@ -3214,6 +3220,7 @@ static int32_t defsparser(scriptfile *script)
static const tokenlist subtokens[] =
{
{ "raw", T_RAW },
{ "glblend", T_GLBLEND },
{ "copy", T_COPY },
{ "undef", T_UNDEF },
};
@ -3343,6 +3350,10 @@ static int32_t defsparser(scriptfile *script)
setblendtab(id, sourcetable);
didLoadTransluc = 1;
#ifdef USE_OPENGL
glblend[id] = glblend[source];
#endif
break;
}
case T_UNDEF:
@ -3352,8 +3363,129 @@ static int32_t defsparser(scriptfile *script)
didLoadTransluc = 0;
if (id == 0)
paletteloaded &= ~PALETTE_TRANSLUC;
#ifdef USE_OPENGL
glblend[id] = defaultglblend;
#endif
break;
}
case T_GLBLEND:
{
char *glblendblockend;
static const tokenlist glblendtokens[] =
{
{ "forward", T_FORWARD },
{ "reverse", T_REVERSE },
{ "both", T_BOTH },
};
if (scriptfile_getbraces(script,&glblendblockend))
break;
#ifdef USE_OPENGL
glblend_t * const glb = glblend + id;
*glb = nullglblend;
#endif
while (script->textptr < glblendblockend)
{
int32_t glblendtoken = getatoken(script,glblendtokens,ARRAY_SIZE(glblendtokens));
switch (glblendtoken)
{
case T_FORWARD:
case T_REVERSE:
case T_BOTH:
{
char *glblenddefblockend;
static const tokenlist glblenddeftokens[] =
{
{ "src", T_SRC },
{ "sfactor", T_SRC },
{ "top", T_SRC },
{ "dst", T_DST },
{ "dfactor", T_DST },
{ "bottom", T_DST },
{ "alpha", T_ALPHA },
};
if (scriptfile_getbraces(script,&glblenddefblockend))
break;
#ifdef USE_OPENGL
glblenddef_t * const glbdef = glb->def + (glblendtoken == T_REVERSE);
#endif
while (script->textptr < glblenddefblockend)
{
int32_t glblenddeftoken = getatoken(script,glblenddeftokens,ARRAY_SIZE(glblenddeftokens));
switch (glblenddeftoken)
{
case T_SRC:
case T_DST:
{
static const tokenlist glBlendFuncTokens[] =
{
{ "ZERO", T_ZERO },
{ "ONE", T_ONE },
{ "SRC_COLOR", T_SRC_COLOR },
{ "ONE_MINUS_SRC_COLOR", T_ONE_MINUS_SRC_COLOR },
{ "SRC_ALPHA", T_SRC_ALPHA },
{ "ONE_MINUS_SRC_ALPHA", T_ONE_MINUS_SRC_ALPHA },
{ "DST_ALPHA", T_DST_ALPHA },
{ "ONE_MINUS_DST_ALPHA", T_ONE_MINUS_DST_ALPHA },
{ "DST_COLOR", T_DST_COLOR },
{ "ONE_MINUS_DST_COLOR", T_ONE_MINUS_DST_COLOR },
};
int32_t factortoken = getatoken(script,glBlendFuncTokens,ARRAY_SIZE(glBlendFuncTokens));
#ifdef USE_OPENGL
uint8_t * const factor = glblenddeftoken == T_SRC ? &glbdef->src : &glbdef->dst;
switch (factortoken)
{
case T_ZERO: *factor = BLENDFACTOR_ZERO; break;
case T_ONE: *factor = BLENDFACTOR_ONE; break;
case T_SRC_COLOR: *factor = BLENDFACTOR_SRC_COLOR; break;
case T_ONE_MINUS_SRC_COLOR: *factor = BLENDFACTOR_ONE_MINUS_SRC_COLOR; break;
case T_SRC_ALPHA: *factor = BLENDFACTOR_SRC_ALPHA; break;
case T_ONE_MINUS_SRC_ALPHA: *factor = BLENDFACTOR_ONE_MINUS_SRC_ALPHA; break;
case T_DST_ALPHA: *factor = BLENDFACTOR_DST_ALPHA; break;
case T_ONE_MINUS_DST_ALPHA: *factor = BLENDFACTOR_ONE_MINUS_DST_ALPHA; break;
case T_DST_COLOR: *factor = BLENDFACTOR_DST_COLOR; break;
case T_ONE_MINUS_DST_COLOR: *factor = BLENDFACTOR_ONE_MINUS_DST_COLOR; break;
}
#else
UNREFERENCED_PARAMETER(factortoken);
#endif
break;
}
case T_ALPHA:
{
double tempalpha;
scriptfile_getdouble(script,&tempalpha);
#ifdef USE_OPENGL
glbdef->alpha = (float)tempalpha;
#endif
break;
}
}
}
#ifdef USE_OPENGL
if (glblendtoken == T_BOTH)
glb->def[1] = *glbdef;
#endif
break;
}
}
}
}
default:
break;
}
@ -3373,6 +3505,17 @@ static int32_t defsparser(scriptfile *script)
switch (value)
{
case 0: /*case 1:*/ case 2: case 4: case 8: case 16: case 32: case 64: case 128:
#ifdef USE_OPENGL
for (int32_t a = 1, value2 = value*2; a <= value; ++a)
{
float finv2value = 0.5f/(float)value;
glblend_t * const glb = glblend + a;
*glb = defaultglblend;
glb->def[0].alpha = (float)(value2-a) * finv2value;
glb->def[1].alpha = (float)a * finv2value;
}
#endif
numalphatabs = value;
break;
default:

View file

@ -6503,7 +6503,7 @@ static void dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t
#ifdef USE_OPENGL
if (getrendermode() >= REND_POLYMOST && in3dmode())
{
polymost_dorotatesprite(sx,sy,z,a,picnum,dashade,dapalnum,dastat,daalpha,cx1,cy1,cx2,cy2,uniqid);
polymost_dorotatesprite(sx,sy,z,a,picnum,dashade,dapalnum,dastat,daalpha,dablend,cx1,cy1,cx2,cy2,uniqid);
return;
}
#else

View file

@ -2202,9 +2202,11 @@ static int32_t polymost_md3draw(md3model_t *m, const uspritetype *tspr)
if (have_basepal_tint())
hictinting_apply(pc, MAXPALOOKUPS-1);
pc[3] = (tspr->cstat&2) ? !(tspr->cstat&512) ? (2.f/3.f) : (1.f/3.f) : 1.0f;
pc[3] = (tspr->cstat&2) ? glblend[tspr->blend].def[!!(tspr->cstat&512)].alpha : 1.0f;
pc[3] *= 1.0f - sext->alpha;
handle_blend(!!(tspr->cstat & 2), tspr->blend, !!(tspr->cstat & 512));
if (m->usesalpha) //Sprites with alpha in texture
{
// bglEnable(GL_BLEND);// bglBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

View file

@ -107,6 +107,11 @@ void loadpalette(void)
initfastcolorlookup_scale(30, 59, 11);
initfastcolorlookup_gridvectors();
#ifdef USE_OPENGL
for (size_t x = 0; x < MAXBLENDTABS; ++x)
glblend[x] = defaultglblend;
#endif
int32_t fil;
if ((fil = kopen4load("palette.dat", 0)) == -1)
return;
@ -465,6 +470,51 @@ const char *(getblendtab) (int32_t blend)
}
#endif
#ifdef USE_OPENGL
glblend_t const nullglblend =
{
{
{ 1.f, BLENDFACTOR_ONE, BLENDFACTOR_ZERO, 0 },
{ 1.f, BLENDFACTOR_ONE, BLENDFACTOR_ZERO, 0 },
},
};
glblend_t const defaultglblend =
{
{
{ 2.f/3.f, BLENDFACTOR_SRC_ALPHA, BLENDFACTOR_ONE_MINUS_SRC_ALPHA, 0 },
{ 1.f/3.f, BLENDFACTOR_SRC_ALPHA, BLENDFACTOR_ONE_MINUS_SRC_ALPHA, 0 },
},
};
glblend_t glblend[MAXBLENDTABS];
void handle_blend(uint8_t enable, uint8_t blend, uint8_t def)
{
static GLenum const blendFuncTokens[NUMBLENDFACTORS] =
{
GL_ZERO,
GL_ONE,
GL_SRC_COLOR,
GL_ONE_MINUS_SRC_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA,
GL_DST_ALPHA,
GL_ONE_MINUS_DST_ALPHA,
GL_DST_COLOR,
GL_ONE_MINUS_DST_COLOR,
};
if (!enable)
{
bglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
return;
}
glblenddef_t const * const glbdef = glblend[blend].def + def;
bglBlendFunc(blendFuncTokens[glbdef->src], blendFuncTokens[glbdef->dst]);
}
#endif
int32_t setpalookup(int32_t palnum, const uint8_t *shtab)
{
if (numshades != 32)

View file

@ -125,7 +125,17 @@ int32_t r_downsizevar = -1;
static float fogresult, fogresult2;
coltypef fogcol, fogtable[MAXPALOOKUPS];
static const float float_trans[4] = { 1.0f, 1.0f, 2.f/3.f, 1.f/3.f };
static float float_trans(uint32_t maskprops, uint8_t blend)
{
switch (maskprops)
{
case DAMETH_TRANS1:
case DAMETH_TRANS2:
return glblend[blend].def[maskprops-2].alpha;
default:
return 1.0f;
}
}
char ptempbuf[MAXWALLSB<<1];
@ -1623,6 +1633,7 @@ void polymost_setupglowtexture(const int32_t texunits, const int32_t tex)
// drawpoly's hack globals
static int32_t pow2xsplit = 0, skyclamphack = 0;
static float drawpoly_alpha = 0.f;
static uint8_t drawpoly_blend = 0;
static inline pthtyp *our_texcache_fetch(int32_t dameth)
{
@ -1837,7 +1848,9 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
pc[0] = pc[1] = pc[2] = getshadefactor(globalshade);
// spriteext full alpha control
pc[3] = float_trans[method & DAMETH_MASKPROPS] * (1.f - drawpoly_alpha);
pc[3] = float_trans(method & DAMETH_MASKPROPS, drawpoly_blend) * (1.f - drawpoly_alpha);
handle_blend((method & DAMETH_MASKPROPS) > DAMETH_MASK, drawpoly_blend, (method & DAMETH_MASKPROPS) == DAMETH_TRANS2);
if (pth)
{
@ -2042,6 +2055,8 @@ do
bglLoadIdentity();
bglMatrixMode(GL_MODELVIEW);
bglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (getrendermode() != REND_POLYMOST)
return;
@ -2157,6 +2172,7 @@ static void polymost_domost(float x0, float y0, float x1, float y1)
float const slop = (dm1.y - dm0.y) / (dm1.x - dm0.x);
drawpoly_alpha = 0.f;
drawpoly_blend = 0;
vec2f_t n0, n1;
float spx[4];
@ -2737,6 +2753,7 @@ static void polymost_internal_nonparallaxed(vec2f_t n0, vec2f_t n1, float ryp0,
pow2xsplit = 0;
drawpoly_alpha = 0.f;
drawpoly_blend = 0;
calc_and_apply_fog(globalpicnum, fogpal_shade(sec, global_cf_shade), sec->visibility,
POLYMOST_CHOOSE_FOG_PAL(global_cf_fogpal, global_cf_pal));
@ -2831,6 +2848,7 @@ static inline int polymost_getclosestpointonwall(vec2_t const * const pos, int32
static void polymost_drawalls(int32_t const bunch)
{
drawpoly_alpha = 0.f;
drawpoly_blend = 0;
int32_t const sectnum = thesector[bunchfirst[bunch]];
usectortype const * const sec = (usectortype *)&sector[sectnum];
@ -4245,6 +4263,7 @@ void polymost_drawmaskwall(int32_t damaskwallcnt)
pow2xsplit = 0;
skyclamphack = 0;
drawpoly_alpha = 0.f;
drawpoly_blend = 0;
polymost_drawpoly(dpxy, n, method);
}
@ -4365,7 +4384,10 @@ void polymost_drawsprite(int32_t snum)
if (tspr->cstat & 2)
method = DAMETH_CLAMPED | ((tspr->cstat & 512) ? DAMETH_TRANS2 : DAMETH_TRANS1);
handle_blend(!!(tspr->cstat & 2), tspr->blend, !!(tspr->cstat & 512));
drawpoly_alpha = spriteext[spritenum].alpha;
drawpoly_blend = tspr->blend;
sec = (usectortype *)&sector[tspr->sectnum];
@ -4952,7 +4974,7 @@ EDUKE32_STATIC_ASSERT((int)RS_YFLIP == (int)HUDFLAG_FLIPPED);
//cx1,... clip window (actual screen coords)
void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
int8_t dashade, char dapalnum, int32_t dastat, uint8_t daalpha, int32_t uniqid)
int8_t dashade, char dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend, int32_t uniqid)
{
float d, cosang, sinang, cosang2, sinang2;
float m[4][4];
@ -5124,6 +5146,7 @@ void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a,
}
spriteext[tspr.owner].alpha = daalpha * (1.0f / 255.0f);
tspr.blend = dablend;
bglDisable(GL_FOG);
@ -5177,12 +5200,12 @@ void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a,
}
void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
int8_t dashade, char dapalnum, int32_t dastat, uint8_t daalpha,
int8_t dashade, char dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend,
int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, int32_t uniqid)
{
if (usemodels && tile2model[picnum].hudmem[(dastat&4)>>2])
{
polymost_dorotatespritemodel(sx, sy, z, a, picnum, dashade, dapalnum, dastat, daalpha, uniqid);
polymost_dorotatespritemodel(sx, sy, z, a, picnum, dashade, dapalnum, dastat, daalpha, dablend, uniqid);
return;
}
@ -5251,6 +5274,8 @@ void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16
method |= DAMETH_MASK;
}
handle_blend(!!(dastat & RS_TRANS1), dablend, !!(dastat & RS_TRANS2));
#ifdef POLYMER
if (getrendermode() == REND_POLYMER)
{
@ -5264,6 +5289,7 @@ void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16
#endif
drawpoly_alpha = daalpha * (1.0f / 255.0f);
drawpoly_blend = dablend;
vec2_t const siz = tilesiz[globalpicnum];
vec2_t ofs ={ 0, 0 };
@ -5595,10 +5621,12 @@ void polymost_fillpolygon(int32_t npoints)
float const f = getshadefactor(globalshade);
if (((globalorientation>>7)&3) > 1)
uint8_t const maskprops = (globalorientation>>7)&DAMETH_MASKPROPS;
handle_blend(maskprops > DAMETH_MASK, 0, maskprops == DAMETH_TRANS2);
if (maskprops > DAMETH_MASK)
{
bglEnable(GL_BLEND);
bglColor4f(f, f, f, float_trans[(globalorientation>>7)&3]);
bglColor4f(f, f, f, float_trans(maskprops, 0));
}
else
{

View file

@ -978,9 +978,11 @@ int32_t polymost_voxdraw(voxmodel_t *m, const uspritetype *tspr)
(float)(numshades-min(max((globalshade * shadescale)+m->shadeoff, 0), numshades)) / (float)numshades;
hictinting_apply(pc, globalpal);
pc[3] = (tspr->cstat&2) ? !(tspr->cstat&512) ? (2.f/3.f) : (1.f/3.f) : 1.0f;
pc[3] = (tspr->cstat&2) ? glblend[tspr->blend].def[!!(tspr->cstat&512)].alpha : 1.0f;
pc[3] *= 1.0f - spriteext[tspr->owner].alpha;
handle_blend(!!(tspr->cstat & 2), tspr->blend, !!(tspr->cstat & 512));
if ((tspr->cstat&2) || spriteext[tspr->owner].alpha > 0.f || pc[3] < 1.0f)
bglEnable(GL_BLEND); //else bglDisable(GL_BLEND);
//------------