mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 01:01:33 +00:00
Implement blend modes
This commit is contained in:
parent
dfc85ec21a
commit
b872222b50
23 changed files with 415 additions and 180 deletions
|
@ -655,6 +655,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
|
|||
rsp->flags = LONG(players[i].mo->flags);
|
||||
rsp->flags2 = LONG(players[i].mo->flags2);
|
||||
rsp->renderflags = LONG(players[i].mo->renderflags);
|
||||
rsp->blendmode = LONG(players[i].mo->blendmode);
|
||||
|
||||
rsp->radius = LONG(players[i].mo->radius);
|
||||
rsp->height = LONG(players[i].mo->height);
|
||||
|
@ -794,7 +795,6 @@ static void resynch_read_player(resynch_pak *rsp)
|
|||
players[i].mo->eflags = (UINT16)SHORT(rsp->eflags);
|
||||
players[i].mo->flags = LONG(rsp->flags);
|
||||
players[i].mo->flags2 = LONG(rsp->flags2);
|
||||
players[i].mo->renderflags = LONG(rsp->renderflags);
|
||||
players[i].mo->friction = LONG(rsp->friction);
|
||||
players[i].mo->health = LONG(rsp->health);
|
||||
players[i].mo->momx = LONG(rsp->momx);
|
||||
|
@ -809,6 +809,8 @@ static void resynch_read_player(resynch_pak *rsp)
|
|||
players[i].mo->frame = LONG(rsp->frame);
|
||||
players[i].mo->sprite2 = rsp->sprite2;
|
||||
players[i].mo->anim_duration = SHORT(rsp->anim_duration);
|
||||
players[i].mo->renderflags = LONG(rsp->renderflags);
|
||||
players[i].mo->blendmode = LONG(rsp->blendmode);
|
||||
|
||||
players[i].mo->spritexscale = LONG(rsp->spritexscale);
|
||||
players[i].mo->spriteyscale = LONG(rsp->spriteyscale);
|
||||
|
|
|
@ -300,6 +300,7 @@ typedef struct
|
|||
UINT32 flags2;
|
||||
UINT16 eflags;
|
||||
UINT32 renderflags;
|
||||
INT32 blendmode;
|
||||
|
||||
fixed_t radius;
|
||||
fixed_t height;
|
||||
|
|
|
@ -9580,6 +9580,15 @@ struct {
|
|||
{"tr_trans90",tr_trans90},
|
||||
{"NUMTRANSMAPS",NUMTRANSMAPS},
|
||||
|
||||
// Alpha styles (blend modes)
|
||||
{"AST_COPY",AST_COPY},
|
||||
{"AST_TRANSLUCENT",AST_TRANSLUCENT},
|
||||
{"AST_ADD",AST_ADD},
|
||||
{"AST_SUBTRACT",AST_SUBTRACT},
|
||||
{"AST_REVERSESUBTRACT",AST_REVERSESUBTRACT},
|
||||
{"AST_MODULATE",AST_MODULATE},
|
||||
{"AST_OVERLAY",AST_OVERLAY},
|
||||
|
||||
// Render flags
|
||||
{"RF_HORIZONTALFLIP",RF_HORIZONTALFLIP},
|
||||
{"RF_VERTICALFLIP",RF_VERTICALFLIP},
|
||||
|
|
|
@ -293,7 +293,7 @@ static void F_DoWipe(fademask_t *fademask)
|
|||
else
|
||||
{
|
||||
// pointer to transtable that this mask would use
|
||||
transtbl = transtables + ((9 - *mask)<<FF_TRANSSHIFT);
|
||||
transtbl = R_GetTranslucencyTable((9 - *mask) + 1);
|
||||
|
||||
// DRAWING LOOP
|
||||
while (draw_linestogo--)
|
||||
|
|
|
@ -175,35 +175,32 @@ typedef struct
|
|||
// You pass a combination of these flags to DrawPolygon()
|
||||
enum EPolyFlags
|
||||
{
|
||||
// the first 5 are mutually exclusive
|
||||
|
||||
PF_Masked = 0x00000001, // Poly is alpha scaled and 0 alpha pels are discarded (holes in texture)
|
||||
// Mutually exclusive blend flags
|
||||
PF_Masked = 0x00000001, // Poly is alpha scaled and 0 alpha pixels are discarded (holes in texture)
|
||||
PF_Translucent = 0x00000002, // Poly is transparent, alpha = level of transparency
|
||||
PF_Additive = 0x00000004, // Poly is added to the frame buffer
|
||||
PF_Environment = 0x00000008, // Poly should be drawn environment mapped.
|
||||
// Hurdler: used for text drawing
|
||||
PF_Substractive = 0x00000010, // for splat
|
||||
PF_NoAlphaTest = 0x00000020, // hiden param
|
||||
PF_Fog = 0x00000040, // Fog blocks
|
||||
PF_Blending = (PF_Environment|PF_Additive|PF_Translucent|PF_Masked|PF_Substractive|PF_Fog)&~PF_NoAlphaTest,
|
||||
PF_Environment = 0x00000004, // Poly should be drawn environment mapped. (Hurdler: used for text drawing)
|
||||
PF_Additive = 0x00000008, // Additive color blending
|
||||
PF_AdditiveSource = 0x00000010, // Source blending factor is additive. This is the opposite of regular additive blending.
|
||||
PF_Subtractive = 0x00000020, // Subtractive color blending
|
||||
PF_ReverseSubtract = 0x00000040, // Reverse subtract, used in wall splats (decals)
|
||||
PF_Multiplicative = 0x00000080, // Multiplicative color blending
|
||||
PF_Fog = 0x20000000, // Fog blocks
|
||||
PF_NoAlphaTest = 0x40000000, // Disables alpha testing
|
||||
PF_Blending = (PF_Masked|PF_Translucent|PF_Environment|PF_Additive|PF_AdditiveSource|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Fog) & ~PF_NoAlphaTest,
|
||||
|
||||
// other flag bits
|
||||
|
||||
PF_Occlude = 0x00000100, // Update the depth buffer
|
||||
PF_NoDepthTest = 0x00000200, // Disable the depth test mode
|
||||
PF_Invisible = 0x00000400, // Disable write to color buffer
|
||||
PF_Decal = 0x00000800, // Enable polygon offset
|
||||
// other flag bits
|
||||
PF_Occlude = 0x00000100, // Updates the depth buffer
|
||||
PF_NoDepthTest = 0x00000200, // Disables the depth test mode
|
||||
PF_Invisible = 0x00000400, // Disables write to color buffer
|
||||
PF_Decal = 0x00000800, // Enables polygon offset
|
||||
PF_Modulated = 0x00001000, // Modulation (multiply output with constant ARGB)
|
||||
// When set, pass the color constant into the FSurfaceInfo -> PolyColor
|
||||
PF_NoTexture = 0x00002000, // Use the small white texture
|
||||
PF_Corona = 0x00004000, // Tell the rendrer we are drawing a corona
|
||||
PF_Ripple = 0x00008000, // Water shader effect
|
||||
PF_RemoveYWrap = 0x00010000, // Force clamp texture on Y
|
||||
PF_ForceWrapX = 0x00020000, // Force repeat texture on X
|
||||
PF_ForceWrapY = 0x00040000, // Force repeat texture on Y
|
||||
PF_Clip = 0x40000000, // clip to frustum and nearz plane (glide only, automatic in opengl)
|
||||
PF_NoZClip = 0x20000000, // in conjonction with PF_Clip
|
||||
PF_Debug = 0x80000000 // print debug message in driver :)
|
||||
PF_NoTexture = 0x00002000, // Disables texturing
|
||||
PF_Corona = 0x00004000, // Tells the renderer we are drawing a corona
|
||||
PF_Ripple = 0x00008000, // Water effect shader
|
||||
PF_RemoveYWrap = 0x00010000, // Forces clamp texture on Y
|
||||
PF_ForceWrapX = 0x00020000, // Forces repeat texture on X
|
||||
PF_ForceWrapY = 0x00040000 // Forces repeat texture on Y
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -571,7 +571,7 @@ void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum)
|
|||
// But then, the question is: why not 0 instead of PF_Masked ?
|
||||
// or maybe PF_Environment ??? (like what I said above)
|
||||
// BP: PF_Environment don't change anything ! and 0 is undifined
|
||||
HWD.pfnDrawPolygon(NULL, v, 4, PF_Translucent | PF_NoDepthTest | PF_Clip | PF_NoZClip);
|
||||
HWD.pfnDrawPolygon(NULL, v, 4, PF_Translucent | PF_NoDepthTest);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
|
|
|
@ -35,8 +35,7 @@
|
|||
|
||||
#define DL_HIGH_QUALITY
|
||||
//#define STATICLIGHT //Hurdler: TODO!
|
||||
//#define LIGHTMAPFLAGS (PF_Masked|PF_Clip|PF_NoAlphaTest) // debug see overdraw
|
||||
#define LIGHTMAPFLAGS (PF_Modulated|PF_Additive|PF_Clip)
|
||||
#define LIGHTMAPFLAGS (PF_Modulated|PF_AdditiveSource)
|
||||
|
||||
#ifdef ALAM_LIGHTING
|
||||
static dynlights_t view_dynlights[2]; // 2 players in splitscreen mode
|
||||
|
@ -1056,7 +1055,7 @@ void HWR_DoCoronasLighting(FOutVector *outVerts, gl_vissprite_t *spr)
|
|||
|
||||
HWR_GetPic(coronalumpnum); /// \todo use different coronas
|
||||
|
||||
HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_Additive | PF_Clip | PF_Corona | PF_NoDepthTest);
|
||||
HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_AdditiveSource | PF_Corona | PF_NoDepthTest);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1144,7 +1143,7 @@ void HWR_DrawCoronas(void)
|
|||
light[3].y = cy+size*1.33f;
|
||||
light[3].s = 0.0f; light[3].t = 1.0f;
|
||||
|
||||
HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_Additive | PF_Clip | PF_NoDepthTest | PF_Corona);
|
||||
HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_AdditiveSource | PF_NoDepthTest | PF_Corona);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -695,28 +695,71 @@ static void HWR_RenderSkyPlane(extrasubsector_t *xsub, fixed_t fixedheight)
|
|||
v3d->z = pv->y;
|
||||
}
|
||||
|
||||
HWD.pfnDrawPolygon(NULL, planeVerts, nrPlaneVerts,
|
||||
PF_Clip|PF_Invisible|PF_NoTexture|PF_Occlude);
|
||||
HWD.pfnDrawPolygon(NULL, planeVerts, nrPlaneVerts, PF_Invisible|PF_NoTexture|PF_Occlude);
|
||||
}
|
||||
#endif //polysky
|
||||
|
||||
#endif //doplanes
|
||||
|
||||
FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf)
|
||||
FBITFIELD HWR_GetBlendModeFlag(INT32 ast)
|
||||
{
|
||||
switch (ast)
|
||||
{
|
||||
case AST_ADD:
|
||||
return PF_Additive;
|
||||
case AST_SUBTRACT:
|
||||
return PF_Subtractive;
|
||||
case AST_REVERSESUBTRACT:
|
||||
return PF_ReverseSubtract;
|
||||
case AST_MODULATE:
|
||||
return PF_Multiplicative;
|
||||
default:
|
||||
return PF_Translucent;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT8 HWR_GetTranstableAlpha(INT32 transtablenum)
|
||||
{
|
||||
switch (transtablenum)
|
||||
{
|
||||
case 0 : pSurf->PolyColor.s.alpha = 0x00;return PF_Masked;
|
||||
case tr_trans10 : pSurf->PolyColor.s.alpha = 0xe6;return PF_Translucent;
|
||||
case tr_trans20 : pSurf->PolyColor.s.alpha = 0xcc;return PF_Translucent;
|
||||
case tr_trans30 : pSurf->PolyColor.s.alpha = 0xb3;return PF_Translucent;
|
||||
case tr_trans40 : pSurf->PolyColor.s.alpha = 0x99;return PF_Translucent;
|
||||
case tr_trans50 : pSurf->PolyColor.s.alpha = 0x80;return PF_Translucent;
|
||||
case tr_trans60 : pSurf->PolyColor.s.alpha = 0x66;return PF_Translucent;
|
||||
case tr_trans70 : pSurf->PolyColor.s.alpha = 0x4c;return PF_Translucent;
|
||||
case tr_trans80 : pSurf->PolyColor.s.alpha = 0x33;return PF_Translucent;
|
||||
case tr_trans90 : pSurf->PolyColor.s.alpha = 0x19;return PF_Translucent;
|
||||
case 0 : return 0xff;
|
||||
case tr_trans10 : return 0xe6;
|
||||
case tr_trans20 : return 0xcc;
|
||||
case tr_trans30 : return 0xb3;
|
||||
case tr_trans40 : return 0x99;
|
||||
case tr_trans50 : return 0x80;
|
||||
case tr_trans60 : return 0x66;
|
||||
case tr_trans70 : return 0x4c;
|
||||
case tr_trans80 : return 0x33;
|
||||
case tr_trans90 : return 0x19;
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 transtablenum, FSurfaceInfo *pSurf)
|
||||
{
|
||||
if (!transtablenum)
|
||||
{
|
||||
pSurf->PolyColor.s.alpha = 0xff;
|
||||
return PF_Masked;
|
||||
}
|
||||
|
||||
pSurf->PolyColor.s.alpha = HWR_GetTranstableAlpha(transtablenum);
|
||||
return HWR_GetBlendModeFlag(style);
|
||||
}
|
||||
|
||||
FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf)
|
||||
{
|
||||
if (!transtablenum)
|
||||
{
|
||||
pSurf->PolyColor.s.alpha = 0x00;
|
||||
return PF_Masked;
|
||||
}
|
||||
|
||||
pSurf->PolyColor.s.alpha = HWR_GetTranstableAlpha(transtablenum);
|
||||
return PF_Translucent;
|
||||
}
|
||||
|
||||
|
@ -2770,10 +2813,10 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
|
|||
if (blendmode & PF_Translucent)
|
||||
{
|
||||
Surf.PolyColor.s.alpha = (UINT8)alpha;
|
||||
blendmode |= PF_Modulated|PF_Occlude|PF_Clip;
|
||||
blendmode |= PF_Modulated|PF_Occlude;
|
||||
}
|
||||
else
|
||||
blendmode |= PF_Masked|PF_Modulated|PF_Clip;
|
||||
blendmode |= PF_Masked|PF_Modulated;
|
||||
|
||||
HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode, 1, false); // floor shader
|
||||
}
|
||||
|
@ -3443,7 +3486,7 @@ static void HWR_LinkDrawHackFinish(void)
|
|||
{
|
||||
// draw sprite shape, only to z-buffer
|
||||
HWR_GetPatch(linkdrawlist[i].spr->gpatch);
|
||||
HWR_ProcessPolygon(&surf, linkdrawlist[i].verts, 4, PF_Translucent|PF_Occlude|PF_Invisible|PF_Clip, 0, false);
|
||||
HWR_ProcessPolygon(&surf, linkdrawlist[i].verts, 4, PF_Translucent|PF_Occlude|PF_Invisible, 0, false);
|
||||
}
|
||||
// reset list
|
||||
linkdrawcount = 0;
|
||||
|
@ -3587,7 +3630,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
HWR_Lighting(&sSurf, 0, colormap);
|
||||
sSurf.PolyColor.s.alpha = alpha;
|
||||
|
||||
HWR_ProcessPolygon(&sSurf, shadowVerts, 4, PF_Translucent|PF_Modulated|PF_Clip, 3, false); // sprite shader
|
||||
HWR_ProcessPolygon(&sSurf, shadowVerts, 4, PF_Translucent|PF_Modulated, 3, false); // sprite shader
|
||||
}
|
||||
|
||||
// This is expecting a pointer to an array containing 4 wallVerts for a sprite
|
||||
|
@ -3741,10 +3784,10 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
|||
else if (spr->mobj->flags2 & MF2_SHADOW)
|
||||
{
|
||||
Surf.PolyColor.s.alpha = 0x40;
|
||||
blend = PF_Translucent;
|
||||
blend = HWR_GetBlendModeFlag(spr->mobj->blendmode);
|
||||
}
|
||||
else if (spr->mobj->frame & FF_TRANSMASK)
|
||||
blend = HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
|
||||
blend = HWR_SurfaceBlend(spr->mobj->blendmode, (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
|
||||
else
|
||||
{
|
||||
// BP: i agree that is little better in environement but it don't
|
||||
|
@ -3752,7 +3795,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
|||
// Hurdler: PF_Environement would be cool, but we need to fix
|
||||
// the issue with the fog before
|
||||
Surf.PolyColor.s.alpha = 0xFF;
|
||||
blend = PF_Translucent|occlusion;
|
||||
blend = HWR_GetBlendModeFlag(spr->mobj->blendmode)|occlusion;
|
||||
if (!occlusion) use_linkdraw_hack = true;
|
||||
}
|
||||
|
||||
|
@ -3860,7 +3903,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
|||
|
||||
Surf.PolyColor.s.alpha = alpha;
|
||||
|
||||
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, 3, false); // sprite shader
|
||||
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, 3, false); // sprite shader
|
||||
|
||||
if (use_linkdraw_hack)
|
||||
HWR_LinkDrawHackAdd(wallVerts, spr);
|
||||
|
@ -3889,7 +3932,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
|||
|
||||
Surf.PolyColor.s.alpha = alpha;
|
||||
|
||||
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, 3, false); // sprite shader
|
||||
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, 3, false); // sprite shader
|
||||
|
||||
if (use_linkdraw_hack)
|
||||
HWR_LinkDrawHackAdd(wallVerts, spr);
|
||||
|
@ -4156,10 +4199,10 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
|||
else if (spr->mobj->flags2 & MF2_SHADOW)
|
||||
{
|
||||
Surf.PolyColor.s.alpha = 0x40;
|
||||
blend = PF_Translucent;
|
||||
blend = HWR_GetBlendModeFlag(spr->mobj->blendmode);
|
||||
}
|
||||
else if (spr->mobj->frame & FF_TRANSMASK)
|
||||
blend = HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
|
||||
blend = HWR_SurfaceBlend(spr->mobj->blendmode, (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
|
||||
else
|
||||
{
|
||||
// BP: i agree that is little better in environement but it don't
|
||||
|
@ -4167,7 +4210,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
|||
// Hurdler: PF_Environement would be cool, but we need to fix
|
||||
// the issue with the fog before
|
||||
Surf.PolyColor.s.alpha = 0xFF;
|
||||
blend = PF_Translucent|occlusion;
|
||||
blend = HWR_GetBlendModeFlag(spr->mobj->blendmode)|occlusion;
|
||||
if (!occlusion) use_linkdraw_hack = true;
|
||||
}
|
||||
|
||||
|
@ -4183,7 +4226,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
|||
if (!occlusion) use_linkdraw_hack = true;
|
||||
}
|
||||
|
||||
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, 3, false); // sprite shader
|
||||
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, 3, false); // sprite shader
|
||||
|
||||
if (use_linkdraw_hack)
|
||||
HWR_LinkDrawHackAdd(wallVerts, spr);
|
||||
|
@ -4271,10 +4314,10 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
|
|||
if (spr->mobj->flags2 & MF2_SHADOW)
|
||||
{
|
||||
Surf.PolyColor.s.alpha = 0x40;
|
||||
blend = PF_Translucent;
|
||||
blend = HWR_GetBlendModeFlag(spr->mobj->blendmode);
|
||||
}
|
||||
else if (spr->mobj->frame & FF_TRANSMASK)
|
||||
blend = HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
|
||||
blend = HWR_SurfaceBlend(spr->mobj->blendmode, (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
|
||||
else
|
||||
{
|
||||
// BP: i agree that is little better in environement but it don't
|
||||
|
@ -4282,10 +4325,10 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
|
|||
// Hurdler: PF_Environement would be cool, but we need to fix
|
||||
// the issue with the fog before
|
||||
Surf.PolyColor.s.alpha = 0xFF;
|
||||
blend = PF_Translucent|PF_Occlude;
|
||||
blend = HWR_GetBlendModeFlag(spr->mobj->blendmode)|PF_Occlude;
|
||||
}
|
||||
|
||||
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, 3, false); // sprite shader
|
||||
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, 3, false); // sprite shader
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -4749,7 +4792,7 @@ static void HWR_DrawSprites(void)
|
|||
// (Other states probably don't matter. Here I left them same as in LinkDrawHackFinish)
|
||||
// Without this workaround the rest of the draw calls in this frame (including UI, screen texture)
|
||||
// can get drawn using an incorrect glBlendFunc, resulting in a occasional black screen.
|
||||
HWD.pfnSetBlend(PF_Translucent|PF_Occlude|PF_Clip|PF_Masked);
|
||||
HWD.pfnSetBlend(PF_Translucent|PF_Occlude|PF_Masked);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
@ -6422,7 +6465,7 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
|
||||
Surf.PolyColor.s.alpha = 0xc0; // match software mode
|
||||
|
||||
HWD.pfnDrawPolygon(&Surf, v, 4, PF_Modulated|PF_Additive|PF_NoTexture|PF_NoDepthTest|PF_Clip|PF_NoZClip);
|
||||
HWD.pfnDrawPolygon(&Surf, v, 4, PF_Modulated|PF_AdditiveSource|PF_NoTexture|PF_NoDepthTest);
|
||||
}
|
||||
|
||||
// Capture the screen for intermission and screen waving
|
||||
|
|
|
@ -54,7 +54,6 @@ boolean HWR_Screenshot(const char *pathname);
|
|||
void HWR_AddCommands(void);
|
||||
void HWR_AddSessionCommands(void);
|
||||
void transform(float *cx, float *cy, float *cz);
|
||||
FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf);
|
||||
INT32 HWR_GetTextureUsed(void);
|
||||
void HWR_DoPostProcessor(player_t *player);
|
||||
void HWR_StartScreenWipe(void);
|
||||
|
@ -65,10 +64,15 @@ void HWR_DoTintedWipe(UINT8 wipenum, UINT8 scrnnum);
|
|||
void HWR_MakeScreenFinalTexture(void);
|
||||
void HWR_DrawScreenFinalTexture(int width, int height);
|
||||
|
||||
// This stuff is put here so MD2's can use them
|
||||
// This stuff is put here so models can use them
|
||||
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap);
|
||||
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work
|
||||
|
||||
UINT8 HWR_GetTranstableAlpha(INT32 transtablenum);
|
||||
FBITFIELD HWR_GetBlendModeFlag(INT32 ast);
|
||||
FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 transtablenum, FSurfaceInfo *pSurf);
|
||||
FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf);
|
||||
|
||||
void HWR_ReadShaders(UINT16 wadnum, boolean PK3);
|
||||
boolean HWR_LoadShaders(void);
|
||||
|
||||
|
|
|
@ -1317,11 +1317,17 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
//durs = tics;
|
||||
|
||||
if (spr->mobj->flags2 & MF2_SHADOW)
|
||||
{
|
||||
Surf.PolyColor.s.alpha = 0x40;
|
||||
Surf.PolyFlags = HWR_GetBlendModeFlag(spr->mobj->blendmode);
|
||||
}
|
||||
else if (spr->mobj->frame & FF_TRANSMASK)
|
||||
HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
|
||||
Surf.PolyFlags = HWR_SurfaceBlend(spr->mobj->blendmode, (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
|
||||
else
|
||||
{
|
||||
Surf.PolyColor.s.alpha = 0xFF;
|
||||
Surf.PolyFlags = 0;
|
||||
}
|
||||
|
||||
// dont forget to enabled the depth test because we can't do this like
|
||||
// before: polygons models are not sorted
|
||||
|
|
|
@ -425,6 +425,10 @@ static PFNglBufferData pglBufferData;
|
|||
typedef void (APIENTRY * PFNglDeleteBuffers) (GLsizei n, const GLuint *buffers);
|
||||
static PFNglDeleteBuffers pglDeleteBuffers;
|
||||
|
||||
/* 2.0 functions */
|
||||
typedef void (APIENTRY * PFNglBlendEquation) (GLenum mode);
|
||||
static PFNglBlendEquation pglBlendEquation;
|
||||
|
||||
|
||||
/* 1.2 Parms */
|
||||
/* GL_CLAMP_TO_EDGE_EXT */
|
||||
|
@ -892,6 +896,9 @@ void SetupGLFunc4(void)
|
|||
pglBufferData = GetGLFunc("glBufferData");
|
||||
pglDeleteBuffers = GetGLFunc("glDeleteBuffers");
|
||||
|
||||
/* 2.0 funcs */
|
||||
pglBlendEquation = GetGLFunc("glBlendEquation");
|
||||
|
||||
#ifdef GL_SHADERS
|
||||
pglCreateShader = GetGLFunc("glCreateShader");
|
||||
pglShaderSource = GetGLFunc("glShaderSource");
|
||||
|
@ -1286,6 +1293,7 @@ void SetStates(void)
|
|||
|
||||
pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
pglEnable(GL_ALPHA_TEST);
|
||||
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
|
||||
|
||||
//pglBlendFunc(GL_ONE, GL_ZERO); // copy pixel to frame buffer (opaque)
|
||||
|
@ -1554,64 +1562,110 @@ EXPORT void HWRAPI(Draw2DLine) (F2DCoord * v1,
|
|||
pglEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
static void Clamp2D(GLenum pname)
|
||||
{
|
||||
pglTexParameteri(GL_TEXTURE_2D, pname, GL_CLAMP); // fallback clamp
|
||||
pglTexParameteri(GL_TEXTURE_2D, pname, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
|
||||
// -----------------+
|
||||
// SetBlend : Set render mode
|
||||
// -----------------+
|
||||
// PF_Masked - we could use an ALPHA_TEST of GL_EQUAL, and alpha ref of 0,
|
||||
// is it faster when pixels are discarded ?
|
||||
|
||||
static void Clamp2D(GLenum pname)
|
||||
{
|
||||
pglTexParameteri(GL_TEXTURE_2D, pname, GL_CLAMP); // fallback clamp
|
||||
pglTexParameteri(GL_TEXTURE_2D, pname, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
static void SetBlendEquation(GLenum mode)
|
||||
{
|
||||
if (pglBlendEquation)
|
||||
pglBlendEquation(mode);
|
||||
}
|
||||
|
||||
static void SetBlendMode(FBITFIELD flags)
|
||||
{
|
||||
// Set blending function
|
||||
switch (flags)
|
||||
{
|
||||
case PF_Translucent & PF_Blending:
|
||||
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
|
||||
break;
|
||||
case PF_Masked & PF_Blending:
|
||||
// Hurdler: does that mean lighting is only made by alpha src?
|
||||
// it sounds ok, but not for polygonsmooth
|
||||
pglBlendFunc(GL_SRC_ALPHA, GL_ZERO); // 0 alpha = holes in texture
|
||||
break;
|
||||
case PF_Additive & PF_Blending:
|
||||
case PF_Subtractive & PF_Blending:
|
||||
case PF_ReverseSubtract & PF_Blending:
|
||||
case PF_Environment & PF_Blending:
|
||||
pglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
case PF_AdditiveSource & PF_Blending:
|
||||
pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest
|
||||
break;
|
||||
case PF_Multiplicative & PF_Blending:
|
||||
pglBlendFunc(GL_DST_COLOR, GL_ZERO);
|
||||
break;
|
||||
case PF_Fog & PF_Fog:
|
||||
// Sryder: Fog
|
||||
// multiplies input colour by input alpha, and destination colour by input colour, then adds them
|
||||
pglBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR);
|
||||
break;
|
||||
default: // must be 0, otherwise it's an error
|
||||
// No blending
|
||||
pglBlendFunc(GL_ONE, GL_ZERO); // the same as no blending
|
||||
break;
|
||||
}
|
||||
|
||||
// Set blending equation
|
||||
switch (flags)
|
||||
{
|
||||
case PF_Subtractive & PF_Blending:
|
||||
SetBlendEquation(GL_FUNC_SUBTRACT);
|
||||
break;
|
||||
case PF_ReverseSubtract & PF_Blending:
|
||||
// good for shadow
|
||||
// not really but what else ?
|
||||
SetBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
||||
break;
|
||||
default:
|
||||
SetBlendEquation(GL_FUNC_ADD);
|
||||
break;
|
||||
}
|
||||
|
||||
// Alpha test
|
||||
switch (flags)
|
||||
{
|
||||
case PF_Masked & PF_Blending:
|
||||
pglAlphaFunc(GL_GREATER, 0.5f);
|
||||
break;
|
||||
case PF_Translucent & PF_Blending:
|
||||
case PF_Additive & PF_Blending:
|
||||
case PF_AdditiveSource & PF_Blending:
|
||||
case PF_Subtractive & PF_Blending:
|
||||
case PF_ReverseSubtract & PF_Blending:
|
||||
case PF_Environment & PF_Blending:
|
||||
case PF_Multiplicative & PF_Blending:
|
||||
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
|
||||
break;
|
||||
case PF_Fog & PF_Fog:
|
||||
pglAlphaFunc(GL_ALWAYS, 0.0f); // Don't discard zero alpha fragments
|
||||
break;
|
||||
default:
|
||||
pglAlphaFunc(GL_GREATER, 0.5f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
|
||||
{
|
||||
FBITFIELD Xor;
|
||||
Xor = CurrentPolyFlags^PolyFlags;
|
||||
if (Xor & (PF_Blending|PF_RemoveYWrap|PF_ForceWrapX|PF_ForceWrapY|PF_Occlude|PF_NoTexture|PF_Modulated|PF_NoDepthTest|PF_Decal|PF_Invisible|PF_NoAlphaTest))
|
||||
if (Xor & (PF_Blending|PF_RemoveYWrap|PF_ForceWrapX|PF_ForceWrapY|PF_Occlude|PF_NoTexture|PF_Modulated|PF_NoDepthTest|PF_Decal|PF_Invisible))
|
||||
{
|
||||
if (Xor&(PF_Blending)) // if blending mode must be changed
|
||||
{
|
||||
switch (PolyFlags & PF_Blending) {
|
||||
case PF_Translucent & PF_Blending:
|
||||
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
|
||||
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
|
||||
break;
|
||||
case PF_Masked & PF_Blending:
|
||||
// Hurdler: does that mean lighting is only made by alpha src?
|
||||
// it sounds ok, but not for polygonsmooth
|
||||
pglBlendFunc(GL_SRC_ALPHA, GL_ZERO); // 0 alpha = holes in texture
|
||||
pglAlphaFunc(GL_GREATER, 0.5f);
|
||||
break;
|
||||
case PF_Additive & PF_Blending:
|
||||
pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest
|
||||
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
|
||||
break;
|
||||
case PF_Environment & PF_Blending:
|
||||
pglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
|
||||
break;
|
||||
case PF_Substractive & PF_Blending:
|
||||
// good for shadow
|
||||
// not really but what else ?
|
||||
pglBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
|
||||
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
|
||||
break;
|
||||
case PF_Fog & PF_Fog:
|
||||
// Sryder: Fog
|
||||
// multiplies input colour by input alpha, and destination colour by input colour, then adds them
|
||||
pglBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR);
|
||||
pglAlphaFunc(GL_ALWAYS, 0.0f); // Don't discard zero alpha fragments
|
||||
break;
|
||||
default : // must be 0, otherwise it's an error
|
||||
// No blending
|
||||
pglBlendFunc(GL_ONE, GL_ZERO); // the same as no blending
|
||||
pglAlphaFunc(GL_GREATER, 0.5f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Xor & PF_Blending) // if blending mode must be changed
|
||||
SetBlendMode(PolyFlags & PF_Blending);
|
||||
|
||||
if (Xor & PF_NoAlphaTest)
|
||||
{
|
||||
if (PolyFlags & PF_NoAlphaTest)
|
||||
|
@ -1628,7 +1682,7 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
|
|||
pglDisable(GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
|
||||
if (Xor&PF_NoDepthTest)
|
||||
if (Xor & PF_NoDepthTest)
|
||||
{
|
||||
if (PolyFlags & PF_NoDepthTest)
|
||||
pglDepthFunc(GL_ALWAYS); //pglDisable(GL_DEPTH_TEST);
|
||||
|
@ -1636,25 +1690,25 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
|
|||
pglDepthFunc(GL_LEQUAL); //pglEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
if (Xor&PF_RemoveYWrap)
|
||||
if (Xor & PF_RemoveYWrap)
|
||||
{
|
||||
if (PolyFlags & PF_RemoveYWrap)
|
||||
Clamp2D(GL_TEXTURE_WRAP_T);
|
||||
}
|
||||
|
||||
if (Xor&PF_ForceWrapX)
|
||||
if (Xor & PF_ForceWrapX)
|
||||
{
|
||||
if (PolyFlags & PF_ForceWrapX)
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
}
|
||||
|
||||
if (Xor&PF_ForceWrapY)
|
||||
if (Xor & PF_ForceWrapY)
|
||||
{
|
||||
if (PolyFlags & PF_ForceWrapY)
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
}
|
||||
|
||||
if (Xor&PF_Modulated)
|
||||
if (Xor & PF_Modulated)
|
||||
{
|
||||
#if defined (__unix__) || defined (UNIXCOMMON)
|
||||
if (oglflags & GLF_NOTEXENV)
|
||||
|
@ -2613,7 +2667,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
|
|||
else
|
||||
pglColor4ubv((GLubyte*)&Surface->PolyColor.s);
|
||||
|
||||
SetBlend((poly.alpha < 1 ? PF_Translucent : (PF_Masked|PF_Occlude))|PF_Modulated);
|
||||
SetBlend((poly.alpha < 1 ? Surface->PolyFlags : (PF_Masked|PF_Occlude))|PF_Modulated);
|
||||
|
||||
tint.red = byte2float[Surface->TintColor.s.red];
|
||||
tint.green = byte2float[Surface->TintColor.s.green];
|
||||
|
@ -3194,7 +3248,7 @@ EXPORT void HWRAPI(DoScreenWipe)(void)
|
|||
|
||||
pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
SetBlend(PF_Modulated|PF_NoDepthTest|PF_Clip|PF_NoZClip);
|
||||
SetBlend(PF_Modulated|PF_NoDepthTest);
|
||||
pglEnable(GL_TEXTURE_2D);
|
||||
|
||||
// Draw the original screen
|
||||
|
@ -3204,7 +3258,7 @@ EXPORT void HWRAPI(DoScreenWipe)(void)
|
|||
pglVertexPointer(3, GL_FLOAT, 0, screenVerts);
|
||||
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest|PF_Clip|PF_NoZClip);
|
||||
SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest);
|
||||
|
||||
// Draw the end screen that fades in
|
||||
pglActiveTexture(GL_TEXTURE0);
|
||||
|
|
|
@ -64,6 +64,7 @@ enum mobj_e {
|
|||
mobj_renderflags,
|
||||
mobj_skin,
|
||||
mobj_color,
|
||||
mobj_blendmode,
|
||||
mobj_bnext,
|
||||
mobj_bprev,
|
||||
mobj_hnext,
|
||||
|
@ -139,6 +140,7 @@ static const char *const mobj_opt[] = {
|
|||
"renderflags",
|
||||
"skin",
|
||||
"color",
|
||||
"blendmode",
|
||||
"bnext",
|
||||
"bprev",
|
||||
"hnext",
|
||||
|
@ -315,6 +317,9 @@ static int mobj_get(lua_State *L)
|
|||
case mobj_color:
|
||||
lua_pushinteger(L, mo->color);
|
||||
break;
|
||||
case mobj_blendmode:
|
||||
lua_pushinteger(L, mo->blendmode);
|
||||
break;
|
||||
case mobj_bnext:
|
||||
LUA_PushUserdata(L, mo->bnext, META_MOBJ);
|
||||
break;
|
||||
|
@ -650,6 +655,9 @@ static int mobj_set(lua_State *L)
|
|||
mo->color = newcolor;
|
||||
break;
|
||||
}
|
||||
case mobj_blendmode:
|
||||
mo->blendmode = (INT32)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mobj_bnext:
|
||||
return NOSETPOS;
|
||||
case mobj_bprev:
|
||||
|
|
|
@ -10454,7 +10454,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
mobj->tics = st->tics;
|
||||
mobj->sprite = st->sprite;
|
||||
mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits..
|
||||
mobj->renderflags = 0;
|
||||
P_SetupStateAnimation(mobj, st);
|
||||
|
||||
mobj->friction = ORIG_FRICTION;
|
||||
|
@ -10471,6 +10470,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
mobj->destscale = FRACUNIT/2;
|
||||
|
||||
// Sprite rendering
|
||||
mobj->blendmode = AST_TRANSLUCENT;
|
||||
mobj->spritexscale = mobj->spriteyscale = mobj->scale;
|
||||
mobj->spritexoffset = mobj->spriteyoffset = 0;
|
||||
mobj->floorspriteslope = NULL;
|
||||
|
|
|
@ -265,6 +265,7 @@ typedef enum {
|
|||
// Ran the thinker this tic.
|
||||
PCF_THUNK = 32,
|
||||
} precipflag_t;
|
||||
|
||||
// Map Object definition.
|
||||
typedef struct mobj_s
|
||||
{
|
||||
|
@ -287,6 +288,7 @@ typedef struct mobj_s
|
|||
UINT16 anim_duration; // for FF_ANIMATE states
|
||||
|
||||
UINT32 renderflags; // render flags
|
||||
INT32 blendmode; // blend mode
|
||||
fixed_t spritexscale, spriteyscale;
|
||||
fixed_t spritexoffset, spriteyoffset;
|
||||
struct pslope_s *floorspriteslope; // The slope that the floorsprite is rotated by
|
||||
|
@ -405,7 +407,7 @@ typedef struct precipmobj_s
|
|||
struct precipmobj_s **sprev; // killough 8/11/98: change to ptr-to-ptr
|
||||
|
||||
// More drawing info: to determine current sprite.
|
||||
angle_t angle, pitch, roll; // orientation
|
||||
angle_t angle, pitch, roll; // orientation
|
||||
angle_t rollangle;
|
||||
spritenum_t sprite; // used to find patch_t and flip value
|
||||
UINT32 frame; // frame number, plus bits see p_pspr.h
|
||||
|
@ -413,6 +415,7 @@ typedef struct precipmobj_s
|
|||
UINT16 anim_duration; // for FF_ANIMATE states
|
||||
|
||||
UINT32 renderflags; // render flags
|
||||
INT32 blendmode; // blend mode
|
||||
fixed_t spritexscale, spriteyscale;
|
||||
fixed_t spritexoffset, spriteyoffset;
|
||||
struct pslope_s *floorspriteslope; // The slope that the floorsprite is rotated by
|
||||
|
|
|
@ -1395,11 +1395,12 @@ typedef enum
|
|||
MD2_ROLLANGLE = 1<<14,
|
||||
MD2_SHADOWSCALE = 1<<15,
|
||||
MD2_RENDERFLAGS = 1<<16,
|
||||
MD2_SPRITEXSCALE = 1<<17,
|
||||
MD2_SPRITEYSCALE = 1<<18,
|
||||
MD2_SPRITEXOFFSET = 1<<19,
|
||||
MD2_SPRITEYOFFSET = 1<<20,
|
||||
MD2_FLOORSPRITESLOPE = 1<<21,
|
||||
MD2_BLENDMODE = 1<<17,
|
||||
MD2_SPRITEXSCALE = 1<<18,
|
||||
MD2_SPRITEYSCALE = 1<<19,
|
||||
MD2_SPRITEXOFFSET = 1<<20,
|
||||
MD2_SPRITEYOFFSET = 1<<21,
|
||||
MD2_FLOORSPRITESLOPE = 1<<22,
|
||||
} mobj_diff2_t;
|
||||
|
||||
typedef enum
|
||||
|
@ -1614,6 +1615,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
diff2 |= MD2_SHADOWSCALE;
|
||||
if (mobj->renderflags)
|
||||
diff2 |= MD2_RENDERFLAGS;
|
||||
if (mobj->renderflags)
|
||||
diff2 |= MD2_BLENDMODE;
|
||||
if (mobj->spritexscale != FRACUNIT)
|
||||
diff2 |= MD2_SPRITEXSCALE;
|
||||
if (mobj->spriteyscale != FRACUNIT)
|
||||
|
@ -1775,6 +1778,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
WRITEFIXED(save_p, mobj->shadowscale);
|
||||
if (diff2 & MD2_RENDERFLAGS)
|
||||
WRITEUINT32(save_p, mobj->renderflags);
|
||||
if (diff2 & MD2_BLENDMODE)
|
||||
WRITEINT32(save_p, mobj->blendmode);
|
||||
if (diff2 & MD2_SPRITEXSCALE)
|
||||
WRITEFIXED(save_p, mobj->spritexscale);
|
||||
if (diff2 & MD2_SPRITEYSCALE)
|
||||
|
@ -2813,6 +2818,8 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
mobj->shadowscale = READFIXED(save_p);
|
||||
if (diff2 & MD2_RENDERFLAGS)
|
||||
mobj->renderflags = READUINT32(save_p);
|
||||
if (diff2 & MD2_BLENDMODE)
|
||||
mobj->blendmode = READINT32(save_p);
|
||||
if (diff2 & MD2_SPRITEXSCALE)
|
||||
mobj->spritexscale = READFIXED(save_p);
|
||||
if (diff2 & MD2_SPRITEYSCALE)
|
||||
|
|
|
@ -175,13 +175,15 @@ UINT8 ASTBlendPaletteIndexes(UINT8 background, UINT8 foreground, int style, UINT
|
|||
if (alpha <= ASTTextureBlendingThreshold[1])
|
||||
{
|
||||
UINT8 *mytransmap;
|
||||
INT32 trans;
|
||||
|
||||
// Is the patch way too translucent? Don't blend then.
|
||||
if (alpha < ASTTextureBlendingThreshold[0])
|
||||
return background;
|
||||
|
||||
// The equation's not exact but it works as intended. I'll call it a day for now.
|
||||
mytransmap = transtables + ((8*(alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT);
|
||||
trans = (8*(alpha) + 255/8)/(255 - 255/11);
|
||||
mytransmap = R_GetTranslucencyTable(trans + 1);
|
||||
if (background != 0xFF)
|
||||
return *(mytransmap + (background<<8) + foreground);
|
||||
}
|
||||
|
|
108
src/r_draw.c
108
src/r_draw.c
|
@ -75,6 +75,7 @@ UINT8 *dc_source;
|
|||
#define NUMTRANSTABLES 9 // how many translucency tables are used
|
||||
|
||||
UINT8 *transtables; // translucency tables
|
||||
UINT8 *blendtables[NUMBLENDMAPS];
|
||||
|
||||
/** \brief R_DrawTransColumn uses this
|
||||
*/
|
||||
|
@ -116,10 +117,6 @@ float focallengthf, zeroheight;
|
|||
|
||||
UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask;
|
||||
|
||||
// ==========================================================================
|
||||
// OLD DOOM FUZZY EFFECT
|
||||
// ==========================================================================
|
||||
|
||||
// =========================================================================
|
||||
// TRANSLATION COLORMAP CODE
|
||||
// =========================================================================
|
||||
|
@ -139,11 +136,11 @@ UINT8 skincolor_modified[MAXSKINCOLORS];
|
|||
|
||||
CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1];
|
||||
|
||||
/** \brief The R_InitTranslationTables
|
||||
#define TRANSTAB_AMTMUL10 (256.0f / 10.0f)
|
||||
|
||||
load in color translation tables
|
||||
/** \brief Initializes the translucency tables used by the Software renderer.
|
||||
*/
|
||||
void R_InitTranslationTables(void)
|
||||
void R_InitTranslucencyTables(void)
|
||||
{
|
||||
// Load here the transparency lookup tables 'TINTTAB'
|
||||
// NOTE: the TINTTAB resource MUST BE aligned on 64k for the asm
|
||||
|
@ -160,17 +157,94 @@ void R_InitTranslationTables(void)
|
|||
W_ReadLump(W_GetNumForName("TRANS70"), transtables+0x60000);
|
||||
W_ReadLump(W_GetNumForName("TRANS80"), transtables+0x70000);
|
||||
W_ReadLump(W_GetNumForName("TRANS90"), transtables+0x80000);
|
||||
|
||||
R_GenerateBlendTables();
|
||||
}
|
||||
|
||||
void R_GenerateBlendTables(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
/** \brief Generates a translation colormap.
|
||||
for (i = 0; i < NUMBLENDMAPS; i++)
|
||||
{
|
||||
if (i == blendtab_modulate)
|
||||
continue;
|
||||
blendtables[i] = Z_MallocAlign((NUMTRANSTABLES + 1) * 0x10000, PU_STATIC, NULL, 16);
|
||||
}
|
||||
|
||||
\param dest_colormap colormap to populate
|
||||
\param skinnum number of skin, TC_DEFAULT or TC_BOSS
|
||||
\param color translation color
|
||||
for (i = 0; i <= 9; i++)
|
||||
{
|
||||
const size_t offs = (0x10000 * i);
|
||||
const UINT8 alpha = TRANSTAB_AMTMUL10 * i;
|
||||
|
||||
\return void
|
||||
*/
|
||||
R_GenerateTranslucencyTable(blendtables[blendtab_add] + offs, AST_ADD, alpha);
|
||||
R_GenerateTranslucencyTable(blendtables[blendtab_subtract] + offs, AST_SUBTRACT, alpha);
|
||||
R_GenerateTranslucencyTable(blendtables[blendtab_reversesubtract] + offs, AST_REVERSESUBTRACT, alpha);
|
||||
}
|
||||
|
||||
// Modulation blending only requires a single table
|
||||
blendtables[blendtab_modulate] = Z_MallocAlign(0x10000, PU_STATIC, NULL, 16);
|
||||
R_GenerateTranslucencyTable(blendtables[blendtab_modulate], AST_MODULATE, 0);
|
||||
}
|
||||
|
||||
static colorlookup_t transtab_lut;
|
||||
|
||||
void R_GenerateTranslucencyTable(UINT8 *table, int style, UINT8 blendamt)
|
||||
{
|
||||
INT16 bg, fg;
|
||||
|
||||
if (table == NULL)
|
||||
I_Error("R_GenerateTranslucencyTable: input table was NULL!");
|
||||
|
||||
InitColorLUT(&transtab_lut, pMasterPalette, false);
|
||||
|
||||
for (bg = 0; bg < 0xFF; bg++)
|
||||
{
|
||||
for (fg = 0; fg < 0xFF; fg++)
|
||||
{
|
||||
RGBA_t backrgba = V_GetMasterColor(bg);
|
||||
RGBA_t frontrgba = V_GetMasterColor(fg);
|
||||
RGBA_t result;
|
||||
|
||||
result.rgba = ASTBlendPixel(backrgba, frontrgba, style, blendamt);
|
||||
table[((bg * 0x100) + fg)] = GetColorLUT(&transtab_lut, result.s.red, result.s.green, result.s.blue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define ClipTransLevel(trans) max(min((trans), NUMTRANSMAPS-2), 0)
|
||||
|
||||
UINT8 *R_GetTranslucencyTable(INT32 alphalevel)
|
||||
{
|
||||
return transtables + (ClipTransLevel(alphalevel-1) << FF_TRANSSHIFT);
|
||||
}
|
||||
|
||||
UINT8 *R_GetBlendTable(int style, INT32 alphalevel)
|
||||
{
|
||||
size_t offs = (ClipTransLevel(alphalevel) << FF_TRANSSHIFT);
|
||||
|
||||
// Lactozilla: Returns the equivalent to AST_TRANSLUCENT
|
||||
// if no alpha style matches any of the blend tables.
|
||||
switch (style)
|
||||
{
|
||||
case AST_ADD:
|
||||
return blendtables[blendtab_add] + offs;
|
||||
case AST_SUBTRACT:
|
||||
return blendtables[blendtab_subtract] + offs;
|
||||
case AST_REVERSESUBTRACT:
|
||||
return blendtables[blendtab_reversesubtract] + offs;
|
||||
case AST_MODULATE:
|
||||
return blendtables[blendtab_modulate];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Return a normal translucency table
|
||||
if (--alphalevel >= 0)
|
||||
return transtables + (ClipTransLevel(alphalevel) << FF_TRANSSHIFT);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Define for getting accurate color brightness readings according to how the human eye sees them.
|
||||
// https://en.wikipedia.org/wiki/Relative_luminance
|
||||
|
@ -228,6 +302,14 @@ static void R_RainbowColormap(UINT8 *dest_colormap, UINT16 skincolor)
|
|||
|
||||
#undef SETBRIGHTNESS
|
||||
|
||||
/** \brief Generates a translation colormap.
|
||||
|
||||
\param dest_colormap colormap to populate
|
||||
\param skinnum number of skin, TC_DEFAULT or TC_BOSS
|
||||
\param color translation color
|
||||
|
||||
\return void
|
||||
*/
|
||||
static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, UINT16 color)
|
||||
{
|
||||
INT32 i, starttranscolor, skinramplength;
|
||||
|
|
24
src/r_draw.h
24
src/r_draw.h
|
@ -37,7 +37,6 @@ extern UINT8 dc_hires;
|
|||
extern UINT8 *dc_source; // first pixel in a column
|
||||
|
||||
// translucency stuff here
|
||||
extern UINT8 *transtables; // translucency tables, should be (*transtables)[5][256][256]
|
||||
extern UINT8 *dc_transmap;
|
||||
|
||||
// translation stuff here
|
||||
|
@ -111,17 +110,36 @@ extern lumpnum_t viewborderlump[8];
|
|||
#define TC_BLINK -6 // For item blinking, according to kart
|
||||
#define TC_DASHMODE -7 // For Metal Sonic's dashmode
|
||||
|
||||
// Custom player skin translation
|
||||
// Initialize color translation tables, for player rendering etc.
|
||||
void R_InitTranslationTables(void);
|
||||
UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags);
|
||||
void R_FlushTranslationColormapCache(void);
|
||||
UINT16 R_GetColorByName(const char *name);
|
||||
UINT16 R_GetSuperColorByName(const char *name);
|
||||
|
||||
extern UINT8 *transtables; // translucency tables, should be (*transtables)[5][256][256]
|
||||
|
||||
enum
|
||||
{
|
||||
blendtab_add,
|
||||
blendtab_subtract,
|
||||
blendtab_reversesubtract,
|
||||
blendtab_modulate,
|
||||
NUMBLENDMAPS
|
||||
};
|
||||
|
||||
extern UINT8 *blendtables[NUMBLENDMAPS];
|
||||
|
||||
void R_InitTranslucencyTables(void);
|
||||
void R_GenerateBlendTables(void);
|
||||
void R_GenerateTranslucencyTable(UINT8 *table, int style, UINT8 blendamt);
|
||||
|
||||
UINT8 *R_GetTranslucencyTable(INT32 alphalevel);
|
||||
UINT8 *R_GetBlendTable(int style, INT32 alphalevel);
|
||||
|
||||
// Color ramp modification should force a recache
|
||||
extern UINT8 skincolor_modified[];
|
||||
|
||||
// Custom player skin translation
|
||||
void R_InitViewBuffer(INT32 width, INT32 height);
|
||||
void R_InitViewBorder(void);
|
||||
void R_VideoErase(size_t ofs, INT32 count);
|
||||
|
|
|
@ -1010,8 +1010,8 @@ void R_Init(void)
|
|||
//I_OutputMsg("\nR_InitLightTables");
|
||||
R_InitLightTables();
|
||||
|
||||
//I_OutputMsg("\nR_InitTranslationTables\n");
|
||||
R_InitTranslationTables();
|
||||
//I_OutputMsg("\nR_InitTranslucencyTables\n");
|
||||
R_InitTranslucencyTables();
|
||||
|
||||
R_InitDrawNodes();
|
||||
|
||||
|
|
|
@ -780,7 +780,7 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
else if (pl->polyobj->translucency > 0)
|
||||
{
|
||||
spanfunctype = (pl->polyobj->flags & POF_SPLAT) ? SPANDRAWFUNC_TRANSSPLAT : SPANDRAWFUNC_TRANS;
|
||||
ds_transmap = transtables + ((pl->polyobj->translucency-1)<<FF_TRANSSHIFT);
|
||||
ds_transmap = R_GetTranslucencyTable(pl->polyobj->translucency);
|
||||
}
|
||||
else if (pl->polyobj->flags & POF_SPLAT) // Opaque, but allow transparent flat pixels
|
||||
spanfunctype = SPANDRAWFUNC_SPLAT;
|
||||
|
@ -819,23 +819,23 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
if (pl->ffloor->alpha < 12)
|
||||
return; // Don't even draw it
|
||||
else if (pl->ffloor->alpha < 38)
|
||||
ds_transmap = transtables + ((tr_trans90-1)<<FF_TRANSSHIFT);
|
||||
ds_transmap = R_GetTranslucencyTable(tr_trans90);
|
||||
else if (pl->ffloor->alpha < 64)
|
||||
ds_transmap = transtables + ((tr_trans80-1)<<FF_TRANSSHIFT);
|
||||
ds_transmap = R_GetTranslucencyTable(tr_trans80);
|
||||
else if (pl->ffloor->alpha < 89)
|
||||
ds_transmap = transtables + ((tr_trans70-1)<<FF_TRANSSHIFT);
|
||||
ds_transmap = R_GetTranslucencyTable(tr_trans70);
|
||||
else if (pl->ffloor->alpha < 115)
|
||||
ds_transmap = transtables + ((tr_trans60-1)<<FF_TRANSSHIFT);
|
||||
ds_transmap = R_GetTranslucencyTable(tr_trans60);
|
||||
else if (pl->ffloor->alpha < 140)
|
||||
ds_transmap = transtables + ((tr_trans50-1)<<FF_TRANSSHIFT);
|
||||
ds_transmap = R_GetTranslucencyTable(tr_trans50);
|
||||
else if (pl->ffloor->alpha < 166)
|
||||
ds_transmap = transtables + ((tr_trans40-1)<<FF_TRANSSHIFT);
|
||||
ds_transmap = R_GetTranslucencyTable(tr_trans40);
|
||||
else if (pl->ffloor->alpha < 192)
|
||||
ds_transmap = transtables + ((tr_trans30-1)<<FF_TRANSSHIFT);
|
||||
ds_transmap = R_GetTranslucencyTable(tr_trans30);
|
||||
else if (pl->ffloor->alpha < 217)
|
||||
ds_transmap = transtables + ((tr_trans20-1)<<FF_TRANSSHIFT);
|
||||
ds_transmap = R_GetTranslucencyTable(tr_trans20);
|
||||
else if (pl->ffloor->alpha < 243)
|
||||
ds_transmap = transtables + ((tr_trans10-1)<<FF_TRANSSHIFT);
|
||||
ds_transmap = R_GetTranslucencyTable(tr_trans10);
|
||||
else // Opaque, but allow transparent flat pixels
|
||||
spanfunctype = SPANDRAWFUNC_SPLAT;
|
||||
|
||||
|
@ -1082,7 +1082,7 @@ using the palette colors.
|
|||
if (spanfunc == spanfuncs[BASEDRAWFUNC])
|
||||
{
|
||||
INT32 i;
|
||||
ds_transmap = transtables + ((tr_trans50-1)<<FF_TRANSSHIFT);
|
||||
ds_transmap = R_GetTranslucencyTable(tr_trans50);
|
||||
spanfunc = spanfuncs[SPANDRAWFUNC_TRANS];
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
|
|
22
src/r_segs.c
22
src/r_segs.c
|
@ -147,7 +147,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
|
||||
if (ldef->alpha > 0 && ldef->alpha < FRACUNIT)
|
||||
{
|
||||
dc_transmap = transtables + ((R_GetLinedefTransTable(ldef->alpha) - 1) << FF_TRANSSHIFT);
|
||||
dc_transmap = R_GetTranslucencyTable(R_GetLinedefTransTable(ldef->alpha));
|
||||
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
|
||||
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
if (curline->polyseg->translucency >= NUMTRANSMAPS)
|
||||
return;
|
||||
|
||||
dc_transmap = transtables + ((curline->polyseg->translucency-1)<<FF_TRANSSHIFT);
|
||||
dc_transmap = R_GetTranslucencyTable(curline->polyseg->translucency);
|
||||
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
|
||||
}
|
||||
|
||||
|
@ -580,23 +580,23 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
if (pfloor->alpha < 12)
|
||||
return; // Don't even draw it
|
||||
else if (pfloor->alpha < 38)
|
||||
dc_transmap = transtables + ((tr_trans90-1)<<FF_TRANSSHIFT);
|
||||
dc_transmap = R_GetTranslucencyTable(tr_trans90);
|
||||
else if (pfloor->alpha < 64)
|
||||
dc_transmap = transtables + ((tr_trans80-1)<<FF_TRANSSHIFT);
|
||||
dc_transmap = R_GetTranslucencyTable(tr_trans80);
|
||||
else if (pfloor->alpha < 89)
|
||||
dc_transmap = transtables + ((tr_trans70-1)<<FF_TRANSSHIFT);
|
||||
dc_transmap = R_GetTranslucencyTable(tr_trans70);
|
||||
else if (pfloor->alpha < 115)
|
||||
dc_transmap = transtables + ((tr_trans60-1)<<FF_TRANSSHIFT);
|
||||
dc_transmap = R_GetTranslucencyTable(tr_trans60);
|
||||
else if (pfloor->alpha < 140)
|
||||
dc_transmap = transtables + ((tr_trans50-1)<<FF_TRANSSHIFT);
|
||||
dc_transmap = R_GetTranslucencyTable(tr_trans50);
|
||||
else if (pfloor->alpha < 166)
|
||||
dc_transmap = transtables + ((tr_trans40-1)<<FF_TRANSSHIFT);
|
||||
dc_transmap = R_GetTranslucencyTable(tr_trans40);
|
||||
else if (pfloor->alpha < 192)
|
||||
dc_transmap = transtables + ((tr_trans30-1)<<FF_TRANSSHIFT);
|
||||
dc_transmap = R_GetTranslucencyTable(tr_trans30);
|
||||
else if (pfloor->alpha < 217)
|
||||
dc_transmap = transtables + ((tr_trans20-1)<<FF_TRANSSHIFT);
|
||||
dc_transmap = R_GetTranslucencyTable(tr_trans20);
|
||||
else if (pfloor->alpha < 243)
|
||||
dc_transmap = transtables + ((tr_trans10-1)<<FF_TRANSSHIFT);
|
||||
dc_transmap = R_GetTranslucencyTable(tr_trans10);
|
||||
else
|
||||
fuzzy = false; // Opaque
|
||||
|
||||
|
|
|
@ -1375,7 +1375,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
|
|||
else
|
||||
shadow->extra_colormap = thing->subsector->sector->extra_colormap;
|
||||
|
||||
shadow->transmap = transtables + (trans<<FF_TRANSSHIFT);
|
||||
shadow->transmap = R_GetTranslucencyTable(trans + 1);
|
||||
shadow->colormap = scalelight[0][0]; // full dark!
|
||||
|
||||
objectsdrawn++;
|
||||
|
@ -2007,8 +2007,8 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
vis->scale += FixedMul(scalestep, spriteyscale) * (vis->x1 - x1);
|
||||
}
|
||||
|
||||
if (cv_translucency.value && trans)
|
||||
vis->transmap = transtables + ((trans-1)<<FF_TRANSSHIFT);
|
||||
if ((thing->blendmode != AST_COPY) && cv_translucency.value)
|
||||
vis->transmap = R_GetBlendTable(thing->blendmode, trans);
|
||||
else
|
||||
vis->transmap = NULL;
|
||||
|
||||
|
|
|
@ -551,7 +551,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
|
|||
|
||||
if (alphalevel)
|
||||
{
|
||||
v_translevel = transtables + ((alphalevel-1)<<FF_TRANSSHIFT);
|
||||
v_translevel = R_GetTranslucencyTable(alphalevel);
|
||||
patchdrawfunc = translucentpdraw;
|
||||
}
|
||||
}
|
||||
|
@ -851,7 +851,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
|
|||
|
||||
if (alphalevel)
|
||||
{
|
||||
v_translevel = transtables + ((alphalevel-1)<<FF_TRANSSHIFT);
|
||||
v_translevel = R_GetTranslucencyTable(alphalevel);
|
||||
patchdrawfunc = translucentpdraw;
|
||||
}
|
||||
}
|
||||
|
@ -1500,7 +1500,7 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
|
|||
// Jimita (12-04-2018)
|
||||
if (alphalevel)
|
||||
{
|
||||
fadetable = ((UINT8 *)transtables + ((alphalevel-1)<<FF_TRANSSHIFT) + (c*256));
|
||||
fadetable = R_GetTranslucencyTable(alphalevel) + (c*256);
|
||||
for (;(--h >= 0) && dest < deststop; dest += vid.width)
|
||||
{
|
||||
u = 0;
|
||||
|
@ -1683,7 +1683,7 @@ void V_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c, UINT16 color, U
|
|||
|
||||
fadetable = ((color & 0xFF00) // Color is not palette index?
|
||||
? ((UINT8 *)colormaps + strength*256) // Do COLORMAP fade.
|
||||
: ((UINT8 *)transtables + ((9-strength)<<FF_TRANSSHIFT) + color*256)); // Else, do TRANSMAP** fade.
|
||||
: ((UINT8 *)R_GetTranslucencyTable((9-strength)+1) + color*256)); // Else, do TRANSMAP** fade.
|
||||
for (;(--h >= 0) && dest < deststop; dest += vid.width)
|
||||
{
|
||||
u = 0;
|
||||
|
@ -1829,7 +1829,7 @@ void V_DrawFadeScreen(UINT16 color, UINT8 strength)
|
|||
? ((UINT8 *)(((color & 0x0F00) == 0x0A00) ? fadecolormap // Do fadecolormap fade.
|
||||
: (((color & 0x0F00) == 0x0B00) ? fadecolormap + (256 * FADECOLORMAPROWS) // Do white fadecolormap fade.
|
||||
: colormaps)) + strength*256) // Do COLORMAP fade.
|
||||
: ((UINT8 *)transtables + ((9-strength)<<FF_TRANSSHIFT) + color*256)); // Else, do TRANSMAP** fade.
|
||||
: ((UINT8 *)R_GetTranslucencyTable((9-strength)+1) + color*256)); // Else, do TRANSMAP** fade.
|
||||
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
|
||||
UINT8 *buf = screens[0];
|
||||
|
||||
|
@ -3565,7 +3565,7 @@ void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param)
|
|||
angle_t disStart = (leveltime * 128) & FINEMASK; // in 0 to FINEANGLE
|
||||
INT32 newpix;
|
||||
INT32 sine;
|
||||
//UINT8 *transme = transtables + ((tr_trans50-1)<<FF_TRANSSHIFT);
|
||||
//UINT8 *transme = R_GetTranslucencyTable(tr_trans50);
|
||||
|
||||
for (y = yoffset; y < yoffset+height; y++)
|
||||
{
|
||||
|
@ -3622,7 +3622,7 @@ Unoptimized version
|
|||
INT32 x, y;
|
||||
|
||||
// TODO: Add a postimg_param so that we can pick the translucency level...
|
||||
UINT8 *transme = transtables + ((param-1)<<FF_TRANSSHIFT);
|
||||
UINT8 *transme = R_GetTranslucencyTable(param);
|
||||
|
||||
for (y = yoffset; y < yoffset+height; y++)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue