2018-06-19 21:52:01 +00:00
//
//---------------------------------------------------------------------------
//
// Copyright(C) 2000-2018 Christoph Oelckers
// All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/
//
//--------------------------------------------------------------------------
//
/*
* * gl_drawinfo . cpp
* * Basic scene draw info management class
* *
*/
# include "a_sharedglobal.h"
# include "r_utility.h"
# include "r_sky.h"
# include "d_player.h"
# include "g_levellocals.h"
# include "hw_fakeflat.h"
2018-06-23 21:02:56 +00:00
# include "hw_portal.h"
2018-10-25 20:45:55 +00:00
# include "hw_renderstate.h"
2018-10-28 17:49:29 +00:00
# include "hw_drawinfo.h"
2018-10-28 22:32:13 +00:00
# include "po_man.h"
2018-10-29 08:58:37 +00:00
# include "r_data/models/models.h"
2018-06-19 21:52:01 +00:00
# include "hwrenderer/utility/hw_clock.h"
# include "hwrenderer/utility/hw_cvars.h"
2018-10-28 17:49:29 +00:00
# include "hwrenderer/data/hw_viewpointbuffer.h"
2018-10-28 22:18:19 +00:00
# include "hwrenderer/data/flatvertices.h"
2018-10-28 21:58:35 +00:00
# include "hwrenderer/dynlights/hw_lightbuffer.h"
2018-10-29 08:58:37 +00:00
# include "hwrenderer/utility/hw_vrmodes.h"
2018-10-28 18:19:46 +00:00
# include "hw_clipper.h"
2018-06-19 21:52:01 +00:00
2018-06-22 19:32:38 +00:00
EXTERN_CVAR ( Float , r_visibility )
CVAR ( Bool , gl_bandedswlight , false , CVAR_ARCHIVE )
2018-10-28 21:58:35 +00:00
CVAR ( Bool , gl_sort_textures , false , CVAR_ARCHIVE | CVAR_GLOBALCONFIG )
2018-06-22 19:32:38 +00:00
2018-06-19 21:52:01 +00:00
sector_t * hw_FakeFlat ( sector_t * sec , sector_t * dest , area_t in_area , bool back ) ;
//==========================================================================
//
//
//
//==========================================================================
2018-10-28 18:39:31 +00:00
class FDrawInfoList
{
public :
TDeletingArray < HWDrawInfo * > mList ;
HWDrawInfo * GetNew ( ) ;
void Release ( HWDrawInfo * ) ;
} ;
FDrawInfoList di_list ;
//==========================================================================
//
// Try to reuse the lists as often as possible as they contain resources that
// are expensive to create and delete.
//
// Note: If multithreading gets used, this class needs synchronization.
//
//==========================================================================
HWDrawInfo * FDrawInfoList : : GetNew ( )
{
if ( mList . Size ( ) > 0 )
{
HWDrawInfo * di ;
mList . Pop ( di ) ;
return di ;
}
2018-10-29 11:54:10 +00:00
return new HWDrawInfo ;
2018-10-28 18:39:31 +00:00
}
void FDrawInfoList : : Release ( HWDrawInfo * di )
{
2018-10-29 11:54:10 +00:00
di - > DrawScene = nullptr ;
2018-10-28 18:39:31 +00:00
di - > ClearBuffers ( ) ;
mList . Push ( di ) ;
}
//==========================================================================
//
// Sets up a new drawinfo struct
//
//==========================================================================
2018-10-29 11:25:41 +00:00
HWDrawInfo * HWDrawInfo : : StartDrawInfo ( HWDrawInfo * parent , FRenderViewpoint & parentvp , HWViewpointUniforms * uniforms )
2018-10-28 18:39:31 +00:00
{
HWDrawInfo * di = di_list . GetNew ( ) ;
2018-10-29 11:54:10 +00:00
if ( parent ) di - > DrawScene = parent - > DrawScene ;
2018-10-28 18:39:31 +00:00
di - > StartScene ( parentvp , uniforms ) ;
return di ;
}
//==========================================================================
//
//
//
//==========================================================================
static Clipper staticClipper ; // Since all scenes are processed sequentially we only need one clipper.
static HWDrawInfo * gl_drawinfo ; // This is a linked list of all active DrawInfos and needed to free the memory arena after the last one goes out of scope.
2018-10-28 18:19:46 +00:00
void HWDrawInfo : : StartScene ( FRenderViewpoint & parentvp , HWViewpointUniforms * uniforms )
{
2018-10-28 18:39:31 +00:00
staticClipper . Clear ( ) ;
mClipper = & staticClipper ;
2018-10-28 18:19:46 +00:00
Viewpoint = parentvp ;
if ( uniforms )
{
VPUniforms = * uniforms ;
// The clip planes will never be inherited from the parent drawinfo.
VPUniforms . mClipLine . X = - 1000001.f ;
VPUniforms . mClipHeight = 0 ;
}
else VPUniforms . SetDefaults ( ) ;
mClipper - > SetViewpoint ( Viewpoint ) ;
ClearBuffers ( ) ;
for ( int i = 0 ; i < GLDL_TYPES ; i + + ) drawlists [ i ] . Reset ( ) ;
hudsprites . Clear ( ) ;
vpIndex = 0 ;
// Fullbright information needs to be propagated from the main view.
if ( outer ! = nullptr ) FullbrightFlags = outer - > FullbrightFlags ;
else FullbrightFlags = 0 ;
2018-10-28 18:39:31 +00:00
outer = gl_drawinfo ;
gl_drawinfo = this ;
2018-10-28 18:19:46 +00:00
}
2018-10-28 18:39:31 +00:00
//==========================================================================
//
//
//
//==========================================================================
HWDrawInfo * HWDrawInfo : : EndDrawInfo ( )
{
assert ( this = = gl_drawinfo ) ;
for ( int i = 0 ; i < GLDL_TYPES ; i + + ) drawlists [ i ] . Reset ( ) ;
gl_drawinfo = outer ;
di_list . Release ( this ) ;
if ( gl_drawinfo = = nullptr )
ResetRenderDataAllocator ( ) ;
return gl_drawinfo ;
}
//==========================================================================
//
//
//
//==========================================================================
2018-08-15 18:20:27 +00:00
void HWDrawInfo : : ClearBuffers ( )
{
2018-11-06 17:20:59 +00:00
otherFloorPlanes . Clear ( ) ;
otherCeilingPlanes . Clear ( ) ;
floodFloorSegs . Clear ( ) ;
floodCeilingSegs . Clear ( ) ;
2018-08-15 18:20:27 +00:00
2018-06-19 21:52:01 +00:00
// clear all the lists that might not have been cleared already
MissingUpperTextures . Clear ( ) ;
MissingLowerTextures . Clear ( ) ;
MissingUpperSegs . Clear ( ) ;
MissingLowerSegs . Clear ( ) ;
SubsectorHacks . Clear ( ) ;
2018-11-06 20:41:16 +00:00
//CeilingStacks.Clear();
//FloorStacks.Clear();
2018-06-19 21:52:01 +00:00
HandledSubsectors . Clear ( ) ;
spriteindex = 0 ;
CurrentMapSections . Resize ( level . NumMapSections ) ;
CurrentMapSections . Zero ( ) ;
2018-11-05 00:01:48 +00:00
section_renderflags . Resize ( level . sections . allSections . Size ( ) ) ;
2018-06-19 21:52:01 +00:00
ss_renderflags . Resize ( level . subsectors . Size ( ) ) ;
no_renderflags . Resize ( level . subsectors . Size ( ) ) ;
2018-11-05 00:01:48 +00:00
memset ( & section_renderflags [ 0 ] , 0 , level . sections . allSections . Size ( ) * sizeof ( section_renderflags [ 0 ] ) ) ;
2018-06-19 21:52:01 +00:00
memset ( & ss_renderflags [ 0 ] , 0 , level . subsectors . Size ( ) * sizeof ( ss_renderflags [ 0 ] ) ) ;
memset ( & no_renderflags [ 0 ] , 0 , level . nodes . Size ( ) * sizeof ( no_renderflags [ 0 ] ) ) ;
2018-10-21 11:53:50 +00:00
Decals [ 0 ] . Clear ( ) ;
Decals [ 1 ] . Clear ( ) ;
2018-06-19 21:52:01 +00:00
mClipPortal = nullptr ;
2018-06-23 11:51:19 +00:00
mCurrentPortal = nullptr ;
2018-06-19 21:52:01 +00:00
}
//==========================================================================
//
//
//
//==========================================================================
void HWDrawInfo : : UpdateCurrentMapSection ( )
{
const int mapsection = R_PointInSubsector ( Viewpoint . Pos ) - > mapsection ;
CurrentMapSections . Set ( mapsection ) ;
}
//-----------------------------------------------------------------------------
//
// Sets the area the camera is in
//
//-----------------------------------------------------------------------------
void HWDrawInfo : : SetViewArea ( )
{
auto & vp = Viewpoint ;
// The render_sector is better suited to represent the current position in GL
vp . sector = R_PointInSubsector ( vp . Pos ) - > render_sector ;
// Get the heightsec state from the render sector, not the current one!
if ( vp . sector - > GetHeightSec ( ) )
{
in_area = vp . Pos . Z < = vp . sector - > heightsec - > floorplane . ZatPoint ( vp . Pos ) ? area_below :
( vp . Pos . Z > vp . sector - > heightsec - > ceilingplane . ZatPoint ( vp . Pos ) & &
! ( vp . sector - > heightsec - > MoreFlags & SECMF_FAKEFLOORONLY ) ) ? area_above : area_normal ;
}
else
{
in_area = level . HasHeightSecs ? area_default : area_normal ; // depends on exposed lower sectors, if map contains heightsecs.
}
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
int HWDrawInfo : : SetFullbrightFlags ( player_t * player )
{
FullbrightFlags = 0 ;
// check for special colormaps
player_t * cplayer = player ? player - > camera - > player : nullptr ;
if ( cplayer )
{
int cm = CM_DEFAULT ;
if ( cplayer - > extralight = = INT_MIN )
{
cm = CM_FIRSTSPECIALCOLORMAP + INVERSECOLORMAP ;
Viewpoint . extralight = 0 ;
FullbrightFlags = Fullbright ;
// This does never set stealth vision.
}
else if ( cplayer - > fixedcolormap ! = NOFIXEDCOLORMAP )
{
cm = CM_FIRSTSPECIALCOLORMAP + cplayer - > fixedcolormap ;
FullbrightFlags = Fullbright ;
if ( gl_enhanced_nv_stealth > 2 ) FullbrightFlags | = StealthVision ;
}
else if ( cplayer - > fixedlightlevel ! = - 1 )
{
auto torchtype = PClass : : FindActor ( NAME_PowerTorch ) ;
auto litetype = PClass : : FindActor ( NAME_PowerLightAmp ) ;
for ( AInventory * in = cplayer - > mo - > Inventory ; in ; in = in - > Inventory )
{
//PalEntry color = in->CallGetBlend();
// Need special handling for light amplifiers
if ( in - > IsKindOf ( torchtype ) )
{
FullbrightFlags = Fullbright ;
if ( gl_enhanced_nv_stealth > 1 ) FullbrightFlags | = StealthVision ;
}
else if ( in - > IsKindOf ( litetype ) )
{
FullbrightFlags = Fullbright ;
if ( gl_enhanced_nightvision ) FullbrightFlags | = Nightvision ;
if ( gl_enhanced_nv_stealth > 0 ) FullbrightFlags | = StealthVision ;
}
}
}
return cm ;
}
else
{
return CM_DEFAULT ;
}
}
//-----------------------------------------------------------------------------
//
// R_FrustumAngle
//
//-----------------------------------------------------------------------------
angle_t HWDrawInfo : : FrustumAngle ( )
{
float tilt = fabs ( Viewpoint . HWAngles . Pitch . Degrees ) ;
// If the pitch is larger than this you can look all around at a FOV of 90°
if ( tilt > 46.0f ) return 0xffffffff ;
// ok, this is a gross hack that barely works...
// but at least it doesn't overestimate too much...
double floatangle = 2.0 + ( 45.0 + ( ( tilt / 1.9 ) ) ) * Viewpoint . FieldOfView . Degrees * 48.0 / AspectMultiplier ( r_viewwindow . WidescreenRatio ) / 90.0 ;
angle_t a1 = DAngle ( floatangle ) . BAMs ( ) ;
if ( a1 > = ANGLE_180 ) return 0xffffffff ;
return a1 ;
}
2018-06-23 11:25:23 +00:00
//-----------------------------------------------------------------------------
//
// Setup the modelview matrix
//
//-----------------------------------------------------------------------------
void HWDrawInfo : : SetViewMatrix ( const FRotator & angles , float vx , float vy , float vz , bool mirror , bool planemirror )
{
2018-06-23 18:57:02 +00:00
float mult = mirror ? - 1.f : 1.f ;
2018-06-23 11:25:23 +00:00
float planemult = planemirror ? - level . info - > pixelstretch : level . info - > pixelstretch ;
VPUniforms . mViewMatrix . loadIdentity ( ) ;
VPUniforms . mViewMatrix . rotate ( angles . Roll . Degrees , 0.0f , 0.0f , 1.0f ) ;
VPUniforms . mViewMatrix . rotate ( angles . Pitch . Degrees , 1.0f , 0.0f , 0.0f ) ;
VPUniforms . mViewMatrix . rotate ( angles . Yaw . Degrees , 0.0f , mult , 0.0f ) ;
VPUniforms . mViewMatrix . translate ( vx * mult , - vz * planemult , - vy ) ;
VPUniforms . mViewMatrix . scale ( - mult , planemult , 1 ) ;
}
//-----------------------------------------------------------------------------
//
// SetupView
// Setup the view rotation matrix for the given viewpoint
//
//-----------------------------------------------------------------------------
2018-10-28 21:20:51 +00:00
void HWDrawInfo : : SetupView ( FRenderState & state , float vx , float vy , float vz , bool mirror , bool planemirror )
2018-06-23 11:25:23 +00:00
{
auto & vp = Viewpoint ;
vp . SetViewAngle ( r_viewwindow ) ;
SetViewMatrix ( vp . HWAngles , vx , vy , vz , mirror , planemirror ) ;
SetCameraPos ( vp . Pos ) ;
2018-10-28 17:49:29 +00:00
VPUniforms . CalcDependencies ( ) ;
2018-10-28 21:20:51 +00:00
vpIndex = screen - > mViewpoints - > SetViewpoint ( state , & VPUniforms ) ;
2018-06-23 11:25:23 +00:00
}
2018-06-22 19:32:38 +00:00
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
2018-10-24 05:35:22 +00:00
HWPortal * HWDrawInfo : : FindPortal ( const void * src )
2018-06-23 21:02:56 +00:00
{
int i = Portals . Size ( ) - 1 ;
while ( i > = 0 & & Portals [ i ] & & Portals [ i ] - > GetSource ( ) ! = src ) i - - ;
return i > = 0 ? Portals [ i ] : nullptr ;
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
2018-06-22 19:32:38 +00:00
void HWViewpointUniforms : : SetDefaults ( )
{
mProjectionMatrix . loadIdentity ( ) ;
mViewMatrix . loadIdentity ( ) ;
mNormalViewMatrix . loadIdentity ( ) ;
mViewHeight = viewheight ;
2018-06-22 21:49:39 +00:00
mGlobVis = ( float ) R_GetGlobVis ( r_viewwindow , r_visibility ) / 32.f ;
2018-06-22 19:32:38 +00:00
mPalLightLevels = static_cast < int > ( gl_bandedswlight ) | ( static_cast < int > ( gl_fogmode ) < < 8 ) ;
2018-06-22 21:49:39 +00:00
mClipLine . X = - 10000000.0f ;
2018-09-29 11:23:40 +00:00
mShadowmapFilter = gl_shadowmap_filter ;
2018-06-22 19:32:38 +00:00
}
2018-10-21 11:53:50 +00:00
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
GLDecal * HWDrawInfo : : AddDecal ( bool onmirror )
{
auto decal = ( GLDecal * ) RenderDataAllocator . Alloc ( sizeof ( GLDecal ) ) ;
Decals [ onmirror ? 1 : 0 ] . Push ( decal ) ;
return decal ;
}
2018-10-28 22:32:13 +00:00
//-----------------------------------------------------------------------------
//
// CreateScene
//
// creates the draw lists for the current scene
//
//-----------------------------------------------------------------------------
void HWDrawInfo : : CreateScene ( )
{
const auto & vp = Viewpoint ;
angle_t a1 = FrustumAngle ( ) ;
mClipper - > SafeAddClipRangeRealAngles ( vp . Angles . Yaw . BAMs ( ) + a1 , vp . Angles . Yaw . BAMs ( ) - a1 ) ;
// reset the portal manager
screen - > mPortalState - > StartFrame ( ) ;
PO_LinkToSubsectors ( ) ;
ProcessAll . Clock ( ) ;
// clip the scene and fill the drawlists
screen - > mVertexData - > Map ( ) ;
screen - > mLights - > Map ( ) ;
2018-10-30 13:58:04 +00:00
RenderBSP ( level . HeadNode ( ) ) ;
2018-10-28 22:32:13 +00:00
// And now the crappy hacks that have to be done to avoid rendering anomalies.
// These cannot be multithreaded when the time comes because all these depend
// on the global 'validcount' variable.
HandleMissingTextures ( in_area ) ; // Missing upper/lower textures
HandleHackedSubsectors ( ) ; // open sector hacks for deep water
PrepareUnhandledMissingTextures ( ) ;
2018-11-06 19:31:44 +00:00
DispatchRenderHacks ( ) ;
2018-10-28 22:32:13 +00:00
screen - > mLights - > Unmap ( ) ;
screen - > mVertexData - > Unmap ( ) ;
ProcessAll . Unclock ( ) ;
}
2018-10-28 21:58:35 +00:00
//-----------------------------------------------------------------------------
//
// RenderScene
//
// Draws the current draw lists for the non GLSL renderer
//
//-----------------------------------------------------------------------------
void HWDrawInfo : : RenderScene ( FRenderState & state )
{
const auto & vp = Viewpoint ;
RenderAll . Clock ( ) ;
state . SetDepthMask ( true ) ;
2018-10-31 11:48:09 +00:00
screen - > mLights - > BindBase ( ) ;
2018-10-28 21:58:35 +00:00
state . EnableFog ( true ) ;
state . SetRenderStyle ( STYLE_Source ) ;
if ( gl_sort_textures )
{
drawlists [ GLDL_PLAINWALLS ] . SortWalls ( ) ;
drawlists [ GLDL_PLAINFLATS ] . SortFlats ( ) ;
drawlists [ GLDL_MASKEDWALLS ] . SortWalls ( ) ;
drawlists [ GLDL_MASKEDFLATS ] . SortFlats ( ) ;
drawlists [ GLDL_MASKEDWALLSOFS ] . SortWalls ( ) ;
}
// Part 1: solid geometry. This is set up so that there are no transparent parts
state . SetDepthFunc ( DF_Less ) ;
state . AlphaFunc ( Alpha_GEqual , 0.f ) ;
state . ClearDepthBias ( ) ;
state . EnableTexture ( gl_texture ) ;
state . EnableBrightmap ( true ) ;
drawlists [ GLDL_PLAINWALLS ] . DrawWalls ( this , state , false ) ;
drawlists [ GLDL_PLAINFLATS ] . DrawFlats ( this , state , false ) ;
// Part 2: masked geometry. This is set up so that only pixels with alpha>gl_mask_threshold will show
state . AlphaFunc ( Alpha_GEqual , gl_mask_threshold ) ;
drawlists [ GLDL_MASKEDWALLS ] . DrawWalls ( this , state , false ) ;
drawlists [ GLDL_MASKEDFLATS ] . DrawFlats ( this , state , false ) ;
// Part 3: masked geometry with polygon offset. This list is empty most of the time so only waste time on it when in use.
if ( drawlists [ GLDL_MASKEDWALLSOFS ] . Size ( ) > 0 )
{
state . SetDepthBias ( - 1 , - 128 ) ;
drawlists [ GLDL_MASKEDWALLSOFS ] . DrawWalls ( this , state , false ) ;
state . ClearDepthBias ( ) ;
}
drawlists [ GLDL_MODELS ] . Draw ( this , state , false ) ;
state . SetRenderStyle ( STYLE_Translucent ) ;
// Part 4: Draw decals (not a real pass)
state . SetDepthFunc ( DF_LEqual ) ;
DrawDecals ( state , Decals [ 0 ] ) ;
RenderAll . Unclock ( ) ;
}
//-----------------------------------------------------------------------------
//
// RenderTranslucent
//
//-----------------------------------------------------------------------------
void HWDrawInfo : : RenderTranslucent ( FRenderState & state )
{
RenderAll . Clock ( ) ;
// final pass: translucent stuff
state . AlphaFunc ( Alpha_GEqual , gl_mask_sprite_threshold ) ;
state . SetRenderStyle ( STYLE_Translucent ) ;
state . EnableBrightmap ( true ) ;
drawlists [ GLDL_TRANSLUCENTBORDER ] . Draw ( this , state , true ) ;
state . SetDepthMask ( false ) ;
drawlists [ GLDL_TRANSLUCENT ] . DrawSorted ( this , state ) ;
state . EnableBrightmap ( false ) ;
state . AlphaFunc ( Alpha_GEqual , 0.5f ) ;
state . SetDepthMask ( true ) ;
RenderAll . Unclock ( ) ;
}
2018-10-28 22:18:19 +00:00
//-----------------------------------------------------------------------------
//
// RenderTranslucent
//
//-----------------------------------------------------------------------------
void HWDrawInfo : : RenderPortal ( HWPortal * p , FRenderState & state , bool usestencil )
{
auto gp = static_cast < HWPortal * > ( p ) ;
gp - > SetupStencil ( this , state , usestencil ) ;
2018-10-29 11:25:41 +00:00
auto new_di = StartDrawInfo ( this , Viewpoint , & VPUniforms ) ;
2018-10-28 22:18:19 +00:00
new_di - > mCurrentPortal = gp ;
state . SetLightIndex ( - 1 ) ;
gp - > DrawContents ( new_di , state ) ;
new_di - > EndDrawInfo ( ) ;
2018-10-30 18:28:47 +00:00
state . SetVertexBuffer ( screen - > mVertexData ) ;
2018-10-28 22:18:19 +00:00
screen - > mViewpoints - > Bind ( state , vpIndex ) ;
gp - > RemoveStencil ( this , state , usestencil ) ;
}
2018-10-29 08:58:37 +00:00
//-----------------------------------------------------------------------------
//
// Draws player sprites and color blend
//
//-----------------------------------------------------------------------------
void HWDrawInfo : : EndDrawScene ( sector_t * viewsector , FRenderState & state )
{
state . EnableFog ( false ) ;
// [BB] HUD models need to be rendered here.
const bool renderHUDModel = IsHUDModelForPlayerAvailable ( players [ consoleplayer ] . camera - > player ) ;
if ( renderHUDModel )
{
// [BB] The HUD model should be drawn over everything else already drawn.
state . Clear ( CT_Depth ) ;
DrawPlayerSprites ( true , state ) ;
}
state . EnableStencil ( false ) ;
state . SetViewport ( screen - > mScreenViewport . left , screen - > mScreenViewport . top , screen - > mScreenViewport . width , screen - > mScreenViewport . height ) ;
// Restore standard rendering state
state . SetRenderStyle ( STYLE_Translucent ) ;
state . ResetColor ( ) ;
state . EnableTexture ( true ) ;
state . SetScissor ( 0 , 0 , - 1 , - 1 ) ;
}
void HWDrawInfo : : DrawEndScene2D ( sector_t * viewsector , FRenderState & state )
{
const bool renderHUDModel = IsHUDModelForPlayerAvailable ( players [ consoleplayer ] . camera - > player ) ;
auto vrmode = VRMode : : GetVRMode ( true ) ;
HWViewpointUniforms vp = VPUniforms ;
vp . mViewMatrix . loadIdentity ( ) ;
vp . mProjectionMatrix = vrmode - > GetHUDSpriteProjection ( ) ;
screen - > mViewpoints - > SetViewpoint ( state , & vp ) ;
state . EnableDepthTest ( false ) ;
state . EnableMultisampling ( false ) ;
DrawPlayerSprites ( false , state ) ;
state . SetSoftLightLevel ( - 1 ) ;
// Restore standard rendering state
state . SetRenderStyle ( STYLE_Translucent ) ;
state . ResetColor ( ) ;
state . EnableTexture ( true ) ;
state . SetScissor ( 0 , 0 , - 1 , - 1 ) ;
}
2018-10-29 09:21:52 +00:00
//-----------------------------------------------------------------------------
//
// sets 3D viewport and initial state
//
//-----------------------------------------------------------------------------
void HWDrawInfo : : Set3DViewport ( FRenderState & state )
{
// Always clear all buffers with scissor test disabled.
// This is faster on newer hardware because it allows the GPU to skip
// reading from slower memory where the full buffers are stored.
state . SetScissor ( 0 , 0 , - 1 , - 1 ) ;
state . Clear ( CT_Color | CT_Depth | CT_Stencil ) ;
const auto & bounds = screen - > mSceneViewport ;
state . SetViewport ( bounds . left , bounds . top , bounds . width , bounds . height ) ;
state . SetScissor ( bounds . left , bounds . top , bounds . width , bounds . height ) ;
state . EnableMultisampling ( true ) ;
state . EnableDepthTest ( true ) ;
state . EnableStencil ( true ) ;
state . SetStencil ( 0 , SOP_Keep , SF_AllOn ) ;
}
2018-10-29 11:25:41 +00:00
//-----------------------------------------------------------------------------
//
// R_RenderView - renders one view - either the screen or a camera texture
//
//-----------------------------------------------------------------------------
2018-10-29 11:54:10 +00:00
void HWDrawInfo : : ProcessScene ( bool toscreen , const std : : function < void ( HWDrawInfo * , int ) > & drawScene )
2018-10-29 11:25:41 +00:00
{
screen - > mPortalState - > BeginScene ( ) ;
int mapsection = R_PointInSubsector ( Viewpoint . Pos ) - > mapsection ;
CurrentMapSections . Set ( mapsection ) ;
2018-10-29 11:54:10 +00:00
DrawScene = drawScene ;
DrawScene ( this , toscreen ? DM_MAINVIEW : DM_OFFSCREEN ) ;
2018-10-29 11:25:41 +00:00
}
2018-11-08 19:39:44 +00:00
//==========================================================================
//
//
//
//==========================================================================
void HWDrawInfo : : AddSubsectorToPortal ( FSectorPortalGroup * ptg , subsector_t * sub )
{
auto portal = FindPortal ( ptg ) ;
if ( ! portal )
{
2018-11-14 19:59:24 +00:00
portal = new HWSectorStackPortal ( screen - > mPortalState , ptg ) ;
2018-11-08 19:39:44 +00:00
Portals . Push ( portal ) ;
}
2018-11-14 19:59:24 +00:00
auto ptl = static_cast < HWSectorStackPortal * > ( portal ) ;
2018-11-08 19:39:44 +00:00
ptl - > AddSubsector ( sub ) ;
}