Compare commits
9
Commits
v10
...
shaderspriteclip
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80024497b1 | ||
|
|
684de4c8d0 | ||
|
|
c989aa3fcf | ||
|
|
bab83386d4 | ||
|
|
8b21048387 | ||
|
|
b22b4d7f84 | ||
|
|
014d61b373 | ||
|
|
ac2ba6e4bf | ||
|
|
94e0e7fb70 |
No files matched your search
@@ -173,6 +173,7 @@ enum
|
||||
SHADER_FLOOR = 0,
|
||||
SHADER_WALL,
|
||||
SHADER_SPRITE,
|
||||
SHADER_SPRITECLIPHACK,
|
||||
SHADER_MODEL,
|
||||
SHADER_WATER,
|
||||
SHADER_FOG,
|
||||
|
||||
+91
-77
@@ -3379,74 +3379,109 @@ static void HWR_DrawSpriteShadow(gl_vissprite_t *spr, GLPatch_t *gpatch)
|
||||
}
|
||||
|
||||
// This is expecting a pointer to an array containing 4 wallVerts for a sprite
|
||||
static void HWR_RotateSpritePolyToAim(gl_vissprite_t *spr, FOutVector *wallVerts, const boolean precip)
|
||||
static void HWR_RotateSpritePolyToAim(gl_vissprite_t *spr, FOutVector *wallVerts, const boolean precip, const boolean papersprite)
|
||||
{
|
||||
if (cv_glspritebillboarding.value && spr && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE) && wallVerts)
|
||||
if (!cv_glspritebillboarding.value || !spr || !spr->mobj || papersprite || !wallVerts)
|
||||
{
|
||||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
float basey, lowy;
|
||||
INT32 dist = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cv_maxinterpdist.value)
|
||||
dist = R_QuickCamDist(spr->mobj->x, spr->mobj->y);
|
||||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
float basey, lowy;
|
||||
INT32 dist = -1;
|
||||
|
||||
// do interpolation
|
||||
if (R_UsingFrameInterpolation() && !paused && (!cv_maxinterpdist.value || dist < cv_maxinterpdist.value))
|
||||
if (cv_maxinterpdist.value)
|
||||
dist = R_QuickCamDist(spr->mobj->x, spr->mobj->y);
|
||||
|
||||
// do interpolation
|
||||
if (R_UsingFrameInterpolation() && !paused && (!cv_maxinterpdist.value || dist < cv_maxinterpdist.value))
|
||||
{
|
||||
if (precip)
|
||||
{
|
||||
if (precip)
|
||||
{
|
||||
R_InterpolatePrecipMobjState((precipmobj_t *)spr->mobj, rendertimefrac, &interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolateMobjState(spr->mobj, rendertimefrac, &interp);
|
||||
}
|
||||
R_InterpolatePrecipMobjState((precipmobj_t *)spr->mobj, rendertimefrac, &interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (precip)
|
||||
{
|
||||
R_InterpolatePrecipMobjState((precipmobj_t *)spr->mobj, FRACUNIT, &interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolateMobjState(spr->mobj, FRACUNIT, &interp);
|
||||
}
|
||||
R_InterpolateMobjState(spr->mobj, rendertimefrac, &interp);
|
||||
}
|
||||
|
||||
if (!precip && P_MobjFlip(spr->mobj) == -1) // precip doesn't have eflags so they can't flip
|
||||
}
|
||||
else
|
||||
{
|
||||
if (precip)
|
||||
{
|
||||
basey = FIXED_TO_FLOAT(interp.z + spr->mobj->height);
|
||||
R_InterpolatePrecipMobjState((precipmobj_t *)spr->mobj, FRACUNIT, &interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
basey = FIXED_TO_FLOAT(interp.z);
|
||||
R_InterpolateMobjState(spr->mobj, FRACUNIT, &interp);
|
||||
}
|
||||
lowy = wallVerts[0].y;
|
||||
}
|
||||
|
||||
// Rotate sprites to fully billboard with the camera
|
||||
// X, Y, AND Z need to be manipulated for the polys to rotate around the
|
||||
// origin, because of how the origin setting works I believe that should
|
||||
// be mobj->z or mobj->z + mobj->height
|
||||
wallVerts[2].y = wallVerts[3].y = (spr->gzt - basey) * gl_viewludsin + basey;
|
||||
wallVerts[0].y = wallVerts[1].y = (lowy - basey) * gl_viewludsin + basey;
|
||||
// translate back to be around 0 before translating back
|
||||
wallVerts[3].x += ((spr->gzt - basey) * gl_viewludcos) * gl_viewcos;
|
||||
wallVerts[2].x += ((spr->gzt - basey) * gl_viewludcos) * gl_viewcos;
|
||||
if (!precip && P_MobjFlip(spr->mobj) == -1) // precip doesn't have eflags so they can't flip
|
||||
{
|
||||
basey = FIXED_TO_FLOAT(interp.z + spr->mobj->height);
|
||||
}
|
||||
else
|
||||
{
|
||||
basey = FIXED_TO_FLOAT(interp.z);
|
||||
}
|
||||
lowy = wallVerts[0].y;
|
||||
|
||||
wallVerts[0].x += ((lowy - basey) * gl_viewludcos) * gl_viewcos;
|
||||
wallVerts[1].x += ((lowy - basey) * gl_viewludcos) * gl_viewcos;
|
||||
// Rotate sprites to fully billboard with the camera
|
||||
// X, Y, AND Z need to be manipulated for the polys to rotate around the
|
||||
// origin, because of how the origin setting works I believe that should
|
||||
// be mobj->z or mobj->z + mobj->height
|
||||
wallVerts[2].y = wallVerts[3].y = (spr->gzt - basey) * gl_viewludsin + basey;
|
||||
wallVerts[0].y = wallVerts[1].y = (lowy - basey) * gl_viewludsin + basey;
|
||||
// translate back to be around 0 before translating back
|
||||
wallVerts[3].x += ((spr->gzt - basey) * gl_viewludcos) * gl_viewcos;
|
||||
wallVerts[2].x += ((spr->gzt - basey) * gl_viewludcos) * gl_viewcos;
|
||||
|
||||
wallVerts[3].z += ((spr->gzt - basey) * gl_viewludcos) * gl_viewsin;
|
||||
wallVerts[2].z += ((spr->gzt - basey) * gl_viewludcos) * gl_viewsin;
|
||||
wallVerts[0].x += ((lowy - basey) * gl_viewludcos) * gl_viewcos;
|
||||
wallVerts[1].x += ((lowy - basey) * gl_viewludcos) * gl_viewcos;
|
||||
|
||||
wallVerts[0].z += ((lowy - basey) * gl_viewludcos) * gl_viewsin;
|
||||
wallVerts[1].z += ((lowy - basey) * gl_viewludcos) * gl_viewsin;
|
||||
wallVerts[3].z += ((spr->gzt - basey) * gl_viewludcos) * gl_viewsin;
|
||||
wallVerts[2].z += ((spr->gzt - basey) * gl_viewludcos) * gl_viewsin;
|
||||
|
||||
wallVerts[0].z += ((lowy - basey) * gl_viewludcos) * gl_viewsin;
|
||||
wallVerts[1].z += ((lowy - basey) * gl_viewludcos) * gl_viewsin;
|
||||
}
|
||||
|
||||
static inline void HWR_ApplyDispoffset(gl_vissprite_t *spr, FOutVector *wallVerts, const boolean papersprite)
|
||||
{
|
||||
// dont push papersprites near the cam unless they have a dispoffset
|
||||
if (papersprite || HWR_UseShader())
|
||||
{
|
||||
// if it has a dispoffset, push it a little towards the camera
|
||||
if (spr->dispoffset)
|
||||
{
|
||||
float co = -gl_viewcos*(0.05f*spr->dispoffset);
|
||||
float si = -gl_viewsin*(0.05f*spr->dispoffset);
|
||||
wallVerts[0].z = wallVerts[3].z = wallVerts[0].z+si;
|
||||
wallVerts[1].z = wallVerts[2].z = wallVerts[1].z+si;
|
||||
wallVerts[0].x = wallVerts[3].x = wallVerts[0].x+co;
|
||||
wallVerts[1].x = wallVerts[2].x = wallVerts[1].x+co;
|
||||
}
|
||||
|
||||
HWR_RotateSpritePolyToAim(spr, wallVerts, false, papersprite);
|
||||
return;
|
||||
}
|
||||
|
||||
HWR_RotateSpritePolyToAim(spr, wallVerts, false, papersprite);
|
||||
|
||||
float sprdist = sqrtf((spr->x1 - gl_viewx)*(spr->x1 - gl_viewx) + (spr->z1 - gl_viewy)*(spr->z1 - gl_viewy) + (spr->gzt - gl_viewz)*(spr->gzt - gl_viewz));
|
||||
float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist;
|
||||
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
{
|
||||
wallVerts[i].x += (gl_viewx - wallVerts[i].x)*distfact;
|
||||
wallVerts[i].z += (gl_viewy - wallVerts[i].z)*distfact;
|
||||
wallVerts[i].y += (gl_viewz - wallVerts[i].y)*distfact;
|
||||
}
|
||||
}
|
||||
|
||||
static void HWR_SplitSprite(gl_vissprite_t *spr)
|
||||
static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
|
||||
{
|
||||
FOutVector wallVerts[4];
|
||||
FOutVector baseWallVerts[4]; // This is what the verts should end up as
|
||||
@@ -3526,18 +3561,8 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
||||
baseWallVerts[0].t = baseWallVerts[1].t = gpatch->max_t;
|
||||
}
|
||||
|
||||
// Let dispoffset work first since this adjust each vertex
|
||||
HWR_RotateSpritePolyToAim(spr, baseWallVerts, false);
|
||||
|
||||
// push it toward the camera to mitigate floor-clipping sprites
|
||||
float sprdist = sqrtf((spr->x1 - gl_viewx)*(spr->x1 - gl_viewx) + (spr->z1 - gl_viewy)*(spr->z1 - gl_viewy) + (spr->gzt - gl_viewz)*(spr->gzt - gl_viewz));
|
||||
float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
baseWallVerts[i].x += (gl_viewx - baseWallVerts[i].x)*distfact;
|
||||
baseWallVerts[i].z += (gl_viewy - baseWallVerts[i].z)*distfact;
|
||||
baseWallVerts[i].y += (gl_viewz - baseWallVerts[i].y)*distfact;
|
||||
}
|
||||
HWR_ApplyDispoffset(spr, baseWallVerts, papersprite);
|
||||
|
||||
realtop = top = baseWallVerts[3].y;
|
||||
realbot = bot = baseWallVerts[0].y;
|
||||
@@ -3577,7 +3602,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
||||
|
||||
if (HWR_UseShader())
|
||||
{
|
||||
shader = SHADER_SPRITE;
|
||||
shader = (papersprite ? SHADER_SPRITE : SHADER_SPRITECLIPHACK);
|
||||
blend |= PF_ColorMapped;
|
||||
}
|
||||
|
||||
@@ -3655,7 +3680,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
||||
wallVerts[1].y = endbot;
|
||||
|
||||
// The x and y only need to be adjusted in the case that it's not a papersprite
|
||||
if (cv_glspritebillboarding.value && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE))
|
||||
if (cv_glspritebillboarding.value && spr->mobj && !papersprite)
|
||||
{
|
||||
// Get the x and z of the vertices so billboarding draws correctly
|
||||
realheight = realbot - realtop;
|
||||
@@ -3731,9 +3756,11 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
||||
if (!spr->mobj->subsector)
|
||||
return;
|
||||
|
||||
const boolean papersprite = (spr->mobj->frame & FF_PAPERSPRITE);
|
||||
|
||||
if (spr->mobj->subsector->sector->numlights)
|
||||
{
|
||||
HWR_SplitSprite(spr);
|
||||
HWR_SplitSprite(spr, papersprite);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3799,20 +3826,8 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
||||
HWR_DrawSpriteShadow(spr, gpatch);
|
||||
}
|
||||
|
||||
// Let dispoffset work first since this adjust each vertex
|
||||
// ...nah
|
||||
HWR_RotateSpritePolyToAim(spr, wallVerts, false);
|
||||
|
||||
// push it toward the camera to mitigate floor-clipping sprites
|
||||
float sprdist = sqrtf((spr->x1 - gl_viewx)*(spr->x1 - gl_viewx) + (spr->z1 - gl_viewy)*(spr->z1 - gl_viewy) + (spr->gzt - gl_viewz)*(spr->gzt - gl_viewz));
|
||||
float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist;
|
||||
size_t i;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
wallVerts[i].x += (gl_viewx - wallVerts[i].x)*distfact;
|
||||
wallVerts[i].z += (gl_viewy - wallVerts[i].z)*distfact;
|
||||
wallVerts[i].y += (gl_viewz - wallVerts[i].y)*distfact;
|
||||
}
|
||||
HWR_ApplyDispoffset(spr, wallVerts, papersprite);
|
||||
|
||||
// This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black.
|
||||
// sprite lighting by modulating the RGB components
|
||||
@@ -3852,7 +3867,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
||||
|
||||
if (HWR_UseShader())
|
||||
{
|
||||
shader = SHADER_SPRITE;
|
||||
shader = (papersprite ? SHADER_SPRITE : SHADER_SPRITECLIPHACK);
|
||||
blend |= PF_ColorMapped;
|
||||
}
|
||||
|
||||
@@ -3894,8 +3909,7 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
|
||||
wallVerts[0].z = wallVerts[3].z = spr->z1;
|
||||
wallVerts[1].z = wallVerts[2].z = spr->z2;
|
||||
|
||||
// Let dispoffset work first since this adjust each vertex
|
||||
HWR_RotateSpritePolyToAim(spr, wallVerts, true);
|
||||
HWR_RotateSpritePolyToAim(spr, wallVerts, true, false);
|
||||
|
||||
wallVerts[0].s = wallVerts[3].s = 0;
|
||||
wallVerts[2].s = wallVerts[1].s = gpatch->max_s;
|
||||
|
||||
@@ -35,6 +35,9 @@ static struct {
|
||||
// Sprite shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
|
||||
|
||||
// Sprite clipping hack shader (for pulling things out of the floor)
|
||||
{GLSL_SPRITECLIP_HACK_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
|
||||
|
||||
// Model shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
|
||||
|
||||
|
||||
@@ -31,6 +31,16 @@
|
||||
"gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"}\0"
|
||||
|
||||
// Sprite clipping makes me want to McFucking Die
|
||||
#define GLSL_SPRITECLIP_HACK_VERTEX_SHADER \
|
||||
"void main(void) {\n" \
|
||||
"gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"gl_FrontColor = gl_Color;\n" \
|
||||
"gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \
|
||||
"gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"gl_Position.z -= 160.0 / gl_Position.z;\n" \
|
||||
"}\0"
|
||||
|
||||
// ==================
|
||||
// Fragment shaders
|
||||
// ==================
|
||||
|
||||
Reference in new issue
Block a user