mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-13 16:07:45 +00:00
Decal rendering to r_decal
This commit is contained in:
parent
50c525161b
commit
99e263e1b3
6 changed files with 318 additions and 264 deletions
|
@ -830,6 +830,7 @@ set( FASTMATH_PCH_SOURCES
|
||||||
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
|
swrenderer/scene/r_wallsprite.cpp
|
||||||
|
swrenderer/scene/r_decal.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
|
||||||
|
|
|
@ -60,13 +60,6 @@ CVAR(Float, r_lod_bias, -1.5, 0); // To do: add CVAR_ARCHIVE | CVAR_GLOBALCONFIG
|
||||||
|
|
||||||
namespace swrenderer
|
namespace swrenderer
|
||||||
{
|
{
|
||||||
extern "C" short spanend[MAXHEIGHT];
|
|
||||||
extern float rw_light;
|
|
||||||
extern float rw_lightstep;
|
|
||||||
extern int wallshade;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
DrawSpanLLVMCommand::DrawSpanLLVMCommand()
|
DrawSpanLLVMCommand::DrawSpanLLVMCommand()
|
||||||
{
|
{
|
||||||
using namespace drawerargs;
|
using namespace drawerargs;
|
||||||
|
|
296
src/swrenderer/scene/r_decal.cpp
Normal file
296
src/swrenderer/scene/r_decal.cpp
Normal file
|
@ -0,0 +1,296 @@
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "templates.h"
|
||||||
|
#include "i_system.h"
|
||||||
|
#include "doomdef.h"
|
||||||
|
#include "doomstat.h"
|
||||||
|
#include "doomdata.h"
|
||||||
|
#include "p_lnspec.h"
|
||||||
|
#include "swrenderer/r_main.h"
|
||||||
|
#include "swrenderer/scene/r_things.h"
|
||||||
|
#include "r_sky.h"
|
||||||
|
#include "v_video.h"
|
||||||
|
#include "m_swap.h"
|
||||||
|
#include "w_wad.h"
|
||||||
|
#include "stats.h"
|
||||||
|
#include "a_sharedglobal.h"
|
||||||
|
#include "d_net.h"
|
||||||
|
#include "g_level.h"
|
||||||
|
#include "r_bsp.h"
|
||||||
|
#include "r_plane.h"
|
||||||
|
#include "r_decal.h"
|
||||||
|
#include "r_3dfloors.h"
|
||||||
|
#include "swrenderer/drawers/r_draw.h"
|
||||||
|
#include "v_palette.h"
|
||||||
|
#include "r_data/colormaps.h"
|
||||||
|
#include "r_walldraw.h"
|
||||||
|
#include "r_draw_segment.h"
|
||||||
|
#include "r_portal.h"
|
||||||
|
#include "r_wallsprite.h"
|
||||||
|
#include "r_draw_segment.h"
|
||||||
|
#include "r_segs.h"
|
||||||
|
#include "swrenderer/r_memory.h"
|
||||||
|
|
||||||
|
namespace swrenderer
|
||||||
|
{
|
||||||
|
void R_RenderDecals(side_t *sidedef, drawseg_t *draw_segment)
|
||||||
|
{
|
||||||
|
for (DBaseDecal *decal = sidedef->AttachedDecals; decal != NULL; decal = decal->WallNext)
|
||||||
|
{
|
||||||
|
R_RenderDecal(sidedef, decal, draw_segment, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pass = 0: when seg is first drawn
|
||||||
|
// = 1: drawing masked textures (including sprites)
|
||||||
|
// Currently, only pass = 0 is done or used
|
||||||
|
|
||||||
|
void R_RenderDecal(side_t *wall, DBaseDecal *decal, drawseg_t *clipper, int pass)
|
||||||
|
{
|
||||||
|
DVector2 decal_left, decal_right, decal_pos;
|
||||||
|
int x1, x2;
|
||||||
|
double yscale;
|
||||||
|
BYTE flipx;
|
||||||
|
double zpos;
|
||||||
|
int needrepeat = 0;
|
||||||
|
sector_t *front, *back;
|
||||||
|
bool calclighting;
|
||||||
|
bool rereadcolormap;
|
||||||
|
FDynamicColormap *usecolormap;
|
||||||
|
|
||||||
|
if (decal->RenderFlags & RF_INVISIBLE || !viewactive || !decal->PicNum.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Determine actor z
|
||||||
|
zpos = decal->Z;
|
||||||
|
front = curline->frontsector;
|
||||||
|
back = (curline->backsector != NULL) ? curline->backsector : curline->frontsector;
|
||||||
|
switch (decal->RenderFlags & RF_RELMASK)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
zpos = decal->Z;
|
||||||
|
break;
|
||||||
|
case RF_RELUPPER:
|
||||||
|
if (curline->linedef->flags & ML_DONTPEGTOP)
|
||||||
|
{
|
||||||
|
zpos = decal->Z + front->GetPlaneTexZ(sector_t::ceiling);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zpos = decal->Z + back->GetPlaneTexZ(sector_t::ceiling);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RF_RELLOWER:
|
||||||
|
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
|
||||||
|
{
|
||||||
|
zpos = decal->Z + front->GetPlaneTexZ(sector_t::ceiling);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zpos = decal->Z + back->GetPlaneTexZ(sector_t::floor);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RF_RELMID:
|
||||||
|
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
|
||||||
|
{
|
||||||
|
zpos = decal->Z + front->GetPlaneTexZ(sector_t::floor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zpos = decal->Z + front->GetPlaneTexZ(sector_t::ceiling);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WallSpriteTile = TexMan(decal->PicNum, true);
|
||||||
|
flipx = (BYTE)(decal->RenderFlags & RF_XFLIP);
|
||||||
|
|
||||||
|
if (WallSpriteTile == NULL || WallSpriteTile->UseType == FTexture::TEX_Null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine left and right edges of sprite. Since this sprite is bound
|
||||||
|
// to a wall, we use the wall's angle instead of the decal's. This is
|
||||||
|
// pretty much the same as what R_AddLine() does.
|
||||||
|
|
||||||
|
FWallCoords savecoord = WallC;
|
||||||
|
|
||||||
|
double edge_right = WallSpriteTile->GetWidth();
|
||||||
|
double edge_left = WallSpriteTile->LeftOffset;
|
||||||
|
edge_right = (edge_right - edge_left) * decal->ScaleX;
|
||||||
|
edge_left *= decal->ScaleX;
|
||||||
|
|
||||||
|
double dcx, dcy;
|
||||||
|
decal->GetXY(wall, dcx, dcy);
|
||||||
|
decal_pos = { dcx, dcy };
|
||||||
|
|
||||||
|
DVector2 angvec = (curline->v2->fPos() - curline->v1->fPos()).Unit();
|
||||||
|
|
||||||
|
decal_left = decal_pos - edge_left * angvec - ViewPos;
|
||||||
|
decal_right = decal_pos + edge_right * angvec - ViewPos;
|
||||||
|
|
||||||
|
if (WallC.Init(decal_left, decal_right, TOO_CLOSE_Z))
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
x1 = WallC.sx1;
|
||||||
|
x2 = WallC.sx2;
|
||||||
|
|
||||||
|
if (x1 >= clipper->x2 || x2 <= clipper->x1)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
WallT.InitFromWallCoords(&WallC);
|
||||||
|
|
||||||
|
// Get the top and bottom clipping arrays
|
||||||
|
switch (decal->RenderFlags & RF_CLIPMASK)
|
||||||
|
{
|
||||||
|
case RF_CLIPFULL:
|
||||||
|
if (curline->backsector == NULL)
|
||||||
|
{
|
||||||
|
if (pass != 0)
|
||||||
|
{
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
mceilingclip = walltop;
|
||||||
|
mfloorclip = wallbottom;
|
||||||
|
}
|
||||||
|
else if (pass == 0)
|
||||||
|
{
|
||||||
|
mceilingclip = walltop;
|
||||||
|
mfloorclip = ceilingclip;
|
||||||
|
needrepeat = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mceilingclip = openings + clipper->sprtopclip - clipper->x1;
|
||||||
|
mfloorclip = openings + clipper->sprbottomclip - clipper->x1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RF_CLIPUPPER:
|
||||||
|
if (pass != 0)
|
||||||
|
{
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
mceilingclip = walltop;
|
||||||
|
mfloorclip = ceilingclip;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RF_CLIPMID:
|
||||||
|
if (curline->backsector != NULL && pass != 2)
|
||||||
|
{
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
mceilingclip = openings + clipper->sprtopclip - clipper->x1;
|
||||||
|
mfloorclip = openings + clipper->sprbottomclip - clipper->x1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RF_CLIPLOWER:
|
||||||
|
if (pass != 0)
|
||||||
|
{
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
mceilingclip = floorclip;
|
||||||
|
mfloorclip = wallbottom;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
yscale = decal->ScaleY;
|
||||||
|
dc_texturemid = WallSpriteTile->TopOffset + (zpos - ViewPos.Z) / yscale;
|
||||||
|
|
||||||
|
// Clip sprite to drawseg
|
||||||
|
x1 = MAX<int>(clipper->x1, x1);
|
||||||
|
x2 = MIN<int>(clipper->x2, x2);
|
||||||
|
if (x1 >= x2)
|
||||||
|
{
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrepWall(swall, lwall, WallSpriteTile->GetWidth(), x1, x2);
|
||||||
|
|
||||||
|
if (flipx)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int right = (WallSpriteTile->GetWidth() << FRACBITS) - 1;
|
||||||
|
|
||||||
|
for (i = x1; i < x2; i++)
|
||||||
|
{
|
||||||
|
lwall[i] = right - lwall[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare lighting
|
||||||
|
calclighting = false;
|
||||||
|
usecolormap = basecolormap;
|
||||||
|
rereadcolormap = true;
|
||||||
|
|
||||||
|
// Decals that are added to the scene must fade to black.
|
||||||
|
if (decal->RenderStyle == LegacyRenderStyles[STYLE_Add] && usecolormap->Fade != 0)
|
||||||
|
{
|
||||||
|
usecolormap = GetSpecialLights(usecolormap->Color, 0, usecolormap->Desaturate);
|
||||||
|
rereadcolormap = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
rw_light = rw_lightleft + (x1 - savecoord.sx1) * rw_lightstep;
|
||||||
|
if (fixedlightlev >= 0)
|
||||||
|
R_SetColorMapLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : usecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
||||||
|
else if (fixedcolormap != NULL)
|
||||||
|
R_SetColorMapLight(fixedcolormap, 0, 0);
|
||||||
|
else if (!foggy && (decal->RenderFlags & RF_FULLBRIGHT))
|
||||||
|
R_SetColorMapLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : usecolormap, 0, 0);
|
||||||
|
else
|
||||||
|
calclighting = true;
|
||||||
|
|
||||||
|
// Draw it
|
||||||
|
if (decal->RenderFlags & RF_YFLIP)
|
||||||
|
{
|
||||||
|
sprflipvert = true;
|
||||||
|
yscale = -yscale;
|
||||||
|
dc_texturemid -= WallSpriteTile->GetHeight();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprflipvert = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float maskedScaleY = float(1 / yscale);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int x = x1;
|
||||||
|
|
||||||
|
bool visible = R_SetPatchStyle(decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor);
|
||||||
|
|
||||||
|
// R_SetPatchStyle can modify basecolormap.
|
||||||
|
if (rereadcolormap)
|
||||||
|
{
|
||||||
|
usecolormap = basecolormap;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visible)
|
||||||
|
{
|
||||||
|
while (x < x2)
|
||||||
|
{
|
||||||
|
if (calclighting)
|
||||||
|
{ // calculate lighting
|
||||||
|
R_SetColorMapLight(usecolormap, rw_light, wallshade);
|
||||||
|
}
|
||||||
|
R_WallSpriteColumn(x, maskedScaleY);
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this sprite is RF_CLIPFULL on a two-sided line, needrepeat will
|
||||||
|
// be set 1 if we need to draw on the lower wall. In all other cases,
|
||||||
|
// needrepeat will be 0, and the while will fail.
|
||||||
|
mceilingclip = floorclip;
|
||||||
|
mfloorclip = wallbottom;
|
||||||
|
R_FinishSetPatchStyle();
|
||||||
|
} while (needrepeat--);
|
||||||
|
|
||||||
|
colfunc = basecolfunc;
|
||||||
|
|
||||||
|
R_FinishSetPatchStyle();
|
||||||
|
done:
|
||||||
|
WallC = savecoord;
|
||||||
|
}
|
||||||
|
}
|
13
src/swrenderer/scene/r_decal.h
Normal file
13
src/swrenderer/scene/r_decal.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct side_t;
|
||||||
|
class DBaseDecal;
|
||||||
|
|
||||||
|
namespace swrenderer
|
||||||
|
{
|
||||||
|
struct drawseg_t;
|
||||||
|
|
||||||
|
void R_RenderDecals(side_t *wall, drawseg_t *draw_segment);
|
||||||
|
void R_RenderDecal(side_t *wall, DBaseDecal *first, drawseg_t *clipper, int pass);
|
||||||
|
}
|
|
@ -52,6 +52,7 @@
|
||||||
#include "r_draw_segment.h"
|
#include "r_draw_segment.h"
|
||||||
#include "r_portal.h"
|
#include "r_portal.h"
|
||||||
#include "r_wallsprite.h"
|
#include "r_wallsprite.h"
|
||||||
|
#include "r_decal.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);
|
|
||||||
|
|
||||||
inline bool IsFogBoundary (sector_t *front, sector_t *back)
|
inline bool IsFogBoundary (sector_t *front, sector_t *back)
|
||||||
{
|
{
|
||||||
|
@ -1810,10 +1810,7 @@ bool R_StoreWallRange (int start, int stop)
|
||||||
// [ZZ] Only if not an active mirror
|
// [ZZ] Only if not an active mirror
|
||||||
if (!rw_markportal)
|
if (!rw_markportal)
|
||||||
{
|
{
|
||||||
for (DBaseDecal *decal = curline->sidedef->AttachedDecals; decal != NULL; decal = decal->WallNext)
|
R_RenderDecals(curline->sidedef, draw_segment);
|
||||||
{
|
|
||||||
R_RenderDecal (curline->sidedef, decal, draw_segment, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rw_markportal)
|
if (rw_markportal)
|
||||||
|
@ -2035,256 +2032,4 @@ void PrepLWall(fixed_t *upos, double walxrepeat, int x1, int x2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pass = 0: when seg is first drawn
|
|
||||||
// = 1: drawing masked textures (including sprites)
|
|
||||||
// Currently, only pass = 0 is done or used
|
|
||||||
|
|
||||||
static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, int pass)
|
|
||||||
{
|
|
||||||
DVector2 decal_left, decal_right, decal_pos;
|
|
||||||
int x1, x2;
|
|
||||||
double yscale;
|
|
||||||
BYTE flipx;
|
|
||||||
double zpos;
|
|
||||||
int needrepeat = 0;
|
|
||||||
sector_t *front, *back;
|
|
||||||
bool calclighting;
|
|
||||||
bool rereadcolormap;
|
|
||||||
FDynamicColormap *usecolormap;
|
|
||||||
|
|
||||||
if (decal->RenderFlags & RF_INVISIBLE || !viewactive || !decal->PicNum.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Determine actor z
|
|
||||||
zpos = decal->Z;
|
|
||||||
front = curline->frontsector;
|
|
||||||
back = (curline->backsector != NULL) ? curline->backsector : curline->frontsector;
|
|
||||||
switch (decal->RenderFlags & RF_RELMASK)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
zpos = decal->Z;
|
|
||||||
break;
|
|
||||||
case RF_RELUPPER:
|
|
||||||
if (curline->linedef->flags & ML_DONTPEGTOP)
|
|
||||||
{
|
|
||||||
zpos = decal->Z + front->GetPlaneTexZ(sector_t::ceiling);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
zpos = decal->Z + back->GetPlaneTexZ(sector_t::ceiling);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RF_RELLOWER:
|
|
||||||
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
|
|
||||||
{
|
|
||||||
zpos = decal->Z + front->GetPlaneTexZ(sector_t::ceiling);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
zpos = decal->Z + back->GetPlaneTexZ(sector_t::floor);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RF_RELMID:
|
|
||||||
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
|
|
||||||
{
|
|
||||||
zpos = decal->Z + front->GetPlaneTexZ(sector_t::floor);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
zpos = decal->Z + front->GetPlaneTexZ(sector_t::ceiling);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WallSpriteTile = TexMan(decal->PicNum, true);
|
|
||||||
flipx = (BYTE)(decal->RenderFlags & RF_XFLIP);
|
|
||||||
|
|
||||||
if (WallSpriteTile == NULL || WallSpriteTile->UseType == FTexture::TEX_Null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine left and right edges of sprite. Since this sprite is bound
|
|
||||||
// to a wall, we use the wall's angle instead of the decal's. This is
|
|
||||||
// pretty much the same as what R_AddLine() does.
|
|
||||||
|
|
||||||
FWallCoords savecoord = WallC;
|
|
||||||
|
|
||||||
double edge_right = WallSpriteTile->GetWidth();
|
|
||||||
double edge_left = WallSpriteTile->LeftOffset;
|
|
||||||
edge_right = (edge_right - edge_left) * decal->ScaleX;
|
|
||||||
edge_left *= decal->ScaleX;
|
|
||||||
|
|
||||||
double dcx, dcy;
|
|
||||||
decal->GetXY(wall, dcx, dcy);
|
|
||||||
decal_pos = { dcx, dcy };
|
|
||||||
|
|
||||||
DVector2 angvec = (curline->v2->fPos() - curline->v1->fPos()).Unit();
|
|
||||||
|
|
||||||
decal_left = decal_pos - edge_left * angvec - ViewPos;
|
|
||||||
decal_right = decal_pos + edge_right * angvec - ViewPos;
|
|
||||||
|
|
||||||
if (WallC.Init(decal_left, decal_right, TOO_CLOSE_Z))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
x1 = WallC.sx1;
|
|
||||||
x2 = WallC.sx2;
|
|
||||||
|
|
||||||
if (x1 >= clipper->x2 || x2 <= clipper->x1)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
WallT.InitFromWallCoords(&WallC);
|
|
||||||
|
|
||||||
// Get the top and bottom clipping arrays
|
|
||||||
switch (decal->RenderFlags & RF_CLIPMASK)
|
|
||||||
{
|
|
||||||
case RF_CLIPFULL:
|
|
||||||
if (curline->backsector == NULL)
|
|
||||||
{
|
|
||||||
if (pass != 0)
|
|
||||||
{
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
mceilingclip = walltop;
|
|
||||||
mfloorclip = wallbottom;
|
|
||||||
}
|
|
||||||
else if (pass == 0)
|
|
||||||
{
|
|
||||||
mceilingclip = walltop;
|
|
||||||
mfloorclip = ceilingclip;
|
|
||||||
needrepeat = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mceilingclip = openings + clipper->sprtopclip - clipper->x1;
|
|
||||||
mfloorclip = openings + clipper->sprbottomclip - clipper->x1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RF_CLIPUPPER:
|
|
||||||
if (pass != 0)
|
|
||||||
{
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
mceilingclip = walltop;
|
|
||||||
mfloorclip = ceilingclip;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RF_CLIPMID:
|
|
||||||
if (curline->backsector != NULL && pass != 2)
|
|
||||||
{
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
mceilingclip = openings + clipper->sprtopclip - clipper->x1;
|
|
||||||
mfloorclip = openings + clipper->sprbottomclip - clipper->x1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RF_CLIPLOWER:
|
|
||||||
if (pass != 0)
|
|
||||||
{
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
mceilingclip = floorclip;
|
|
||||||
mfloorclip = wallbottom;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
yscale = decal->ScaleY;
|
|
||||||
dc_texturemid = WallSpriteTile->TopOffset + (zpos - ViewPos.Z) / yscale;
|
|
||||||
|
|
||||||
// Clip sprite to drawseg
|
|
||||||
x1 = MAX<int>(clipper->x1, x1);
|
|
||||||
x2 = MIN<int>(clipper->x2, x2);
|
|
||||||
if (x1 >= x2)
|
|
||||||
{
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrepWall (swall, lwall, WallSpriteTile->GetWidth(), x1, x2);
|
|
||||||
|
|
||||||
if (flipx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int right = (WallSpriteTile->GetWidth() << FRACBITS) - 1;
|
|
||||||
|
|
||||||
for (i = x1; i < x2; i++)
|
|
||||||
{
|
|
||||||
lwall[i] = right - lwall[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare lighting
|
|
||||||
calclighting = false;
|
|
||||||
usecolormap = basecolormap;
|
|
||||||
rereadcolormap = true;
|
|
||||||
|
|
||||||
// Decals that are added to the scene must fade to black.
|
|
||||||
if (decal->RenderStyle == LegacyRenderStyles[STYLE_Add] && usecolormap->Fade != 0)
|
|
||||||
{
|
|
||||||
usecolormap = GetSpecialLights(usecolormap->Color, 0, usecolormap->Desaturate);
|
|
||||||
rereadcolormap = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
rw_light = rw_lightleft + (x1 - savecoord.sx1) * rw_lightstep;
|
|
||||||
if (fixedlightlev >= 0)
|
|
||||||
R_SetColorMapLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : usecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
|
||||||
else if (fixedcolormap != NULL)
|
|
||||||
R_SetColorMapLight(fixedcolormap, 0, 0);
|
|
||||||
else if (!foggy && (decal->RenderFlags & RF_FULLBRIGHT))
|
|
||||||
R_SetColorMapLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : usecolormap, 0, 0);
|
|
||||||
else
|
|
||||||
calclighting = true;
|
|
||||||
|
|
||||||
// Draw it
|
|
||||||
if (decal->RenderFlags & RF_YFLIP)
|
|
||||||
{
|
|
||||||
sprflipvert = true;
|
|
||||||
yscale = -yscale;
|
|
||||||
dc_texturemid -= WallSpriteTile->GetHeight();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprflipvert = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
float maskedScaleY = float(1 / yscale);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
int x = x1;
|
|
||||||
|
|
||||||
bool visible = R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor);
|
|
||||||
|
|
||||||
// R_SetPatchStyle can modify basecolormap.
|
|
||||||
if (rereadcolormap)
|
|
||||||
{
|
|
||||||
usecolormap = basecolormap;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (visible)
|
|
||||||
{
|
|
||||||
while (x < x2)
|
|
||||||
{
|
|
||||||
if (calclighting)
|
|
||||||
{ // calculate lighting
|
|
||||||
R_SetColorMapLight(usecolormap, rw_light, wallshade);
|
|
||||||
}
|
|
||||||
R_WallSpriteColumn(x, maskedScaleY);
|
|
||||||
x++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this sprite is RF_CLIPFULL on a two-sided line, needrepeat will
|
|
||||||
// be set 1 if we need to draw on the lower wall. In all other cases,
|
|
||||||
// needrepeat will be 0, and the while will fail.
|
|
||||||
mceilingclip = floorclip;
|
|
||||||
mfloorclip = wallbottom;
|
|
||||||
R_FinishSetPatchStyle ();
|
|
||||||
} while (needrepeat--);
|
|
||||||
|
|
||||||
colfunc = basecolfunc;
|
|
||||||
|
|
||||||
R_FinishSetPatchStyle ();
|
|
||||||
done:
|
|
||||||
WallC = savecoord;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,12 +43,18 @@ void PrepLWall (fixed_t *lwall, double walxrepeat, int x1, int x2);
|
||||||
|
|
||||||
void R_RenderSegLoop ();
|
void R_RenderSegLoop ();
|
||||||
|
|
||||||
|
extern short walltop[MAXWIDTH]; // [RH] record max extents of wall
|
||||||
|
extern short wallbottom[MAXWIDTH];
|
||||||
|
extern short wallupper[MAXWIDTH];
|
||||||
|
extern short walllower[MAXWIDTH];
|
||||||
extern float swall[MAXWIDTH];
|
extern float swall[MAXWIDTH];
|
||||||
extern fixed_t lwall[MAXWIDTH];
|
extern fixed_t lwall[MAXWIDTH];
|
||||||
|
extern double lwallscale;
|
||||||
extern float rw_light; // [RH] Scale lights with viewsize adjustments
|
extern float rw_light; // [RH] Scale lights with viewsize adjustments
|
||||||
extern float rw_lightstep;
|
extern float rw_lightstep;
|
||||||
extern float rw_lightleft;
|
extern float rw_lightleft;
|
||||||
extern fixed_t rw_offset;
|
extern fixed_t rw_offset;
|
||||||
|
extern int wallshade;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue