mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-24 21:11:52 +00:00
Move flat and slope plane drawing to their own files, isolate and privatize their working variables
This commit is contained in:
parent
447b162534
commit
f354cc8c67
9 changed files with 590 additions and 495 deletions
|
@ -832,6 +832,8 @@ set( FASTMATH_PCH_SOURCES
|
||||||
swrenderer/scene/r_wallsprite.cpp
|
swrenderer/scene/r_wallsprite.cpp
|
||||||
swrenderer/scene/r_decal.cpp
|
swrenderer/scene/r_decal.cpp
|
||||||
swrenderer/scene/r_skyplane.cpp
|
swrenderer/scene/r_skyplane.cpp
|
||||||
|
swrenderer/scene/r_flatplane.cpp
|
||||||
|
swrenderer/scene/r_slopeplane.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
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "scene/r_things.h"
|
#include "scene/r_things.h"
|
||||||
#include "drawers/r_draw.h"
|
#include "drawers/r_draw.h"
|
||||||
#include "scene/r_plane.h"
|
#include "scene/r_plane.h"
|
||||||
|
#include "scene/r_flatplane.h"
|
||||||
#include "scene/r_bsp.h"
|
#include "scene/r_bsp.h"
|
||||||
#include "scene/r_draw_segment.h"
|
#include "scene/r_draw_segment.h"
|
||||||
#include "scene/r_portal_segment.h"
|
#include "scene/r_portal_segment.h"
|
||||||
|
@ -491,45 +492,7 @@ void R_SetupFreelook()
|
||||||
globaluclip = -CenterY / InvZtoScale;
|
globaluclip = -CenterY / InvZtoScale;
|
||||||
globaldclip = (viewheight - CenterY) / InvZtoScale;
|
globaldclip = (viewheight - CenterY) / InvZtoScale;
|
||||||
|
|
||||||
//centeryfrac &= 0xffff0000;
|
R_SetupPlaneSlope();
|
||||||
int e, i;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
e = viewheight;
|
|
||||||
float focus = float(FocalLengthY);
|
|
||||||
float den;
|
|
||||||
float cy = float(CenterY);
|
|
||||||
if (i < centery)
|
|
||||||
{
|
|
||||||
den = cy - i - 0.5f;
|
|
||||||
if (e <= centery)
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
yslope[i] = focus / den;
|
|
||||||
den -= 1;
|
|
||||||
} while (++i < e);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
yslope[i] = focus / den;
|
|
||||||
den -= 1;
|
|
||||||
} while (++i < centery);
|
|
||||||
den = i - cy + 0.5f;
|
|
||||||
do {
|
|
||||||
yslope[i] = focus / den;
|
|
||||||
den += 1;
|
|
||||||
} while (++i < e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
den = i - cy + 0.5f;
|
|
||||||
do {
|
|
||||||
yslope[i] = focus / den;
|
|
||||||
den += 1;
|
|
||||||
} while (++i < e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
359
src/swrenderer/scene/r_flatplane.cpp
Normal file
359
src/swrenderer/scene/r_flatplane.cpp
Normal file
|
@ -0,0 +1,359 @@
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <float.h>
|
||||||
|
#include "templates.h"
|
||||||
|
#include "i_system.h"
|
||||||
|
#include "w_wad.h"
|
||||||
|
#include "doomdef.h"
|
||||||
|
#include "doomstat.h"
|
||||||
|
#include "swrenderer/r_main.h"
|
||||||
|
#include "swrenderer/scene/r_things.h"
|
||||||
|
#include "r_sky.h"
|
||||||
|
#include "stats.h"
|
||||||
|
#include "v_video.h"
|
||||||
|
#include "a_sharedglobal.h"
|
||||||
|
#include "c_console.h"
|
||||||
|
#include "cmdlib.h"
|
||||||
|
#include "d_net.h"
|
||||||
|
#include "g_level.h"
|
||||||
|
#include "r_bsp.h"
|
||||||
|
#include "r_flatplane.h"
|
||||||
|
#include "r_segs.h"
|
||||||
|
#include "r_3dfloors.h"
|
||||||
|
#include "v_palette.h"
|
||||||
|
#include "r_data/colormaps.h"
|
||||||
|
#include "swrenderer/drawers/r_draw_rgba.h"
|
||||||
|
#include "gl/dynlights/gl_dynlight.h"
|
||||||
|
#include "r_walldraw.h"
|
||||||
|
#include "r_clip_segment.h"
|
||||||
|
#include "r_draw_segment.h"
|
||||||
|
#include "r_portal.h"
|
||||||
|
#include "r_plane.h"
|
||||||
|
#include "swrenderer/r_memory.h"
|
||||||
|
|
||||||
|
namespace swrenderer
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
double planeheight;
|
||||||
|
bool plane_shade;
|
||||||
|
int planeshade;
|
||||||
|
fixed_t pviewx, pviewy;
|
||||||
|
float yslope[MAXHEIGHT];
|
||||||
|
fixed_t xscale, yscale;
|
||||||
|
double xstepscale, ystepscale;
|
||||||
|
double basexfrac, baseyfrac;
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_DrawNormalPlane(visplane_t *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked)
|
||||||
|
{
|
||||||
|
using namespace drawerargs;
|
||||||
|
|
||||||
|
if (alpha <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double planeang = (pl->xform.Angle + pl->xform.baseAngle).Radians();
|
||||||
|
double xstep, ystep, leftxfrac, leftyfrac, rightxfrac, rightyfrac;
|
||||||
|
double x;
|
||||||
|
|
||||||
|
xscale = xs_ToFixed(32 - ds_xbits, _xscale);
|
||||||
|
yscale = xs_ToFixed(32 - ds_ybits, _yscale);
|
||||||
|
if (planeang != 0)
|
||||||
|
{
|
||||||
|
double cosine = cos(planeang), sine = sin(planeang);
|
||||||
|
pviewx = FLOAT2FIXED(pl->xform.xOffs + ViewPos.X * cosine - ViewPos.Y * sine);
|
||||||
|
pviewy = FLOAT2FIXED(pl->xform.yOffs - ViewPos.X * sine - ViewPos.Y * cosine);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pviewx = FLOAT2FIXED(pl->xform.xOffs + ViewPos.X);
|
||||||
|
pviewy = FLOAT2FIXED(pl->xform.yOffs - ViewPos.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
pviewx = FixedMul(xscale, pviewx);
|
||||||
|
pviewy = FixedMul(yscale, pviewy);
|
||||||
|
|
||||||
|
// left to right mapping
|
||||||
|
planeang += (ViewAngle - 90).Radians();
|
||||||
|
|
||||||
|
// Scale will be unit scale at FocalLengthX (normally SCREENWIDTH/2) distance
|
||||||
|
xstep = cos(planeang) / FocalLengthX;
|
||||||
|
ystep = -sin(planeang) / FocalLengthX;
|
||||||
|
|
||||||
|
// [RH] flip for mirrors
|
||||||
|
if (MirrorFlags & RF_XFLIP)
|
||||||
|
{
|
||||||
|
xstep = -xstep;
|
||||||
|
ystep = -ystep;
|
||||||
|
}
|
||||||
|
|
||||||
|
planeang += M_PI / 2;
|
||||||
|
double cosine = cos(planeang), sine = -sin(planeang);
|
||||||
|
x = pl->right - centerx - 0.5;
|
||||||
|
rightxfrac = _xscale * (cosine + x * xstep);
|
||||||
|
rightyfrac = _yscale * (sine + x * ystep);
|
||||||
|
x = pl->left - centerx - 0.5;
|
||||||
|
leftxfrac = _xscale * (cosine + x * xstep);
|
||||||
|
leftyfrac = _yscale * (sine + x * ystep);
|
||||||
|
|
||||||
|
basexfrac = rightxfrac;
|
||||||
|
baseyfrac = rightyfrac;
|
||||||
|
xstepscale = (rightxfrac - leftxfrac) / (pl->right - pl->left);
|
||||||
|
ystepscale = (rightyfrac - leftyfrac) / (pl->right - pl->left);
|
||||||
|
|
||||||
|
planeheight = fabs(pl->height.Zat0() - ViewPos.Z);
|
||||||
|
|
||||||
|
GlobVis = r_FloorVisibility / planeheight;
|
||||||
|
ds_light = 0;
|
||||||
|
if (fixedlightlev >= 0)
|
||||||
|
{
|
||||||
|
R_SetDSColorMapLight(basecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
||||||
|
plane_shade = false;
|
||||||
|
}
|
||||||
|
else if (fixedcolormap)
|
||||||
|
{
|
||||||
|
R_SetDSColorMapLight(fixedcolormap, 0, 0);
|
||||||
|
plane_shade = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
plane_shade = true;
|
||||||
|
planeshade = LIGHT2SHADE(pl->lightlevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spanfunc != &SWPixelFormatDrawers::FillSpan)
|
||||||
|
{
|
||||||
|
if (masked)
|
||||||
|
{
|
||||||
|
if (alpha < OPAQUE || additive)
|
||||||
|
{
|
||||||
|
if (!additive)
|
||||||
|
{
|
||||||
|
spanfunc = &SWPixelFormatDrawers::DrawSpanMaskedTranslucent;
|
||||||
|
dc_srcblend = Col2RGB8[alpha >> 10];
|
||||||
|
dc_destblend = Col2RGB8[(OPAQUE - alpha) >> 10];
|
||||||
|
dc_srcalpha = alpha;
|
||||||
|
dc_destalpha = OPAQUE - alpha;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spanfunc = &SWPixelFormatDrawers::DrawSpanMaskedAddClamp;
|
||||||
|
dc_srcblend = Col2RGB8_LessPrecision[alpha >> 10];
|
||||||
|
dc_destblend = Col2RGB8_LessPrecision[FRACUNIT >> 10];
|
||||||
|
dc_srcalpha = alpha;
|
||||||
|
dc_destalpha = FRACUNIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spanfunc = &SWPixelFormatDrawers::DrawSpanMasked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (alpha < OPAQUE || additive)
|
||||||
|
{
|
||||||
|
if (!additive)
|
||||||
|
{
|
||||||
|
spanfunc = &SWPixelFormatDrawers::DrawSpanTranslucent;
|
||||||
|
dc_srcblend = Col2RGB8[alpha >> 10];
|
||||||
|
dc_destblend = Col2RGB8[(OPAQUE - alpha) >> 10];
|
||||||
|
dc_srcalpha = alpha;
|
||||||
|
dc_destalpha = OPAQUE - alpha;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spanfunc = &SWPixelFormatDrawers::DrawSpanAddClamp;
|
||||||
|
dc_srcblend = Col2RGB8_LessPrecision[alpha >> 10];
|
||||||
|
dc_destblend = Col2RGB8_LessPrecision[FRACUNIT >> 10];
|
||||||
|
dc_srcalpha = alpha;
|
||||||
|
dc_destalpha = FRACUNIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spanfunc = &SWPixelFormatDrawers::DrawSpan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
R_MapVisPlane(pl, R_MapPlane, R_StepPlane);
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_StepPlane()
|
||||||
|
{
|
||||||
|
basexfrac -= xstepscale;
|
||||||
|
baseyfrac -= ystepscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_MapPlane(int y, int x1, int x2)
|
||||||
|
{
|
||||||
|
using namespace drawerargs;
|
||||||
|
|
||||||
|
double distance;
|
||||||
|
|
||||||
|
#ifdef RANGECHECK
|
||||||
|
if (x2 < x1 || x1<0 || x2 >= viewwidth || (unsigned)y >= (unsigned)viewheight)
|
||||||
|
{
|
||||||
|
I_FatalError("R_MapPlane: %i, %i at %i", x1, x2, y);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// [RH] Notice that I dumped the caching scheme used by Doom.
|
||||||
|
// It did not offer any appreciable speedup.
|
||||||
|
|
||||||
|
distance = planeheight * yslope[y];
|
||||||
|
|
||||||
|
if (ds_xbits != 0)
|
||||||
|
{
|
||||||
|
ds_xstep = xs_ToFixed(32 - ds_xbits, distance * xstepscale);
|
||||||
|
ds_xfrac = xs_ToFixed(32 - ds_xbits, distance * basexfrac) + pviewx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ds_xstep = 0;
|
||||||
|
ds_xfrac = 0;
|
||||||
|
}
|
||||||
|
if (ds_ybits != 0)
|
||||||
|
{
|
||||||
|
ds_ystep = xs_ToFixed(32 - ds_ybits, distance * ystepscale);
|
||||||
|
ds_yfrac = xs_ToFixed(32 - ds_ybits, distance * baseyfrac) + pviewy;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ds_ystep = 0;
|
||||||
|
ds_yfrac = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r_swtruecolor)
|
||||||
|
{
|
||||||
|
double distance2 = planeheight * yslope[(y + 1 < viewheight) ? y + 1 : y - 1];
|
||||||
|
double xmagnitude = fabs(ystepscale * (distance2 - distance) * FocalLengthX);
|
||||||
|
double ymagnitude = fabs(xstepscale * (distance2 - distance) * FocalLengthX);
|
||||||
|
double magnitude = MAX(ymagnitude, xmagnitude);
|
||||||
|
double min_lod = -1000.0;
|
||||||
|
ds_lod = MAX(log2(magnitude) + r_lod_bias, min_lod);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plane_shade)
|
||||||
|
{
|
||||||
|
// Determine lighting based on the span's distance from the viewer.
|
||||||
|
R_SetDSColorMapLight(basecolormap, (float)(GlobVis * fabs(CenterY - y)), planeshade);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r_dynlights)
|
||||||
|
{
|
||||||
|
// Find row position in view space
|
||||||
|
float zspan = (float)(planeheight / (fabs(y + 0.5 - CenterY) / InvZtoScale));
|
||||||
|
dc_viewpos.X = (float)((x1 + 0.5 - CenterX) / CenterX * zspan);
|
||||||
|
dc_viewpos.Y = zspan;
|
||||||
|
dc_viewpos.Z = (float)((CenterY - y - 0.5) / InvZtoScale * zspan);
|
||||||
|
dc_viewpos_step.X = (float)(zspan / CenterX);
|
||||||
|
|
||||||
|
static TriLight lightbuffer[64 * 1024];
|
||||||
|
static int nextlightindex = 0;
|
||||||
|
|
||||||
|
// Setup lights for column
|
||||||
|
dc_num_lights = 0;
|
||||||
|
dc_lights = lightbuffer + nextlightindex;
|
||||||
|
visplane_light *cur_node = ds_light_list;
|
||||||
|
while (cur_node && nextlightindex < 64 * 1024)
|
||||||
|
{
|
||||||
|
double lightX = cur_node->lightsource->X() - ViewPos.X;
|
||||||
|
double lightY = cur_node->lightsource->Y() - ViewPos.Y;
|
||||||
|
double lightZ = cur_node->lightsource->Z() - ViewPos.Z;
|
||||||
|
|
||||||
|
float lx = (float)(lightX * ViewSin - lightY * ViewCos);
|
||||||
|
float ly = (float)(lightX * ViewTanCos + lightY * ViewTanSin) - dc_viewpos.Y;
|
||||||
|
float lz = (float)lightZ - dc_viewpos.Z;
|
||||||
|
|
||||||
|
// Precalculate the constant part of the dot here so the drawer doesn't have to.
|
||||||
|
float lconstant = ly * ly + lz * lz;
|
||||||
|
|
||||||
|
// Include light only if it touches this row
|
||||||
|
float radius = cur_node->lightsource->GetRadius();
|
||||||
|
if (radius * radius >= lconstant)
|
||||||
|
{
|
||||||
|
uint32_t red = cur_node->lightsource->GetRed();
|
||||||
|
uint32_t green = cur_node->lightsource->GetGreen();
|
||||||
|
uint32_t blue = cur_node->lightsource->GetBlue();
|
||||||
|
|
||||||
|
nextlightindex++;
|
||||||
|
auto &light = dc_lights[dc_num_lights++];
|
||||||
|
light.x = lx;
|
||||||
|
light.y = lconstant;
|
||||||
|
light.radius = 256.0f / radius;
|
||||||
|
light.color = (red << 16) | (green << 8) | blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_node = cur_node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextlightindex == 64 * 1024)
|
||||||
|
nextlightindex = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dc_num_lights = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ds_y = y;
|
||||||
|
ds_x1 = x1;
|
||||||
|
ds_x2 = x2;
|
||||||
|
|
||||||
|
(R_Drawers()->*spanfunc)();
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_DrawColoredPlane(visplane_t *pl)
|
||||||
|
{
|
||||||
|
R_MapVisPlane(pl, R_MapColoredPlane, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_MapColoredPlane(int y, int x1, int x2)
|
||||||
|
{
|
||||||
|
R_Drawers()->DrawColoredSpan(y, x1, x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_SetupPlaneSlope()
|
||||||
|
{
|
||||||
|
int e, i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
e = viewheight;
|
||||||
|
float focus = float(FocalLengthY);
|
||||||
|
float den;
|
||||||
|
float cy = float(CenterY);
|
||||||
|
if (i < centery)
|
||||||
|
{
|
||||||
|
den = cy - i - 0.5f;
|
||||||
|
if (e <= centery)
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
yslope[i] = focus / den;
|
||||||
|
den -= 1;
|
||||||
|
} while (++i < e);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
yslope[i] = focus / den;
|
||||||
|
den -= 1;
|
||||||
|
} while (++i < centery);
|
||||||
|
den = i - cy + 0.5f;
|
||||||
|
do {
|
||||||
|
yslope[i] = focus / den;
|
||||||
|
den += 1;
|
||||||
|
} while (++i < e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
den = i - cy + 0.5f;
|
||||||
|
do {
|
||||||
|
yslope[i] = focus / den;
|
||||||
|
den += 1;
|
||||||
|
} while (++i < e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
src/swrenderer/scene/r_flatplane.h
Normal file
16
src/swrenderer/scene/r_flatplane.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "r_visible_plane.h"
|
||||||
|
|
||||||
|
namespace swrenderer
|
||||||
|
{
|
||||||
|
void R_SetupPlaneSlope();
|
||||||
|
|
||||||
|
void R_DrawNormalPlane(visplane_t *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked);
|
||||||
|
void R_MapPlane(int y, int x1, int x2);
|
||||||
|
void R_StepPlane();
|
||||||
|
|
||||||
|
void R_DrawColoredPlane(visplane_t *pl);
|
||||||
|
void R_MapColoredPlane(int y, int x1, int x2);
|
||||||
|
}
|
|
@ -66,6 +66,8 @@
|
||||||
#include "r_draw_segment.h"
|
#include "r_draw_segment.h"
|
||||||
#include "r_portal.h"
|
#include "r_portal.h"
|
||||||
#include "r_skyplane.h"
|
#include "r_skyplane.h"
|
||||||
|
#include "r_flatplane.h"
|
||||||
|
#include "r_slopeplane.h"
|
||||||
#include "swrenderer/r_memory.h"
|
#include "swrenderer/r_memory.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -109,176 +111,10 @@ short ceilingclip[MAXWIDTH];
|
||||||
// texture mapping
|
// texture mapping
|
||||||
//
|
//
|
||||||
|
|
||||||
static double planeheight;
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
//
|
|
||||||
// spanend holds the end of a plane span in each screen row
|
|
||||||
//
|
|
||||||
short spanend[MAXHEIGHT];
|
short spanend[MAXHEIGHT];
|
||||||
|
|
||||||
int planeshade;
|
|
||||||
FVector3 plane_sz, plane_su, plane_sv;
|
|
||||||
float planelightfloat;
|
|
||||||
bool plane_shade;
|
|
||||||
fixed_t pviewx, pviewy;
|
|
||||||
}
|
|
||||||
|
|
||||||
float yslope[MAXHEIGHT];
|
|
||||||
static fixed_t xscale, yscale;
|
|
||||||
static double xstepscale, ystepscale;
|
|
||||||
static double basexfrac, baseyfrac;
|
|
||||||
|
|
||||||
void R_DrawSinglePlane (visplane_t *, fixed_t alpha, bool additive, bool masked);
|
void R_DrawSinglePlane (visplane_t *, fixed_t alpha, bool additive, bool masked);
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// R_MapPlane
|
|
||||||
//
|
|
||||||
// Globals used: planeheight, ds_source, basexscale, baseyscale,
|
|
||||||
// pviewx, pviewy, xoffs, yoffs, basecolormap, xscale, yscale.
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void R_MapPlane (int y, int x1)
|
|
||||||
{
|
|
||||||
int x2 = spanend[y];
|
|
||||||
double distance;
|
|
||||||
|
|
||||||
#ifdef RANGECHECK
|
|
||||||
if (x2 < x1 || x1<0 || x2>=viewwidth || (unsigned)y>=(unsigned)viewheight)
|
|
||||||
{
|
|
||||||
I_FatalError ("R_MapPlane: %i, %i at %i", x1, x2, y);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// [RH] Notice that I dumped the caching scheme used by Doom.
|
|
||||||
// It did not offer any appreciable speedup.
|
|
||||||
|
|
||||||
distance = planeheight * yslope[y];
|
|
||||||
|
|
||||||
if (ds_xbits != 0)
|
|
||||||
{
|
|
||||||
ds_xstep = xs_ToFixed(32 - ds_xbits, distance * xstepscale);
|
|
||||||
ds_xfrac = xs_ToFixed(32 - ds_xbits, distance * basexfrac) + pviewx;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ds_xstep = 0;
|
|
||||||
ds_xfrac = 0;
|
|
||||||
}
|
|
||||||
if (ds_ybits != 0)
|
|
||||||
{
|
|
||||||
ds_ystep = xs_ToFixed(32 - ds_ybits, distance * ystepscale);
|
|
||||||
ds_yfrac = xs_ToFixed(32 - ds_ybits, distance * baseyfrac) + pviewy;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ds_ystep = 0;
|
|
||||||
ds_yfrac = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r_swtruecolor)
|
|
||||||
{
|
|
||||||
double distance2 = planeheight * yslope[(y + 1 < viewheight) ? y + 1 : y - 1];
|
|
||||||
double xmagnitude = fabs(ystepscale * (distance2 - distance) * FocalLengthX);
|
|
||||||
double ymagnitude = fabs(xstepscale * (distance2 - distance) * FocalLengthX);
|
|
||||||
double magnitude = MAX(ymagnitude, xmagnitude);
|
|
||||||
double min_lod = -1000.0;
|
|
||||||
ds_lod = MAX(log2(magnitude) + r_lod_bias, min_lod);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plane_shade)
|
|
||||||
{
|
|
||||||
// Determine lighting based on the span's distance from the viewer.
|
|
||||||
R_SetDSColorMapLight(basecolormap, GlobVis * fabs(CenterY - y), planeshade);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r_dynlights)
|
|
||||||
{
|
|
||||||
// Find row position in view space
|
|
||||||
float zspan = planeheight / (fabs(y + 0.5 - CenterY) / InvZtoScale);
|
|
||||||
dc_viewpos.X = (float)((x1 + 0.5 - CenterX) / CenterX * zspan);
|
|
||||||
dc_viewpos.Y = zspan;
|
|
||||||
dc_viewpos.Z = (float)((CenterY - y - 0.5) / InvZtoScale * zspan);
|
|
||||||
dc_viewpos_step.X = (float)(zspan / CenterX);
|
|
||||||
|
|
||||||
static TriLight lightbuffer[64 * 1024];
|
|
||||||
static int nextlightindex = 0;
|
|
||||||
|
|
||||||
// Setup lights for column
|
|
||||||
dc_num_lights = 0;
|
|
||||||
dc_lights = lightbuffer + nextlightindex;
|
|
||||||
visplane_light *cur_node = ds_light_list;
|
|
||||||
while (cur_node && nextlightindex < 64 * 1024)
|
|
||||||
{
|
|
||||||
double lightX = cur_node->lightsource->X() - ViewPos.X;
|
|
||||||
double lightY = cur_node->lightsource->Y() - ViewPos.Y;
|
|
||||||
double lightZ = cur_node->lightsource->Z() - ViewPos.Z;
|
|
||||||
|
|
||||||
float lx = (float)(lightX * ViewSin - lightY * ViewCos);
|
|
||||||
float ly = (float)(lightX * ViewTanCos + lightY * ViewTanSin) - dc_viewpos.Y;
|
|
||||||
float lz = (float)lightZ - dc_viewpos.Z;
|
|
||||||
|
|
||||||
// Precalculate the constant part of the dot here so the drawer doesn't have to.
|
|
||||||
float lconstant = ly * ly + lz * lz;
|
|
||||||
|
|
||||||
// Include light only if it touches this row
|
|
||||||
float radius = cur_node->lightsource->GetRadius();
|
|
||||||
if (radius * radius >= lconstant)
|
|
||||||
{
|
|
||||||
uint32_t red = cur_node->lightsource->GetRed();
|
|
||||||
uint32_t green = cur_node->lightsource->GetGreen();
|
|
||||||
uint32_t blue = cur_node->lightsource->GetBlue();
|
|
||||||
|
|
||||||
nextlightindex++;
|
|
||||||
auto &light = dc_lights[dc_num_lights++];
|
|
||||||
light.x = lx;
|
|
||||||
light.y = lconstant;
|
|
||||||
light.radius = 256.0f / radius;
|
|
||||||
light.color = (red << 16) | (green << 8) | blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_node = cur_node->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nextlightindex == 64 * 1024)
|
|
||||||
nextlightindex = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dc_num_lights = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ds_y = y;
|
|
||||||
ds_x1 = x1;
|
|
||||||
ds_x2 = x2;
|
|
||||||
|
|
||||||
(R_Drawers()->*spanfunc)();
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// R_MapTiltedPlane
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void R_MapTiltedPlane (int y, int x1)
|
|
||||||
{
|
|
||||||
R_Drawers()->DrawTiltedSpan(y, x1, spanend[y], plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// R_MapColoredPlane
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void R_MapColoredPlane(int y, int x1)
|
|
||||||
{
|
|
||||||
R_Drawers()->DrawColoredSpan(y, x1, spanend[y]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void R_DrawFogBoundarySection(int y, int y2, int x1)
|
void R_DrawFogBoundarySection(int y, int y2, int x1)
|
||||||
{
|
{
|
||||||
for (; y < y2; ++y)
|
for (; y < y2; ++y)
|
||||||
|
@ -790,7 +626,7 @@ void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske
|
||||||
if (r_drawflat)
|
if (r_drawflat)
|
||||||
{ // [RH] no texture mapping
|
{ // [RH] no texture mapping
|
||||||
ds_color += 4;
|
ds_color += 4;
|
||||||
R_MapVisPlane (pl, R_MapColoredPlane);
|
R_DrawColoredPlane(pl);
|
||||||
}
|
}
|
||||||
else if (pl->picnum == skyflatnum)
|
else if (pl->picnum == skyflatnum)
|
||||||
{ // sky flat
|
{ // sky flat
|
||||||
|
@ -818,7 +654,6 @@ void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske
|
||||||
double yscale = pl->xform.yScale * tex->Scale.Y;
|
double yscale = pl->xform.yScale * tex->Scale.Y;
|
||||||
|
|
||||||
basecolormap = pl->colormap;
|
basecolormap = pl->colormap;
|
||||||
planeshade = LIGHT2SHADE(pl->lightlevel);
|
|
||||||
|
|
||||||
if (r_drawflat || (!pl->height.isSlope() && !tilt))
|
if (r_drawflat || (!pl->height.isSlope() && !tilt))
|
||||||
{
|
{
|
||||||
|
@ -832,277 +667,6 @@ void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske
|
||||||
NetUpdate ();
|
NetUpdate ();
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// R_DrawNormalPlane
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked)
|
|
||||||
{
|
|
||||||
if (alpha <= 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
double planeang = (pl->xform.Angle + pl->xform.baseAngle).Radians();
|
|
||||||
double xstep, ystep, leftxfrac, leftyfrac, rightxfrac, rightyfrac;
|
|
||||||
double x;
|
|
||||||
|
|
||||||
xscale = xs_ToFixed(32 - ds_xbits, _xscale);
|
|
||||||
yscale = xs_ToFixed(32 - ds_ybits, _yscale);
|
|
||||||
if (planeang != 0)
|
|
||||||
{
|
|
||||||
double cosine = cos(planeang), sine = sin(planeang);
|
|
||||||
pviewx = FLOAT2FIXED(pl->xform.xOffs + ViewPos.X * cosine - ViewPos.Y * sine);
|
|
||||||
pviewy = FLOAT2FIXED(pl->xform.yOffs - ViewPos.X * sine - ViewPos.Y * cosine);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pviewx = FLOAT2FIXED(pl->xform.xOffs + ViewPos.X);
|
|
||||||
pviewy = FLOAT2FIXED(pl->xform.yOffs - ViewPos.Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
pviewx = FixedMul (xscale, pviewx);
|
|
||||||
pviewy = FixedMul (yscale, pviewy);
|
|
||||||
|
|
||||||
// left to right mapping
|
|
||||||
planeang += (ViewAngle - 90).Radians();
|
|
||||||
|
|
||||||
// Scale will be unit scale at FocalLengthX (normally SCREENWIDTH/2) distance
|
|
||||||
xstep = cos(planeang) / FocalLengthX;
|
|
||||||
ystep = -sin(planeang) / FocalLengthX;
|
|
||||||
|
|
||||||
// [RH] flip for mirrors
|
|
||||||
if (MirrorFlags & RF_XFLIP)
|
|
||||||
{
|
|
||||||
xstep = -xstep;
|
|
||||||
ystep = -ystep;
|
|
||||||
}
|
|
||||||
|
|
||||||
planeang += M_PI/2;
|
|
||||||
double cosine = cos(planeang), sine = -sin(planeang);
|
|
||||||
x = pl->right - centerx - 0.5;
|
|
||||||
rightxfrac = _xscale * (cosine + x * xstep);
|
|
||||||
rightyfrac = _yscale * (sine + x * ystep);
|
|
||||||
x = pl->left - centerx - 0.5;
|
|
||||||
leftxfrac = _xscale * (cosine + x * xstep);
|
|
||||||
leftyfrac = _yscale * (sine + x * ystep);
|
|
||||||
|
|
||||||
basexfrac = rightxfrac;
|
|
||||||
baseyfrac = rightyfrac;
|
|
||||||
xstepscale = (rightxfrac - leftxfrac) / (pl->right - pl->left);
|
|
||||||
ystepscale = (rightyfrac - leftyfrac) / (pl->right - pl->left);
|
|
||||||
|
|
||||||
planeheight = fabs(pl->height.Zat0() - ViewPos.Z);
|
|
||||||
|
|
||||||
GlobVis = r_FloorVisibility / planeheight;
|
|
||||||
ds_light = 0;
|
|
||||||
if (fixedlightlev >= 0)
|
|
||||||
{
|
|
||||||
R_SetDSColorMapLight(basecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
|
||||||
plane_shade = false;
|
|
||||||
}
|
|
||||||
else if (fixedcolormap)
|
|
||||||
{
|
|
||||||
R_SetDSColorMapLight(fixedcolormap, 0, 0);
|
|
||||||
plane_shade = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
plane_shade = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spanfunc != &SWPixelFormatDrawers::FillSpan)
|
|
||||||
{
|
|
||||||
if (masked)
|
|
||||||
{
|
|
||||||
if (alpha < OPAQUE || additive)
|
|
||||||
{
|
|
||||||
if (!additive)
|
|
||||||
{
|
|
||||||
spanfunc = &SWPixelFormatDrawers::DrawSpanMaskedTranslucent;
|
|
||||||
dc_srcblend = Col2RGB8[alpha>>10];
|
|
||||||
dc_destblend = Col2RGB8[(OPAQUE-alpha)>>10];
|
|
||||||
dc_srcalpha = alpha;
|
|
||||||
dc_destalpha = OPAQUE - alpha;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
spanfunc = &SWPixelFormatDrawers::DrawSpanMaskedAddClamp;
|
|
||||||
dc_srcblend = Col2RGB8_LessPrecision[alpha>>10];
|
|
||||||
dc_destblend = Col2RGB8_LessPrecision[FRACUNIT>>10];
|
|
||||||
dc_srcalpha = alpha;
|
|
||||||
dc_destalpha = FRACUNIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
spanfunc = &SWPixelFormatDrawers::DrawSpanMasked;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (alpha < OPAQUE || additive)
|
|
||||||
{
|
|
||||||
if (!additive)
|
|
||||||
{
|
|
||||||
spanfunc = &SWPixelFormatDrawers::DrawSpanTranslucent;
|
|
||||||
dc_srcblend = Col2RGB8[alpha>>10];
|
|
||||||
dc_destblend = Col2RGB8[(OPAQUE-alpha)>>10];
|
|
||||||
dc_srcalpha = alpha;
|
|
||||||
dc_destalpha = OPAQUE - alpha;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
spanfunc = &SWPixelFormatDrawers::DrawSpanAddClamp;
|
|
||||||
dc_srcblend = Col2RGB8_LessPrecision[alpha>>10];
|
|
||||||
dc_destblend = Col2RGB8_LessPrecision[FRACUNIT>>10];
|
|
||||||
dc_srcalpha = alpha;
|
|
||||||
dc_destalpha = FRACUNIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
spanfunc = &SWPixelFormatDrawers::DrawSpan;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
R_MapVisPlane (pl, R_MapPlane);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// R_DrawTiltedPlane
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void R_DrawTiltedPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked)
|
|
||||||
{
|
|
||||||
static const float ifloatpow2[16] =
|
|
||||||
{
|
|
||||||
// ifloatpow2[i] = 1 / (1 << i)
|
|
||||||
64.f, 32.f, 16.f, 8.f, 4.f, 2.f, 1.f, 0.5f,
|
|
||||||
0.25f, 0.125f, 0.0625f, 0.03125f, 0.015625f, 0.0078125f,
|
|
||||||
0.00390625f, 0.001953125f
|
|
||||||
/*, 0.0009765625f, 0.00048828125f, 0.000244140625f,
|
|
||||||
1.220703125e-4f, 6.103515625e-5, 3.0517578125e-5*/
|
|
||||||
};
|
|
||||||
double lxscale, lyscale;
|
|
||||||
double xscale, yscale;
|
|
||||||
FVector3 p, m, n;
|
|
||||||
double ang, planeang, cosine, sine;
|
|
||||||
double zeroheight;
|
|
||||||
|
|
||||||
if (alpha <= 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
lxscale = _xscale * ifloatpow2[ds_xbits];
|
|
||||||
lyscale = _yscale * ifloatpow2[ds_ybits];
|
|
||||||
xscale = 64.f / lxscale;
|
|
||||||
yscale = 64.f / lyscale;
|
|
||||||
zeroheight = pl->height.ZatPoint(ViewPos);
|
|
||||||
|
|
||||||
pviewx = xs_ToFixed(32 - ds_xbits, pl->xform.xOffs * pl->xform.xScale);
|
|
||||||
pviewy = xs_ToFixed(32 - ds_ybits, pl->xform.yOffs * pl->xform.yScale);
|
|
||||||
planeang = (pl->xform.Angle + pl->xform.baseAngle).Radians();
|
|
||||||
|
|
||||||
// p is the texture origin in view space
|
|
||||||
// Don't add in the offsets at this stage, because doing so can result in
|
|
||||||
// errors if the flat is rotated.
|
|
||||||
ang = M_PI*3/2 - ViewAngle.Radians();
|
|
||||||
cosine = cos(ang), sine = sin(ang);
|
|
||||||
p[0] = ViewPos.X * cosine - ViewPos.Y * sine;
|
|
||||||
p[2] = ViewPos.X * sine + ViewPos.Y * cosine;
|
|
||||||
p[1] = pl->height.ZatPoint(0.0, 0.0) - ViewPos.Z;
|
|
||||||
|
|
||||||
// m is the v direction vector in view space
|
|
||||||
ang = ang - M_PI / 2 - planeang;
|
|
||||||
cosine = cos(ang), sine = sin(ang);
|
|
||||||
m[0] = yscale * cosine;
|
|
||||||
m[2] = yscale * sine;
|
|
||||||
// m[1] = pl->height.ZatPointF (0, iyscale) - pl->height.ZatPointF (0,0));
|
|
||||||
// VectorScale2 (m, 64.f/VectorLength(m));
|
|
||||||
|
|
||||||
// n is the u direction vector in view space
|
|
||||||
#if 0
|
|
||||||
//let's use the sin/cosine we already know instead of computing new ones
|
|
||||||
ang += M_PI/2
|
|
||||||
n[0] = -xscale * cos(ang);
|
|
||||||
n[2] = -xscale * sin(ang);
|
|
||||||
#else
|
|
||||||
n[0] = xscale * sine;
|
|
||||||
n[2] = -xscale * cosine;
|
|
||||||
#endif
|
|
||||||
// n[1] = pl->height.ZatPointF (ixscale, 0) - pl->height.ZatPointF (0,0));
|
|
||||||
// VectorScale2 (n, 64.f/VectorLength(n));
|
|
||||||
|
|
||||||
// This code keeps the texture coordinates constant across the x,y plane no matter
|
|
||||||
// how much you slope the surface. Use the commented-out code above instead to keep
|
|
||||||
// the textures a constant size across the surface's plane instead.
|
|
||||||
cosine = cos(planeang), sine = sin(planeang);
|
|
||||||
m[1] = pl->height.ZatPoint(ViewPos.X + yscale * sine, ViewPos.Y + yscale * cosine) - zeroheight;
|
|
||||||
n[1] = -(pl->height.ZatPoint(ViewPos.X - xscale * cosine, ViewPos.Y + xscale * sine) - zeroheight);
|
|
||||||
|
|
||||||
plane_su = p ^ m;
|
|
||||||
plane_sv = p ^ n;
|
|
||||||
plane_sz = m ^ n;
|
|
||||||
|
|
||||||
plane_su.Z *= FocalLengthX;
|
|
||||||
plane_sv.Z *= FocalLengthX;
|
|
||||||
plane_sz.Z *= FocalLengthX;
|
|
||||||
|
|
||||||
plane_su.Y *= IYaspectMul;
|
|
||||||
plane_sv.Y *= IYaspectMul;
|
|
||||||
plane_sz.Y *= IYaspectMul;
|
|
||||||
|
|
||||||
// Premultiply the texture vectors with the scale factors
|
|
||||||
plane_su *= 4294967296.f;
|
|
||||||
plane_sv *= 4294967296.f;
|
|
||||||
|
|
||||||
if (MirrorFlags & RF_XFLIP)
|
|
||||||
{
|
|
||||||
plane_su[0] = -plane_su[0];
|
|
||||||
plane_sv[0] = -plane_sv[0];
|
|
||||||
plane_sz[0] = -plane_sz[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
planelightfloat = (r_TiltVisibility * lxscale * lyscale) / (fabs(pl->height.ZatPoint(ViewPos) - ViewPos.Z)) / 65536.f;
|
|
||||||
|
|
||||||
if (pl->height.fC() > 0)
|
|
||||||
planelightfloat = -planelightfloat;
|
|
||||||
|
|
||||||
if (fixedlightlev >= 0)
|
|
||||||
{
|
|
||||||
R_SetDSColorMapLight(basecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
|
||||||
plane_shade = false;
|
|
||||||
}
|
|
||||||
else if (fixedcolormap)
|
|
||||||
{
|
|
||||||
R_SetDSColorMapLight(fixedcolormap, 0, 0);
|
|
||||||
plane_shade = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
R_SetDSColorMapLight(basecolormap, 0, 0);
|
|
||||||
plane_shade = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hack in support for 1 x Z and Z x 1 texture sizes
|
|
||||||
if (ds_ybits == 0)
|
|
||||||
{
|
|
||||||
plane_sv[2] = plane_sv[1] = plane_sv[0] = 0;
|
|
||||||
}
|
|
||||||
if (ds_xbits == 0)
|
|
||||||
{
|
|
||||||
plane_su[2] = plane_su[1] = plane_su[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
R_MapVisPlane (pl, R_MapTiltedPlane);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// R_MapVisPlane
|
// R_MapVisPlane
|
||||||
|
@ -1113,7 +677,7 @@ void R_DrawTiltedPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1))
|
void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1, int x2), void(*stepfunc)())
|
||||||
{
|
{
|
||||||
int x = pl->right - 1;
|
int x = pl->right - 1;
|
||||||
int t2 = pl->top[x];
|
int t2 = pl->top[x];
|
||||||
|
@ -1137,12 +701,16 @@ void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1))
|
||||||
stop = MIN (t1, b2);
|
stop = MIN (t1, b2);
|
||||||
while (t2 < stop)
|
while (t2 < stop)
|
||||||
{
|
{
|
||||||
mapfunc (t2++, xr);
|
int y = t2++;
|
||||||
|
int x2 = spanend[y];
|
||||||
|
mapfunc (y, xr, x2);
|
||||||
}
|
}
|
||||||
stop = MAX (b1, t2);
|
stop = MAX (b1, t2);
|
||||||
while (b2 > stop)
|
while (b2 > stop)
|
||||||
{
|
{
|
||||||
mapfunc (--b2, xr);
|
int y = --b2;
|
||||||
|
int x2 = spanend[y];
|
||||||
|
mapfunc (y, xr, x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark any spans that have just opened
|
// Mark any spans that have just opened
|
||||||
|
@ -1159,13 +727,16 @@ void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1))
|
||||||
|
|
||||||
t2 = pl->top[x];
|
t2 = pl->top[x];
|
||||||
b2 = pl->bottom[x];
|
b2 = pl->bottom[x];
|
||||||
basexfrac -= xstepscale;
|
|
||||||
baseyfrac -= ystepscale;
|
if (stepfunc)
|
||||||
|
stepfunc();
|
||||||
}
|
}
|
||||||
// Draw any spans that are still open
|
// Draw any spans that are still open
|
||||||
while (t2 < b2)
|
while (t2 < b2)
|
||||||
{
|
{
|
||||||
mapfunc (--b2, pl->left);
|
int y = --b2;
|
||||||
|
int x2 = spanend[y];
|
||||||
|
mapfunc (y, pl->left, x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
ds_light_list = nullptr;
|
ds_light_list = nullptr;
|
||||||
|
|
|
@ -36,20 +36,13 @@ extern planefunction_t ceilingfunc_t;
|
||||||
extern short floorclip[MAXWIDTH];
|
extern short floorclip[MAXWIDTH];
|
||||||
extern short ceilingclip[MAXWIDTH];
|
extern short ceilingclip[MAXWIDTH];
|
||||||
|
|
||||||
extern float yslope[MAXHEIGHT];
|
|
||||||
|
|
||||||
void R_ClearPlanes (bool fullclear);
|
void R_ClearPlanes (bool fullclear);
|
||||||
|
|
||||||
void R_AddPlaneLights(visplane_t *plane, FLightNode *light_head);
|
void R_AddPlaneLights(visplane_t *plane, FLightNode *light_head);
|
||||||
|
|
||||||
int R_DrawPlanes ();
|
int R_DrawPlanes ();
|
||||||
void R_DrawSinglePlane(visplane_t *pl, fixed_t alpha, bool additive, bool masked);
|
void R_DrawSinglePlane(visplane_t *pl, fixed_t alpha, bool additive, bool masked);
|
||||||
void R_DrawNormalPlane (visplane_t *pl, double xscale, double yscale, fixed_t alpha, bool additive, bool masked);
|
void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1, int x2), void (*stepfunc)());
|
||||||
void R_DrawTiltedPlane (visplane_t *pl, double xscale, double yscale, fixed_t alpha, bool additive, bool masked);
|
|
||||||
void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1));
|
|
||||||
|
|
||||||
void R_MapTiltedPlane(int y, int x1);
|
|
||||||
void R_MapColoredPlane(int y, int x1);
|
|
||||||
|
|
||||||
void R_DrawFogBoundary(int x1, int x2, short *uclip, short *dclip);
|
void R_DrawFogBoundary(int x1, int x2, short *uclip, short *dclip);
|
||||||
|
|
||||||
|
|
183
src/swrenderer/scene/r_slopeplane.cpp
Normal file
183
src/swrenderer/scene/r_slopeplane.cpp
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <float.h>
|
||||||
|
#include "templates.h"
|
||||||
|
#include "i_system.h"
|
||||||
|
#include "w_wad.h"
|
||||||
|
#include "doomdef.h"
|
||||||
|
#include "doomstat.h"
|
||||||
|
#include "swrenderer/r_main.h"
|
||||||
|
#include "swrenderer/scene/r_things.h"
|
||||||
|
#include "r_sky.h"
|
||||||
|
#include "stats.h"
|
||||||
|
#include "v_video.h"
|
||||||
|
#include "a_sharedglobal.h"
|
||||||
|
#include "c_console.h"
|
||||||
|
#include "cmdlib.h"
|
||||||
|
#include "d_net.h"
|
||||||
|
#include "g_level.h"
|
||||||
|
#include "r_bsp.h"
|
||||||
|
#include "r_slopeplane.h"
|
||||||
|
#include "r_segs.h"
|
||||||
|
#include "r_3dfloors.h"
|
||||||
|
#include "v_palette.h"
|
||||||
|
#include "r_data/colormaps.h"
|
||||||
|
#include "swrenderer/drawers/r_draw_rgba.h"
|
||||||
|
#include "gl/dynlights/gl_dynlight.h"
|
||||||
|
#include "r_walldraw.h"
|
||||||
|
#include "r_clip_segment.h"
|
||||||
|
#include "r_draw_segment.h"
|
||||||
|
#include "r_portal.h"
|
||||||
|
#include "r_plane.h"
|
||||||
|
#include "swrenderer/r_memory.h"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(disable:4244)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace swrenderer
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
FVector3 plane_sz, plane_su, plane_sv;
|
||||||
|
float planelightfloat;
|
||||||
|
bool plane_shade;
|
||||||
|
int planeshade;
|
||||||
|
fixed_t pviewx, pviewy;
|
||||||
|
fixed_t xscale, yscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_DrawTiltedPlane(visplane_t *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked)
|
||||||
|
{
|
||||||
|
using namespace drawerargs;
|
||||||
|
|
||||||
|
static const float ifloatpow2[16] =
|
||||||
|
{
|
||||||
|
// ifloatpow2[i] = 1 / (1 << i)
|
||||||
|
64.f, 32.f, 16.f, 8.f, 4.f, 2.f, 1.f, 0.5f,
|
||||||
|
0.25f, 0.125f, 0.0625f, 0.03125f, 0.015625f, 0.0078125f,
|
||||||
|
0.00390625f, 0.001953125f
|
||||||
|
/*, 0.0009765625f, 0.00048828125f, 0.000244140625f,
|
||||||
|
1.220703125e-4f, 6.103515625e-5, 3.0517578125e-5*/
|
||||||
|
};
|
||||||
|
double lxscale, lyscale;
|
||||||
|
double xscale, yscale;
|
||||||
|
FVector3 p, m, n;
|
||||||
|
double ang, planeang, cosine, sine;
|
||||||
|
double zeroheight;
|
||||||
|
|
||||||
|
if (alpha <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lxscale = _xscale * ifloatpow2[ds_xbits];
|
||||||
|
lyscale = _yscale * ifloatpow2[ds_ybits];
|
||||||
|
xscale = 64.f / lxscale;
|
||||||
|
yscale = 64.f / lyscale;
|
||||||
|
zeroheight = pl->height.ZatPoint(ViewPos);
|
||||||
|
|
||||||
|
pviewx = xs_ToFixed(32 - ds_xbits, pl->xform.xOffs * pl->xform.xScale);
|
||||||
|
pviewy = xs_ToFixed(32 - ds_ybits, pl->xform.yOffs * pl->xform.yScale);
|
||||||
|
planeang = (pl->xform.Angle + pl->xform.baseAngle).Radians();
|
||||||
|
|
||||||
|
// p is the texture origin in view space
|
||||||
|
// Don't add in the offsets at this stage, because doing so can result in
|
||||||
|
// errors if the flat is rotated.
|
||||||
|
ang = M_PI * 3 / 2 - ViewAngle.Radians();
|
||||||
|
cosine = cos(ang), sine = sin(ang);
|
||||||
|
p[0] = ViewPos.X * cosine - ViewPos.Y * sine;
|
||||||
|
p[2] = ViewPos.X * sine + ViewPos.Y * cosine;
|
||||||
|
p[1] = pl->height.ZatPoint(0.0, 0.0) - ViewPos.Z;
|
||||||
|
|
||||||
|
// m is the v direction vector in view space
|
||||||
|
ang = ang - M_PI / 2 - planeang;
|
||||||
|
cosine = cos(ang), sine = sin(ang);
|
||||||
|
m[0] = yscale * cosine;
|
||||||
|
m[2] = yscale * sine;
|
||||||
|
// m[1] = pl->height.ZatPointF (0, iyscale) - pl->height.ZatPointF (0,0));
|
||||||
|
// VectorScale2 (m, 64.f/VectorLength(m));
|
||||||
|
|
||||||
|
// n is the u direction vector in view space
|
||||||
|
#if 0
|
||||||
|
//let's use the sin/cosine we already know instead of computing new ones
|
||||||
|
ang += M_PI / 2
|
||||||
|
n[0] = -xscale * cos(ang);
|
||||||
|
n[2] = -xscale * sin(ang);
|
||||||
|
#else
|
||||||
|
n[0] = xscale * sine;
|
||||||
|
n[2] = -xscale * cosine;
|
||||||
|
#endif
|
||||||
|
// n[1] = pl->height.ZatPointF (ixscale, 0) - pl->height.ZatPointF (0,0));
|
||||||
|
// VectorScale2 (n, 64.f/VectorLength(n));
|
||||||
|
|
||||||
|
// This code keeps the texture coordinates constant across the x,y plane no matter
|
||||||
|
// how much you slope the surface. Use the commented-out code above instead to keep
|
||||||
|
// the textures a constant size across the surface's plane instead.
|
||||||
|
cosine = cos(planeang), sine = sin(planeang);
|
||||||
|
m[1] = pl->height.ZatPoint(ViewPos.X + yscale * sine, ViewPos.Y + yscale * cosine) - zeroheight;
|
||||||
|
n[1] = -(pl->height.ZatPoint(ViewPos.X - xscale * cosine, ViewPos.Y + xscale * sine) - zeroheight);
|
||||||
|
|
||||||
|
plane_su = p ^ m;
|
||||||
|
plane_sv = p ^ n;
|
||||||
|
plane_sz = m ^ n;
|
||||||
|
|
||||||
|
plane_su.Z *= FocalLengthX;
|
||||||
|
plane_sv.Z *= FocalLengthX;
|
||||||
|
plane_sz.Z *= FocalLengthX;
|
||||||
|
|
||||||
|
plane_su.Y *= IYaspectMul;
|
||||||
|
plane_sv.Y *= IYaspectMul;
|
||||||
|
plane_sz.Y *= IYaspectMul;
|
||||||
|
|
||||||
|
// Premultiply the texture vectors with the scale factors
|
||||||
|
plane_su *= 4294967296.f;
|
||||||
|
plane_sv *= 4294967296.f;
|
||||||
|
|
||||||
|
if (MirrorFlags & RF_XFLIP)
|
||||||
|
{
|
||||||
|
plane_su[0] = -plane_su[0];
|
||||||
|
plane_sv[0] = -plane_sv[0];
|
||||||
|
plane_sz[0] = -plane_sz[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
planelightfloat = (r_TiltVisibility * lxscale * lyscale) / (fabs(pl->height.ZatPoint(ViewPos) - ViewPos.Z)) / 65536.f;
|
||||||
|
|
||||||
|
if (pl->height.fC() > 0)
|
||||||
|
planelightfloat = -planelightfloat;
|
||||||
|
|
||||||
|
if (fixedlightlev >= 0)
|
||||||
|
{
|
||||||
|
R_SetDSColorMapLight(basecolormap, 0, FIXEDLIGHT2SHADE(fixedlightlev));
|
||||||
|
plane_shade = false;
|
||||||
|
}
|
||||||
|
else if (fixedcolormap)
|
||||||
|
{
|
||||||
|
R_SetDSColorMapLight(fixedcolormap, 0, 0);
|
||||||
|
plane_shade = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
R_SetDSColorMapLight(basecolormap, 0, 0);
|
||||||
|
plane_shade = true;
|
||||||
|
planeshade = LIGHT2SHADE(pl->lightlevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hack in support for 1 x Z and Z x 1 texture sizes
|
||||||
|
if (ds_ybits == 0)
|
||||||
|
{
|
||||||
|
plane_sv[2] = plane_sv[1] = plane_sv[0] = 0;
|
||||||
|
}
|
||||||
|
if (ds_xbits == 0)
|
||||||
|
{
|
||||||
|
plane_su[2] = plane_su[1] = plane_su[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
R_MapVisPlane(pl, R_MapTiltedPlane, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_MapTiltedPlane(int y, int x1, int x2)
|
||||||
|
{
|
||||||
|
R_Drawers()->DrawTiltedSpan(y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy);
|
||||||
|
}
|
||||||
|
}
|
10
src/swrenderer/scene/r_slopeplane.h
Normal file
10
src/swrenderer/scene/r_slopeplane.h
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "r_visible_plane.h"
|
||||||
|
|
||||||
|
namespace swrenderer
|
||||||
|
{
|
||||||
|
void R_DrawTiltedPlane(visplane_t *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked);
|
||||||
|
void R_MapTiltedPlane(int y, int x1, int x2);
|
||||||
|
}
|
|
@ -82,9 +82,6 @@ int CleanWidth, CleanHeight;
|
||||||
// Above minus 1 (or 1, if they are already 1)
|
// Above minus 1 (or 1, if they are already 1)
|
||||||
int CleanXfac_1, CleanYfac_1, CleanWidth_1, CleanHeight_1;
|
int CleanXfac_1, CleanYfac_1, CleanWidth_1, CleanHeight_1;
|
||||||
|
|
||||||
// FillSimplePoly uses this
|
|
||||||
extern "C" short spanend[MAXHEIGHT];
|
|
||||||
|
|
||||||
CVAR (Bool, hud_scale, true, CVAR_ARCHIVE);
|
CVAR (Bool, hud_scale, true, CVAR_ARCHIVE);
|
||||||
|
|
||||||
// For routines that take RGB colors, cache the previous lookup in case there
|
// For routines that take RGB colors, cache the previous lookup in case there
|
||||||
|
@ -1406,6 +1403,7 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Travel down the right edge and create an outline of that edge.
|
// Travel down the right edge and create an outline of that edge.
|
||||||
|
static short spanend[MAXHEIGHT];
|
||||||
pt1 = toppt;
|
pt1 = toppt;
|
||||||
pt2 = toppt + 1; if (pt2 > npoints) pt2 = 0;
|
pt2 = toppt + 1; if (pt2 > npoints) pt2 = 0;
|
||||||
y1 = xs_RoundToInt(points[pt1].Y + 0.5f);
|
y1 = xs_RoundToInt(points[pt1].Y + 0.5f);
|
||||||
|
|
Loading…
Reference in a new issue