#include #include #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 "swrenderer/scene/r_bsp.h" #include "r_slopeplane.h" #include "swrenderer/scene/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 "swrenderer/segments/r_clipsegment.h" #include "swrenderer/segments/r_drawsegment.h" #include "swrenderer/scene/r_portal.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); } }