2017-01-03 06:17:54 +00:00
//
// Copyright (C) 1993-1996 by id Software, Inc.
//
// This source is available for distribution and/or modification
// only under the terms of the DOOM Source Code License as
// published by id Software. All rights reserved.
//
// The source is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
// for more details.
//
2016-12-30 05:08:47 +00:00
# include <stdlib.h>
# include <math.h>
# include "templates.h"
# include "doomdef.h"
# include "d_net.h"
# include "doomstat.h"
# include "m_random.h"
# include "m_bbox.h"
# include "r_portal.h"
# include "r_sky.h"
# include "st_stuff.h"
# include "c_cvars.h"
# include "c_dispatch.h"
# include "v_video.h"
# include "stats.h"
# include "i_video.h"
# include "i_system.h"
# include "a_sharedglobal.h"
# include "r_data/r_translate.h"
# include "p_3dmidtex.h"
# include "r_data/r_interpolate.h"
# include "v_palette.h"
# include "po_man.h"
# include "p_effect.h"
# include "st_start.h"
# include "v_font.h"
# include "r_data/colormaps.h"
# include "p_maputl.h"
# include "p_setup.h"
# include "version.h"
# include "r_utility.h"
# include "r_3dfloors.h"
2017-01-16 05:03:21 +00:00
# include "g_levellocals.h"
2016-12-31 13:45:41 +00:00
# include "swrenderer/drawers/r_draw_rgba.h"
# include "swrenderer/segments/r_clipsegment.h"
# include "swrenderer/segments/r_drawsegment.h"
# include "swrenderer/plane/r_visibleplane.h"
2017-01-11 22:27:35 +00:00
# include "swrenderer/plane/r_visibleplanelist.h"
2017-01-11 14:41:42 +00:00
# include "swrenderer/things/r_visiblesprite.h"
2017-01-11 19:42:39 +00:00
# include "swrenderer/scene/r_opaque_pass.h"
# include "swrenderer/scene/r_translucent_pass.h"
2017-01-12 15:21:46 +00:00
# include "swrenderer/scene/r_scene.h"
# include "swrenderer/scene/r_viewport.h"
# include "swrenderer/scene/r_light.h"
2016-12-30 05:08:47 +00:00
# include "swrenderer/r_memory.h"
CVAR ( Int , r_portal_recursions , 4 , CVAR_ARCHIVE )
CVAR ( Bool , r_highlight_portals , false , CVAR_ARCHIVE )
CVAR ( Bool , r_skyboxes , true , 0 )
// Avoid infinite recursion with stacked sectors by limiting them.
# define MAX_SKYBOX_PLANES 1000
namespace swrenderer
{
2017-01-05 03:55:26 +00:00
RenderPortal * RenderPortal : : Instance ( )
2016-12-30 05:08:47 +00:00
{
2017-01-05 03:55:26 +00:00
static RenderPortal renderportal ;
return & renderportal ;
2016-12-30 05:08:47 +00:00
}
// Draws any recorded sky boxes and then frees them.
//
// The process:
// 1. Move the camera to coincide with the SkyViewpoint.
// 2. Clear out the old planes. (They have already been drawn.)
// 3. Clear a window out of the ClipSegs just large enough for the plane.
// 4. Pretend the existing vissprites and drawsegs aren't there.
// 5. Create a drawseg at 0 distance to clip sprites to the visplane. It
// doesn't need to be associated with a line in the map, since there
// will never be any sprites in front of it.
// 6. Render the BSP, then planes, then masked stuff.
// 7. Restore the previous vissprites and drawsegs.
// 8. Repeat for any other sky boxes.
// 9. Put the camera back where it was to begin with.
//
2017-01-05 03:55:26 +00:00
void RenderPortal : : RenderPlanePortals ( )
2016-12-30 05:08:47 +00:00
{
numskyboxes = 0 ;
2017-01-11 22:08:24 +00:00
VisiblePlaneList * planes = VisiblePlaneList : : Instance ( ) ;
2017-01-26 07:01:44 +00:00
DrawSegmentList * drawseglist = DrawSegmentList : : Instance ( ) ;
2017-01-11 22:08:24 +00:00
2017-01-19 02:02:32 +00:00
if ( ! planes - > HasPortalPlanes ( ) )
2016-12-30 05:08:47 +00:00
return ;
2017-01-04 17:54:14 +00:00
Clip3DFloors : : Instance ( ) - > EnterSkybox ( ) ;
2016-12-30 05:08:47 +00:00
CurrentPortalInSkybox = true ;
int savedextralight = extralight ;
DVector3 savedpos = ViewPos ;
DAngle savedangle = ViewAngle ;
2017-01-26 07:01:44 +00:00
ptrdiff_t savedds_p = drawseglist - > ds_p - drawseglist - > drawsegs ;
size_t savedinteresting = drawseglist - > FirstInterestingDrawseg ;
2017-01-26 08:49:07 +00:00
double savedvisibility = LightVisibility : : Instance ( ) - > GetVisibility ( ) ;
2016-12-30 05:08:47 +00:00
AActor * savedcamera = camera ;
sector_t * savedsector = viewsector ;
2017-01-19 02:11:49 +00:00
for ( VisiblePlane * pl = planes - > PopFirstPortalPlane ( ) ; pl ! = nullptr ; pl = planes - > PopFirstPortalPlane ( ) )
2016-12-30 05:08:47 +00:00
{
if ( pl - > right < pl - > left | | ! r_skyboxes | | numskyboxes = = MAX_SKYBOX_PLANES | | pl - > portal = = nullptr )
{
2017-01-11 22:08:24 +00:00
pl - > Render ( OPAQUE , false , false ) ;
2016-12-30 05:08:47 +00:00
continue ;
}
numskyboxes + + ;
FSectorPortal * port = pl - > portal ;
switch ( port - > mType )
{
case PORTS_SKYVIEWPOINT :
{
// Don't let gun flashes brighten the sky box
2017-01-16 05:03:21 +00:00
AActor * sky = port - > mSkybox ;
2016-12-30 05:08:47 +00:00
extralight = 0 ;
2017-01-26 08:49:07 +00:00
LightVisibility : : Instance ( ) - > SetVisibility ( sky - > args [ 0 ] * 0.25f ) ;
2016-12-30 05:08:47 +00:00
ViewPos = sky - > InterpolatedPosition ( r_TicFracF ) ;
ViewAngle = savedangle + ( sky - > PrevAngles . Yaw + deltaangle ( sky - > PrevAngles . Yaw , sky - > Angles . Yaw ) * r_TicFracF ) ;
2017-01-05 03:55:26 +00:00
CopyStackedViewParameters ( ) ;
2016-12-30 05:08:47 +00:00
break ;
}
case PORTS_STACKEDSECTORTHING :
case PORTS_PORTAL :
case PORTS_LINKEDPORTAL :
extralight = pl - > extralight ;
2017-01-26 08:49:07 +00:00
LightVisibility : : Instance ( ) - > SetVisibility ( pl - > visibility ) ;
2016-12-30 05:08:47 +00:00
ViewPos . X = pl - > viewpos . X + port - > mDisplacement . X ;
ViewPos . Y = pl - > viewpos . Y + port - > mDisplacement . Y ;
ViewPos . Z = pl - > viewpos . Z ;
ViewAngle = pl - > viewangle ;
break ;
case PORTS_HORIZON :
case PORTS_PLANE :
// not implemented yet
default :
2017-01-11 22:08:24 +00:00
pl - > Render ( OPAQUE , false , false ) ;
2016-12-30 05:08:47 +00:00
numskyboxes - - ;
continue ;
}
port - > mFlags | = PORTSF_INSKYBOX ;
2017-01-16 05:03:21 +00:00
if ( port - > mPartner > 0 ) level . sectorPortals [ port - > mPartner ] . mFlags | = PORTSF_INSKYBOX ;
2016-12-30 05:08:47 +00:00
camera = nullptr ;
viewsector = port - > mDestination ;
assert ( viewsector ! = nullptr ) ;
R_SetViewAngle ( ) ;
validcount + + ; // Make sure we see all sprites
2017-01-19 02:19:31 +00:00
planes - > ClearKeepFakePlanes ( ) ;
2017-01-15 21:57:42 +00:00
RenderClipSegment : : Instance ( ) - > Clear ( pl - > left , pl - > right ) ;
2016-12-30 05:08:47 +00:00
WindowLeft = pl - > left ;
WindowRight = pl - > right ;
2017-01-11 19:42:39 +00:00
auto ceilingclip = RenderOpaquePass : : Instance ( ) - > ceilingclip ;
auto floorclip = RenderOpaquePass : : Instance ( ) - > floorclip ;
2017-01-19 02:02:32 +00:00
for ( int i = pl - > left ; i < pl - > right ; i + + )
2016-12-30 05:08:47 +00:00
{
if ( pl - > top [ i ] = = 0x7fff )
{
ceilingclip [ i ] = viewheight ;
floorclip [ i ] = - 1 ;
}
else
{
ceilingclip [ i ] = pl - > top [ i ] ;
floorclip [ i ] = pl - > bottom [ i ] ;
}
}
// Create a drawseg to clip sprites to the sky plane
2017-01-26 07:01:44 +00:00
DrawSegment * draw_segment = drawseglist - > Add ( ) ;
2016-12-30 05:08:47 +00:00
draw_segment - > CurrentPortalUniq = CurrentPortalUniq ;
draw_segment - > siz1 = INT_MAX ;
draw_segment - > siz2 = INT_MAX ;
draw_segment - > sz1 = 0 ;
draw_segment - > sz2 = 0 ;
draw_segment - > x1 = pl - > left ;
draw_segment - > x2 = pl - > right ;
draw_segment - > silhouette = SIL_BOTH ;
2017-01-15 21:21:21 +00:00
draw_segment - > sprbottomclip = RenderMemory : : AllocMemory < short > ( pl - > right - pl - > left ) ;
draw_segment - > sprtopclip = RenderMemory : : AllocMemory < short > ( pl - > right - pl - > left ) ;
draw_segment - > maskedtexturecol = nullptr ;
draw_segment - > swall = nullptr ;
2016-12-30 05:08:47 +00:00
draw_segment - > bFogBoundary = false ;
draw_segment - > curline = nullptr ;
draw_segment - > fake = 0 ;
2017-01-12 19:13:21 +00:00
draw_segment - > foggy = false ;
2017-01-15 21:21:21 +00:00
memcpy ( draw_segment - > sprbottomclip , floorclip + pl - > left , ( pl - > right - pl - > left ) * sizeof ( short ) ) ;
memcpy ( draw_segment - > sprtopclip , ceilingclip + pl - > left , ( pl - > right - pl - > left ) * sizeof ( short ) ) ;
2016-12-30 05:08:47 +00:00
2017-01-26 07:01:44 +00:00
drawseglist - > firstdrawseg = draw_segment ;
drawseglist - > FirstInterestingDrawseg = drawseglist - > InterestingDrawsegs . Size ( ) ;
2016-12-30 05:08:47 +00:00
2017-01-26 07:01:44 +00:00
interestingStack . Push ( drawseglist - > FirstInterestingDrawseg ) ;
ptrdiff_t diffnum = drawseglist - > firstdrawseg - drawseglist - > drawsegs ;
2016-12-30 05:08:47 +00:00
drawsegStack . Push ( diffnum ) ;
2017-01-16 02:46:05 +00:00
VisibleSpriteList : : Instance ( ) - > PushPortal ( ) ;
2016-12-30 05:08:47 +00:00
viewposStack . Push ( ViewPos ) ;
visplaneStack . Push ( pl ) ;
2017-01-11 19:42:39 +00:00
RenderOpaquePass : : Instance ( ) - > RenderScene ( ) ;
2017-01-04 17:54:14 +00:00
Clip3DFloors : : Instance ( ) - > ResetClip ( ) ; // reset clips (floor/ceiling)
2017-01-11 22:08:24 +00:00
planes - > Render ( ) ;
2016-12-30 05:08:47 +00:00
port - > mFlags & = ~ PORTSF_INSKYBOX ;
2017-01-16 05:03:21 +00:00
if ( port - > mPartner > 0 ) level . sectorPortals [ port - > mPartner ] . mFlags & = ~ PORTSF_INSKYBOX ;
2016-12-30 05:08:47 +00:00
}
// Draw all the masked textures in a second pass, in the reverse order they
// were added. This must be done separately from the previous step for the
// sake of nested skyboxes.
2017-01-26 07:01:44 +00:00
while ( interestingStack . Pop ( drawseglist - > FirstInterestingDrawseg ) )
2016-12-30 05:08:47 +00:00
{
ptrdiff_t pd = 0 ;
drawsegStack . Pop ( pd ) ;
2017-01-26 07:01:44 +00:00
drawseglist - > firstdrawseg = drawseglist - > drawsegs + pd ;
2016-12-30 05:08:47 +00:00
// Masked textures and planes need the view coordinates restored for proper positioning.
viewposStack . Pop ( ViewPos ) ;
2017-01-26 07:36:28 +00:00
RenderTranslucentPass : : Instance ( ) - > Render ( ) ;
2016-12-30 05:08:47 +00:00
2017-01-26 07:01:44 +00:00
drawseglist - > ds_p = drawseglist - > firstdrawseg ;
2017-01-16 02:46:05 +00:00
VisibleSpriteList : : Instance ( ) - > PopPortal ( ) ;
2016-12-30 05:08:47 +00:00
2017-01-19 02:11:49 +00:00
VisiblePlane * pl ;
2016-12-30 05:08:47 +00:00
visplaneStack . Pop ( pl ) ;
if ( pl - > Alpha > 0 & & pl - > picnum ! = skyflatnum )
{
2017-01-11 22:08:24 +00:00
pl - > Render ( pl - > Alpha , pl - > Additive , true ) ;
2016-12-30 05:08:47 +00:00
}
}
2017-01-26 07:01:44 +00:00
drawseglist - > firstdrawseg = drawseglist - > drawsegs ;
drawseglist - > ds_p = drawseglist - > drawsegs + savedds_p ;
drawseglist - > InterestingDrawsegs . Resize ( ( unsigned int ) drawseglist - > FirstInterestingDrawseg ) ;
drawseglist - > FirstInterestingDrawseg = savedinteresting ;
2016-12-30 05:08:47 +00:00
camera = savedcamera ;
viewsector = savedsector ;
ViewPos = savedpos ;
2017-01-26 08:49:07 +00:00
LightVisibility : : Instance ( ) - > SetVisibility ( savedvisibility ) ;
2016-12-30 05:08:47 +00:00
extralight = savedextralight ;
ViewAngle = savedangle ;
R_SetViewAngle ( ) ;
CurrentPortalInSkybox = false ;
2017-01-04 17:54:14 +00:00
Clip3DFloors : : Instance ( ) - > LeaveSkybox ( ) ;
2016-12-30 05:08:47 +00:00
2017-01-04 17:54:14 +00:00
if ( Clip3DFloors : : Instance ( ) - > fakeActive ) return ;
2016-12-30 05:08:47 +00:00
2017-01-19 02:02:32 +00:00
planes - > ClearPortalPlanes ( ) ;
2016-12-30 05:08:47 +00:00
}
2017-01-05 03:55:26 +00:00
void RenderPortal : : RenderLinePortals ( )
2016-12-30 05:08:47 +00:00
{
// [RH] Walk through mirrors
// [ZZ] Merged with portals
size_t lastportal = WallPortals . Size ( ) ;
for ( unsigned int i = 0 ; i < lastportal ; i + + )
{
2017-01-24 04:31:39 +00:00
RenderLinePortal ( WallPortals [ i ] , 0 ) ;
2016-12-30 05:08:47 +00:00
}
CurrentPortal = nullptr ;
CurrentPortalUniq = 0 ;
}
2017-01-05 03:55:26 +00:00
void RenderPortal : : RenderLinePortal ( PortalDrawseg * pds , int depth )
2016-12-30 05:08:47 +00:00
{
// [ZZ] check depth. fill portal with black if it's exceeding the visual recursion limit, and continue like nothing happened.
if ( depth > = r_portal_recursions )
{
BYTE color = ( BYTE ) BestColor ( ( DWORD * ) GPalette . BaseColors , 0 , 0 , 0 , 0 , 255 ) ;
int spacing = RenderTarget - > GetPitch ( ) ;
for ( int x = pds - > x1 ; x < pds - > x2 ; x + + )
{
if ( x < 0 | | x > = RenderTarget - > GetWidth ( ) )
continue ;
int Ytop = pds - > ceilingclip [ x - pds - > x1 ] ;
int Ybottom = pds - > floorclip [ x - pds - > x1 ] ;
if ( r_swtruecolor )
{
uint32_t * dest = ( uint32_t * ) RenderTarget - > GetBuffer ( ) + x + Ytop * spacing ;
uint32_t c = GPalette . BaseColors [ color ] . d ;
for ( int y = Ytop ; y < = Ybottom ; y + + )
{
* dest = c ;
dest + = spacing ;
}
}
else
{
BYTE * dest = RenderTarget - > GetBuffer ( ) + x + Ytop * spacing ;
for ( int y = Ytop ; y < = Ybottom ; y + + )
{
* dest = color ;
dest + = spacing ;
}
}
}
if ( r_highlight_portals )
2017-01-05 03:55:26 +00:00
RenderLinePortalHighlight ( pds ) ;
2016-12-30 05:08:47 +00:00
return ;
}
DAngle startang = ViewAngle ;
DVector3 startpos = ViewPos ;
DVector3 savedpath [ 2 ] = { ViewPath [ 0 ] , ViewPath [ 1 ] } ;
ActorRenderFlags savedvisibility = camera ? camera - > renderflags & RF_INVISIBLE : ActorRenderFlags : : FromInt ( 0 ) ;
CurrentPortalUniq + + ;
unsigned int portalsAtStart = WallPortals . Size ( ) ;
if ( pds - > mirror )
{
//vertex_t *v1 = ds->curline->v1;
vertex_t * v1 = pds - > src - > v1 ;
// Reflect the current view behind the mirror.
if ( pds - > src - > Delta ( ) . X = = 0 )
{ // vertical mirror
ViewPos . X = v1 - > fX ( ) - startpos . X + v1 - > fX ( ) ;
}
else if ( pds - > src - > Delta ( ) . Y = = 0 )
{ // horizontal mirror
ViewPos . Y = v1 - > fY ( ) - startpos . Y + v1 - > fY ( ) ;
}
else
{ // any mirror
vertex_t * v2 = pds - > src - > v2 ;
double dx = v2 - > fX ( ) - v1 - > fX ( ) ;
double dy = v2 - > fY ( ) - v1 - > fY ( ) ;
double x1 = v1 - > fX ( ) ;
double y1 = v1 - > fY ( ) ;
double x = startpos . X ;
double y = startpos . Y ;
// the above two cases catch len == 0
double r = ( ( x - x1 ) * dx + ( y - y1 ) * dy ) / ( dx * dx + dy * dy ) ;
ViewPos . X = ( x1 + r * dx ) * 2 - x ;
ViewPos . Y = ( y1 + r * dy ) * 2 - y ;
}
ViewAngle = pds - > src - > Delta ( ) . Angle ( ) * 2 - startang ;
}
else
{
P_TranslatePortalXY ( pds - > src , ViewPos . X , ViewPos . Y ) ;
P_TranslatePortalZ ( pds - > src , ViewPos . Z ) ;
P_TranslatePortalAngle ( pds - > src , ViewAngle ) ;
P_TranslatePortalXY ( pds - > src , ViewPath [ 0 ] . X , ViewPath [ 0 ] . Y ) ;
P_TranslatePortalXY ( pds - > src , ViewPath [ 1 ] . X , ViewPath [ 1 ] . Y ) ;
if ( ! r_showviewer & & camera & & P_PointOnLineSidePrecise ( ViewPath [ 0 ] , pds - > dst ) ! = P_PointOnLineSidePrecise ( ViewPath [ 1 ] , pds - > dst ) )
{
double distp = ( ViewPath [ 0 ] - ViewPath [ 1 ] ) . Length ( ) ;
if ( distp > EQUAL_EPSILON )
{
double dist1 = ( ViewPos - ViewPath [ 0 ] ) . Length ( ) ;
double dist2 = ( ViewPos - ViewPath [ 1 ] ) . Length ( ) ;
if ( dist1 + dist2 < distp + 1 )
{
camera - > renderflags | = RF_INVISIBLE ;
}
}
}
}
ViewSin = ViewAngle . Sin ( ) ;
ViewCos = ViewAngle . Cos ( ) ;
ViewTanSin = FocalTangent * ViewSin ;
ViewTanCos = FocalTangent * ViewCos ;
2017-01-05 03:55:26 +00:00
CopyStackedViewParameters ( ) ;
2016-12-30 05:08:47 +00:00
validcount + + ;
PortalDrawseg * prevpds = CurrentPortal ;
CurrentPortal = pds ;
2017-01-19 02:19:31 +00:00
VisiblePlaneList : : Instance ( ) - > ClearKeepFakePlanes ( ) ;
2017-01-15 21:57:42 +00:00
RenderClipSegment : : Instance ( ) - > Clear ( pds - > x1 , pds - > x2 ) ;
2016-12-30 05:08:47 +00:00
WindowLeft = pds - > x1 ;
WindowRight = pds - > x2 ;
// RF_XFLIP should be removed before calling the root function
int prevmf = MirrorFlags ;
if ( pds - > mirror )
{
if ( MirrorFlags & RF_XFLIP )
MirrorFlags & = ~ RF_XFLIP ;
else MirrorFlags | = RF_XFLIP ;
}
// some portals have height differences, account for this here
2017-01-04 17:54:14 +00:00
Clip3DFloors : : Instance ( ) - > EnterSkybox ( ) ; // push 3D floor height map
2016-12-30 05:08:47 +00:00
CurrentPortalInSkybox = false ; // first portal in a skybox should set this variable to false for proper clipping in skyboxes.
2017-01-04 14:39:47 +00:00
// first pass, set clipping
2017-01-11 19:42:39 +00:00
auto ceilingclip = RenderOpaquePass : : Instance ( ) - > ceilingclip ;
auto floorclip = RenderOpaquePass : : Instance ( ) - > floorclip ;
2016-12-30 05:08:47 +00:00
memcpy ( ceilingclip + pds - > x1 , & pds - > ceilingclip [ 0 ] , pds - > len * sizeof ( * ceilingclip ) ) ;
memcpy ( floorclip + pds - > x1 , & pds - > floorclip [ 0 ] , pds - > len * sizeof ( * floorclip ) ) ;
2017-01-11 19:42:39 +00:00
RenderOpaquePass : : Instance ( ) - > RenderScene ( ) ;
2017-01-04 17:54:14 +00:00
Clip3DFloors : : Instance ( ) - > ResetClip ( ) ; // reset clips (floor/ceiling)
2016-12-30 05:08:47 +00:00
if ( ! savedvisibility & & camera ) camera - > renderflags & = ~ RF_INVISIBLE ;
PlaneCycles . Clock ( ) ;
2017-01-11 22:08:24 +00:00
VisiblePlaneList : : Instance ( ) - > Render ( ) ;
2017-01-05 03:55:26 +00:00
RenderPlanePortals ( ) ;
2016-12-30 05:08:47 +00:00
PlaneCycles . Unclock ( ) ;
double vzp = ViewPos . Z ;
int prevuniq = CurrentPortalUniq ;
// depth check is in another place right now
unsigned int portalsAtEnd = WallPortals . Size ( ) ;
for ( ; portalsAtStart < portalsAtEnd ; portalsAtStart + + )
{
2017-01-24 04:31:39 +00:00
RenderLinePortal ( WallPortals [ portalsAtStart ] , depth + 1 ) ;
2016-12-30 05:08:47 +00:00
}
int prevuniq2 = CurrentPortalUniq ;
CurrentPortalUniq = prevuniq ;
NetUpdate ( ) ;
MaskedCycles . Clock ( ) ; // [ZZ] count sprites in portals/mirrors along with normal ones.
2017-01-26 07:36:28 +00:00
RenderTranslucentPass : : Instance ( ) - > Render ( ) ; // this is required since with portals there often will be cases when more than 80% of the view is inside a portal.
2016-12-30 05:08:47 +00:00
MaskedCycles . Unclock ( ) ;
NetUpdate ( ) ;
2017-01-04 17:54:14 +00:00
Clip3DFloors : : Instance ( ) - > LeaveSkybox ( ) ; // pop 3D floor height map
2016-12-30 05:08:47 +00:00
CurrentPortalUniq = prevuniq2 ;
// draw a red line around a portal if it's being highlighted
if ( r_highlight_portals )
2017-01-05 03:55:26 +00:00
RenderLinePortalHighlight ( pds ) ;
2016-12-30 05:08:47 +00:00
CurrentPortal = prevpds ;
MirrorFlags = prevmf ;
ViewAngle = startang ;
ViewPos = startpos ;
ViewPath [ 0 ] = savedpath [ 0 ] ;
ViewPath [ 1 ] = savedpath [ 1 ] ;
}
2017-01-05 03:55:26 +00:00
void RenderPortal : : RenderLinePortalHighlight ( PortalDrawseg * pds )
2016-12-30 05:08:47 +00:00
{
// [ZZ] NO OVERFLOW CHECKS HERE
// I believe it won't break. if it does, blame me. :(
if ( r_swtruecolor ) // Assuming this is just a debug function
return ;
BYTE color = ( BYTE ) BestColor ( ( DWORD * ) GPalette . BaseColors , 255 , 0 , 0 , 0 , 255 ) ;
BYTE * pixels = RenderTarget - > GetBuffer ( ) ;
// top edge
for ( int x = pds - > x1 ; x < pds - > x2 ; x + + )
{
if ( x < 0 | | x > = RenderTarget - > GetWidth ( ) )
continue ;
int p = x - pds - > x1 ;
int Ytop = pds - > ceilingclip [ p ] ;
int Ybottom = pds - > floorclip [ p ] ;
if ( x = = pds - > x1 | | x = = pds - > x2 - 1 )
{
RenderTarget - > DrawLine ( x , Ytop , x , Ybottom + 1 , color , 0 ) ;
continue ;
}
int YtopPrev = pds - > ceilingclip [ p - 1 ] ;
int YbottomPrev = pds - > floorclip [ p - 1 ] ;
if ( abs ( Ytop - YtopPrev ) > 1 )
RenderTarget - > DrawLine ( x , YtopPrev , x , Ytop , color , 0 ) ;
else * ( pixels + Ytop * RenderTarget - > GetPitch ( ) + x ) = color ;
if ( abs ( Ybottom - YbottomPrev ) > 1 )
RenderTarget - > DrawLine ( x , YbottomPrev , x , Ybottom , color , 0 ) ;
else * ( pixels + Ybottom * RenderTarget - > GetPitch ( ) + x ) = color ;
}
}
2017-01-05 03:55:26 +00:00
void RenderPortal : : CopyStackedViewParameters ( )
{
stacked_viewpos = ViewPos ;
stacked_angle = ViewAngle ;
stacked_extralight = extralight ;
2017-01-26 08:49:07 +00:00
stacked_visibility = LightVisibility : : Instance ( ) - > GetVisibility ( ) ;
2017-01-05 03:55:26 +00:00
}
void RenderPortal : : SetMainPortal ( )
{
WindowLeft = 0 ;
WindowRight = viewwidth ;
MirrorFlags = 0 ;
CurrentPortal = nullptr ;
CurrentPortalUniq = 0 ;
2017-01-24 04:31:39 +00:00
WallPortals . Clear ( ) ;
}
void RenderPortal : : AddLinePortal ( line_t * linedef , int x1 , int x2 , const short * topclip , const short * bottomclip )
{
WallPortals . Push ( RenderMemory : : NewObject < PortalDrawseg > ( linedef , x1 , x2 , topclip , bottomclip ) ) ;
2017-01-05 03:55:26 +00:00
}
2016-12-30 05:08:47 +00:00
}
ADD_STAT ( skyboxes )
{
FString out ;
2017-01-05 03:55:26 +00:00
out . Format ( " %d skybox planes " , swrenderer : : RenderPortal : : Instance ( ) - > numskyboxes ) ;
2016-12-30 05:08:47 +00:00
return out ;
}