From 2f96dcc1a80011024db1cdba7749bd949e7c1c05 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 31 Dec 2016 12:04:23 +0100 Subject: [PATCH] Move fog boundary drawing to r_fogboundary --- src/CMakeLists.txt | 1 + src/swrenderer/scene/r_fogboundary.cpp | 146 +++++++++++++++++++++++++ src/swrenderer/scene/r_fogboundary.h | 10 ++ src/swrenderer/scene/r_plane.cpp | 100 ----------------- src/swrenderer/scene/r_plane.h | 2 - src/swrenderer/scene/r_segs.cpp | 1 + 6 files changed, 158 insertions(+), 102 deletions(-) create mode 100644 src/swrenderer/scene/r_fogboundary.cpp create mode 100644 src/swrenderer/scene/r_fogboundary.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f59bc0fce3..8c1d559ded 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -834,6 +834,7 @@ set( FASTMATH_PCH_SOURCES swrenderer/scene/r_skyplane.cpp swrenderer/scene/r_flatplane.cpp swrenderer/scene/r_slopeplane.cpp + swrenderer/scene/r_fogboundary.cpp polyrenderer/poly_renderer.cpp polyrenderer/scene/poly_scene.cpp polyrenderer/scene/poly_portal.cpp diff --git a/src/swrenderer/scene/r_fogboundary.cpp b/src/swrenderer/scene/r_fogboundary.cpp new file mode 100644 index 0000000000..b8c395aaff --- /dev/null +++ b/src/swrenderer/scene/r_fogboundary.cpp @@ -0,0 +1,146 @@ + +#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 "r_bsp.h" +#include "r_fogboundary.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 + { + short spanend[MAXHEIGHT]; + } + + void R_DrawFogBoundary(int x1, int x2, short *uclip, short *dclip) + { + // This is essentially the same as R_MapVisPlane but with an extra step + // to create new horizontal spans whenever the light changes enough that + // we need to use a new colormap. + + double lightstep = rw_lightstep; + double light = rw_light + rw_lightstep*(x2 - x1 - 1); + int x = x2 - 1; + int t2 = uclip[x]; + int b2 = dclip[x]; + int rcolormap = GETPALOOKUP(light, wallshade); + int lcolormap; + uint8_t *basecolormapdata = basecolormap->Maps; + + if (b2 > t2) + { + fillshort(spanend + t2, b2 - t2, x); + } + + R_SetColorMapLight(basecolormap, (float)light, wallshade); + + uint8_t *fake_dc_colormap = basecolormap->Maps + (GETPALOOKUP(light, wallshade) << COLORMAPSHIFT); + + for (--x; x >= x1; --x) + { + int t1 = uclip[x]; + int b1 = dclip[x]; + const int xr = x + 1; + int stop; + + light -= rw_lightstep; + lcolormap = GETPALOOKUP(light, wallshade); + if (lcolormap != rcolormap) + { + if (t2 < b2 && rcolormap != 0) + { // Colormap 0 is always the identity map, so rendering it is + // just a waste of time. + R_DrawFogBoundarySection(t2, b2, xr); + } + if (t1 < t2) t2 = t1; + if (b1 > b2) b2 = b1; + if (t2 < b2) + { + fillshort(spanend + t2, b2 - t2, x); + } + rcolormap = lcolormap; + R_SetColorMapLight(basecolormap, (float)light, wallshade); + fake_dc_colormap = basecolormap->Maps + (GETPALOOKUP(light, wallshade) << COLORMAPSHIFT); + } + else + { + if (fake_dc_colormap != basecolormapdata) + { + stop = MIN(t1, b2); + while (t2 < stop) + { + int y = t2++; + R_Drawers()->DrawFogBoundaryLine(y, xr, spanend[y]); + } + stop = MAX(b1, t2); + while (b2 > stop) + { + int y = --b2; + R_Drawers()->DrawFogBoundaryLine(y, xr, spanend[y]); + } + } + else + { + t2 = MAX(t2, MIN(t1, b2)); + b2 = MIN(b2, MAX(b1, t2)); + } + + stop = MIN(t2, b1); + while (t1 < stop) + { + spanend[t1++] = x; + } + stop = MAX(b2, t2); + while (b1 > stop) + { + spanend[--b1] = x; + } + } + + t2 = uclip[x]; + b2 = dclip[x]; + } + if (t2 < b2 && rcolormap != 0) + { + R_DrawFogBoundarySection(t2, b2, x1); + } + } + + void R_DrawFogBoundarySection(int y, int y2, int x1) + { + for (; y < y2; ++y) + { + R_Drawers()->DrawFogBoundaryLine(y, x1, spanend[y]); + } + } +} diff --git a/src/swrenderer/scene/r_fogboundary.h b/src/swrenderer/scene/r_fogboundary.h new file mode 100644 index 0000000000..3885bb0da2 --- /dev/null +++ b/src/swrenderer/scene/r_fogboundary.h @@ -0,0 +1,10 @@ + +#pragma once + +#include "r_visible_plane.h" + +namespace swrenderer +{ + void R_DrawFogBoundary(int x1, int x2, short *uclip, short *dclip); + void R_DrawFogBoundarySection(int y, int y2, int x1); +} diff --git a/src/swrenderer/scene/r_plane.cpp b/src/swrenderer/scene/r_plane.cpp index ae8c466951..fff52a62be 100644 --- a/src/swrenderer/scene/r_plane.cpp +++ b/src/swrenderer/scene/r_plane.cpp @@ -115,109 +115,9 @@ short spanend[MAXHEIGHT]; void R_DrawSinglePlane (visplane_t *, fixed_t alpha, bool additive, bool masked); -void R_DrawFogBoundarySection(int y, int y2, int x1) -{ - for (; y < y2; ++y) - { - R_Drawers()->DrawFogBoundaryLine(y, x1, spanend[y]); - } -} //========================================================================== -void R_DrawFogBoundary(int x1, int x2, short *uclip, short *dclip) -{ - // This is essentially the same as R_MapVisPlane but with an extra step - // to create new horizontal spans whenever the light changes enough that - // we need to use a new colormap. - - double lightstep = rw_lightstep; - double light = rw_light + rw_lightstep*(x2 - x1 - 1); - int x = x2 - 1; - int t2 = uclip[x]; - int b2 = dclip[x]; - int rcolormap = GETPALOOKUP(light, wallshade); - int lcolormap; - uint8_t *basecolormapdata = basecolormap->Maps; - - if (b2 > t2) - { - fillshort(spanend + t2, b2 - t2, x); - } - - R_SetColorMapLight(basecolormap, (float)light, wallshade); - - uint8_t *fake_dc_colormap = basecolormap->Maps + (GETPALOOKUP(light, wallshade) << COLORMAPSHIFT); - - for (--x; x >= x1; --x) - { - int t1 = uclip[x]; - int b1 = dclip[x]; - const int xr = x + 1; - int stop; - - light -= rw_lightstep; - lcolormap = GETPALOOKUP(light, wallshade); - if (lcolormap != rcolormap) - { - if (t2 < b2 && rcolormap != 0) - { // Colormap 0 is always the identity map, so rendering it is - // just a waste of time. - R_DrawFogBoundarySection(t2, b2, xr); - } - if (t1 < t2) t2 = t1; - if (b1 > b2) b2 = b1; - if (t2 < b2) - { - fillshort(spanend + t2, b2 - t2, x); - } - rcolormap = lcolormap; - R_SetColorMapLight(basecolormap, (float)light, wallshade); - fake_dc_colormap = basecolormap->Maps + (GETPALOOKUP(light, wallshade) << COLORMAPSHIFT); - } - else - { - if (fake_dc_colormap != basecolormapdata) - { - stop = MIN(t1, b2); - while (t2 < stop) - { - int y = t2++; - R_Drawers()->DrawFogBoundaryLine(y, xr, spanend[y]); - } - stop = MAX(b1, t2); - while (b2 > stop) - { - int y = --b2; - R_Drawers()->DrawFogBoundaryLine(y, xr, spanend[y]); - } - } - else - { - t2 = MAX(t2, MIN(t1, b2)); - b2 = MIN(b2, MAX(b1, t2)); - } - - stop = MIN(t2, b1); - while (t1 < stop) - { - spanend[t1++] = x; - } - stop = MAX(b2, t2); - while (b1 > stop) - { - spanend[--b1] = x; - } - } - - t2 = uclip[x]; - b2 = dclip[x]; - } - if (t2 < b2 && rcolormap != 0) - { - R_DrawFogBoundarySection(t2, b2, x1); - } -} //========================================================================== diff --git a/src/swrenderer/scene/r_plane.h b/src/swrenderer/scene/r_plane.h index ad9e59b9b5..1bc18ec458 100644 --- a/src/swrenderer/scene/r_plane.h +++ b/src/swrenderer/scene/r_plane.h @@ -44,8 +44,6 @@ int R_DrawPlanes (); void R_DrawSinglePlane(visplane_t *pl, 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_DrawFogBoundary(int x1, int x2, short *uclip, short *dclip); - visplane_t *R_FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double alpha, bool additive, const FTransform &xform, int sky, FSectorPortal *portal); visplane_t *R_CheckPlane(visplane_t *pl, int start, int stop); diff --git a/src/swrenderer/scene/r_segs.cpp b/src/swrenderer/scene/r_segs.cpp index 315411b936..e28c2803dc 100644 --- a/src/swrenderer/scene/r_segs.cpp +++ b/src/swrenderer/scene/r_segs.cpp @@ -43,6 +43,7 @@ #include "g_level.h" #include "r_bsp.h" #include "r_plane.h" +#include "r_fogboundary.h" #include "r_segs.h" #include "r_3dfloors.h" #include "swrenderer/drawers/r_draw.h"