2009-04-19 18:07:22 +00:00
#region = = = = = = = = = = = = = = = = = = Copyright ( c ) 2007 Pascal vd Heiden
/ *
* Copyright ( c ) 2007 Pascal vd Heiden , www . codeimp . com
* This program is released under GNU General Public License
*
* 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 General Public License for more details .
*
* /
#endregion
#region = = = = = = = = = = = = = = = = = = Namespaces
using System ;
using System.Collections.Generic ;
using System.Drawing ;
2022-01-04 19:17:12 +00:00
using System.Drawing.Drawing2D ;
2009-04-19 18:07:22 +00:00
using CodeImp.DoomBuilder.Data ;
2015-10-02 14:47:34 +00:00
using CodeImp.DoomBuilder.Geometry ;
2015-12-01 14:51:45 +00:00
using CodeImp.DoomBuilder.GZBuilder.Data ;
2023-06-29 18:37:47 +00:00
using CodeImp.DoomBuilder.GZBuilder.Models ;
2015-10-02 14:47:34 +00:00
using CodeImp.DoomBuilder.Map ;
using CodeImp.DoomBuilder.VisualModes ;
2018-02-03 20:31:34 +00:00
using CodeImp.DoomBuilder.GZBuilder ;
2022-01-04 19:17:12 +00:00
using ColorMap = System . Drawing . Imaging . ColorMap ;
2012-04-17 19:13:47 +00:00
2009-04-19 18:07:22 +00:00
#endregion
namespace CodeImp.DoomBuilder.Rendering
{
internal sealed class Renderer3D : Renderer , IRenderer3D
{
#region = = = = = = = = = = = = = = = = = = Constants
private const float PROJ_NEAR_PLANE = 1f ;
private const float FOG_RANGE = 0.9f ;
2020-01-03 01:22:33 +00:00
private const int MAX_DYNLIGHTS_PER_SURFACE = 64 ;
2016-01-11 13:00:52 +00:00
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Variables
// Matrices
private Matrix projection ;
private Matrix view3d ;
private Matrix billboard ;
private Matrix view2d ;
private Matrix world ;
private Vector3D cameraposition ;
2017-02-09 12:28:54 +00:00
private Vector3D cameravector ;
2019-08-14 10:36:33 +00:00
private ShaderName shaderpass ;
2019-08-16 11:38:53 +00:00
// Window size
private Size windowsize ;
2009-04-19 18:07:22 +00:00
// Frustum
private ProjectedFrustum2D frustum ;
// Thing cage
2013-09-11 09:47:53 +00:00
private bool renderthingcages ;
//mxd
2016-01-14 22:15:54 +00:00
private VisualVertexHandle vertexhandle ;
2013-09-11 09:47:53 +00:00
private int [ ] lightOffsets ;
2022-01-04 19:17:12 +00:00
private Data . ColorMap classicLightingColorMap = null ;
private Texture classicLightingColorMapTex = null ;
2019-12-30 23:08:17 +00:00
// Slope handle
private VisualSlopeHandle visualslopehandle ;
2009-04-19 18:07:22 +00:00
// Crosshair
private FlatVertex [ ] crosshairverts ;
private bool crosshairbusy ;
// Highlighting
private IVisualPickable highlighted ;
private float highlightglow ;
2009-05-05 21:13:50 +00:00
private float highlightglowinv ;
2009-07-07 14:52:39 +00:00
private bool showselection ;
private bool showhighlight ;
2009-04-19 18:07:22 +00:00
2015-09-27 21:09:14 +00:00
//mxd. Solid geometry to be rendered. Must be sorted by sector.
private Dictionary < ImageData , List < VisualGeometry > > solidgeo ;
2009-04-19 18:07:22 +00:00
2015-09-27 21:09:14 +00:00
//mxd. Masked geometry to be rendered. Must be sorted by sector.
private Dictionary < ImageData , List < VisualGeometry > > maskedgeo ;
2009-04-19 18:07:22 +00:00
2015-12-01 14:51:45 +00:00
//mxd. Translucent geometry to be rendered. Must be sorted by camera distance.
2015-09-27 21:09:14 +00:00
private List < VisualGeometry > translucentgeo ;
2016-01-11 13:00:52 +00:00
//mxd. Geometry to be rendered as skybox.
private List < VisualGeometry > skygeo ;
2015-09-27 21:09:14 +00:00
//mxd. Solid things to be rendered (currently(?) there won't be any). Must be sorted by sector.
private Dictionary < ImageData , List < VisualThing > > solidthings ;
//mxd. Masked things to be rendered. Must be sorted by sector.
private Dictionary < ImageData , List < VisualThing > > maskedthings ;
//mxd. Translucent things to be rendered. Must be sorted by camera distance.
private List < VisualThing > translucentthings ;
2015-12-01 14:51:45 +00:00
//mxd. Things with attached dynamic lights
private List < VisualThing > lightthings ;
//mxd. Things, which should be rendered as models
private Dictionary < ModelData , List < VisualThing > > maskedmodelthings ;
//mxd. Things, which should be rendered as translucent models
private List < VisualThing > translucentmodelthings ;
2015-09-27 21:09:14 +00:00
//mxd. All things. Used to render thing cages
private List < VisualThing > allthings ;
2013-03-18 13:52:27 +00:00
//mxd. Visual vertices
2015-10-02 14:47:34 +00:00
private List < VisualVertex > visualvertices ;
2019-12-30 23:08:17 +00:00
// Visual slope handles
2021-02-06 13:51:00 +00:00
private ICollection < VisualSlope > visualslopehandles ;
2019-12-30 23:08:17 +00:00
2015-10-02 14:47:34 +00:00
//mxd. Event lines
private List < Line3D > eventlines ;
2019-12-20 14:17:32 +00:00
// FPS-related
private int fps = 0 ;
private System . Diagnostics . Stopwatch fpsWatch ;
private TextLabel fpsLabel ;
2009-04-19 18:07:22 +00:00
2019-12-20 14:38:54 +00:00
#endregion
2009-04-19 18:07:22 +00:00
2019-12-20 14:38:54 +00:00
#region = = = = = = = = = = = = = = = = = = Properties
2009-04-19 18:07:22 +00:00
2019-12-20 14:38:54 +00:00
public ProjectedFrustum2D Frustum2D { get { return frustum ; } }
2009-04-19 18:07:22 +00:00
public bool DrawThingCages { get { return renderthingcages ; } set { renderthingcages = value ; } }
2009-07-07 14:52:39 +00:00
public bool ShowSelection { get { return showselection ; } set { showselection = value ; } }
public bool ShowHighlight { get { return showhighlight ; } set { showhighlight = value ; } }
2009-04-19 18:07:22 +00:00
2022-01-04 19:17:12 +00:00
protected bool UseIndexedTexture
{
get { return General . Settings . ClassicRendering & & ! fullbrightness ; }
}
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Constructor / Disposer
// Constructor
2019-08-09 21:22:16 +00:00
internal Renderer3D ( RenderDevice graphics ) : base ( graphics )
2009-04-19 18:07:22 +00:00
{
// Initialize
2017-08-27 05:09:28 +00:00
//CreateProjection(); // [ZZ] don't do undefined things once not even ready
2009-04-19 18:07:22 +00:00
CreateMatrices2D ( ) ;
renderthingcages = true ;
2009-07-07 14:52:39 +00:00
showselection = true ;
showhighlight = true ;
2015-10-02 14:47:34 +00:00
eventlines = new List < Line3D > ( ) ; //mxd
2009-04-19 18:07:22 +00:00
// Dummy frustum
frustum = new ProjectedFrustum2D ( new Vector2D ( ) , 0.0f , 0.0f , PROJ_NEAR_PLANE ,
2020-05-21 12:20:02 +00:00
General . Settings . ViewDistance , ( float ) Angle2D . DegToRad ( General . Settings . VisualFOV ) ) ;
2009-04-19 18:07:22 +00:00
2019-12-20 14:17:32 +00:00
fpsLabel = new TextLabel ( ) ;
fpsLabel . AlignX = TextAlignmentX . Left ;
fpsLabel . AlignY = TextAlignmentY . Top ;
fpsLabel . Text = "(FPS unavailable)" ;
fpsWatch = new System . Diagnostics . Stopwatch ( ) ;
2019-12-20 14:38:54 +00:00
// We have no destructor
GC . SuppressFinalize ( this ) ;
2009-04-19 18:07:22 +00:00
}
// Disposer
2016-02-01 22:04:00 +00:00
public override void Dispose ( )
2009-04-19 18:07:22 +00:00
{
// Not already disposed?
if ( ! isdisposed )
{
// Clean up
2016-01-14 22:15:54 +00:00
if ( vertexhandle ! = null ) vertexhandle . Dispose ( ) ; //mxd
2019-12-30 23:08:17 +00:00
if ( visualslopehandle ! = null ) visualslopehandle . Dispose ( ) ;
2009-04-19 18:07:22 +00:00
// Done
base . Dispose ( ) ;
}
}
#endregion
#region = = = = = = = = = = = = = = = = = = Management
// This is called before a device is reset
// (when resized or display adapter was changed)
public override void UnloadResource ( )
{
crosshairverts = null ;
}
// This is called resets when the device is reset
// (when resized or display adapter was changed)
public override void ReloadResource ( )
{
CreateMatrices2D ( ) ;
}
// This makes screen vertices for display
private void CreateCrosshairVerts ( Size texturesize )
{
// Determine coordinates
2014-02-21 14:42:12 +00:00
float width = windowsize . Width ;
float height = windowsize . Height ;
Added, Visual mode, GLDEFS, GLOOME: subtractive glow is now supported.
Changed, Visual mode: changed thing fog calculation logic. Should be closer to GZDoom now.
Fixed, GLDEFS parser: "height" texture parameter was not treated as optional.
Fixed, text lump parsers: in some cases incorrect line number was displayed in error and warning messages.
Fixed, Visual mode: glow effect was not applied to sectors with 3 sidedefs.
Fixed, Visual mode: in some cases glow effect was not updated when replacing textures.
Fixed, general interface: "Full Brightness" button state was not updated during map loading.
Fixed, Drag Linedefs/Vertices/Sectors/Things modes: positions of line length labels were not updated while panning the view.
Cosmetic: added a bunch of new icons.
Cosmetic: changed Visual mode crosshair.
2015-08-27 20:46:49 +00:00
RectangleF rect = new RectangleF ( ( float ) Math . Round ( ( width - texturesize . Width ) * 0.5f ) , ( float ) Math . Round ( ( height - texturesize . Height ) * 0.5f ) , texturesize . Width , texturesize . Height ) ;
2009-04-19 18:07:22 +00:00
// Make vertices
crosshairverts = new FlatVertex [ 4 ] ;
crosshairverts [ 0 ] . x = rect . Left ;
crosshairverts [ 0 ] . y = rect . Top ;
crosshairverts [ 0 ] . c = - 1 ;
crosshairverts [ 1 ] . x = rect . Right ;
crosshairverts [ 1 ] . y = rect . Top ;
crosshairverts [ 1 ] . c = - 1 ;
Added, Visual mode, GLDEFS, GLOOME: subtractive glow is now supported.
Changed, Visual mode: changed thing fog calculation logic. Should be closer to GZDoom now.
Fixed, GLDEFS parser: "height" texture parameter was not treated as optional.
Fixed, text lump parsers: in some cases incorrect line number was displayed in error and warning messages.
Fixed, Visual mode: glow effect was not applied to sectors with 3 sidedefs.
Fixed, Visual mode: in some cases glow effect was not updated when replacing textures.
Fixed, general interface: "Full Brightness" button state was not updated during map loading.
Fixed, Drag Linedefs/Vertices/Sectors/Things modes: positions of line length labels were not updated while panning the view.
Cosmetic: added a bunch of new icons.
Cosmetic: changed Visual mode crosshair.
2015-08-27 20:46:49 +00:00
crosshairverts [ 1 ] . u = 1.0f ;
2009-04-19 18:07:22 +00:00
crosshairverts [ 2 ] . x = rect . Left ;
crosshairverts [ 2 ] . y = rect . Bottom ;
crosshairverts [ 2 ] . c = - 1 ;
Added, Visual mode, GLDEFS, GLOOME: subtractive glow is now supported.
Changed, Visual mode: changed thing fog calculation logic. Should be closer to GZDoom now.
Fixed, GLDEFS parser: "height" texture parameter was not treated as optional.
Fixed, text lump parsers: in some cases incorrect line number was displayed in error and warning messages.
Fixed, Visual mode: glow effect was not applied to sectors with 3 sidedefs.
Fixed, Visual mode: in some cases glow effect was not updated when replacing textures.
Fixed, general interface: "Full Brightness" button state was not updated during map loading.
Fixed, Drag Linedefs/Vertices/Sectors/Things modes: positions of line length labels were not updated while panning the view.
Cosmetic: added a bunch of new icons.
Cosmetic: changed Visual mode crosshair.
2015-08-27 20:46:49 +00:00
crosshairverts [ 2 ] . v = 1.0f ;
2009-04-19 18:07:22 +00:00
crosshairverts [ 3 ] . x = rect . Right ;
crosshairverts [ 3 ] . y = rect . Bottom ;
crosshairverts [ 3 ] . c = - 1 ;
Added, Visual mode, GLDEFS, GLOOME: subtractive glow is now supported.
Changed, Visual mode: changed thing fog calculation logic. Should be closer to GZDoom now.
Fixed, GLDEFS parser: "height" texture parameter was not treated as optional.
Fixed, text lump parsers: in some cases incorrect line number was displayed in error and warning messages.
Fixed, Visual mode: glow effect was not applied to sectors with 3 sidedefs.
Fixed, Visual mode: in some cases glow effect was not updated when replacing textures.
Fixed, general interface: "Full Brightness" button state was not updated during map loading.
Fixed, Drag Linedefs/Vertices/Sectors/Things modes: positions of line length labels were not updated while panning the view.
Cosmetic: added a bunch of new icons.
Cosmetic: changed Visual mode crosshair.
2015-08-27 20:46:49 +00:00
crosshairverts [ 3 ] . u = 1.0f ;
crosshairverts [ 3 ] . v = 1.0f ;
2009-04-19 18:07:22 +00:00
}
#endregion
2009-05-04 06:13:56 +00:00
#region = = = = = = = = = = = = = = = = = = Resources
2009-04-19 18:07:22 +00:00
2014-09-16 08:51:27 +00:00
//mxd
internal void UpdateVertexHandle ( )
{
2016-01-14 22:15:54 +00:00
if ( vertexhandle ! = null )
{
vertexhandle . UnloadResource ( ) ;
vertexhandle . ReloadResource ( ) ;
}
2013-09-11 09:47:53 +00:00
}
2009-04-19 18:07:22 +00:00
2019-12-30 23:08:17 +00:00
internal void UpdateVisualSlopeHandle ( )
{
if ( visualslopehandle ! = null )
{
visualslopehandle . UnloadResource ( ) ;
visualslopehandle . ReloadResource ( ) ;
}
}
2009-04-19 18:07:22 +00:00
#endregion
2019-12-30 23:08:17 +00:00
2009-04-19 18:07:22 +00:00
#region = = = = = = = = = = = = = = = = = = Presentation
// This creates the projection
internal void CreateProjection ( )
{
// Calculate aspect
2024-02-24 21:09:57 +00:00
float screenheight = General . Map . Graphics . RenderTarget . ClientSize . Height * ( General . Settings . DOOMStretchView ? General . Map . Data . InvertedVerticalViewStretch : 1.0f ) ; //mxd
2014-09-20 18:34:06 +00:00
float aspect = General . Map . Graphics . RenderTarget . ClientSize . Width / screenheight ;
2009-04-19 18:07:22 +00:00
// The DirectX PerspectiveFovRH matrix method calculates the scaling in X and Y as follows:
// yscale = 1 / tan(fovY / 2)
// xscale = yscale / aspect
// The fov specified in the method is the FOV over Y, but we want the user to specify the FOV
// over X, so calculate what it would be over Y first;
2020-05-21 12:20:02 +00:00
float fov = ( float ) Angle2D . DegToRad ( General . Settings . VisualFOV ) ;
2009-04-19 18:07:22 +00:00
float reversefov = 1.0f / ( float ) Math . Tan ( fov / 2.0f ) ;
float reversefovy = reversefov * aspect ;
2019-08-22 21:28:26 +00:00
float fovy = ( float ) Math . Atan ( 1.0f / reversefovy ) ;
2009-04-19 18:07:22 +00:00
// Make the projection matrix
2019-08-15 12:49:49 +00:00
projection = Matrix . PerspectiveFov ( fovy , aspect , PROJ_NEAR_PLANE , General . Settings . ViewDistance ) ;
2022-09-03 11:07:16 +00:00
2022-09-13 17:45:27 +00:00
// We also need to re-create the 2D matrices, otherwise the corsshair will be distorted after the viewport is resized. See
// https://github.com/jewalky/UltimateDoomBuilder/issues/321
// and
// https://github.com/jewalky/UltimateDoomBuilder/issues/777
2022-09-03 11:07:16 +00:00
CreateMatrices2D ( ) ;
crosshairverts = null ;
2009-04-19 18:07:22 +00:00
}
// This creates matrices for a camera view
public void PositionAndLookAt ( Vector3D pos , Vector3D lookat )
{
// Calculate delta vector
cameraposition = pos ;
2017-02-09 12:28:54 +00:00
Vector3D delta = lookat - pos ;
cameravector = delta . GetNormal ( ) ;
2020-05-18 16:14:54 +00:00
double anglexy = delta . GetAngleXY ( ) ;
double anglez = delta . GetAngleZ ( ) ;
2009-04-19 18:07:22 +00:00
// Create frustum
2020-05-18 16:14:54 +00:00
frustum = new ProjectedFrustum2D ( pos , ( float ) anglexy , ( float ) anglez , PROJ_NEAR_PLANE ,
General . Settings . ViewDistance , ( float ) Angle2D . DegToRad ( General . Settings . VisualFOV ) ) ;
2019-08-15 12:49:49 +00:00
// Make the view matrix
2020-01-03 01:22:33 +00:00
view3d = Matrix . LookAt ( RenderDevice . V3 ( pos ) , RenderDevice . V3 ( lookat ) , new Vector3f ( 0f , 0f , 1f ) ) ;
2009-04-19 18:07:22 +00:00
// Make the billboard matrix
2020-05-18 16:14:54 +00:00
billboard = Matrix . RotationZ ( ( float ) ( anglexy + Angle2D . PI ) ) ;
2009-04-19 18:07:22 +00:00
}
2022-01-04 19:17:12 +00:00
// volte: Set the active colormap for classic lighting
public void SetClassicLightingColorMap ( Data . ColorMap colormap )
{
if ( colormap = = classicLightingColorMap )
{
return ;
}
classicLightingColorMap = colormap ;
if ( classicLightingColorMap = = null )
{
classicLightingColorMapTex = null ;
}
else
{
classicLightingColorMapTex = new Texture ( graphics , classicLightingColorMap . CreateBitmap ( ) ) ;
}
}
2009-04-19 18:07:22 +00:00
// This creates 2D view matrix
private void CreateMatrices2D ( )
{
windowsize = graphics . RenderTarget . ClientSize ;
2014-02-21 14:42:12 +00:00
Matrix scaling = Matrix . Scaling ( ( 1f / windowsize . Width ) * 2f , ( 1f / windowsize . Height ) * - 2f , 1f ) ;
2009-04-19 18:07:22 +00:00
Matrix translate = Matrix . Translation ( - ( float ) windowsize . Width * 0.5f , - ( float ) windowsize . Height * 0.5f , 0f ) ;
2015-10-02 14:47:34 +00:00
view2d = translate * scaling ;
2009-04-19 18:07:22 +00:00
}
2022-01-04 19:17:12 +00:00
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Start / Finish
// This starts rendering
public bool Start ( )
{
2020-09-26 16:15:01 +00:00
if ( General . Settings . ShowFPS & & ! fpsWatch . IsRunning )
2019-12-20 14:17:32 +00:00
fpsWatch . Start ( ) ;
2019-08-08 01:19:11 +00:00
// Start drawing
graphics . StartRendering ( true , General . Colors . Background . ToColorValue ( ) ) ;
// Beginning renderstates
2019-08-09 22:46:51 +00:00
graphics . SetCullMode ( Cull . None ) ;
graphics . SetZEnable ( false ) ;
graphics . SetAlphaBlendEnable ( false ) ;
graphics . SetAlphaTestEnable ( false ) ;
graphics . SetSourceBlend ( Blend . SourceAlpha ) ;
graphics . SetDestinationBlend ( Blend . InverseSourceAlpha ) ;
2020-01-03 01:22:33 +00:00
graphics . SetUniform ( UniformName . fogsettings , new Vector4f ( - 1.0f ) ) ;
2019-08-22 16:43:54 +00:00
graphics . SetUniform ( UniformName . fogcolor , General . Colors . Background . ToColorValue ( ) ) ;
2019-08-16 12:01:27 +00:00
graphics . SetUniform ( UniformName . texturefactor , new Color4 ( 1f , 1f , 1f , 1f ) ) ;
2022-01-31 18:49:26 +00:00
graphics . SetUniform ( UniformName . doomlightlevels , General . Map . Config . DoomLightLevels ) ;
2019-08-16 12:01:27 +00:00
graphics . SetUniform ( UniformName . highlightcolor , new Color4 ( ) ) ; //mxd
2022-01-04 19:17:12 +00:00
TextureFilter texFilter = ( ! General . Settings . ClassicRendering & & General . Settings . VisualBilinear ) ? TextureFilter . Linear : TextureFilter . Nearest ;
MipmapFilter mipFilter = General . Settings . ClassicRendering ? MipmapFilter . None : MipmapFilter . Linear ;
float aniso = General . Settings . ClassicRendering ? 0 : General . Settings . FilterAnisotropy ;
graphics . SetSamplerFilter ( texFilter , texFilter , mipFilter , aniso ) ;
2019-08-08 01:19:11 +00:00
2019-12-15 20:47:06 +00:00
// Texture addressing
graphics . SetSamplerState ( TextureAddress . Wrap ) ;
2019-08-08 01:19:11 +00:00
2022-01-04 19:17:12 +00:00
// Matrices
2019-08-08 01:19:11 +00:00
world = Matrix . Identity ;
2019-12-19 02:12:44 +00:00
graphics . SetUniform ( UniformName . projection , ref projection ) ;
graphics . SetUniform ( UniformName . world , ref world ) ;
graphics . SetUniform ( UniformName . view , ref view3d ) ;
2016-01-14 22:15:54 +00:00
2019-08-08 01:19:11 +00:00
// Highlight
if ( General . Settings . AnimateVisualSelection )
{
highlightglow = ( float ) Math . Sin ( Clock . CurrentTime / 100.0f ) * 0.1f + 0.4f ;
highlightglowinv = - highlightglow + 0.8f ;
2009-04-19 18:07:22 +00:00
}
else
{
2019-08-08 01:19:11 +00:00
highlightglow = 0.4f ;
highlightglowinv = 0.3f ;
2009-04-19 18:07:22 +00:00
}
2019-08-08 01:19:11 +00:00
// Determine shader pass to use
2022-01-04 19:17:12 +00:00
if ( fullbrightness )
{
shaderpass = ShaderName . world3d_fullbright ;
}
else if ( General . Settings . ClassicRendering )
{
shaderpass = ShaderName . world3d_classic ;
}
else
{
shaderpass = ShaderName . world3d_main ;
}
2019-08-08 01:19:11 +00:00
// Create crosshair vertices
if ( crosshairverts = = null )
CreateCrosshairVerts ( new Size ( General . Map . Data . Crosshair3D . Width , General . Map . Data . Crosshair3D . Height ) ) ;
//mxd. Crate vertex handle
if ( vertexhandle = = null ) vertexhandle = new VisualVertexHandle ( ) ;
2019-12-30 23:08:17 +00:00
// Create slope handle
if ( visualslopehandle = = null ) visualslopehandle = new VisualSlopeHandle ( ) ;
2019-08-08 01:19:11 +00:00
// Ready
return true ;
2009-04-19 18:07:22 +00:00
}
// This begins rendering world geometry
public void StartGeometry ( )
{
2015-09-27 21:09:14 +00:00
// Make collections
solidgeo = new Dictionary < ImageData , List < VisualGeometry > > ( ) ; //mxd
maskedgeo = new Dictionary < ImageData , List < VisualGeometry > > ( ) ; //mxd
translucentgeo = new List < VisualGeometry > ( ) ; //mxd
2016-01-11 13:00:52 +00:00
skygeo = new List < VisualGeometry > ( ) ; //mxd
2015-09-27 21:09:14 +00:00
solidthings = new Dictionary < ImageData , List < VisualThing > > ( ) ; //mxd
maskedthings = new Dictionary < ImageData , List < VisualThing > > ( ) ; //mxd
translucentthings = new List < VisualThing > ( ) ; //mxd
2015-12-01 14:51:45 +00:00
maskedmodelthings = new Dictionary < ModelData , List < VisualThing > > ( ) ; //mxd
translucentmodelthings = new List < VisualThing > ( ) ; //mxd
2015-09-27 21:09:14 +00:00
lightthings = new List < VisualThing > ( ) ; //mxd
allthings = new List < VisualThing > ( ) ; //mxd
2009-04-19 18:07:22 +00:00
}
// This ends rendering world geometry
public void FinishGeometry ( )
{
2015-09-27 21:09:14 +00:00
//mxd. Sort lights
if ( General . Settings . GZDrawLightsMode ! = LightRenderMode . NONE & & ! fullbrightness & & lightthings . Count > 0 )
2014-12-03 23:15:26 +00:00
UpdateLights ( ) ;
2017-04-29 10:56:06 +00:00
2013-09-11 09:47:53 +00:00
// Initial renderstates
2019-08-15 12:49:49 +00:00
graphics . SetCullMode ( Cull . Clockwise ) ;
2019-08-09 22:46:51 +00:00
graphics . SetZEnable ( true ) ;
graphics . SetZWriteEnable ( true ) ;
graphics . SetAlphaBlendEnable ( false ) ;
graphics . SetAlphaTestEnable ( false ) ;
2019-08-16 12:01:27 +00:00
graphics . SetUniform ( UniformName . texturefactor , new Color4 ( 1f , 1f , 1f , 1f ) ) ;
2009-04-19 18:07:22 +00:00
2019-08-16 12:01:27 +00:00
//mxd. SKY PASS
if ( skygeo . Count > 0 )
2016-01-11 13:00:52 +00:00
{
world = Matrix . Identity ;
2019-12-19 02:12:44 +00:00
graphics . SetUniform ( UniformName . world , ref world ) ;
2016-01-11 13:00:52 +00:00
RenderSky ( skygeo ) ;
}
2009-04-19 18:07:22 +00:00
// SOLID PASS
2012-08-10 12:08:08 +00:00
world = Matrix . Identity ;
2019-12-19 02:12:44 +00:00
graphics . SetUniform ( UniformName . world , ref world ) ;
2020-01-03 01:22:33 +00:00
RenderSinglePass ( solidgeo , solidthings , lightthings ) ;
2009-04-19 18:07:22 +00:00
2015-12-01 14:51:45 +00:00
//mxd. Render models, without backface culling
if ( maskedmodelthings . Count > 0 )
{
2019-08-09 22:46:51 +00:00
graphics . SetAlphaTestEnable ( true ) ;
graphics . SetCullMode ( Cull . None ) ;
2020-01-03 01:22:33 +00:00
RenderModels ( false , lightthings ) ;
2019-08-15 12:49:49 +00:00
graphics . SetCullMode ( Cull . Clockwise ) ;
2015-12-01 14:51:45 +00:00
}
2012-04-17 19:13:47 +00:00
2009-04-19 18:07:22 +00:00
// MASK PASS
2015-12-01 14:51:45 +00:00
if ( maskedgeo . Count > 0 | | maskedthings . Count > 0 )
{
world = Matrix . Identity ;
2019-12-19 02:12:44 +00:00
graphics . SetUniform ( UniformName . world , ref world ) ;
2019-12-18 13:24:54 +00:00
graphics . SetAlphaTestEnable ( true ) ;
2020-01-03 01:22:33 +00:00
RenderSinglePass ( maskedgeo , maskedthings , lightthings ) ;
2015-12-01 14:51:45 +00:00
}
2013-09-11 09:47:53 +00:00
2015-09-27 21:09:14 +00:00
// ALPHA AND ADDITIVE PASS
2015-12-01 14:51:45 +00:00
if ( translucentgeo . Count > 0 | | translucentthings . Count > 0 )
{
world = Matrix . Identity ;
2019-12-19 02:12:44 +00:00
graphics . SetUniform ( UniformName . world , ref world ) ;
2019-12-18 13:24:54 +00:00
graphics . SetAlphaBlendEnable ( true ) ;
2019-08-09 22:46:51 +00:00
graphics . SetAlphaTestEnable ( false ) ;
graphics . SetZWriteEnable ( false ) ;
graphics . SetSourceBlend ( Blend . SourceAlpha ) ;
2020-01-03 01:22:33 +00:00
RenderTranslucentPass ( translucentgeo , translucentthings , lightthings ) ;
2015-12-01 14:51:45 +00:00
}
//mxd. Render translucent models, with backface culling
if ( translucentmodelthings . Count > 0 )
{
2019-08-09 22:46:51 +00:00
graphics . SetAlphaBlendEnable ( true ) ;
graphics . SetAlphaTestEnable ( false ) ;
graphics . SetZWriteEnable ( false ) ;
graphics . SetSourceBlend ( Blend . SourceAlpha ) ;
2020-01-03 01:22:33 +00:00
RenderModels ( true , lightthings ) ;
2017-07-26 15:35:22 +00:00
}
// THING CAGES
if ( renderthingcages )
2015-12-01 14:51:45 +00:00
{
world = Matrix . Identity ;
2019-12-19 02:12:44 +00:00
graphics . SetUniform ( UniformName . world , ref world ) ;
2019-12-18 13:24:54 +00:00
RenderThingCages ( ) ;
2015-12-01 14:51:45 +00:00
}
2009-04-19 18:07:22 +00:00
2013-03-18 13:52:27 +00:00
//mxd. Visual vertices
RenderVertices ( ) ;
2019-12-30 23:08:17 +00:00
// Slope handles
if ( General . Map . UDMF /* && General.Settings.ShowVisualSlopeHandles */ )
RenderSlopeHandles ( ) ;
2015-08-08 21:56:43 +00:00
//mxd. Event lines
2019-12-30 23:08:17 +00:00
if ( General . Settings . GZShowEventLines ) RenderArrows ( eventlines ) ;
2009-04-19 18:07:22 +00:00
// Remove references
2019-08-17 01:21:11 +00:00
graphics . SetTexture ( null ) ;
2009-04-19 18:07:22 +00:00
2015-09-27 21:09:14 +00:00
//mxd. Trash collections
solidgeo = null ;
maskedgeo = null ;
translucentgeo = null ;
2016-01-11 13:00:52 +00:00
skygeo = null ;
2015-09-27 21:09:14 +00:00
solidthings = null ;
maskedthings = null ;
translucentthings = null ;
allthings = null ;
lightthings = null ;
2015-12-01 14:51:45 +00:00
maskedmodelthings = null ;
translucentmodelthings = null ;
2015-09-27 21:09:14 +00:00
visualvertices = null ;
2019-12-20 14:17:32 +00:00
2020-09-26 16:15:01 +00:00
if ( General . Settings . ShowFPS )
{
fps + + ;
if ( fpsWatch . ElapsedMilliseconds > 1000 )
{
fpsLabel . Text = string . Format ( "{0} FPS" , fps ) ;
fps = 0 ;
fpsWatch . Restart ( ) ;
}
}
2019-12-20 14:38:54 +00:00
}
2009-04-19 18:07:22 +00:00
2017-02-09 12:28:54 +00:00
// [ZZ] black renderer magic here.
// todo maybe implement proper frustum culling eventually?
// Frustum2D.IntersectCircle doesn't seem to work here.
private bool CullLight ( VisualThing t )
{
Vector3D lightToCamera = ( cameraposition - t . CenterV3D ) . GetNormal ( ) ;
double angdiff = Vector3D . DotProduct ( lightToCamera , cameravector ) ;
if ( angdiff < = 0 )
return true ; // light in front of the camera. it's not negative because I don't want to calculate things twice and need the vector to point at camera.
// otherwise check light size: large lights might have center on the back, but radius in front of the camera.
Vector3D lightToCameraWithRadius = ( cameraposition - ( t . CenterV3D + lightToCamera * t . LightRadius ) ) . GetNormal ( ) ;
double angdiffWithRadius = Vector3D . DotProduct ( lightToCameraWithRadius , cameravector ) ;
if ( angdiffWithRadius < = 0 )
return true ; // light's radius extension is in front of the camera.
return false ;
}
//mxd
private void UpdateLights ( )
2014-12-03 23:15:26 +00:00
{
2017-02-09 12:28:54 +00:00
// Calculate distance to camera
foreach ( VisualThing t in lightthings ) t . CalculateCameraDistance ( cameraposition ) ;
// Sort by it, closer ones first
lightthings . Sort ( ( t1 , t2 ) = > Math . Sign ( t1 . CameraDistance - t2 . CameraDistance ) ) ;
// Gather the closest
List < VisualThing > tl = new List < VisualThing > ( lightthings . Count ) ;
// Break on either end of things of max dynamic lights reached
for ( int i = 0 ; i < lightthings . Count & & tl . Count < General . Settings . GZMaxDynamicLights ; i + + )
{
// Make sure we can see this light at all
if ( ! CullLight ( lightthings [ i ] ) )
continue ;
tl . Add ( lightthings [ i ] ) ;
}
// Update the array
lightthings = tl ;
2013-09-11 09:47:53 +00:00
2015-09-27 21:09:14 +00:00
// Sort things by light render style
2018-02-03 20:31:34 +00:00
lightthings . Sort ( ( t1 , t2 ) = > Math . Sign ( t1 . LightType . LightRenderStyle - t2 . LightType . LightRenderStyle ) ) ;
2017-01-19 22:17:43 +00:00
lightOffsets = new int [ 4 ] ;
2015-09-27 21:09:14 +00:00
foreach ( VisualThing t in lightthings )
2014-12-03 23:15:26 +00:00
{
2013-09-11 09:47:53 +00:00
//add light to apropriate array.
2018-02-03 20:31:34 +00:00
switch ( t . LightType . LightRenderStyle )
2014-12-03 23:15:26 +00:00
{
2018-02-03 20:31:34 +00:00
case GZGeneral . LightRenderStyle . NORMAL :
case GZGeneral . LightRenderStyle . VAVOOM : lightOffsets [ 0 ] + + ; break ;
case GZGeneral . LightRenderStyle . ADDITIVE : lightOffsets [ 2 ] + + ; break ;
case GZGeneral . LightRenderStyle . SUBTRACTIVE : lightOffsets [ 3 ] + + ; break ;
2023-09-29 19:19:18 +00:00
case GZGeneral . LightRenderStyle . LIGHTMAP : // Static lights look the same as attenuated lights
2017-02-09 11:28:55 +00:00
default : lightOffsets [ 1 ] + + ; break ; // attenuated
2013-12-23 08:00:19 +00:00
}
2013-09-11 09:47:53 +00:00
}
}
//mxd.
//I never particularly liked old ThingCages, so I wrote this instead.
//It should render faster and it has fancy arrow! :)
2014-12-03 23:15:26 +00:00
private void RenderThingCages ( )
{
2019-08-09 22:46:51 +00:00
graphics . SetAlphaBlendEnable ( true ) ;
graphics . SetAlphaTestEnable ( false ) ;
graphics . SetZWriteEnable ( false ) ;
graphics . SetSourceBlend ( Blend . SourceAlpha ) ;
graphics . SetDestinationBlend ( Blend . SourceAlpha ) ;
2013-09-11 09:47:53 +00:00
2019-08-14 10:36:33 +00:00
graphics . SetShader ( ShaderName . world3d_constant_color ) ;
2013-09-11 09:47:53 +00:00
2015-09-27 21:09:14 +00:00
foreach ( VisualThing t in allthings )
2014-12-03 23:15:26 +00:00
{
2013-09-11 09:47:53 +00:00
// Setup color
2015-09-27 21:09:14 +00:00
Color4 thingcolor ;
if ( t . Selected & & showselection )
2014-12-03 23:15:26 +00:00
{
2015-09-27 21:09:14 +00:00
thingcolor = General . Colors . Selection3D . ToColorValue ( ) ;
2014-12-03 23:15:26 +00:00
}
2015-09-27 21:09:14 +00:00
else
2014-12-03 23:15:26 +00:00
{
2015-09-27 21:09:14 +00:00
thingcolor = t . CageColor ;
if ( t ! = highlighted ) thingcolor . Alpha = 0.6f ;
2013-09-11 09:47:53 +00:00
}
2019-08-14 10:36:33 +00:00
graphics . SetUniform ( UniformName . vertexColor , thingcolor ) ;
2013-09-11 09:47:53 +00:00
//Render cage
2019-08-16 11:07:57 +00:00
graphics . SetVertexBuffer ( t . CageBuffer ) ;
2019-08-16 05:12:26 +00:00
graphics . Draw ( PrimitiveType . LineList , 0 , t . CageLength ) ;
2013-09-11 09:47:53 +00:00
}
2012-04-17 19:13:47 +00:00
2013-09-11 09:47:53 +00:00
// Done
2019-08-16 12:01:27 +00:00
graphics . SetUniform ( UniformName . texturefactor , new Color4 ( 1f , 1f , 1f , 1f ) ) ;
}
2012-09-17 15:41:18 +00:00
2013-03-18 13:52:27 +00:00
//mxd
2014-12-03 23:15:26 +00:00
private void RenderVertices ( )
{
2013-03-18 13:52:27 +00:00
if ( visualvertices = = null ) return ;
2019-08-09 22:46:51 +00:00
graphics . SetAlphaBlendEnable ( true ) ;
graphics . SetAlphaTestEnable ( false ) ;
graphics . SetZWriteEnable ( false ) ;
graphics . SetSourceBlend ( Blend . SourceAlpha ) ;
graphics . SetDestinationBlend ( Blend . SourceAlpha ) ;
2013-03-20 10:25:32 +00:00
2019-08-14 10:36:33 +00:00
graphics . SetShader ( ShaderName . world3d_constant_color ) ;
2013-03-18 13:52:27 +00:00
2014-12-03 23:15:26 +00:00
foreach ( VisualVertex v in visualvertices )
{
2013-03-18 13:52:27 +00:00
world = v . Position ;
2019-12-19 02:12:44 +00:00
graphics . SetUniform ( UniformName . world , ref world ) ;
2013-03-18 13:52:27 +00:00
2019-12-18 13:24:54 +00:00
// Setup color
Color4 color ;
2014-12-03 23:15:26 +00:00
if ( v . Selected & & showselection )
{
2013-03-18 13:52:27 +00:00
color = General . Colors . Selection3D . ToColorValue ( ) ;
2014-12-03 23:15:26 +00:00
}
else
{
2013-05-02 11:03:16 +00:00
color = v . HaveHeightOffset ? General . Colors . InfoLine . ToColorValue ( ) : General . Colors . Vertices . ToColorValue ( ) ;
2013-03-18 13:52:27 +00:00
if ( v ! = highlighted ) color . Alpha = 0.6f ;
}
2019-08-14 10:36:33 +00:00
graphics . SetUniform ( UniformName . vertexColor , color ) ;
2013-03-18 13:52:27 +00:00
//Commence drawing!!11
2019-08-16 11:07:57 +00:00
graphics . SetVertexBuffer ( v . CeilingVertex ? vertexhandle . Upper : vertexhandle . Lower ) ;
2019-08-16 05:12:26 +00:00
graphics . Draw ( PrimitiveType . LineList , 0 , 8 ) ;
2013-03-18 13:52:27 +00:00
}
// Done
2019-08-16 12:01:27 +00:00
graphics . SetUniform ( UniformName . texturefactor , new Color4 ( 1f , 1f , 1f , 1f ) ) ;
}
2013-03-18 13:52:27 +00:00
2019-12-30 23:08:17 +00:00
private void RenderSlopeHandles ( )
{
2020-02-24 11:54:59 +00:00
if ( visualslopehandles = = null | | ! showselection ) return ;
2019-12-30 23:08:17 +00:00
graphics . SetAlphaBlendEnable ( true ) ;
graphics . SetAlphaTestEnable ( false ) ;
graphics . SetZWriteEnable ( false ) ;
graphics . SetSourceBlend ( Blend . SourceAlpha ) ;
2020-01-01 20:47:33 +00:00
graphics . SetDestinationBlend ( Blend . InverseSourceAlpha ) ;
2019-12-30 23:08:17 +00:00
2020-01-01 20:47:33 +00:00
graphics . SetShader ( ShaderName . world3d_slope_handle ) ;
2019-12-30 23:08:17 +00:00
foreach ( VisualSlope handle in visualslopehandles )
{
PixelColor color = General . Colors . Vertices ;
if ( handle . Pivot )
color = General . Colors . Guideline ;
else if ( handle . Selected )
color = General . Colors . Selection3D ;
else if ( handle = = highlighted )
color = General . Colors . Highlight3D ;
else if ( handle . SmartPivot )
color = General . Colors . Vertices ;
world = handle . Position ;
2020-01-01 20:47:33 +00:00
graphics . SetUniform ( UniformName . world , ref world ) ;
graphics . SetUniform ( UniformName . vertexColor , color . ToColorValue ( ) ) ;
2021-01-30 21:01:55 +00:00
if ( handle . Type = = VisualSlopeType . Line )
{
graphics . SetUniform ( UniformName . slopeHandleLength , ( float ) handle . Length ) ;
graphics . SetVertexBuffer ( visualslopehandle . LineGeometry ) ;
graphics . Draw ( PrimitiveType . TriangleList , 0 , 2 ) ;
}
else if ( handle . Type = = VisualSlopeType . Vertex )
{
graphics . SetUniform ( UniformName . slopeHandleLength , 1.0f ) ;
graphics . SetVertexBuffer ( visualslopehandle . VertexGeometry ) ;
graphics . Draw ( PrimitiveType . TriangleList , 0 , 1 ) ;
}
2019-12-30 23:08:17 +00:00
}
// Done
graphics . SetUniform ( UniformName . texturefactor , new Color4 ( 1f , 1f , 1f , 1f ) ) ;
}
2013-09-11 09:47:53 +00:00
//mxd
2015-08-08 21:56:43 +00:00
private void RenderArrows ( ICollection < Line3D > lines )
2014-12-03 23:15:26 +00:00
{
2015-08-08 21:56:43 +00:00
// Calculate required points count
if ( lines . Count = = 0 ) return ;
int pointscount = 0 ;
2015-12-14 12:34:31 +00:00
foreach ( Line3D line in lines ) pointscount + = ( line . RenderArrowhead ? 6 : 2 ) ; // 4 extra points for the arrowhead
2015-08-08 21:56:43 +00:00
if ( pointscount < 2 ) return ;
2013-09-11 09:47:53 +00:00
//create vertices
2015-08-08 21:56:43 +00:00
WorldVertex [ ] verts = new WorldVertex [ pointscount ] ;
2014-12-03 23:15:26 +00:00
const float scaler = 20f ;
2015-08-08 21:56:43 +00:00
pointscount = 0 ;
foreach ( Line3D line in lines )
2014-12-03 23:15:26 +00:00
{
2015-12-28 15:01:53 +00:00
int color = line . Color . ToInt ( ) ;
2015-08-08 21:56:43 +00:00
// Add regular points
2020-05-21 12:20:02 +00:00
verts [ pointscount ] . x = ( float ) line . Start . x ;
verts [ pointscount ] . y = ( float ) line . Start . y ;
verts [ pointscount ] . z = ( float ) line . Start . z ;
2015-08-08 21:56:43 +00:00
verts [ pointscount ] . c = color ;
pointscount + + ;
2020-05-21 12:20:02 +00:00
verts [ pointscount ] . x = ( float ) line . End . x ;
verts [ pointscount ] . y = ( float ) line . End . y ;
verts [ pointscount ] . z = ( float ) line . End . z ;
2015-08-08 21:56:43 +00:00
verts [ pointscount ] . c = color ;
pointscount + + ;
// Add arrowhead
2015-12-14 12:34:31 +00:00
if ( line . RenderArrowhead )
2015-08-08 21:56:43 +00:00
{
2020-05-21 12:20:02 +00:00
double nz = line . GetDelta ( ) . GetNormal ( ) . z * scaler ;
double angle = line . GetAngle ( ) ;
Vector3D a1 = new Vector3D ( line . End . x - scaler * Math . Sin ( angle - 0.46f ) , line . End . y + scaler * Math . Cos ( angle - 0.46f ) , line . End . z - nz ) ;
Vector3D a2 = new Vector3D ( line . End . x - scaler * Math . Sin ( angle + 0.46f ) , line . End . y + scaler * Math . Cos ( angle + 0.46f ) , line . End . z - nz ) ;
2015-08-08 21:56:43 +00:00
verts [ pointscount ] = verts [ pointscount - 1 ] ;
2020-05-21 12:20:02 +00:00
verts [ pointscount + 1 ] . x = ( float ) a1 . x ;
verts [ pointscount + 1 ] . y = ( float ) a1 . y ;
verts [ pointscount + 1 ] . z = ( float ) a1 . z ;
2015-08-08 21:56:43 +00:00
verts [ pointscount + 1 ] . c = color ;
verts [ pointscount + 2 ] = verts [ pointscount - 1 ] ;
2020-05-21 12:20:02 +00:00
verts [ pointscount + 3 ] . x = ( float ) a2 . x ;
verts [ pointscount + 3 ] . y = ( float ) a2 . y ;
verts [ pointscount + 3 ] . z = ( float ) a2 . z ;
2015-08-08 21:56:43 +00:00
verts [ pointscount + 3 ] . c = color ;
pointscount + = 4 ;
}
2013-09-11 09:47:53 +00:00
}
2019-08-16 09:24:22 +00:00
VertexBuffer vb = new VertexBuffer ( ) ;
2019-08-15 00:52:21 +00:00
graphics . SetBufferData ( vb , verts ) ;
2013-09-11 09:47:53 +00:00
//begin rendering
2019-08-09 22:46:51 +00:00
graphics . SetAlphaBlendEnable ( true ) ;
graphics . SetAlphaTestEnable ( false ) ;
graphics . SetZWriteEnable ( false ) ;
graphics . SetSourceBlend ( Blend . SourceAlpha ) ;
graphics . SetDestinationBlend ( Blend . SourceAlpha ) ;
2013-09-11 09:47:53 +00:00
2019-08-14 10:36:33 +00:00
graphics . SetShader ( ShaderName . world3d_vertex_color ) ;
2013-09-11 09:47:53 +00:00
world = Matrix . Identity ;
2019-12-19 02:12:44 +00:00
graphics . SetUniform ( UniformName . world , ref world ) ;
2013-09-11 09:47:53 +00:00
2019-12-18 13:24:54 +00:00
//render
graphics . SetVertexBuffer ( vb ) ;
2019-08-16 05:12:26 +00:00
graphics . Draw ( PrimitiveType . LineList , 0 , pointscount / 2 ) ;
2012-09-17 15:41:18 +00:00
2013-09-11 09:47:53 +00:00
// Done
2019-08-16 12:01:27 +00:00
graphics . SetUniform ( UniformName . texturefactor , new Color4 ( 1f , 1f , 1f , 1f ) ) ;
vb . Dispose ( ) ;
2013-09-11 09:47:53 +00:00
}
2009-04-19 18:07:22 +00:00
// This performs a single render pass
2020-01-03 01:22:33 +00:00
private void RenderSinglePass ( Dictionary < ImageData , List < VisualGeometry > > geopass , Dictionary < ImageData , List < VisualThing > > thingspass , List < VisualThing > lights )
2009-04-19 18:07:22 +00:00
{
2015-10-02 14:47:34 +00:00
ImageData curtexture ;
2019-08-14 10:36:33 +00:00
ShaderName currentshaderpass = shaderpass ;
ShaderName highshaderpass = ( ShaderName ) ( shaderpass + 2 ) ;
2009-04-19 18:07:22 +00:00
2020-01-03 01:22:33 +00:00
// Begin rendering with this shader
graphics . SetShader ( shaderpass ) ;
// Light data arrays
Vector4f [ ] lightColor = new Vector4f [ MAX_DYNLIGHTS_PER_SURFACE ] ;
Vector4f [ ] lightPosAndRadius = new Vector4f [ MAX_DYNLIGHTS_PER_SURFACE ] ;
Vector4f [ ] lightOrientation = new Vector4f [ MAX_DYNLIGHTS_PER_SURFACE ] ;
Vector2f [ ] light2Radius = new Vector2f [ MAX_DYNLIGHTS_PER_SURFACE ] ;
graphics . SetUniform ( UniformName . lightsEnabled , lights . Count > 0 ) ;
2020-01-03 01:55:34 +00:00
graphics . SetUniform ( UniformName . ignoreNormals , false ) ;
2012-04-17 19:13:47 +00:00
2020-01-03 01:22:33 +00:00
bool hadlights = false ;
2022-01-04 19:17:12 +00:00
// volte: Set textures for classic lighting
if ( classicLightingColorMap ! = null )
{
graphics . SetUniform ( UniformName . colormapSize , new Vector2i ( classicLightingColorMapTex . Width , classicLightingColorMapTex . Height ) ) ;
graphics . SetTexture ( classicLightingColorMapTex , 1 ) ;
graphics . SetSamplerFilter ( TextureFilter . Nearest , TextureFilter . Nearest , MipmapFilter . None , 0 , 1 ) ;
graphics . SetSamplerState ( TextureAddress . Clamp , 1 ) ;
}
2020-01-03 01:22:33 +00:00
// Render the geometry collected
foreach ( KeyValuePair < ImageData , List < VisualGeometry > > group in geopass )
2009-04-19 18:07:22 +00:00
{
2020-01-12 22:10:57 +00:00
curtexture = group . Key ;
2009-04-19 18:07:22 +00:00
2022-01-04 19:17:12 +00:00
// Apply texture
Texture texture = UseIndexedTexture ? curtexture . IndexedTexture : curtexture . Texture ;
graphics . SetTexture ( texture ) ;
graphics . SetUniform ( UniformName . drawPaletted , texture . UserData = = ImageData . TEXTURE_INDEXED ) ;
2015-09-27 21:09:14 +00:00
//mxd. Sort geometry by sector index
group . Value . Sort ( ( g1 , g2 ) = > g1 . Sector . Sector . FixedIndex - g2 . Sector . Sector . FixedIndex ) ;
2009-04-19 18:07:22 +00:00
// Go for all geometry that uses this texture
VisualSector sector = null ;
2013-09-11 09:47:53 +00:00
2009-04-19 18:07:22 +00:00
foreach ( VisualGeometry g in group . Value )
{
2020-01-03 01:22:33 +00:00
int lightIndex = 0 ;
foreach ( VisualThing light in lights )
{
if ( BoundingBoxesIntersect ( g . BoundingBox , light . BoundingBox ) )
{
//t.LightType.LightRenderStyle
//Vector4f lightColor, lightPosAndRadius, lightOrientation, light2Radius;
lightColor [ lightIndex ] = light . LightColor . ToVector ( ) ;
lightPosAndRadius [ lightIndex ] = new Vector4f ( light . Center , light . LightRadius ) ;
// set type of light
if ( light . LightType . LightType = = GZGeneral . LightType . SPOT )
{
lightOrientation [ lightIndex ] = new Vector4f ( light . VectorLookAt , 1f ) ;
light2Radius [ lightIndex ] = new Vector2f ( CosDeg ( light . LightSpotRadius1 ) , CosDeg ( light . LightSpotRadius2 ) ) ;
}
else lightOrientation [ lightIndex ] . W = 0f ;
lightIndex + + ;
if ( lightIndex > = lightColor . Length )
break ;
}
}
bool havelights = ( lightIndex > 0 ) ;
for ( int i = lightIndex ; i < lightColor . Length ; i + + )
lightColor [ i ] . W = 0 ;
if ( havelights ! = hadlights | | havelights )
{
graphics . SetUniform ( UniformName . lightColor , lightColor ) ;
if ( havelights )
{
graphics . SetUniform ( UniformName . lightPosAndRadius , lightPosAndRadius ) ;
graphics . SetUniform ( UniformName . lightOrientation , lightOrientation ) ;
graphics . SetUniform ( UniformName . light2Radius , light2Radius ) ;
}
}
hadlights = havelights ;
2009-04-19 18:07:22 +00:00
// Changing sector?
if ( ! object . ReferenceEquals ( g . Sector , sector ) )
{
// Update the sector if needed
2019-08-15 00:52:21 +00:00
if ( g . Sector . NeedsUpdateGeo ) g . Sector . Update ( graphics ) ;
2009-04-19 18:07:22 +00:00
// Only do this sector when a vertexbuffer is created
2015-10-02 14:47:34 +00:00
//mxd. No Map means that sector was deleted recently, I suppose
2015-12-28 15:01:53 +00:00
if ( g . Sector . GeometryBuffer ! = null & & g . Sector . Sector . Map ! = null )
2009-04-19 18:07:22 +00:00
{
// Change current sector
sector = g . Sector ;
// Set stream source
2019-08-16 11:07:57 +00:00
graphics . SetVertexBuffer ( sector . GeometryBuffer ) ;
2009-04-19 18:07:22 +00:00
}
else
{
sector = null ;
}
2012-06-03 15:13:22 +00:00
}
2019-08-14 10:36:33 +00:00
graphics . SetUniform ( UniformName . desaturation , 0.0f ) ;
2018-04-10 16:41:35 +00:00
if ( sector ! = null )
2009-04-19 18:07:22 +00:00
{
2009-05-01 20:31:17 +00:00
// Determine the shader pass we want to use for this object
2019-08-14 10:36:33 +00:00
ShaderName wantedshaderpass = ( ( ( g = = highlighted ) & & showhighlight ) | | ( g . Selected & & showselection ) ) ? highshaderpass : shaderpass ;
2012-05-13 20:51:41 +00:00
Added, Visual mode, GLDEFS, GLOOME: subtractive glow is now supported.
Changed, Visual mode: changed thing fog calculation logic. Should be closer to GZDoom now.
Fixed, GLDEFS parser: "height" texture parameter was not treated as optional.
Fixed, text lump parsers: in some cases incorrect line number was displayed in error and warning messages.
Fixed, Visual mode: glow effect was not applied to sectors with 3 sidedefs.
Fixed, Visual mode: in some cases glow effect was not updated when replacing textures.
Fixed, general interface: "Full Brightness" button state was not updated during map loading.
Fixed, Drag Linedefs/Vertices/Sectors/Things modes: positions of line length labels were not updated while panning the view.
Cosmetic: added a bunch of new icons.
Cosmetic: changed Visual mode crosshair.
2015-08-27 20:46:49 +00:00
//mxd. Render fog?
2022-01-04 19:17:12 +00:00
if ( General . Settings . GZDrawFog & & ! fullbrightness & & ! General . Settings . ClassicRendering & & sector . Sector . FogMode ! = SectorFogMode . NONE )
2013-09-11 09:47:53 +00:00
wantedshaderpass + = 8 ;
2009-05-01 20:31:17 +00:00
// Switch shader pass?
if ( currentshaderpass ! = wantedshaderpass )
2009-04-19 18:07:22 +00:00
{
2019-08-13 02:12:04 +00:00
graphics . SetShader ( wantedshaderpass ) ;
2009-05-01 20:31:17 +00:00
currentshaderpass = wantedshaderpass ;
2015-10-02 14:47:34 +00:00
//mxd. Set variables for fog rendering?
2019-08-14 10:36:33 +00:00
if ( wantedshaderpass > ShaderName . world3d_p7 )
2015-10-02 14:47:34 +00:00
{
2019-08-14 10:36:33 +00:00
graphics . SetUniform ( UniformName . modelnormal , Matrix . Identity ) ;
2018-05-27 05:53:54 +00:00
}
2009-04-19 18:07:22 +00:00
}
2022-01-04 19:17:12 +00:00
// volte: set sector light level for classic rendering mode
2022-01-31 18:49:26 +00:00
graphics . SetUniform ( UniformName . sectorLightLevel , sector . Sector . Brightness ) ;
2015-10-02 14:47:34 +00:00
//mxd. Set variables for fog rendering?
2019-08-14 10:36:33 +00:00
if ( wantedshaderpass > ShaderName . world3d_p7 )
2009-05-04 06:13:56 +00:00
{
2020-05-18 16:14:54 +00:00
graphics . SetUniform ( UniformName . campos , new Vector4f ( ( float ) cameraposition . x , ( float ) cameraposition . y , ( float ) cameraposition . z , g . FogFactor ) ) ;
2020-01-03 01:22:33 +00:00
graphics . SetUniform ( UniformName . sectorfogcolor , sector . Sector . FogColor ) ;
2009-05-04 06:13:56 +00:00
}
2018-04-10 16:41:35 +00:00
2015-10-02 14:47:34 +00:00
// Set the colors to use
2019-08-14 10:36:33 +00:00
graphics . SetUniform ( UniformName . highlightcolor , CalculateHighlightColor ( ( g = = highlighted ) & & showhighlight , ( g . Selected & & showselection ) ) ) ;
2015-10-02 14:47:34 +00:00
2018-04-10 16:41:35 +00:00
// [ZZ] include desaturation factor
2020-05-23 08:01:52 +00:00
graphics . SetUniform ( UniformName . desaturation , ( float ) sector . Sector . Desaturation ) ;
2018-04-10 16:41:35 +00:00
2023-07-08 20:39:50 +00:00
// Skew
graphics . SetUniform ( UniformName . skew , g . Skew ) ;
2009-04-19 18:07:22 +00:00
// Render!
2019-08-16 05:12:26 +00:00
graphics . Draw ( PrimitiveType . TriangleList , g . VertexOffset , g . Triangles ) ;
2009-04-19 18:07:22 +00:00
}
}
}
2023-07-09 09:45:47 +00:00
// Done with geometry, reset potentially lingering skew setting
graphics . SetUniform ( UniformName . skew , new Vector2f ( 0.0f , 0.0f ) ) ;
graphics . SetUniform ( UniformName . lightsEnabled , false ) ;
2020-01-03 01:22:33 +00:00
// Get things for this pass
if ( thingspass . Count > 0 )
2009-04-19 18:07:22 +00:00
{
2009-04-26 20:20:40 +00:00
// Texture addressing
2019-08-17 01:21:11 +00:00
graphics . SetSamplerState ( TextureAddress . Clamp ) ;
2019-08-09 22:46:51 +00:00
graphics . SetCullMode ( Cull . None ) ; //mxd. Disable backside culling, because otherwise sprites with positive ScaleY and negative ScaleX will be facing away from the camera...
2009-04-19 18:07:22 +00:00
2015-10-02 14:47:34 +00:00
Color4 vertexcolor = new Color4 ( ) ; //mxd
2009-04-26 20:20:40 +00:00
// Render things collected
foreach ( KeyValuePair < ImageData , List < VisualThing > > group in thingspass )
2009-04-19 18:07:22 +00:00
{
2015-09-27 21:09:14 +00:00
if ( group . Key is UnknownImage ) continue ;
2020-01-12 22:10:57 +00:00
curtexture = group . Key ;
2015-09-27 21:09:14 +00:00
2022-01-04 19:17:12 +00:00
// Apply texture
Texture texture = UseIndexedTexture ? curtexture . IndexedTexture : curtexture . Texture ;
graphics . SetTexture ( texture ) ;
graphics . SetUniform ( UniformName . drawPaletted , texture . UserData = = ImageData . TEXTURE_INDEXED ) ;
2015-09-27 21:09:14 +00:00
// Render all things with this texture
foreach ( VisualThing t in group . Value )
{
// Update buffer if needed
t . Update ( ) ;
2020-12-12 10:48:46 +00:00
//mxd. Check 3D distance. Check against MaxValue to save doing GetLenthSq if there's not DistanceCheck defined
if ( t . Info . DistanceCheckSq < double . MaxValue )
{
t . CalculateCameraDistance ( cameraposition ) ;
if ( t . CameraDistance > t . Info . DistanceCheckSq )
continue ;
}
2016-04-13 10:07:46 +00:00
2015-09-27 21:09:14 +00:00
// Only do this sector when a vertexbuffer is created
2020-12-12 10:48:46 +00:00
if ( t . GeometryBuffer ! = null )
2009-04-26 20:20:40 +00:00
{
2015-09-27 21:09:14 +00:00
// Determine the shader pass we want to use for this object
2019-08-14 10:36:33 +00:00
ShaderName wantedshaderpass = ( ( ( t = = highlighted ) & & showhighlight ) | | ( t . Selected & & showselection ) ) ? highshaderpass : shaderpass ;
2012-04-17 19:13:47 +00:00
2015-10-02 14:47:34 +00:00
//mxd. If fog is enagled, switch to shader, which calculates it
2022-01-04 19:17:12 +00:00
if ( General . Settings . GZDrawFog & & ! fullbrightness & & ! General . Settings . ClassicRendering & & t . Thing . Sector ! = null & & t . Thing . Sector . FogMode ! = SectorFogMode . NONE )
2015-09-27 21:09:14 +00:00
wantedshaderpass + = 8 ;
2013-09-11 09:47:53 +00:00
2015-10-02 14:47:34 +00:00
//mxd. Create the matrix for positioning
world = CreateThingPositionMatrix ( t ) ;
//mxd. If current thing is light - set it's color to light color
2022-06-02 18:18:35 +00:00
if ( t . LightType ! = null & & t . LightType . LightInternal & & t . LightType . LightType ! = GZGeneral . LightType . SUN & & ! fullbrightness & & ! General . Settings . ClassicRendering )
2015-09-27 21:09:14 +00:00
{
2015-10-02 14:47:34 +00:00
wantedshaderpass + = 4 ; // Render using one of passes, which uses World3D.VertexColor
vertexcolor = t . LightColor ;
2015-09-27 21:09:14 +00:00
}
2015-10-02 14:47:34 +00:00
//mxd. Check if Thing is affected by dynamic lights and set color accordingly
2022-01-04 19:17:12 +00:00
else if ( General . Settings . GZDrawLightsMode ! = LightRenderMode . NONE & & ! fullbrightness & & ! General . Settings . ClassicRendering & & lightthings . Count > 0 )
2015-09-27 21:09:14 +00:00
{
2016-03-23 21:26:26 +00:00
Color4 litcolor = GetLitColorForThing ( t ) ;
2015-10-02 14:47:34 +00:00
if ( litcolor . ToArgb ( ) ! = 0 )
2014-10-20 12:16:51 +00:00
{
2015-10-02 14:47:34 +00:00
wantedshaderpass + = 4 ; // Render using one of passes, which uses World3D.VertexColor
vertexcolor = new Color4 ( t . VertexColor ) + litcolor ;
2013-09-11 09:47:53 +00:00
}
2015-09-27 21:09:14 +00:00
}
2015-10-02 14:47:34 +00:00
else
{
vertexcolor = new Color4 ( ) ;
}
2013-09-11 09:47:53 +00:00
2015-09-27 21:09:14 +00:00
// Switch shader pass?
if ( currentshaderpass ! = wantedshaderpass )
{
2019-08-13 02:12:04 +00:00
graphics . SetShader ( wantedshaderpass ) ;
2015-09-27 21:09:14 +00:00
currentshaderpass = wantedshaderpass ;
}
2013-09-11 09:47:53 +00:00
2015-10-02 14:47:34 +00:00
//mxd. Set variables for fog rendering?
2019-08-14 10:36:33 +00:00
if ( wantedshaderpass > ShaderName . world3d_p7 )
2015-09-27 21:09:14 +00:00
{
2019-08-14 10:36:33 +00:00
graphics . SetUniform ( UniformName . modelnormal , Matrix . Identity ) ;
2020-05-18 16:14:54 +00:00
graphics . SetUniform ( UniformName . campos , new Vector4f ( ( float ) cameraposition . x , ( float ) cameraposition . y , ( float ) cameraposition . z , t . FogFactor ) ) ;
2015-09-27 21:09:14 +00:00
}
Model rendering (all modes): UDMF scale, pitch and roll are now displayed.
Thing Edit Form, UDMF: added controls for setting pitch, roll, scale, render style, fill color, alpha, health and score.
Visual mode, UDMF: UDMF scale is now applied when rendering sprites.
Added Thing Statistics form (Edit -> View Thing Types...), which shows all loaded thing types with some additional info.
Visual mode: sprites with negative ScaleX and positive ScaleY were not rendered properly.
Classic modes: display was not updated after loading a sprite.
Current testing engine change was not saved on closing the program when no other game configuration settings were changed.
2014-04-30 10:01:22 +00:00
2015-10-02 14:47:34 +00:00
// Set the colors to use
2022-01-04 19:17:12 +00:00
if ( t . Thing . Sector ! = null )
{
2022-01-31 18:49:26 +00:00
graphics . SetUniform ( UniformName . sectorLightLevel , t . Thing . Sector . Brightness ) ;
2022-01-04 19:17:12 +00:00
graphics . SetUniform ( UniformName . sectorfogcolor , t . Thing . Sector . FogColor ) ;
}
2019-08-14 10:36:33 +00:00
graphics . SetUniform ( UniformName . vertexColor , vertexcolor ) ;
graphics . SetUniform ( UniformName . highlightcolor , CalculateHighlightColor ( ( t = = highlighted ) & & showhighlight , ( t . Selected & & showselection ) ) ) ;
2012-05-20 00:56:59 +00:00
2017-03-25 03:19:42 +00:00
// [ZZ] check if we want stencil
2019-08-14 10:36:33 +00:00
graphics . SetUniform ( UniformName . stencilColor , t . StencilColor . ToColorValue ( ) ) ;
2017-03-25 03:19:42 +00:00
2018-04-10 16:41:35 +00:00
// [ZZ] apply desaturation
if ( t . Thing . Sector ! = null )
2020-05-23 08:01:52 +00:00
graphics . SetUniform ( UniformName . desaturation , ( float ) t . Thing . Sector . Desaturation ) ;
2019-08-14 10:36:33 +00:00
else graphics . SetUniform ( UniformName . desaturation , 0.0f ) ;
2018-04-10 16:41:35 +00:00
2017-03-25 03:19:42 +00:00
// Apply changes
2019-12-19 02:12:44 +00:00
graphics . SetUniform ( UniformName . world , world ) ;
2012-04-17 19:13:47 +00:00
2019-12-18 13:24:54 +00:00
// Apply buffer
graphics . SetVertexBuffer ( t . GeometryBuffer ) ;
2012-04-17 19:13:47 +00:00
2015-09-27 21:09:14 +00:00
// Render!
2019-08-16 05:12:26 +00:00
graphics . Draw ( PrimitiveType . TriangleList , 0 , t . Triangles ) ;
2017-03-25 03:19:42 +00:00
}
2009-04-19 18:07:22 +00:00
}
2012-04-17 19:13:47 +00:00
2017-03-25 03:19:42 +00:00
// [ZZ]
2019-08-16 03:37:03 +00:00
graphics . SetUniform ( UniformName . stencilColor , new Color4 ( 1f , 1f , 1f , 0f ) ) ;
2017-03-25 03:19:42 +00:00
}
// Texture addressing
2019-08-17 01:21:11 +00:00
graphics . SetSamplerState ( TextureAddress . Wrap ) ;
2019-08-15 12:49:49 +00:00
graphics . SetCullMode ( Cull . Clockwise ) ; //mxd
2009-04-19 18:07:22 +00:00
}
}
2009-05-05 21:13:50 +00:00
2015-09-27 21:09:14 +00:00
//mxd
2020-01-03 01:22:33 +00:00
private void RenderTranslucentPass ( List < VisualGeometry > geopass , List < VisualThing > thingspass , List < VisualThing > lights )
2015-09-27 21:09:14 +00:00
{
2019-08-14 10:36:33 +00:00
ShaderName currentshaderpass = shaderpass ;
ShaderName highshaderpass = ( ShaderName ) ( shaderpass + 2 ) ;
2015-09-27 21:09:14 +00:00
// Sort geometry by camera distance. First vertex of the BoundingBox is it's center
2017-04-29 10:56:06 +00:00
geopass . Sort ( delegate ( VisualGeometry vg1 , VisualGeometry vg2 )
2015-09-27 21:09:14 +00:00
{
2017-04-29 10:56:06 +00:00
if ( vg1 = = vg2 )
return 0 ;
double dist1 , dist2 ;
Vector3D cameraPos = General . Map . VisualCamera . Position ;
Vector2D cameraPos2 = new Vector2D ( cameraPos ) ;
// if one of the things being compared is a plane, use easier formula. (3d floor compatibility)
if ( vg1 . GeometryType = = VisualGeometryType . FLOOR | | vg1 . GeometryType = = VisualGeometryType . CEILING | |
vg2 . GeometryType = = VisualGeometryType . FLOOR | | vg2 . GeometryType = = VisualGeometryType . CEILING )
{
// more magic
dist1 = Math . Abs ( vg1 . BoundingBox [ 0 ] . z - cameraPos . z ) ;
dist2 = Math . Abs ( vg2 . BoundingBox [ 0 ] . z - cameraPos . z ) ;
}
else
{
dist1 = ( General . Map . VisualCamera . Position - vg1 . BoundingBox [ 0 ] ) . GetLengthSq ( ) ;
dist2 = ( General . Map . VisualCamera . Position - vg2 . BoundingBox [ 0 ] ) . GetLengthSq ( ) ;
}
2015-09-27 21:09:14 +00:00
2017-04-29 10:56:06 +00:00
return ( int ) ( dist2 - dist1 ) ;
2020-01-03 01:22:33 +00:00
2017-04-29 10:56:06 +00:00
} ) ;
2015-09-27 21:09:14 +00:00
2015-10-02 14:47:34 +00:00
ImageData curtexture ;
2015-09-27 21:09:14 +00:00
VisualSector sector = null ;
RenderPass currentpass = RenderPass . Solid ;
long curtexturename = 0 ;
2015-10-02 14:47:34 +00:00
float fogfactor = - 1 ;
// Begin rendering with this shader
2019-08-13 02:12:04 +00:00
graphics . SetShader ( shaderpass ) ;
2015-09-27 21:09:14 +00:00
2020-01-03 01:22:33 +00:00
// Light data arrays
Vector4f [ ] lightColor = new Vector4f [ MAX_DYNLIGHTS_PER_SURFACE ] ;
Vector4f [ ] lightPosAndRadius = new Vector4f [ MAX_DYNLIGHTS_PER_SURFACE ] ;
Vector4f [ ] lightOrientation = new Vector4f [ MAX_DYNLIGHTS_PER_SURFACE ] ;
Vector2f [ ] light2Radius = new Vector2f [ MAX_DYNLIGHTS_PER_SURFACE ] ;
graphics . SetUniform ( UniformName . lightsEnabled , lights . Count > 0 ) ;
2020-01-03 01:55:34 +00:00
graphics . SetUniform ( UniformName . ignoreNormals , false ) ;
2020-01-03 01:22:33 +00:00
bool hadlights = false ;
// Go for all geometry
foreach ( VisualGeometry g in geopass )
2015-09-27 21:09:14 +00:00
{
2020-01-03 01:22:33 +00:00
int lightIndex = 0 ;
foreach ( VisualThing light in lights )
{
if ( BoundingBoxesIntersect ( g . BoundingBox , light . BoundingBox ) )
{
//t.LightType.LightRenderStyle
//Vector4f lightColor, lightPosAndRadius, lightOrientation, light2Radius;
lightColor [ lightIndex ] = light . LightColor . ToVector ( ) ;
lightPosAndRadius [ lightIndex ] = new Vector4f ( light . Center , light . LightRadius ) ;
// set type of light
if ( light . LightType . LightType = = GZGeneral . LightType . SPOT )
{
lightOrientation [ lightIndex ] = new Vector4f ( light . VectorLookAt , 1f ) ;
light2Radius [ lightIndex ] = new Vector2f ( CosDeg ( light . LightSpotRadius1 ) , CosDeg ( light . LightSpotRadius2 ) ) ;
}
else lightOrientation [ lightIndex ] . W = 0f ;
lightIndex + + ;
if ( lightIndex > = lightColor . Length )
break ;
}
}
bool havelights = ( lightIndex > 0 ) ;
for ( int i = lightIndex ; i < lightColor . Length ; i + + )
lightColor [ i ] . W = 0 ;
if ( havelights ! = hadlights | | havelights )
{
graphics . SetUniform ( UniformName . lightColor , lightColor ) ;
if ( havelights )
{
graphics . SetUniform ( UniformName . lightPosAndRadius , lightPosAndRadius ) ;
graphics . SetUniform ( UniformName . lightOrientation , lightOrientation ) ;
graphics . SetUniform ( UniformName . light2Radius , light2Radius ) ;
}
}
hadlights = havelights ;
// Change blend mode?
if ( g . RenderPass ! = currentpass )
2015-09-27 21:09:14 +00:00
{
switch ( g . RenderPass )
{
case RenderPass . Additive :
2019-08-09 22:46:51 +00:00
graphics . SetDestinationBlend ( Blend . One ) ;
2015-09-27 21:09:14 +00:00
break ;
case RenderPass . Alpha :
2019-08-09 22:46:51 +00:00
graphics . SetDestinationBlend ( Blend . InverseSourceAlpha ) ;
2015-09-27 21:09:14 +00:00
break ;
}
currentpass = g . RenderPass ;
}
// Change texture?
if ( g . Texture . LongName ! = curtexturename )
{
2020-01-12 22:10:57 +00:00
curtexture = g . Texture ;
2015-09-27 21:09:14 +00:00
2022-01-04 19:17:12 +00:00
// Apply texture
Texture texture = UseIndexedTexture ? curtexture . IndexedTexture : curtexture . Texture ;
graphics . SetTexture ( texture ) ;
graphics . SetUniform ( UniformName . drawPaletted , texture . UserData = = ImageData . TEXTURE_INDEXED ) ;
2015-09-27 21:09:14 +00:00
curtexturename = g . Texture . LongName ;
}
// Changing sector?
if ( ! object . ReferenceEquals ( g . Sector , sector ) )
{
// Update the sector if needed
2019-08-15 00:52:21 +00:00
if ( g . Sector . NeedsUpdateGeo ) g . Sector . Update ( graphics ) ;
2015-09-27 21:09:14 +00:00
// Only do this sector when a vertexbuffer is created
2015-10-02 14:47:34 +00:00
//mxd. No Map means that sector was deleted recently, I suppose
2015-09-27 21:09:14 +00:00
if ( g . Sector . GeometryBuffer ! = null & & g . Sector . Sector . Map ! = null )
{
// Change current sector
sector = g . Sector ;
// Set stream source
2019-08-16 11:07:57 +00:00
graphics . SetVertexBuffer ( sector . GeometryBuffer ) ;
2015-09-27 21:09:14 +00:00
}
else
{
sector = null ;
}
}
2018-04-10 16:41:35 +00:00
if ( sector ! = null )
{
// Determine the shader pass we want to use for this object
2019-08-14 10:36:33 +00:00
ShaderName wantedshaderpass = ( ( ( g = = highlighted ) & & showhighlight ) | | ( g . Selected & & showselection ) ) ? highshaderpass : shaderpass ;
2015-09-27 21:09:14 +00:00
2018-04-10 16:41:35 +00:00
//mxd. Render fog?
2022-01-04 19:17:12 +00:00
if ( General . Settings . GZDrawFog & & ! fullbrightness & & ! General . Settings . ClassicRendering & & sector . Sector . FogMode ! = SectorFogMode . NONE )
2018-04-10 16:41:35 +00:00
wantedshaderpass + = 8 ;
2015-09-27 21:09:14 +00:00
2018-04-10 16:41:35 +00:00
// Switch shader pass?
if ( currentshaderpass ! = wantedshaderpass )
{
2019-08-13 02:12:04 +00:00
graphics . SetShader ( wantedshaderpass ) ;
2018-04-10 16:41:35 +00:00
currentshaderpass = wantedshaderpass ;
2015-09-27 21:09:14 +00:00
2018-04-10 16:41:35 +00:00
//mxd. Set variables for fog rendering?
2019-08-14 10:36:33 +00:00
if ( wantedshaderpass > ShaderName . world3d_p7 )
2018-04-10 16:41:35 +00:00
{
2019-08-14 10:36:33 +00:00
graphics . SetUniform ( UniformName . modelnormal , Matrix . Identity ) ;
2018-04-10 16:41:35 +00:00
}
}
2015-09-27 21:09:14 +00:00
2018-04-10 16:41:35 +00:00
// Set variables for fog rendering?
2019-08-14 10:36:33 +00:00
if ( wantedshaderpass > ShaderName . world3d_p7 & & g . FogFactor ! = fogfactor )
2018-04-10 16:41:35 +00:00
{
2020-05-18 16:14:54 +00:00
graphics . SetUniform ( UniformName . campos , new Vector4f ( ( float ) cameraposition . x , ( float ) cameraposition . y , ( float ) cameraposition . z , g . FogFactor ) ) ;
2018-04-10 16:41:35 +00:00
fogfactor = g . FogFactor ;
}
2015-09-27 21:09:14 +00:00
2018-04-10 16:41:35 +00:00
//
2020-05-23 08:01:52 +00:00
graphics . SetUniform ( UniformName . desaturation , ( float ) sector . Sector . Desaturation ) ;
2015-10-02 14:47:34 +00:00
2023-07-09 09:45:47 +00:00
// Skew
graphics . SetUniform ( UniformName . skew , g . Skew ) ;
// Set the colors to use
graphics . SetUniform ( UniformName . sectorfogcolor , sector . Sector . FogColor ) ;
2019-08-14 10:36:33 +00:00
graphics . SetUniform ( UniformName . highlightcolor , CalculateHighlightColor ( ( g = = highlighted ) & & showhighlight , ( g . Selected & & showselection ) ) ) ;
2018-04-10 16:41:35 +00:00
// Render!
2019-08-16 05:12:26 +00:00
graphics . Draw ( PrimitiveType . TriangleList , g . VertexOffset , g . Triangles ) ;
2018-04-10 16:41:35 +00:00
}
2019-08-14 10:36:33 +00:00
else graphics . SetUniform ( UniformName . desaturation , 0.0f ) ;
2018-04-10 16:41:35 +00:00
}
2015-09-27 21:09:14 +00:00
2023-07-09 09:45:47 +00:00
// Done with geometry, reset potentially lingering skew setting
graphics . SetUniform ( UniformName . skew , new Vector2f ( 0.0f , 0.0f ) ) ;
graphics . SetUniform ( UniformName . lightsEnabled , false ) ;
2020-01-03 01:22:33 +00:00
// Get things for this pass
if ( thingspass . Count > 0 )
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
{
// Texture addressing
2019-08-17 01:21:11 +00:00
graphics . SetSamplerState ( TextureAddress . Clamp ) ;
2019-08-09 22:46:51 +00:00
graphics . SetCullMode ( Cull . None ) ; //mxd. Disable backside culling, because otherwise sprites with positive ScaleY and negative ScaleX will be facing away from the camera...
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
// Sort geometry by camera distance. First vertex of the BoundingBox is it's center
2016-01-11 13:00:52 +00:00
thingspass . Sort ( delegate ( VisualThing vt1 , VisualThing vt2 )
{
if ( vt1 = = vt2 ) return 0 ;
return ( int ) ( ( General . Map . VisualCamera . Position - vt2 . BoundingBox [ 0 ] ) . GetLengthSq ( )
- ( General . Map . VisualCamera . Position - vt1 . BoundingBox [ 0 ] ) . GetLengthSq ( ) ) ;
} ) ;
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
// Reset vars
currentpass = RenderPass . Solid ;
curtexturename = 0 ;
2015-10-02 14:47:34 +00:00
Color4 vertexcolor = new Color4 ( ) ;
fogfactor = - 1 ;
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
// Render things collected
foreach ( VisualThing t in thingspass )
{
2016-04-13 10:07:46 +00:00
// Update buffer if needed
t . Update ( ) ;
2019-12-29 12:00:10 +00:00
//mxd. Check 3D distance. Check against MaxValue to save doing GetLenthSq if there's not DistanceCheck defined
2020-12-12 10:48:46 +00:00
if ( t . Info . DistanceCheckSq < double . MaxValue )
{
t . CalculateCameraDistance ( cameraposition ) ;
if ( t . CameraDistance > t . Info . DistanceCheckSq )
continue ;
}
2016-04-11 23:05:16 +00:00
t . UpdateSpriteFrame ( ) ; // Set correct texture, geobuffer and triangles count
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
if ( t . Texture is UnknownImage ) continue ;
// Change blend mode?
if ( t . RenderPass ! = currentpass )
{
switch ( t . RenderPass )
{
case RenderPass . Additive :
2019-08-09 22:46:51 +00:00
graphics . SetDestinationBlend ( Blend . One ) ;
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
break ;
case RenderPass . Alpha :
2019-08-09 22:46:51 +00:00
graphics . SetDestinationBlend ( Blend . InverseSourceAlpha ) ;
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
break ;
}
currentpass = t . RenderPass ;
}
// Change texture?
if ( t . Texture . LongName ! = curtexturename )
{
2020-01-12 22:10:57 +00:00
curtexture = t . Texture ;
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
2022-01-04 19:17:12 +00:00
// Apply texture
Texture texture = UseIndexedTexture ? curtexture . IndexedTexture : curtexture . Texture ;
graphics . SetTexture ( texture ) ;
graphics . SetUniform ( UniformName . drawPaletted , texture . UserData = = ImageData . TEXTURE_INDEXED ) ;
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
curtexturename = t . Texture . LongName ;
}
// Only do this sector when a vertexbuffer is created
if ( t . GeometryBuffer ! = null )
{
// Determine the shader pass we want to use for this object
2019-08-14 10:36:33 +00:00
ShaderName wantedshaderpass = ( ( ( t = = highlighted ) & & showhighlight ) | | ( t . Selected & & showselection ) ) ? highshaderpass : shaderpass ;
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
//mxd. if fog is enagled, switch to shader, which calculates it
2022-01-04 19:17:12 +00:00
if ( General . Settings . GZDrawFog & & ! fullbrightness & & ! General . Settings . ClassicRendering & & t . Thing . Sector ! = null & & t . Thing . Sector . FogMode ! = SectorFogMode . NONE )
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
wantedshaderpass + = 8 ;
2015-10-02 14:47:34 +00:00
//mxd. Create the matrix for positioning
world = CreateThingPositionMatrix ( t ) ;
//mxd. If current thing is light - set it's color to light color
2022-01-04 19:17:12 +00:00
if ( t . LightType ! = null & & t . LightType . LightInternal & & ! fullbrightness & & ! General . Settings . ClassicRendering )
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
{
2015-10-02 14:47:34 +00:00
wantedshaderpass + = 4 ; // Render using one of passes, which uses World3D.VertexColor
vertexcolor = t . LightColor ;
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
}
2015-10-02 14:47:34 +00:00
//mxd. Check if Thing is affected by dynamic lights and set color accordingly
2022-01-04 19:17:12 +00:00
else if ( General . Settings . GZDrawLightsMode ! = LightRenderMode . NONE & & ! fullbrightness & & ! General . Settings . ClassicRendering & & lightthings . Count > 0 )
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
{
2016-03-23 21:26:26 +00:00
Color4 litcolor = GetLitColorForThing ( t ) ;
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
if ( litcolor . ToArgb ( ) ! = 0 )
{
2015-10-02 14:47:34 +00:00
wantedshaderpass + = 4 ; // Render using one of passes, which uses World3D.VertexColor
vertexcolor = new Color4 ( t . VertexColor ) + litcolor ;
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
}
}
2015-10-02 14:47:34 +00:00
else
{
vertexcolor = new Color4 ( ) ;
}
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
// Switch shader pass?
if ( currentshaderpass ! = wantedshaderpass )
{
2019-08-13 02:12:04 +00:00
graphics . SetShader ( wantedshaderpass ) ;
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
currentshaderpass = wantedshaderpass ;
}
2016-03-23 21:26:26 +00:00
//mxd. Set variables for fog rendering?
2019-08-14 10:36:33 +00:00
if ( wantedshaderpass > ShaderName . world3d_p7 )
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
{
2019-08-14 10:36:33 +00:00
graphics . SetUniform ( UniformName . modelnormal , Matrix . Identity ) ;
2018-05-27 05:53:54 +00:00
if ( t . FogFactor ! = fogfactor )
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
{
2020-05-18 16:14:54 +00:00
graphics . SetUniform ( UniformName . campos , new Vector4f ( ( float ) cameraposition . x , ( float ) cameraposition . y , ( float ) cameraposition . z , t . FogFactor ) ) ;
2016-03-23 21:26:26 +00:00
fogfactor = t . FogFactor ;
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
}
}
2019-08-13 02:12:04 +00:00
// Set the colors to use
2020-01-03 01:22:33 +00:00
graphics . SetUniform ( UniformName . sectorfogcolor , t . Thing . Sector . FogColor ) ;
2019-08-14 10:36:33 +00:00
graphics . SetUniform ( UniformName . vertexColor , vertexcolor ) ;
graphics . SetUniform ( UniformName . highlightcolor , CalculateHighlightColor ( ( t = = highlighted ) & & showhighlight , ( t . Selected & & showselection ) ) ) ;
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
2017-03-25 03:19:42 +00:00
// [ZZ] check if we want stencil
2019-08-14 10:36:33 +00:00
graphics . SetUniform ( UniformName . stencilColor , t . StencilColor . ToColorValue ( ) ) ;
2017-03-25 03:19:42 +00:00
2018-04-10 16:41:35 +00:00
//
2020-05-23 08:01:52 +00:00
graphics . SetUniform ( UniformName . desaturation , ( float ) t . Thing . Sector . Desaturation ) ;
2018-04-10 16:41:35 +00:00
2023-07-09 09:45:47 +00:00
// Apply changes
graphics . SetUniform ( UniformName . world , world ) ;
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
2019-12-18 13:24:54 +00:00
// Apply buffer
graphics . SetVertexBuffer ( t . GeometryBuffer ) ;
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
// Render!
2019-08-16 05:12:26 +00:00
graphics . Draw ( PrimitiveType . TriangleList , 0 , t . Triangles ) ;
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
}
}
2017-03-25 03:19:42 +00:00
// [ZZ] check if we want stencil
2019-08-16 03:37:03 +00:00
graphics . SetUniform ( UniformName . stencilColor , new Color4 ( 1f , 1f , 1f , 0f ) ) ;
2017-03-25 03:19:42 +00:00
// Texture addressing
2019-08-17 01:21:11 +00:00
graphics . SetSamplerState ( TextureAddress . Wrap ) ;
2019-08-15 12:49:49 +00:00
graphics . SetCullMode ( Cull . Clockwise ) ; //mxd
Added, Visual mode, DECORATE: "Alpha" and "DefaultAlpha" properties are now supported.
Added, Visual mode, DECORATE: "RenderStyle" property is now partially supported.
Added, Visual mode, DECORATE: +BRIGHT flag is now supported.
Added, Visual mode, UDMF: "Alpha" thing property is now supported.
Added, Visual mode, UDMF: "RenderStyle" thing property is now partially supported.
Added, Visual mode, Hexen map format and UDMF: "Translucent" and "Invisible" thing flags are now supported.
Added, Game Configurations: added "alpha" and "renderstyle" Thing and Thing Category properties.
Fixed, Visual mode: blockmap was not updated when moving things using "Move Thing Left/Right/Forward/Backward" and "Move Thing to Cursor Location" actions.
DECORATE parser: added a warning when unable to find actor's parent class.
Internal: current map format can now be checked using "General.Map.UDMF", "General.Map.HEXEN" and "General.Map.DOOM" properties.
Updated documentation ("Game Configuration - Things Settings" page).
2015-09-28 14:57:48 +00:00
}
2015-09-27 21:09:14 +00:00
}
2015-10-02 14:47:34 +00:00
//mxd
private Matrix CreateThingPositionMatrix ( VisualThing t )
{
2016-07-11 22:13:43 +00:00
// Use normal ThingRenderMode when model rendering is disabled for this thing
ThingRenderMode rendermode = t . Thing . RenderMode ;
if ( ( t . Thing . RenderMode = = ThingRenderMode . MODEL | | t . Thing . RenderMode = = ThingRenderMode . VOXEL ) & &
( General . Settings . GZDrawModelsMode = = ModelRenderMode . NONE | |
( General . Settings . GZDrawModelsMode = = ModelRenderMode . SELECTION & & ! t . Selected ) ) )
{
rendermode = ThingRenderMode . NORMAL ;
}
2016-07-04 18:25:47 +00:00
// Create the matrix for positioning
2016-07-11 22:13:43 +00:00
switch ( rendermode )
2015-10-02 14:47:34 +00:00
{
2016-07-04 18:25:47 +00:00
case ThingRenderMode . NORMAL :
if ( t . Info . XYBillboard ) // Apply billboarding?
{
return Matrix . Translation ( 0f , 0f , - t . LocalCenterZ )
2020-05-18 16:14:54 +00:00
* Matrix . RotationX ( ( float ) ( Angle2D . PI - General . Map . VisualCamera . AngleZ ) )
2016-07-04 18:25:47 +00:00
* Matrix . Translation ( 0f , 0f , t . LocalCenterZ )
* billboard
2015-10-02 14:47:34 +00:00
* t . Position ;
2016-07-04 18:25:47 +00:00
}
2016-10-04 09:53:38 +00:00
return billboard * t . Position ;
2016-07-04 18:25:47 +00:00
case ThingRenderMode . FLATSPRITE :
case ThingRenderMode . WALLSPRITE :
case ThingRenderMode . MODEL :
2016-07-11 22:13:43 +00:00
case ThingRenderMode . VOXEL :
2016-10-04 09:53:38 +00:00
return t . Position ;
2016-07-04 18:25:47 +00:00
default : throw new NotImplementedException ( "Unknown ThingRenderMode" ) ;
2015-10-02 14:47:34 +00:00
}
}
2018-02-04 02:18:59 +00:00
private float CosDeg ( float angle )
{
return ( float ) Math . Cos ( Angle2D . DegToRad ( angle ) ) ;
}
2017-02-09 13:03:22 +00:00
//mxd. Render models
2020-01-03 01:22:33 +00:00
private void RenderModels ( bool trans , List < VisualThing > lights )
2014-10-20 12:16:51 +00:00
{
2019-08-14 10:36:33 +00:00
ShaderName shaderpass = ( fullbrightness ? ShaderName . world3d_fullbright : ShaderName . world3d_main_vertexcolor ) ;
ShaderName currentshaderpass = shaderpass ;
ShaderName highshaderpass = ( ShaderName ) ( shaderpass + 2 ) ;
2013-09-11 09:47:53 +00:00
2017-07-26 15:35:22 +00:00
RenderPass currentpass = RenderPass . Solid ;
2013-09-11 09:47:53 +00:00
2017-07-26 15:35:22 +00:00
// Begin rendering with this shader
2020-01-03 01:22:33 +00:00
graphics . SetShader ( currentshaderpass ) ;
// Light data arrays
Vector4f [ ] lightColor = new Vector4f [ MAX_DYNLIGHTS_PER_SURFACE ] ;
Vector4f [ ] lightPosAndRadius = new Vector4f [ MAX_DYNLIGHTS_PER_SURFACE ] ;
Vector4f [ ] lightOrientation = new Vector4f [ MAX_DYNLIGHTS_PER_SURFACE ] ;
Vector2f [ ] light2Radius = new Vector2f [ MAX_DYNLIGHTS_PER_SURFACE ] ;
graphics . SetUniform ( UniformName . lightsEnabled , lights . Count > 0 ) ;
2020-01-03 01:55:34 +00:00
graphics . SetUniform ( UniformName . ignoreNormals , true ) ;
2020-01-03 01:22:33 +00:00
bool hadlights = false ;
2015-12-01 14:51:45 +00:00
2017-07-26 15:35:22 +00:00
List < VisualThing > things ;
if ( trans )
{
// Sort models by camera distance. First vertex of the BoundingBox is it's center
translucentmodelthings . Sort ( ( vt1 , vt2 ) = > ( int ) ( ( General . Map . VisualCamera . Position - vt2 . BoundingBox [ 0 ] ) . GetLengthSq ( )
- ( General . Map . VisualCamera . Position - vt1 . BoundingBox [ 0 ] ) . GetLengthSq ( ) ) ) ;
things = translucentmodelthings ;
}
else
{
things = new List < VisualThing > ( ) ;
foreach ( KeyValuePair < ModelData , List < VisualThing > > group in maskedmodelthings )
foreach ( VisualThing t in group . Value )
things . Add ( t ) ;
}
foreach ( VisualThing t in things )
2015-12-01 14:51:45 +00:00
{
2020-01-03 01:22:33 +00:00
2017-07-26 15:35:22 +00:00
if ( trans )
{
// Change blend mode?
if ( t . RenderPass ! = currentpass )
{
switch ( t . RenderPass )
{
case RenderPass . Additive :
2019-08-09 22:46:51 +00:00
graphics . SetDestinationBlend ( Blend . One ) ;
2017-07-26 15:35:22 +00:00
break ;
2015-12-01 14:51:45 +00:00
2017-07-26 15:35:22 +00:00
case RenderPass . Alpha :
2019-08-09 22:46:51 +00:00
graphics . SetDestinationBlend ( Blend . InverseSourceAlpha ) ;
2017-07-26 15:35:22 +00:00
break ;
}
currentpass = t . RenderPass ;
}
}
2015-12-01 14:51:45 +00:00
2016-04-13 10:07:46 +00:00
// Update buffer if needed
2015-12-01 14:51:45 +00:00
t . Update ( ) ;
2016-04-13 10:07:46 +00:00
2019-12-29 12:00:10 +00:00
// Check 3D distance. Check against MaxValue to save doing GetLenthSq if there's not DistanceCheck defined
2020-12-12 10:48:46 +00:00
if ( t . Info . DistanceCheckSq < double . MaxValue )
{
t . CalculateCameraDistance ( cameraposition ) ;
if ( t . CameraDistance > t . Info . DistanceCheckSq )
continue ;
}
2017-07-26 15:35:22 +00:00
2015-12-01 14:51:45 +00:00
Color4 vertexcolor = new Color4 ( t . VertexColor ) ;
2017-07-26 15:35:22 +00:00
// Check if model is affected by dynamic lights and set color accordingly
2019-08-14 10:36:33 +00:00
graphics . SetUniform ( UniformName . vertexColor , vertexcolor ) ;
2015-12-01 14:51:45 +00:00
// Determine the shader pass we want to use for this object
2019-08-14 10:36:33 +00:00
ShaderName wantedshaderpass = ( ( ( ( t = = highlighted ) & & showhighlight ) | | ( t . Selected & & showselection ) ) ? highshaderpass : shaderpass ) ;
2015-12-01 14:51:45 +00:00
2016-04-13 10:07:46 +00:00
// If fog is enagled, switch to shader, which calculates it
2022-01-04 19:17:12 +00:00
if ( General . Settings . GZDrawFog & & ! fullbrightness & & ! General . Settings . ClassicRendering & & t . Thing . Sector ! = null & & t . Thing . Sector . FogMode ! = SectorFogMode . NONE )
2015-12-01 14:51:45 +00:00
wantedshaderpass + = 8 ;
// Switch shader pass?
2020-01-03 01:22:33 +00:00
if ( currentshaderpass ! = wantedshaderpass )
2015-12-01 14:51:45 +00:00
{
2019-08-13 02:12:04 +00:00
graphics . SetShader ( wantedshaderpass ) ;
2015-12-01 14:51:45 +00:00
currentshaderpass = wantedshaderpass ;
}
2019-08-13 02:12:04 +00:00
// Set the colors to use
2019-08-14 10:36:33 +00:00
graphics . SetUniform ( UniformName . highlightcolor , CalculateHighlightColor ( ( t = = highlighted ) & & showhighlight , ( t . Selected & & showselection ) ) ) ;
2015-12-01 14:51:45 +00:00
// Create the matrix for positioning / rotation
2020-05-21 12:20:02 +00:00
double sx = t . Thing . ScaleX * t . Thing . ActorScale . Width ;
double sy = t . Thing . ScaleY * t . Thing . ActorScale . Height ;
2018-05-27 05:53:54 +00:00
2020-05-21 12:20:02 +00:00
Matrix modelscale = Matrix . Scaling ( ( float ) sx , ( float ) sx , ( float ) sy ) ;
2020-05-18 16:14:54 +00:00
Matrix modelrotation = Matrix . RotationY ( ( float ) - t . Thing . RollRad ) * Matrix . RotationX ( ( float ) - t . Thing . PitchRad ) * Matrix . RotationZ ( ( float ) t . Thing . Angle ) ;
2015-12-01 14:51:45 +00:00
2022-10-21 18:29:30 +00:00
if ( General . Map . Data . ModeldefEntries [ t . Thing . Type ] . UseRotationCenter )
world = General . Map . Data . ModeldefEntries [ t . Thing . Type ] . Transform * modelscale * Matrix . Translation ( - General . Map . Data . ModeldefEntries [ t . Thing . Type ] . RotationCenter ) * modelrotation * Matrix . Translation ( General . Map . Data . ModeldefEntries [ t . Thing . Type ] . RotationCenter ) * t . Position ;
else
world = General . Map . Data . ModeldefEntries [ t . Thing . Type ] . Transform * modelscale * modelrotation * t . Position ;
2019-12-19 02:12:44 +00:00
graphics . SetUniform ( UniformName . world , world ) ;
2015-12-01 14:51:45 +00:00
2019-12-18 13:24:54 +00:00
// Set variables for fog rendering
if ( wantedshaderpass > ShaderName . world3d_p7 )
2015-12-01 14:51:45 +00:00
{
2018-05-27 05:53:54 +00:00
// this is not right...
2019-08-14 10:36:33 +00:00
graphics . SetUniform ( UniformName . modelnormal , General . Map . Data . ModeldefEntries [ t . Thing . Type ] . TransformRotation * modelrotation ) ;
2020-01-03 01:22:33 +00:00
if ( t . Thing . Sector ! = null ) graphics . SetUniform ( UniformName . sectorfogcolor , t . Thing . Sector . FogColor ) ;
2020-05-18 16:14:54 +00:00
graphics . SetUniform ( UniformName . campos , new Vector4f ( ( float ) cameraposition . x , ( float ) cameraposition . y , ( float ) cameraposition . z , t . FogFactor ) ) ;
2015-12-01 14:51:45 +00:00
}
2018-06-23 16:20:39 +00:00
if ( t . Thing . Sector ! = null )
2020-05-23 08:01:52 +00:00
graphics . SetUniform ( UniformName . desaturation , ( float ) t . Thing . Sector . Desaturation ) ;
2019-08-14 10:36:33 +00:00
else graphics . SetUniform ( UniformName . desaturation , 0.0f ) ;
2018-04-10 16:41:35 +00:00
2020-01-03 01:22:33 +00:00
int lightIndex = 0 ;
2015-12-01 14:51:45 +00:00
2020-01-03 01:22:33 +00:00
foreach ( VisualThing light in lights )
{
if ( BoundingBoxesIntersect ( t . BoundingBox , light . BoundingBox ) )
2017-07-26 15:35:22 +00:00
{
2020-01-03 01:22:33 +00:00
//t.LightType.LightRenderStyle
//Vector4f lightColor, lightPosAndRadius, lightOrientation, light2Radius;
2017-07-26 15:35:22 +00:00
2020-01-03 01:22:33 +00:00
lightColor [ lightIndex ] = light . LightColor . ToVector ( ) ;
lightPosAndRadius [ lightIndex ] = new Vector4f ( light . Center , light . LightRadius ) ;
2017-07-26 15:35:22 +00:00
2020-01-03 01:22:33 +00:00
// set type of light
if ( light . LightType . LightType = = GZGeneral . LightType . SPOT )
2017-07-26 15:35:22 +00:00
{
2020-01-03 01:22:33 +00:00
lightOrientation [ lightIndex ] = new Vector4f ( light . VectorLookAt , 1f ) ;
light2Radius [ lightIndex ] = new Vector2f ( CosDeg ( light . LightSpotRadius1 ) , CosDeg ( light . LightSpotRadius2 ) ) ;
2017-07-26 15:35:22 +00:00
}
2020-01-03 01:22:33 +00:00
else lightOrientation [ lightIndex ] . W = 0f ;
2017-07-26 15:35:22 +00:00
2020-01-03 01:22:33 +00:00
lightIndex + + ;
2017-07-26 15:35:22 +00:00
2020-01-03 01:22:33 +00:00
if ( lightIndex > = lightColor . Length )
break ;
2017-07-26 15:35:22 +00:00
2020-01-03 01:22:33 +00:00
}
}
2017-07-26 15:35:22 +00:00
2020-01-03 01:22:33 +00:00
bool havelights = ( lightIndex > 0 ) ;
for ( int i = lightIndex ; i < lightColor . Length ; i + + )
lightColor [ i ] . W = 0 ;
if ( hadlights ! = havelights | | havelights )
{
graphics . SetUniform ( UniformName . lightColor , lightColor ) ;
if ( havelights )
{
graphics . SetUniform ( UniformName . lightPosAndRadius , lightPosAndRadius ) ;
graphics . SetUniform ( UniformName . lightOrientation , lightOrientation ) ;
graphics . SetUniform ( UniformName . light2Radius , light2Radius ) ;
2017-07-26 15:35:22 +00:00
}
}
2020-01-03 01:22:33 +00:00
hadlights = havelights ;
GZModel model = General . Map . Data . ModeldefEntries [ t . Thing . Type ] . Model ;
for ( int j = 0 ; j < model . Meshes . Count ; j + + )
{
graphics . SetTexture ( model . Textures [ j ] ) ;
// Render!
model . Meshes [ j ] . Draw ( graphics ) ;
}
2015-12-01 14:51:45 +00:00
}
2020-01-03 01:22:33 +00:00
graphics . SetUniform ( UniformName . lightsEnabled , false ) ;
2017-10-25 04:58:48 +00:00
}
2013-09-11 09:47:53 +00:00
2016-01-11 13:00:52 +00:00
//mxd
private void RenderSky ( IEnumerable < VisualGeometry > geo )
{
VisualSector sector = null ;
// Set render settings
2019-08-14 10:36:33 +00:00
graphics . SetShader ( ShaderName . world3d_skybox ) ;
2019-08-17 01:21:11 +00:00
graphics . SetTexture ( General . Map . Data . SkyBox ) ;
2020-05-18 16:14:54 +00:00
graphics . SetUniform ( UniformName . campos , new Vector4f ( ( float ) cameraposition . x , ( float ) cameraposition . y , ( float ) cameraposition . z , 0f ) ) ;
2016-01-11 13:00:52 +00:00
foreach ( VisualGeometry g in geo )
{
// Changing sector?
if ( ! object . ReferenceEquals ( g . Sector , sector ) )
{
// Update the sector if needed
2019-08-15 00:52:21 +00:00
if ( g . Sector . NeedsUpdateGeo ) g . Sector . Update ( graphics ) ;
2016-01-11 13:00:52 +00:00
// Only do this sector when a vertexbuffer is created
//mxd. No Map means that sector was deleted recently, I suppose
if ( g . Sector . GeometryBuffer ! = null & & g . Sector . Sector . Map ! = null )
{
// Change current sector
sector = g . Sector ;
// Set stream source
2019-08-16 11:07:57 +00:00
graphics . SetVertexBuffer ( sector . GeometryBuffer ) ;
2016-01-11 13:00:52 +00:00
}
else
{
sector = null ;
}
}
if ( sector ! = null )
{
2019-08-14 10:36:33 +00:00
graphics . SetUniform ( UniformName . highlightcolor , CalculateHighlightColor ( ( g = = highlighted ) & & showhighlight , ( g . Selected & & showselection ) ) ) ;
2019-08-16 05:12:26 +00:00
graphics . Draw ( PrimitiveType . TriangleList , g . VertexOffset , g . Triangles ) ;
2016-01-11 13:00:52 +00:00
}
}
}
2018-02-04 02:18:59 +00:00
// [ZZ] this is copied from GZDoom
private float Smoothstep ( float edge0 , float edge1 , float x )
{
double t = Math . Min ( Math . Max ( ( x - edge0 ) / ( edge1 - edge0 ) , 0.0 ) , 1.0 ) ;
return ( float ) ( t * t * ( 3.0 - 2.0 * t ) ) ;
}
2013-09-11 09:47:53 +00:00
//mxd. This gets color from dynamic lights based on distance to thing.
//thing position must be in absolute cordinates
//(thing.Position.Z value is relative to floor of the sector the thing is in)
2014-12-03 23:15:26 +00:00
private Color4 GetLitColorForThing ( VisualThing t )
{
2013-09-11 09:47:53 +00:00
Color4 litColor = new Color4 ( ) ;
2015-12-01 14:51:45 +00:00
foreach ( VisualThing lt in lightthings )
2014-12-03 23:15:26 +00:00
{
2015-12-01 14:51:45 +00:00
// Don't light self
if ( General . Map . Data . GldefsEntries . ContainsKey ( t . Thing . Type ) & & General . Map . Data . GldefsEntries [ t . Thing . Type ] . DontLightSelf & & t . Thing . Index = = lt . Thing . Index )
2013-09-11 09:47:53 +00:00
continue ;
2020-01-03 01:22:33 +00:00
float distSquared = Vector3f . DistanceSquared ( lt . Center , t . Center ) ;
2018-02-04 02:18:59 +00:00
float radiusSquared = lt . LightRadius * lt . LightRadius ;
2015-09-27 21:09:14 +00:00
if ( distSquared < radiusSquared )
2014-12-03 23:15:26 +00:00
{
2018-02-04 02:18:59 +00:00
int sign = ( lt . LightType . LightRenderStyle = = GZGeneral . LightRenderStyle . SUBTRACTIVE ? - 1 : 1 ) ;
2020-01-03 01:22:33 +00:00
Vector3f L = ( t . Center - lt . Center ) ;
2018-02-04 02:18:59 +00:00
float dist = L . Length ( ) ;
float scaler = 1 - dist / lt . LightRadius * lt . LightColor . Alpha ;
if ( lt . LightType . LightType = = GZGeneral . LightType . SPOT )
{
2020-01-03 01:22:33 +00:00
Vector3f lookAt = lt . VectorLookAt ;
2018-02-04 02:18:59 +00:00
L . Normalize ( ) ;
2020-01-03 01:22:33 +00:00
float cosDir = Vector3f . Dot ( - L , lookAt ) ;
2018-02-04 02:18:59 +00:00
scaler * = ( float ) Smoothstep ( CosDeg ( lt . LightSpotRadius2 ) , CosDeg ( lt . LightSpotRadius1 ) , cosDir ) ;
}
if ( scaler > 0 )
{
litColor . Red + = lt . LightColor . Red * scaler * sign ;
litColor . Green + = lt . LightColor . Green * scaler * sign ;
litColor . Blue + = lt . LightColor . Blue * scaler * sign ;
}
2013-09-11 09:47:53 +00:00
}
}
2015-12-28 15:01:53 +00:00
2013-09-11 09:47:53 +00:00
return litColor ;
}
2009-05-05 21:13:50 +00:00
// This calculates the highlight/selection color
2014-12-03 23:15:26 +00:00
private Color4 CalculateHighlightColor ( bool ishighlighted , bool isselected )
2009-05-05 21:13:50 +00:00
{
2016-01-11 13:00:52 +00:00
if ( ! ishighlighted & & ! isselected ) return new Color4 ( ) ; //mxd
2009-05-05 21:13:50 +00:00
Color4 highlightcolor = isselected ? General . Colors . Selection . ToColorValue ( ) : General . Colors . Highlight . ToColorValue ( ) ;
highlightcolor . Alpha = ishighlighted ? highlightglowinv : highlightglow ;
return highlightcolor ;
}
2009-04-19 18:07:22 +00:00
// This finishes rendering
public void Finish ( )
{
2010-08-22 12:09:32 +00:00
General . Plugins . OnPresentDisplayBegin ( ) ;
2009-04-19 18:07:22 +00:00
// Done
graphics . FinishRendering ( ) ;
graphics . Present ( ) ;
highlighted = null ;
}
#endregion
#region = = = = = = = = = = = = = = = = = = Rendering
// This sets the highlighted object for the rendering
public void SetHighlightedObject ( IVisualPickable obj )
{
highlighted = obj ;
}
// This collects a visual sector's geometry for rendering
public void AddSectorGeometry ( VisualGeometry g )
{
2009-07-04 10:06:35 +00:00
// Must have a texture and vertices
2015-09-27 21:09:14 +00:00
if ( g . Texture ! = null & & g . Triangles > 0 )
2009-04-19 18:07:22 +00:00
{
2016-01-11 13:00:52 +00:00
if ( g . RenderAsSky & & General . Settings . GZDrawSky )
2009-04-19 18:07:22 +00:00
{
2016-01-11 13:00:52 +00:00
skygeo . Add ( g ) ;
}
else
{
switch ( g . RenderPass )
{
case RenderPass . Solid :
if ( ! solidgeo . ContainsKey ( g . Texture ) )
solidgeo . Add ( g . Texture , new List < VisualGeometry > ( ) ) ;
solidgeo [ g . Texture ] . Add ( g ) ;
break ;
case RenderPass . Mask :
if ( ! maskedgeo . ContainsKey ( g . Texture ) )
maskedgeo . Add ( g . Texture , new List < VisualGeometry > ( ) ) ;
maskedgeo [ g . Texture ] . Add ( g ) ;
break ;
case RenderPass . Additive :
case RenderPass . Alpha :
translucentgeo . Add ( g ) ;
break ;
default :
throw new NotImplementedException ( "Geometry rendering of " + g . RenderPass + " render pass is not implemented!" ) ;
}
2009-04-19 18:07:22 +00:00
}
}
}
// This collects a visual sector's geometry for rendering
public void AddThingGeometry ( VisualThing t )
{
2020-03-29 15:30:32 +00:00
// The thing might have changed, especially when doing realtime editing from the edit thing dialog, so update it if necessary
t . Update ( ) ;
2015-12-01 14:51:45 +00:00
//mxd. Gather lights
2019-08-24 10:43:35 +00:00
if ( General . Settings . GZDrawLightsMode ! = LightRenderMode . NONE & & ! fullbrightness & & t . LightType ! = null )
2014-10-20 12:16:51 +00:00
{
2013-09-11 09:47:53 +00:00
t . UpdateLightRadius ( ) ;
2017-02-09 12:28:54 +00:00
if ( t . LightRadius > 0 )
2014-10-20 12:16:51 +00:00
{
2018-02-03 20:31:34 +00:00
if ( t . LightType ! = null & & t . LightType . LightAnimated )
2017-02-09 12:28:54 +00:00
t . UpdateBoundingBox ( ) ;
2015-09-27 21:09:14 +00:00
lightthings . Add ( t ) ;
2013-09-11 09:47:53 +00:00
}
}
2015-12-01 14:51:45 +00:00
//mxd. Gather models
2016-07-11 22:13:43 +00:00
if ( ( t . Thing . RenderMode = = ThingRenderMode . MODEL | | t . Thing . RenderMode = = ThingRenderMode . VOXEL ) & &
2015-06-29 08:15:07 +00:00
( General . Settings . GZDrawModelsMode = = ModelRenderMode . ALL | |
General . Settings . GZDrawModelsMode = = ModelRenderMode . ACTIVE_THINGS_FILTER | |
( General . Settings . GZDrawModelsMode = = ModelRenderMode . SELECTION & & t . Selected ) ) )
2014-10-20 12:16:51 +00:00
{
2017-07-26 16:34:01 +00:00
if ( t . RenderPass = = RenderPass . Mask | |
t . RenderPass = = RenderPass . Solid | |
( t . RenderPass = = RenderPass . Alpha & & ( t . VertexColor & 0xFF000000 ) = = 0xFF000000 ) )
{
ModelData mde = General . Map . Data . ModeldefEntries [ t . Thing . Type ] ;
if ( ! maskedmodelthings . ContainsKey ( mde ) ) maskedmodelthings . Add ( mde , new List < VisualThing > ( ) ) ;
maskedmodelthings [ mde ] . Add ( t ) ;
}
else if ( t . RenderPass = = RenderPass . Alpha | | t . RenderPass = = RenderPass . Additive )
{
translucentmodelthings . Add ( t ) ;
}
else
{
throw new NotImplementedException ( "Thing model rendering of " + t . RenderPass + " render pass is not implemented!" ) ;
}
2015-12-01 14:51:45 +00:00
}
// Gather regular things
2016-04-11 23:05:16 +00:00
else
2009-04-19 18:07:22 +00:00
{
2016-04-11 23:05:16 +00:00
//mxd. Set correct texture, geobuffer and triangles count
t . UpdateSpriteFrame ( ) ;
//Must have a texture!
if ( t . Texture ! = null )
2009-04-19 18:07:22 +00:00
{
2016-04-11 23:05:16 +00:00
//mxd
switch ( t . RenderPass )
{
case RenderPass . Solid :
if ( ! solidthings . ContainsKey ( t . Texture ) ) solidthings . Add ( t . Texture , new List < VisualThing > ( ) ) ;
solidthings [ t . Texture ] . Add ( t ) ;
break ;
2015-09-27 21:09:14 +00:00
2016-04-11 23:05:16 +00:00
case RenderPass . Mask :
if ( ! maskedthings . ContainsKey ( t . Texture ) ) maskedthings . Add ( t . Texture , new List < VisualThing > ( ) ) ;
maskedthings [ t . Texture ] . Add ( t ) ;
break ;
2015-09-27 21:09:14 +00:00
2016-04-11 23:05:16 +00:00
case RenderPass . Additive :
case RenderPass . Alpha :
translucentthings . Add ( t ) ;
break ;
2009-04-19 18:07:22 +00:00
2016-04-11 23:05:16 +00:00
default :
throw new NotImplementedException ( "Thing rendering of " + t . RenderPass + " render pass is not implemented!" ) ;
}
2015-09-27 21:09:14 +00:00
}
2009-04-19 18:07:22 +00:00
}
2015-12-01 14:51:45 +00:00
//mxd. Add to the plain list
allthings . Add ( t ) ;
2009-04-19 18:07:22 +00:00
}
2013-03-18 13:52:27 +00:00
//mxd
2015-10-02 14:47:34 +00:00
public void SetVisualVertices ( List < VisualVertex > verts ) { visualvertices = verts ; }
2021-02-06 13:51:00 +00:00
public void SetVisualSlopeHandles ( ICollection < VisualSlope > handles ) { visualslopehandles = handles ; }
2019-12-30 23:08:17 +00:00
2015-10-02 14:47:34 +00:00
//mxd
public void SetEventLines ( List < Line3D > lines ) { eventlines = lines ; }
2013-03-18 13:52:27 +00:00
2013-09-11 09:47:53 +00:00
//mxd
2015-09-27 21:09:14 +00:00
private static bool BoundingBoxesIntersect ( Vector3D [ ] bbox1 , Vector3D [ ] bbox2 )
2014-10-20 12:16:51 +00:00
{
2015-09-27 21:09:14 +00:00
Vector3D dist = bbox1 [ 0 ] - bbox2 [ 0 ] ;
2013-09-11 09:47:53 +00:00
2015-09-27 21:09:14 +00:00
Vector3D halfSize1 = bbox1 [ 0 ] - bbox1 [ 1 ] ;
Vector3D halfSize2 = bbox2 [ 0 ] - bbox2 [ 1 ] ;
2013-09-11 09:47:53 +00:00
2015-09-27 21:09:14 +00:00
return ( halfSize1 . x + halfSize2 . x > = Math . Abs ( dist . x ) & & halfSize1 . y + halfSize2 . y > = Math . Abs ( dist . y ) & & halfSize1 . z + halfSize2 . z > = Math . Abs ( dist . z ) ) ;
2013-09-11 09:47:53 +00:00
}
2012-04-17 19:13:47 +00:00
2009-04-19 18:07:22 +00:00
// This renders the crosshair
public void RenderCrosshair ( )
{
2015-09-27 21:09:14 +00:00
//mxd
world = Matrix . Identity ;
2019-12-19 02:12:44 +00:00
graphics . SetUniform ( UniformName . world , world ) ;
2019-12-18 13:24:54 +00:00
// Set renderstates
graphics . SetCullMode ( Cull . None ) ;
2019-08-09 22:46:51 +00:00
graphics . SetZEnable ( false ) ;
graphics . SetAlphaBlendEnable ( true ) ;
graphics . SetAlphaTestEnable ( false ) ;
graphics . SetSourceBlend ( Blend . SourceAlpha ) ;
graphics . SetDestinationBlend ( Blend . InverseSourceAlpha ) ;
2019-08-14 10:36:33 +00:00
graphics . SetShader ( ShaderName . display2d_normal ) ;
2019-08-22 16:43:54 +00:00
graphics . SetUniform ( UniformName . projection , world * view2d ) ;
graphics . SetUniform ( UniformName . texturefactor , new Color4 ( 1f , 1f , 1f , 1f ) ) ;
2020-01-03 01:22:33 +00:00
graphics . SetUniform ( UniformName . rendersettings , new Vector4f ( 1.0f , 1.0f , 0.0f , 1.0f ) ) ;
2019-12-29 17:54:22 +00:00
graphics . SetSamplerFilter ( General . Settings . VisualBilinear ? TextureFilter . Linear : TextureFilter . Nearest ) ;
2019-08-22 16:43:54 +00:00
// Texture
if ( crosshairbusy )
2013-09-11 09:47:53 +00:00
{
2019-08-17 01:21:11 +00:00
graphics . SetTexture ( General . Map . Data . CrosshairBusy3D . Texture ) ;
2013-09-11 09:47:53 +00:00
}
else
{
2019-08-17 01:21:11 +00:00
graphics . SetTexture ( General . Map . Data . Crosshair3D . Texture ) ;
2013-09-11 09:47:53 +00:00
}
2009-04-19 18:07:22 +00:00
2013-09-11 09:47:53 +00:00
// Draw
2019-08-22 16:43:54 +00:00
graphics . Draw ( PrimitiveType . TriangleStrip , 0 , 2 , crosshairverts ) ;
2019-12-20 14:17:32 +00:00
2020-09-26 16:15:01 +00:00
if ( General . Settings . ShowFPS )
General . Map . Renderer2D . RenderText ( fpsLabel ) ;
2019-12-20 14:17:32 +00:00
}
2009-04-19 18:07:22 +00:00
2019-08-16 11:07:57 +00:00
// This switches fog on and off
public void SetFogMode ( bool usefog )
2009-04-19 18:07:22 +00:00
{
2019-08-22 16:43:54 +00:00
if ( usefog )
{
2020-01-03 01:22:33 +00:00
graphics . SetUniform ( UniformName . fogsettings , new Vector4f ( General . Settings . ViewDistance * FOG_RANGE , General . Settings . ViewDistance , 0.0f , 0.0f ) ) ;
2019-08-22 16:43:54 +00:00
}
else
{
2020-01-03 01:22:33 +00:00
graphics . SetUniform ( UniformName . fogsettings , new Vector4f ( - 1.0f ) ) ;
2019-08-22 16:43:54 +00:00
}
2009-04-19 18:07:22 +00:00
}
// This siwtches crosshair busy icon on and off
public void SetCrosshairBusy ( bool busy )
{
crosshairbusy = busy ;
}
#endregion
}
}