mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-29 23:23:07 +00:00
Move wallsprite handling to r_wallsprite
This commit is contained in:
parent
98026c5711
commit
50c525161b
6 changed files with 253 additions and 191 deletions
|
@ -829,6 +829,7 @@ set( FASTMATH_PCH_SOURCES
|
||||||
swrenderer/scene/r_visible_sprite.cpp
|
swrenderer/scene/r_visible_sprite.cpp
|
||||||
swrenderer/scene/r_particle.cpp
|
swrenderer/scene/r_particle.cpp
|
||||||
swrenderer/scene/r_playersprite.cpp
|
swrenderer/scene/r_playersprite.cpp
|
||||||
|
swrenderer/scene/r_wallsprite.cpp
|
||||||
polyrenderer/poly_renderer.cpp
|
polyrenderer/poly_renderer.cpp
|
||||||
polyrenderer/scene/poly_scene.cpp
|
polyrenderer/scene/poly_scene.cpp
|
||||||
polyrenderer/scene/poly_portal.cpp
|
polyrenderer/scene/poly_portal.cpp
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include "r_walldraw.h"
|
#include "r_walldraw.h"
|
||||||
#include "r_draw_segment.h"
|
#include "r_draw_segment.h"
|
||||||
#include "r_portal.h"
|
#include "r_portal.h"
|
||||||
|
#include "r_wallsprite.h"
|
||||||
#include "swrenderer/r_memory.h"
|
#include "swrenderer/r_memory.h"
|
||||||
|
|
||||||
#define WALLYREPEAT 8
|
#define WALLYREPEAT 8
|
||||||
|
@ -138,7 +139,6 @@ FTexture *rw_pic;
|
||||||
static fixed_t *maskedtexturecol;
|
static fixed_t *maskedtexturecol;
|
||||||
|
|
||||||
static void R_RenderDecal (side_t *wall, DBaseDecal *first, drawseg_t *clipper, int pass);
|
static void R_RenderDecal (side_t *wall, DBaseDecal *first, drawseg_t *clipper, int pass);
|
||||||
static void WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans));
|
|
||||||
|
|
||||||
inline bool IsFogBoundary (sector_t *front, sector_t *back)
|
inline bool IsFogBoundary (sector_t *front, sector_t *back)
|
||||||
{
|
{
|
||||||
|
@ -2246,10 +2246,10 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
|
||||||
sprflipvert = false;
|
sprflipvert = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MaskedScaleY = float(1 / yscale);
|
float maskedScaleY = float(1 / yscale);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
dc_x = x1;
|
int x = x1;
|
||||||
|
|
||||||
bool visible = R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor);
|
bool visible = R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor);
|
||||||
|
|
||||||
|
@ -2261,14 +2261,14 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
|
||||||
|
|
||||||
if (visible)
|
if (visible)
|
||||||
{
|
{
|
||||||
while (dc_x < x2)
|
while (x < x2)
|
||||||
{
|
{
|
||||||
if (calclighting)
|
if (calclighting)
|
||||||
{ // calculate lighting
|
{ // calculate lighting
|
||||||
R_SetColorMapLight(usecolormap, rw_light, wallshade);
|
R_SetColorMapLight(usecolormap, rw_light, wallshade);
|
||||||
}
|
}
|
||||||
R_WallSpriteColumn ();
|
R_WallSpriteColumn(x, maskedScaleY);
|
||||||
dc_x++;
|
x++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,7 @@
|
||||||
#include "r_portal.h"
|
#include "r_portal.h"
|
||||||
#include "r_particle.h"
|
#include "r_particle.h"
|
||||||
#include "r_playersprite.h"
|
#include "r_playersprite.h"
|
||||||
|
#include "r_wallsprite.h"
|
||||||
#include "swrenderer/r_memory.h"
|
#include "swrenderer/r_memory.h"
|
||||||
|
|
||||||
EXTERN_CVAR(Int, r_drawfuzz)
|
EXTERN_CVAR(Int, r_drawfuzz)
|
||||||
|
@ -109,7 +110,6 @@ struct FCoverageBuffer
|
||||||
};
|
};
|
||||||
|
|
||||||
extern double globaluclip, globaldclip;
|
extern double globaluclip, globaldclip;
|
||||||
extern float MaskedScaleY;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Sprite rotation 0 is facing the viewer,
|
// Sprite rotation 0 is facing the viewer,
|
||||||
|
@ -151,7 +151,6 @@ static vissprite_t **spritesorter;
|
||||||
static int spritesortersize = 0;
|
static int spritesortersize = 0;
|
||||||
static int vsprcount;
|
static int vsprcount;
|
||||||
|
|
||||||
static void R_ProjectWallSprite(AActor *thing, const DVector3 &pos, FTextureID picnum, const DVector2 &scale, INTBOOL flip);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -530,114 +529,6 @@ void R_DrawVisSprite (vissprite_t *vis)
|
||||||
NetUpdate ();
|
NetUpdate ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void R_DrawWallSprite(vissprite_t *spr)
|
|
||||||
{
|
|
||||||
int x1, x2;
|
|
||||||
double iyscale;
|
|
||||||
|
|
||||||
x1 = MAX<int>(spr->x1, spr->wallc.sx1);
|
|
||||||
x2 = MIN<int>(spr->x2, spr->wallc.sx2);
|
|
||||||
if (x1 >= x2)
|
|
||||||
return;
|
|
||||||
WallT.InitFromWallCoords(&spr->wallc);
|
|
||||||
PrepWall(swall, lwall, spr->pic->GetWidth() << FRACBITS, x1, x2);
|
|
||||||
iyscale = 1 / spr->yscale;
|
|
||||||
dc_texturemid = (spr->gzt - ViewPos.Z) * iyscale;
|
|
||||||
if (spr->renderflags & RF_XFLIP)
|
|
||||||
{
|
|
||||||
int right = (spr->pic->GetWidth() << FRACBITS) - 1;
|
|
||||||
|
|
||||||
for (int i = x1; i < x2; i++)
|
|
||||||
{
|
|
||||||
lwall[i] = right - lwall[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Prepare lighting
|
|
||||||
bool calclighting = false;
|
|
||||||
FDynamicColormap *usecolormap = basecolormap;
|
|
||||||
bool rereadcolormap = true;
|
|
||||||
|
|
||||||
// Decals that are added to the scene must fade to black.
|
|
||||||
if (spr->Style.RenderStyle == LegacyRenderStyles[STYLE_Add] && usecolormap->Fade != 0)
|
|
||||||
{
|
|
||||||
usecolormap = GetSpecialLights(usecolormap->Color, 0, usecolormap->Desaturate);
|
|
||||||
rereadcolormap = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int shade = LIGHT2SHADE(spr->sector->lightlevel + r_actualextralight);
|
|
||||||
GlobVis = r_WallVisibility;
|
|
||||||
rw_lightleft = float (GlobVis / spr->wallc.sz1);
|
|
||||||
rw_lightstep = float((GlobVis / spr->wallc.sz2 - rw_lightleft) / (spr->wallc.sx2 - spr->wallc.sx1));
|
|
||||||
rw_light = rw_lightleft + (x1 - spr->wallc.sx1) * rw_lightstep;
|
|
||||||
if (fixedlightlev >= 0)
|
|
||||||
R_SetColorMapLight(usecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
|
||||||
else if (fixedcolormap != NULL)
|
|
||||||
R_SetColorMapLight(fixedcolormap, 0, 0);
|
|
||||||
else if (!foggy && (spr->renderflags & RF_FULLBRIGHT))
|
|
||||||
R_SetColorMapLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : usecolormap, 0, 0);
|
|
||||||
else
|
|
||||||
calclighting = true;
|
|
||||||
|
|
||||||
// Draw it
|
|
||||||
WallSpriteTile = spr->pic;
|
|
||||||
if (spr->renderflags & RF_YFLIP)
|
|
||||||
{
|
|
||||||
sprflipvert = true;
|
|
||||||
iyscale = -iyscale;
|
|
||||||
dc_texturemid -= spr->pic->GetHeight();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprflipvert = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
MaskedScaleY = (float)iyscale;
|
|
||||||
|
|
||||||
dc_x = x1;
|
|
||||||
|
|
||||||
bool visible = R_SetPatchStyle (spr->Style.RenderStyle, spr->Style.Alpha, spr->Translation, spr->FillColor);
|
|
||||||
|
|
||||||
// R_SetPatchStyle can modify basecolormap.
|
|
||||||
if (rereadcolormap)
|
|
||||||
{
|
|
||||||
usecolormap = basecolormap;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!visible)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (dc_x < x2)
|
|
||||||
{
|
|
||||||
if (calclighting)
|
|
||||||
{ // calculate lighting
|
|
||||||
R_SetColorMapLight(usecolormap, rw_light, shade);
|
|
||||||
}
|
|
||||||
if (!R_ClipSpriteColumnWithPortals(spr))
|
|
||||||
R_WallSpriteColumn();
|
|
||||||
dc_x++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
R_FinishSetPatchStyle();
|
|
||||||
}
|
|
||||||
|
|
||||||
void R_WallSpriteColumn ()
|
|
||||||
{
|
|
||||||
float iscale = swall[dc_x] * MaskedScaleY;
|
|
||||||
dc_iscale = FLOAT2FIXED(iscale);
|
|
||||||
spryscale = 1 / iscale;
|
|
||||||
if (sprflipvert)
|
|
||||||
sprtopscreen = CenterY + dc_texturemid * spryscale;
|
|
||||||
else
|
|
||||||
sprtopscreen = CenterY - dc_texturemid * spryscale;
|
|
||||||
|
|
||||||
dc_texturefrac = 0;
|
|
||||||
R_DrawMaskedColumn(WallSpriteTile, lwall[dc_x]);
|
|
||||||
rw_light += rw_lightstep;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop, short *clipbot)
|
void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop, short *clipbot)
|
||||||
{
|
{
|
||||||
|
@ -1142,80 +1033,6 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void R_ProjectWallSprite(AActor *thing, const DVector3 &pos, FTextureID picnum, const DVector2 &scale, int renderflags)
|
|
||||||
{
|
|
||||||
FWallCoords wallc;
|
|
||||||
double x1, x2;
|
|
||||||
DVector2 left, right;
|
|
||||||
double gzb, gzt, tz;
|
|
||||||
FTexture *pic = TexMan(picnum, true);
|
|
||||||
DAngle ang = thing->Angles.Yaw + 90;
|
|
||||||
double angcos = ang.Cos();
|
|
||||||
double angsin = ang.Sin();
|
|
||||||
vissprite_t *vis;
|
|
||||||
|
|
||||||
// Determine left and right edges of sprite. The sprite's angle is its normal,
|
|
||||||
// so the edges are 90 degrees each side of it.
|
|
||||||
x2 = pic->GetScaledWidth();
|
|
||||||
x1 = pic->GetScaledLeftOffset();
|
|
||||||
|
|
||||||
x1 *= scale.X;
|
|
||||||
x2 *= scale.X;
|
|
||||||
|
|
||||||
left.X = pos.X - x1 * angcos - ViewPos.X;
|
|
||||||
left.Y = pos.Y - x1 * angsin - ViewPos.Y;
|
|
||||||
right.X = left.X + x2 * angcos;
|
|
||||||
right.Y = right.Y + x2 * angsin;
|
|
||||||
|
|
||||||
// Is it off-screen?
|
|
||||||
if (wallc.Init(left, right, TOO_CLOSE_Z))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (wallc.sx1 >= WindowRight || wallc.sx2 <= WindowLeft)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Sprite sorting should probably treat these as walls, not sprites,
|
|
||||||
// but right now, I just want to get them drawing.
|
|
||||||
tz = (pos.X - ViewPos.X) * ViewTanCos + (pos.Y - ViewPos.Y) * ViewTanSin;
|
|
||||||
|
|
||||||
int scaled_to = pic->GetScaledTopOffset();
|
|
||||||
int scaled_bo = scaled_to - pic->GetScaledHeight();
|
|
||||||
gzt = pos.Z + scale.Y * scaled_to;
|
|
||||||
gzb = pos.Z + scale.Y * scaled_bo;
|
|
||||||
|
|
||||||
vis = R_NewVisSprite();
|
|
||||||
vis->CurrentPortalUniq = CurrentPortalUniq;
|
|
||||||
vis->x1 = wallc.sx1 < WindowLeft ? WindowLeft : wallc.sx1;
|
|
||||||
vis->x2 = wallc.sx2 >= WindowRight ? WindowRight : wallc.sx2;
|
|
||||||
vis->yscale = (float)scale.Y;
|
|
||||||
vis->idepth = float(1 / tz);
|
|
||||||
vis->depth = (float)tz;
|
|
||||||
vis->sector = thing->Sector;
|
|
||||||
vis->heightsec = NULL;
|
|
||||||
vis->gpos = { (float)pos.X, (float)pos.Y, (float)pos.Z };
|
|
||||||
vis->gzb = (float)gzb;
|
|
||||||
vis->gzt = (float)gzt;
|
|
||||||
vis->deltax = float(pos.X - ViewPos.X);
|
|
||||||
vis->deltay = float(pos.Y - ViewPos.Y);
|
|
||||||
vis->renderflags = renderflags;
|
|
||||||
if(thing->flags5 & MF5_BRIGHT) vis->renderflags |= RF_FULLBRIGHT; // kg3D
|
|
||||||
vis->Style.RenderStyle = thing->RenderStyle;
|
|
||||||
vis->FillColor = thing->fillcolor;
|
|
||||||
vis->Translation = thing->Translation;
|
|
||||||
vis->FakeFlatStat = 0;
|
|
||||||
vis->Style.Alpha = float(thing->Alpha);
|
|
||||||
vis->fakefloor = NULL;
|
|
||||||
vis->fakeceiling = NULL;
|
|
||||||
vis->bInMirror = MirrorFlags & RF_XFLIP;
|
|
||||||
vis->pic = pic;
|
|
||||||
vis->bIsVoxel = false;
|
|
||||||
vis->bWallSprite = true;
|
|
||||||
vis->Style.ColormapNum = GETPALOOKUP(
|
|
||||||
r_SpriteVisibility / MAX(tz, MINZ), spriteshade);
|
|
||||||
vis->Style.BaseColormap = basecolormap;
|
|
||||||
vis->wallc = wallc;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_AddSprites
|
// R_AddSprites
|
||||||
// During BSP traversal, this adds sprites by sector.
|
// During BSP traversal, this adds sprites by sector.
|
||||||
|
|
|
@ -60,7 +60,6 @@ extern int spriteshade;
|
||||||
bool R_ClipSpriteColumnWithPortals(vissprite_t* spr);
|
bool R_ClipSpriteColumnWithPortals(vissprite_t* spr);
|
||||||
|
|
||||||
void R_DrawMaskedColumn (FTexture *texture, fixed_t column, bool unmasked = false);
|
void R_DrawMaskedColumn (FTexture *texture, fixed_t column, bool unmasked = false);
|
||||||
void R_WallSpriteColumn ();
|
|
||||||
|
|
||||||
void R_CacheSprite (spritedef_t *sprite);
|
void R_CacheSprite (spritedef_t *sprite);
|
||||||
void R_SortVisSprites (int (*compare)(const void *, const void *), size_t first);
|
void R_SortVisSprites (int (*compare)(const void *, const void *), size_t first);
|
||||||
|
|
234
src/swrenderer/scene/r_wallsprite.cpp
Normal file
234
src/swrenderer/scene/r_wallsprite.cpp
Normal file
|
@ -0,0 +1,234 @@
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include "p_lnspec.h"
|
||||||
|
#include "templates.h"
|
||||||
|
#include "doomdef.h"
|
||||||
|
#include "m_swap.h"
|
||||||
|
#include "i_system.h"
|
||||||
|
#include "w_wad.h"
|
||||||
|
#include "swrenderer/r_main.h"
|
||||||
|
#include "swrenderer/scene/r_things.h"
|
||||||
|
#include "swrenderer/scene/r_wallsprite.h"
|
||||||
|
#include "c_console.h"
|
||||||
|
#include "c_cvars.h"
|
||||||
|
#include "c_dispatch.h"
|
||||||
|
#include "doomstat.h"
|
||||||
|
#include "v_video.h"
|
||||||
|
#include "sc_man.h"
|
||||||
|
#include "s_sound.h"
|
||||||
|
#include "sbar.h"
|
||||||
|
#include "gi.h"
|
||||||
|
#include "r_sky.h"
|
||||||
|
#include "cmdlib.h"
|
||||||
|
#include "g_level.h"
|
||||||
|
#include "d_net.h"
|
||||||
|
#include "colormatcher.h"
|
||||||
|
#include "d_netinf.h"
|
||||||
|
#include "p_effect.h"
|
||||||
|
#include "r_bsp.h"
|
||||||
|
#include "r_plane.h"
|
||||||
|
#include "r_segs.h"
|
||||||
|
#include "r_3dfloors.h"
|
||||||
|
#include "swrenderer/drawers/r_draw_rgba.h"
|
||||||
|
#include "swrenderer/drawers/r_draw_pal.h"
|
||||||
|
#include "v_palette.h"
|
||||||
|
#include "r_data/r_translate.h"
|
||||||
|
#include "r_data/colormaps.h"
|
||||||
|
#include "r_data/voxels.h"
|
||||||
|
#include "p_local.h"
|
||||||
|
#include "p_maputl.h"
|
||||||
|
#include "r_voxel.h"
|
||||||
|
#include "r_draw_segment.h"
|
||||||
|
#include "r_portal.h"
|
||||||
|
#include "swrenderer/r_memory.h"
|
||||||
|
|
||||||
|
namespace swrenderer
|
||||||
|
{
|
||||||
|
void R_ProjectWallSprite(AActor *thing, const DVector3 &pos, FTextureID picnum, const DVector2 &scale, int renderflags)
|
||||||
|
{
|
||||||
|
FWallCoords wallc;
|
||||||
|
double x1, x2;
|
||||||
|
DVector2 left, right;
|
||||||
|
double gzb, gzt, tz;
|
||||||
|
FTexture *pic = TexMan(picnum, true);
|
||||||
|
DAngle ang = thing->Angles.Yaw + 90;
|
||||||
|
double angcos = ang.Cos();
|
||||||
|
double angsin = ang.Sin();
|
||||||
|
vissprite_t *vis;
|
||||||
|
|
||||||
|
// Determine left and right edges of sprite. The sprite's angle is its normal,
|
||||||
|
// so the edges are 90 degrees each side of it.
|
||||||
|
x2 = pic->GetScaledWidth();
|
||||||
|
x1 = pic->GetScaledLeftOffset();
|
||||||
|
|
||||||
|
x1 *= scale.X;
|
||||||
|
x2 *= scale.X;
|
||||||
|
|
||||||
|
left.X = pos.X - x1 * angcos - ViewPos.X;
|
||||||
|
left.Y = pos.Y - x1 * angsin - ViewPos.Y;
|
||||||
|
right.X = left.X + x2 * angcos;
|
||||||
|
right.Y = right.Y + x2 * angsin;
|
||||||
|
|
||||||
|
// Is it off-screen?
|
||||||
|
if (wallc.Init(left, right, TOO_CLOSE_Z))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (wallc.sx1 >= WindowRight || wallc.sx2 <= WindowLeft)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Sprite sorting should probably treat these as walls, not sprites,
|
||||||
|
// but right now, I just want to get them drawing.
|
||||||
|
tz = (pos.X - ViewPos.X) * ViewTanCos + (pos.Y - ViewPos.Y) * ViewTanSin;
|
||||||
|
|
||||||
|
int scaled_to = pic->GetScaledTopOffset();
|
||||||
|
int scaled_bo = scaled_to - pic->GetScaledHeight();
|
||||||
|
gzt = pos.Z + scale.Y * scaled_to;
|
||||||
|
gzb = pos.Z + scale.Y * scaled_bo;
|
||||||
|
|
||||||
|
vis = R_NewVisSprite();
|
||||||
|
vis->CurrentPortalUniq = CurrentPortalUniq;
|
||||||
|
vis->x1 = wallc.sx1 < WindowLeft ? WindowLeft : wallc.sx1;
|
||||||
|
vis->x2 = wallc.sx2 >= WindowRight ? WindowRight : wallc.sx2;
|
||||||
|
vis->yscale = (float)scale.Y;
|
||||||
|
vis->idepth = float(1 / tz);
|
||||||
|
vis->depth = (float)tz;
|
||||||
|
vis->sector = thing->Sector;
|
||||||
|
vis->heightsec = NULL;
|
||||||
|
vis->gpos = { (float)pos.X, (float)pos.Y, (float)pos.Z };
|
||||||
|
vis->gzb = (float)gzb;
|
||||||
|
vis->gzt = (float)gzt;
|
||||||
|
vis->deltax = float(pos.X - ViewPos.X);
|
||||||
|
vis->deltay = float(pos.Y - ViewPos.Y);
|
||||||
|
vis->renderflags = renderflags;
|
||||||
|
if (thing->flags5 & MF5_BRIGHT) vis->renderflags |= RF_FULLBRIGHT; // kg3D
|
||||||
|
vis->Style.RenderStyle = thing->RenderStyle;
|
||||||
|
vis->FillColor = thing->fillcolor;
|
||||||
|
vis->Translation = thing->Translation;
|
||||||
|
vis->FakeFlatStat = 0;
|
||||||
|
vis->Style.Alpha = float(thing->Alpha);
|
||||||
|
vis->fakefloor = NULL;
|
||||||
|
vis->fakeceiling = NULL;
|
||||||
|
vis->bInMirror = MirrorFlags & RF_XFLIP;
|
||||||
|
vis->pic = pic;
|
||||||
|
vis->bIsVoxel = false;
|
||||||
|
vis->bWallSprite = true;
|
||||||
|
vis->Style.ColormapNum = GETPALOOKUP(
|
||||||
|
r_SpriteVisibility / MAX(tz, MINZ), spriteshade);
|
||||||
|
vis->Style.BaseColormap = basecolormap;
|
||||||
|
vis->wallc = wallc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_DrawWallSprite(vissprite_t *spr)
|
||||||
|
{
|
||||||
|
int x1, x2;
|
||||||
|
double iyscale;
|
||||||
|
|
||||||
|
x1 = MAX<int>(spr->x1, spr->wallc.sx1);
|
||||||
|
x2 = MIN<int>(spr->x2, spr->wallc.sx2);
|
||||||
|
if (x1 >= x2)
|
||||||
|
return;
|
||||||
|
WallT.InitFromWallCoords(&spr->wallc);
|
||||||
|
PrepWall(swall, lwall, spr->pic->GetWidth() << FRACBITS, x1, x2);
|
||||||
|
iyscale = 1 / spr->yscale;
|
||||||
|
dc_texturemid = (spr->gzt - ViewPos.Z) * iyscale;
|
||||||
|
if (spr->renderflags & RF_XFLIP)
|
||||||
|
{
|
||||||
|
int right = (spr->pic->GetWidth() << FRACBITS) - 1;
|
||||||
|
|
||||||
|
for (int i = x1; i < x2; i++)
|
||||||
|
{
|
||||||
|
lwall[i] = right - lwall[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Prepare lighting
|
||||||
|
bool calclighting = false;
|
||||||
|
FDynamicColormap *usecolormap = basecolormap;
|
||||||
|
bool rereadcolormap = true;
|
||||||
|
|
||||||
|
// Decals that are added to the scene must fade to black.
|
||||||
|
if (spr->Style.RenderStyle == LegacyRenderStyles[STYLE_Add] && usecolormap->Fade != 0)
|
||||||
|
{
|
||||||
|
usecolormap = GetSpecialLights(usecolormap->Color, 0, usecolormap->Desaturate);
|
||||||
|
rereadcolormap = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int shade = LIGHT2SHADE(spr->sector->lightlevel + r_actualextralight);
|
||||||
|
GlobVis = r_WallVisibility;
|
||||||
|
rw_lightleft = float(GlobVis / spr->wallc.sz1);
|
||||||
|
rw_lightstep = float((GlobVis / spr->wallc.sz2 - rw_lightleft) / (spr->wallc.sx2 - spr->wallc.sx1));
|
||||||
|
rw_light = rw_lightleft + (x1 - spr->wallc.sx1) * rw_lightstep;
|
||||||
|
if (fixedlightlev >= 0)
|
||||||
|
R_SetColorMapLight(usecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
||||||
|
else if (fixedcolormap != NULL)
|
||||||
|
R_SetColorMapLight(fixedcolormap, 0, 0);
|
||||||
|
else if (!foggy && (spr->renderflags & RF_FULLBRIGHT))
|
||||||
|
R_SetColorMapLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : usecolormap, 0, 0);
|
||||||
|
else
|
||||||
|
calclighting = true;
|
||||||
|
|
||||||
|
// Draw it
|
||||||
|
WallSpriteTile = spr->pic;
|
||||||
|
if (spr->renderflags & RF_YFLIP)
|
||||||
|
{
|
||||||
|
sprflipvert = true;
|
||||||
|
iyscale = -iyscale;
|
||||||
|
dc_texturemid -= spr->pic->GetHeight();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprflipvert = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float maskedScaleY = (float)iyscale;
|
||||||
|
|
||||||
|
int x = x1;
|
||||||
|
|
||||||
|
bool visible = R_SetPatchStyle(spr->Style.RenderStyle, spr->Style.Alpha, spr->Translation, spr->FillColor);
|
||||||
|
|
||||||
|
// R_SetPatchStyle can modify basecolormap.
|
||||||
|
if (rereadcolormap)
|
||||||
|
{
|
||||||
|
usecolormap = basecolormap;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!visible)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (x < x2)
|
||||||
|
{
|
||||||
|
if (calclighting)
|
||||||
|
{ // calculate lighting
|
||||||
|
R_SetColorMapLight(usecolormap, rw_light, shade);
|
||||||
|
}
|
||||||
|
if (!R_ClipSpriteColumnWithPortals(spr))
|
||||||
|
R_WallSpriteColumn(x, maskedScaleY);
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
R_FinishSetPatchStyle();
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_WallSpriteColumn(int x, float maskedScaleY)
|
||||||
|
{
|
||||||
|
using namespace drawerargs;
|
||||||
|
|
||||||
|
dc_x = x;
|
||||||
|
|
||||||
|
float iscale = swall[dc_x] * maskedScaleY;
|
||||||
|
dc_iscale = FLOAT2FIXED(iscale);
|
||||||
|
spryscale = 1 / iscale;
|
||||||
|
if (sprflipvert)
|
||||||
|
sprtopscreen = CenterY + dc_texturemid * spryscale;
|
||||||
|
else
|
||||||
|
sprtopscreen = CenterY - dc_texturemid * spryscale;
|
||||||
|
|
||||||
|
dc_texturefrac = 0;
|
||||||
|
R_DrawMaskedColumn(WallSpriteTile, lwall[dc_x]);
|
||||||
|
rw_light += rw_lightstep;
|
||||||
|
}
|
||||||
|
}
|
11
src/swrenderer/scene/r_wallsprite.h
Normal file
11
src/swrenderer/scene/r_wallsprite.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "r_visible_sprite.h"
|
||||||
|
|
||||||
|
namespace swrenderer
|
||||||
|
{
|
||||||
|
void R_ProjectWallSprite(AActor *thing, const DVector3 &pos, FTextureID picnum, const DVector2 &scale, int renderflags);
|
||||||
|
void R_DrawWallSprite(vissprite_t *spr);
|
||||||
|
void R_WallSpriteColumn(int x, float maskedScaleY);
|
||||||
|
}
|
Loading…
Reference in a new issue