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 ;
2014-10-20 12:16:51 +00:00
using CodeImp.DoomBuilder.Config ;
2009-04-19 18:07:22 +00:00
using SlimDX ;
using CodeImp.DoomBuilder.Geometry ;
using SlimDX.Direct3D9 ;
using CodeImp.DoomBuilder.Data ;
using CodeImp.DoomBuilder.VisualModes ;
using CodeImp.DoomBuilder.Map ;
2013-04-11 11:04:16 +00:00
using CodeImp.DoomBuilder.GZBuilder.Data ; //mxd
using CodeImp.DoomBuilder.GZBuilder.Geometry ; //mxd
using CodeImp.DoomBuilder.GZBuilder.Rendering ; //mxd
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 ;
2014-12-22 21:36:49 +00:00
internal const float GZDOOM_VERTICAL_VIEW_STRETCH = 1.2f ;
internal const float GZDOOM_INVERTED_VERTICAL_VIEW_STRETCH = 1.0f / GZDOOM_VERTICAL_VIEW_STRETCH ;
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Variables
// Matrices
private Matrix projection ;
private Matrix view3d ;
private Matrix billboard ;
private Matrix worldviewproj ;
private Matrix view2d ;
private Matrix world ;
private Vector3D cameraposition ;
private int shaderpass ;
// Window size
private Size windowsize ;
// Frustum
private ProjectedFrustum2D frustum ;
// Thing cage
2013-09-11 09:47:53 +00:00
private bool renderthingcages ;
//mxd
private ThingBoundingBox bbox ;
2013-03-18 13:52:27 +00:00
private VisualVertexHandle vertexHandle ;
private SizelessVisualThingCage sizelessThingHandle ;
2015-09-27 21:09:14 +00:00
private List < VisualThing > lightthings ;
2013-09-11 09:47:53 +00:00
private int [ ] lightOffsets ;
2015-09-27 21:09:14 +00:00
private Dictionary < ModelData , List < VisualThing > > modelthings ;
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-05-04 06:13:56 +00:00
private ColorImage highlightimage ;
private ColorImage selectionimage ;
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-09-27 21:09:14 +00:00
// mxd. Translucent geometry to be rendered. Must be sorted by camera distance.
private List < VisualGeometry > translucentgeo ;
//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 ;
//mxd. All things. Used to render thing cages
private List < VisualThing > allthings ;
2013-03-18 13:52:27 +00:00
//mxd. Visual vertices
private VisualVertex [ ] visualvertices ;
2013-09-11 09:47:53 +00:00
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Properties
public ProjectedFrustum2D Frustum2D { get { return frustum ; } }
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
#endregion
#region = = = = = = = = = = = = = = = = = = Constructor / Disposer
// Constructor
internal Renderer3D ( D3DDevice graphics ) : base ( graphics )
{
// Initialize
CreateProjection ( ) ;
CreateMatrices2D ( ) ;
2014-09-16 20:26:42 +00:00
SetupHelperObjects ( ) ; //mxd
2009-05-04 06:13:56 +00:00
SetupTextures ( ) ;
2009-04-19 18:07:22 +00:00
renderthingcages = true ;
2009-07-07 14:52:39 +00:00
showselection = true ;
showhighlight = true ;
2009-04-19 18:07:22 +00:00
// Dummy frustum
frustum = new ProjectedFrustum2D ( new Vector2D ( ) , 0.0f , 0.0f , PROJ_NEAR_PLANE ,
2014-02-21 14:42:12 +00:00
General . Settings . ViewDistance , Angle2D . DegToRad ( General . Settings . VisualFOV ) ) ;
2009-04-19 18:07:22 +00:00
// We have no destructor
GC . SuppressFinalize ( this ) ;
}
// Disposer
internal override void Dispose ( )
{
// Not already disposed?
if ( ! isdisposed )
{
// Clean up
2009-05-04 06:13:56 +00:00
if ( selectionimage ! = null ) selectionimage . Dispose ( ) ;
if ( highlightimage ! = null ) highlightimage . Dispose ( ) ;
selectionimage = null ;
highlightimage = null ;
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 ;
2012-04-17 19:13:47 +00:00
2009-05-04 06:13:56 +00:00
if ( selectionimage ! = null ) selectionimage . Dispose ( ) ;
if ( highlightimage ! = null ) highlightimage . Dispose ( ) ;
selectionimage = null ;
highlightimage = null ;
2009-04-19 18:07:22 +00:00
}
// This is called resets when the device is reset
// (when resized or display adapter was changed)
public override void ReloadResource ( )
{
CreateMatrices2D ( ) ;
2009-05-04 06:13:56 +00:00
SetupTextures ( ) ;
2009-04-19 18:07:22 +00:00
}
// 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
2009-05-04 06:13:56 +00:00
// This loads the textures for highlight and selection if we need them
private void SetupTextures ( )
{
if ( ! graphics . Shaders . Enabled )
{
highlightimage = new ColorImage ( General . Colors . Highlight , 32 , 32 ) ;
highlightimage . LoadImage ( ) ;
highlightimage . CreateTexture ( ) ;
selectionimage = new ColorImage ( General . Colors . Selection , 32 , 32 ) ;
selectionimage . LoadImage ( ) ;
selectionimage . CreateTexture ( ) ;
}
}
2012-04-17 19:13:47 +00:00
2013-09-11 09:47:53 +00:00
//mxd
2014-09-16 08:51:27 +00:00
private void SetupHelperObjects ( )
{
2014-09-17 12:46:47 +00:00
bbox = new ThingBoundingBox ( ) ;
sizelessThingHandle = new SizelessVisualThingCage ( ) ;
vertexHandle = new VisualVertexHandle ( ) ;
2014-09-16 08:51:27 +00:00
}
//mxd
internal void UpdateVertexHandle ( )
{
2014-09-17 12:46:47 +00:00
vertexHandle . UnloadResource ( ) ;
vertexHandle . ReloadResource ( ) ;
2013-09-11 09:47:53 +00:00
}
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Presentation
// This creates the projection
internal void CreateProjection ( )
{
// Calculate aspect
2014-12-22 21:36:49 +00:00
float screenheight = General . Map . Graphics . RenderTarget . ClientSize . Height * ( General . Settings . GZStretchView ? GZDOOM_INVERTED_VERTICAL_VIEW_STRETCH : 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;
2014-02-21 14:42:12 +00:00
float fov = 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 ;
float fovy = ( float ) Math . Atan ( 1.0f / reversefovy ) * 2.0f ;
// Make the projection matrix
projection = Matrix . PerspectiveFovRH ( fovy , aspect , PROJ_NEAR_PLANE , General . Settings . ViewDistance ) ;
// Apply matrices
ApplyMatrices3D ( ) ;
}
// This creates matrices for a camera view
public void PositionAndLookAt ( Vector3D pos , Vector3D lookat )
{
// Calculate delta vector
cameraposition = pos ;
2014-02-21 14:42:12 +00:00
Vector3D delta = lookat - pos ;
float anglexy = delta . GetAngleXY ( ) ;
float anglez = delta . GetAngleZ ( ) ;
2009-04-19 18:07:22 +00:00
// Create frustum
frustum = new ProjectedFrustum2D ( pos , anglexy , anglez , PROJ_NEAR_PLANE ,
2013-08-08 11:04:13 +00:00
General . Settings . ViewDistance , Angle2D . DegToRad ( General . Settings . VisualFOV ) ) ;
2009-04-19 18:07:22 +00:00
// Make the view matrix
view3d = Matrix . LookAtRH ( D3DDevice . V3 ( pos ) , D3DDevice . V3 ( lookat ) , new Vector3 ( 0f , 0f , 1f ) ) ;
// Make the billboard matrix
billboard = Matrix . RotationZ ( anglexy + Angle2D . PI ) ;
}
// 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 ) ;
view2d = Matrix . Multiply ( translate , scaling ) ;
}
// This applies the matrices
private void ApplyMatrices3D ( )
{
worldviewproj = world * view3d * projection ;
graphics . Shaders . World3D . WorldViewProj = worldviewproj ;
graphics . Device . SetTransform ( TransformState . World , world ) ;
graphics . Device . SetTransform ( TransformState . Projection , projection ) ;
graphics . Device . SetTransform ( TransformState . View , view3d ) ;
}
// This sets the appropriate view matrix
public void ApplyMatrices2D ( )
{
graphics . Device . SetTransform ( TransformState . World , world ) ;
graphics . Device . SetTransform ( TransformState . Projection , Matrix . Identity ) ;
graphics . Device . SetTransform ( TransformState . View , view2d ) ;
}
#endregion
#region = = = = = = = = = = = = = = = = = = Start / Finish
// This starts rendering
public bool Start ( )
{
// Start drawing
if ( graphics . StartRendering ( true , General . Colors . Background . ToColorValue ( ) , graphics . BackBuffer , graphics . DepthBuffer ) )
{
2013-09-11 09:47:53 +00:00
// Beginning renderstates
2009-04-19 18:07:22 +00:00
graphics . Device . SetRenderState ( RenderState . CullMode , Cull . None ) ;
graphics . Device . SetRenderState ( RenderState . ZEnable , false ) ;
graphics . Device . SetRenderState ( RenderState . AlphaBlendEnable , false ) ;
graphics . Device . SetRenderState ( RenderState . AlphaTestEnable , false ) ;
graphics . Device . SetRenderState ( RenderState . SourceBlend , Blend . SourceAlpha ) ;
graphics . Device . SetRenderState ( RenderState . DestinationBlend , Blend . InverseSourceAlpha ) ;
graphics . Device . SetRenderState ( RenderState . FogEnable , false ) ;
graphics . Device . SetRenderState ( RenderState . FogDensity , 1.0f ) ;
graphics . Device . SetRenderState ( RenderState . FogColor , General . Colors . Background . ToInt ( ) ) ;
graphics . Device . SetRenderState ( RenderState . FogStart , General . Settings . ViewDistance * FOG_RANGE ) ;
graphics . Device . SetRenderState ( RenderState . FogEnd , General . Settings . ViewDistance ) ;
graphics . Device . SetRenderState ( RenderState . FogTableMode , FogMode . Linear ) ;
graphics . Device . SetRenderState ( RenderState . RangeFogEnable , false ) ;
graphics . Device . SetRenderState ( RenderState . TextureFactor , - 1 ) ;
graphics . Shaders . World3D . SetHighlightColor ( 0 ) ;
2009-04-26 20:20:40 +00:00
// Texture addressing
graphics . Device . SetSamplerState ( 0 , SamplerState . AddressU , TextureAddress . Wrap ) ;
graphics . Device . SetSamplerState ( 0 , SamplerState . AddressV , TextureAddress . Wrap ) ;
graphics . Device . SetSamplerState ( 0 , SamplerState . AddressW , TextureAddress . Wrap ) ;
2009-04-19 18:07:22 +00:00
// Matrices
world = Matrix . Identity ;
ApplyMatrices3D ( ) ;
// Highlight
2009-05-04 06:13:56 +00:00
if ( General . Settings . AnimateVisualSelection )
{
2014-05-20 09:09:28 +00:00
float time = Clock . CurrentTime ;
2009-05-06 07:26:12 +00:00
highlightglow = ( float ) Math . Sin ( time / 100.0f ) * 0.1f + 0.4f ;
2013-09-11 09:47:53 +00:00
highlightglowinv = - highlightglow + 0.8f ;
2009-05-04 06:13:56 +00:00
}
else
{
2009-05-06 07:26:12 +00:00
highlightglow = 0.4f ;
highlightglowinv = 0.3f ;
2009-05-04 06:13:56 +00:00
}
2009-04-19 18:07:22 +00:00
// Determine shader pass to use
2015-09-25 13:20:53 +00:00
shaderpass = ( fullbrightness ? 1 : 0 ) ;
2009-04-19 18:07:22 +00:00
// Create crosshair vertices
if ( crosshairverts = = null )
CreateCrosshairVerts ( new Size ( General . Map . Data . Crosshair3D . Width , General . Map . Data . Crosshair3D . Height ) ) ;
// Ready
return true ;
}
else
{
// Can't render now
return false ;
}
}
// 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
solidthings = new Dictionary < ImageData , List < VisualThing > > ( ) ; //mxd
maskedthings = new Dictionary < ImageData , List < VisualThing > > ( ) ; //mxd
translucentthings = new List < VisualThing > ( ) ; //mxd
modelthings = new Dictionary < ModelData , List < VisualThing > > ( ) ; //mxd
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 ( ) ;
2013-09-11 09:47:53 +00:00
// Initial renderstates
2009-04-19 18:07:22 +00:00
graphics . Device . SetRenderState ( RenderState . CullMode , Cull . Counterclockwise ) ;
graphics . Device . SetRenderState ( RenderState . ZEnable , true ) ;
graphics . Device . SetRenderState ( RenderState . ZWriteEnable , true ) ;
graphics . Device . SetRenderState ( RenderState . AlphaBlendEnable , false ) ;
graphics . Device . SetRenderState ( RenderState . AlphaTestEnable , false ) ;
graphics . Device . SetRenderState ( RenderState . TextureFactor , - 1 ) ;
graphics . Shaders . World3D . Begin ( ) ;
// SOLID PASS
2012-08-10 12:08:08 +00:00
world = Matrix . Identity ;
2009-04-19 18:07:22 +00:00
ApplyMatrices3D ( ) ;
2015-09-27 21:09:14 +00:00
RenderSinglePass ( solidgeo , solidthings ) ;
2009-04-19 18:07:22 +00:00
2015-09-27 21:09:14 +00:00
//mxd. Render models, without culling.
2013-03-18 13:52:27 +00:00
graphics . Device . SetRenderState ( RenderState . AlphaTestEnable , true ) ;
2013-09-11 09:47:53 +00:00
graphics . Device . SetRenderState ( RenderState . CullMode , Cull . None ) ;
RenderModels ( ) ;
2013-03-18 13:52:27 +00:00
graphics . Device . SetRenderState ( RenderState . CullMode , Cull . Counterclockwise ) ;
2012-04-17 19:13:47 +00:00
2009-04-19 18:07:22 +00:00
// MASK PASS
2013-09-11 09:47:53 +00:00
world = Matrix . Identity ;
ApplyMatrices3D ( ) ;
2015-09-27 21:09:14 +00:00
RenderSinglePass ( maskedgeo , maskedthings ) ;
2013-09-11 09:47:53 +00:00
2015-09-27 21:09:14 +00:00
//mxd. LIGHT PASS
2013-09-11 09:47:53 +00:00
world = Matrix . Identity ;
ApplyMatrices3D ( ) ;
graphics . Device . SetRenderState ( RenderState . AlphaBlendEnable , true ) ;
graphics . Device . SetRenderState ( RenderState . AlphaTestEnable , false ) ;
graphics . Device . SetRenderState ( RenderState . ZWriteEnable , false ) ;
2015-09-27 21:09:14 +00:00
graphics . Device . SetRenderState ( RenderState . DestinationBlend , Blend . One ) ;
if ( General . Settings . GZDrawLightsMode ! = LightRenderMode . NONE & & ! fullbrightness & & lightthings . Count > 0 )
{
RenderLights ( solidgeo , lightthings ) ;
RenderLights ( maskedgeo , lightthings ) ;
}
// ALPHA AND ADDITIVE PASS
world = Matrix . Identity ;
ApplyMatrices3D ( ) ;
2013-09-11 09:47:53 +00:00
graphics . Device . SetRenderState ( RenderState . SourceBlend , Blend . SourceAlpha ) ;
2015-09-27 21:09:14 +00:00
RenderTranslucentPass ( translucentgeo , translucentthings ) ;
2013-09-11 09:47:53 +00:00
2015-09-27 21:09:14 +00:00
// THING CAGES
2012-04-17 19:13:47 +00:00
if ( renderthingcages ) RenderThingCages ( ) ;
2009-04-19 18:07:22 +00:00
2013-03-18 13:52:27 +00:00
//mxd. Visual vertices
RenderVertices ( ) ;
2015-08-08 21:56:43 +00:00
//mxd. Event lines
2015-09-27 21:09:14 +00:00
if ( General . Settings . GZShowEventLines ) RenderArrows ( LinksCollector . GetThingLinks ( allthings ) ) ;
2009-04-19 18:07:22 +00:00
// Remove references
graphics . Shaders . World3D . Texture1 = null ;
// Done
graphics . Shaders . World3D . End ( ) ;
2015-09-27 21:09:14 +00:00
//mxd. Trash collections
solidgeo = null ;
maskedgeo = null ;
translucentgeo = null ;
solidthings = null ;
maskedthings = null ;
translucentthings = null ;
allthings = null ;
lightthings = null ;
modelthings = null ;
visualvertices = null ;
2009-04-19 18:07:22 +00:00
}
2013-09-11 09:47:53 +00:00
//mxd
2015-09-27 21:09:14 +00:00
private void UpdateLights ( )
2014-12-03 23:15:26 +00:00
{
2015-09-27 21:09:14 +00:00
if ( lightthings . Count > General . Settings . GZMaxDynamicLights )
2014-12-03 23:15:26 +00:00
{
2015-09-27 21:09:14 +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 > ( General . Settings . GZMaxDynamicLights ) ;
for ( int i = 0 ; i < General . Settings . GZMaxDynamicLights ; i + + ) tl . Add ( lightthings [ i ] ) ;
lightthings = tl ;
2013-09-11 09:47:53 +00:00
}
2015-09-27 21:09:14 +00:00
// Sort things by light render style
lightthings . Sort ( ( t1 , t2 ) = > Math . Sign ( t1 . LightRenderStyle - t2 . LightRenderStyle ) ) ;
2013-09-11 09:47:53 +00:00
lightOffsets = new int [ 3 ] ;
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.
2014-12-03 23:15:26 +00:00
switch ( t . LightRenderStyle )
{
2013-12-23 08:00:19 +00:00
case DynamicLightRenderStyle . NORMAL :
2015-09-27 21:09:14 +00:00
case DynamicLightRenderStyle . VAVOOM : lightOffsets [ 0 ] + + ; break ;
case DynamicLightRenderStyle . ADDITIVE : lightOffsets [ 1 ] + + ; break ;
default : lightOffsets [ 2 ] + + ; break ;
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 ( )
{
2013-09-11 09:47:53 +00:00
graphics . Device . SetRenderState ( RenderState . AlphaBlendEnable , true ) ;
graphics . Device . SetRenderState ( RenderState . AlphaTestEnable , false ) ;
graphics . Device . SetRenderState ( RenderState . ZWriteEnable , false ) ;
graphics . Device . SetRenderState ( RenderState . SourceBlend , Blend . SourceAlpha ) ;
graphics . Device . SetRenderState ( RenderState . DestinationBlend , Blend . SourceAlpha ) ;
graphics . Shaders . World3D . BeginPass ( 16 ) ;
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 matrix
world = Matrix . Multiply ( t . CageScales , t . Position ) ;
ApplyMatrices3D ( ) ;
// 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
}
2015-09-27 21:09:14 +00:00
graphics . Shaders . World3D . VertexColor = thingcolor ;
2013-09-11 09:47:53 +00:00
//Render cage
graphics . Shaders . World3D . ApplySettings ( ) ;
2013-03-18 13:52:27 +00:00
2014-12-03 23:15:26 +00:00
if ( t . Sizeless )
{
2013-03-18 13:52:27 +00:00
graphics . Device . SetStreamSource ( 0 , sizelessThingHandle . Shape , 0 , WorldVertex . Stride ) ;
graphics . Device . DrawPrimitives ( PrimitiveType . LineList , 0 , 3 ) ;
2014-12-03 23:15:26 +00:00
}
else
{
2013-03-18 13:52:27 +00:00
graphics . Device . SetStreamSource ( 0 , bbox . Cage , 0 , WorldVertex . Stride ) ;
graphics . Device . DrawPrimitives ( PrimitiveType . LineList , 0 , 12 ) ;
}
2012-04-17 19:13:47 +00:00
2013-09-11 09:47:53 +00:00
//and arrow
2015-09-27 21:09:14 +00:00
if ( t . Thing . IsDirectional )
2014-12-03 23:15:26 +00:00
{
2013-12-02 09:26:09 +00:00
float sx = t . CageScales . M11 ;
Matrix arrowScaler = Matrix . Scaling ( sx , sx , sx ) ; //scale arrow evenly based on thing width\depth
2015-09-27 21:09:14 +00:00
if ( t . Sizeless )
2013-12-02 09:26:09 +00:00
world = Matrix . Multiply ( arrowScaler , t . Position ) ;
2014-12-03 23:15:26 +00:00
else
2013-12-02 09:26:09 +00:00
world = Matrix . Multiply ( arrowScaler , t . Position * Matrix . Translation ( 0.0f , 0.0f , t . CageScales . M33 / 2 ) ) ;
Added, Visual mode, UDMF: added "Change Pitch Clockwise", "Change Pitch Counterclockwise", "Change Roll Clockwise" and "Change Roll Counterclockwise" actions.
Added, Visual mode, UDMF: added "Increase Scale" and "Decrease Scale" actions.
Added, Visual mode, UDMF: "Reset Texture Offsets" action now resets scale when used on things.
Added, Visual mode, UDMF: "Reset Local Texture Offsets" action now resets scale, pitch and roll when used on things.
Changed, Visual mode, UDMF: "Reset Texture Offsets" action now only resets texture offsets (previously it also reset texture scale).
Changed, Visual mode, UDMF: "Reset Local Texture Offsets" action now resets texture offsets, scale and brightness of sidedefs and also rotation of floors/ceilings.
Changed, Visual mode, UDMF: thing box arrow now displays pitch and roll for things, which have attached model and appropriate MODELDEF flags.
Changed, Thing Edit Form, UDMF: negative pitch and roll can now be entered.
Updated documentation.
2015-03-30 21:44:04 +00:00
Matrix rot = Matrix . RotationY ( - t . Thing . RollRad ) * Matrix . RotationX ( - t . Thing . PitchRad ) * Matrix . RotationZ ( t . Thing . Angle ) ;
2013-12-02 09:26:09 +00:00
world = Matrix . Multiply ( rot , world ) ;
ApplyMatrices3D ( ) ;
2012-04-17 19:13:47 +00:00
2013-12-02 09:26:09 +00:00
graphics . Shaders . World3D . ApplySettings ( ) ;
graphics . Device . SetStreamSource ( 0 , bbox . Arrow , 0 , WorldVertex . Stride ) ;
graphics . Device . DrawPrimitives ( PrimitiveType . LineList , 0 , 5 ) ;
}
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
graphics . Shaders . World3D . EndPass ( ) ;
graphics . Device . SetRenderState ( RenderState . TextureFactor , - 1 ) ;
}
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 ;
2013-03-20 10:25:32 +00:00
graphics . Device . SetRenderState ( RenderState . AlphaBlendEnable , true ) ;
graphics . Device . SetRenderState ( RenderState . AlphaTestEnable , false ) ;
graphics . Device . SetRenderState ( RenderState . ZWriteEnable , false ) ;
graphics . Device . SetRenderState ( RenderState . SourceBlend , Blend . SourceAlpha ) ;
graphics . Device . SetRenderState ( RenderState . DestinationBlend , Blend . SourceAlpha ) ;
2013-03-18 13:52:27 +00:00
graphics . Shaders . World3D . BeginPass ( 16 ) ;
2014-12-03 23:15:26 +00:00
foreach ( VisualVertex v in visualvertices )
{
2013-03-18 13:52:27 +00:00
world = v . Position ;
ApplyMatrices3D ( ) ;
// Setup color
2014-02-21 14:42:12 +00:00
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 ;
}
graphics . Shaders . World3D . VertexColor = color ;
//Commence drawing!!11
graphics . Shaders . World3D . ApplySettings ( ) ;
graphics . Device . SetStreamSource ( 0 , v . CeilingVertex ? vertexHandle . Upper : vertexHandle . Lower , 0 , WorldVertex . Stride ) ;
2013-03-21 11:23:29 +00:00
graphics . Device . DrawPrimitives ( PrimitiveType . LineList , 0 , 8 ) ;
2013-03-18 13:52:27 +00:00
}
// Done
graphics . Shaders . World3D . EndPass ( ) ;
2013-03-20 10:25:32 +00:00
graphics . Device . SetRenderState ( RenderState . TextureFactor , - 1 ) ;
2013-03-18 13:52:27 +00:00
}
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 ;
foreach ( Line3D line in lines ) pointscount + = ( line . renderarrowhead ? 6 : 2 ) ; // 4 extra points for the arrowhead
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
int color ;
pointscount = 0 ;
foreach ( Line3D line in lines )
2014-12-03 23:15:26 +00:00
{
2015-08-08 21:56:43 +00:00
color = line . color . ToInt ( ) ;
// Add regular points
verts [ pointscount ] . x = line . v1 . x ;
verts [ pointscount ] . y = line . v1 . y ;
verts [ pointscount ] . z = line . v1 . z ;
verts [ pointscount ] . c = color ;
pointscount + + ;
verts [ pointscount ] . x = line . v2 . x ;
verts [ pointscount ] . y = line . v2 . y ;
verts [ pointscount ] . z = line . v2 . z ;
verts [ pointscount ] . c = color ;
pointscount + + ;
// Add arrowhead
if ( line . renderarrowhead )
{
float nz = line . GetDelta ( ) . GetNormal ( ) . z * scaler ;
float angle = line . GetAngle ( ) ;
Vector3D a1 = new Vector3D ( line . v2 . x - scaler * ( float ) Math . Sin ( angle - 0.46f ) , line . v2 . y + scaler * ( float ) Math . Cos ( angle - 0.46f ) , line . v2 . z - nz ) ;
Vector3D a2 = new Vector3D ( line . v2 . x - scaler * ( float ) Math . Sin ( angle + 0.46f ) , line . v2 . y + scaler * ( float ) Math . Cos ( angle + 0.46f ) , line . v2 . z - nz ) ;
verts [ pointscount ] = verts [ pointscount - 1 ] ;
verts [ pointscount + 1 ] . x = a1 . x ;
verts [ pointscount + 1 ] . y = a1 . y ;
verts [ pointscount + 1 ] . z = a1 . z ;
verts [ pointscount + 1 ] . c = color ;
verts [ pointscount + 2 ] = verts [ pointscount - 1 ] ;
verts [ pointscount + 3 ] . x = a2 . x ;
verts [ pointscount + 3 ] . y = a2 . y ;
verts [ pointscount + 3 ] . z = a2 . z ;
verts [ pointscount + 3 ] . c = color ;
pointscount + = 4 ;
}
2013-09-11 09:47:53 +00:00
}
VertexBuffer vb = new VertexBuffer ( General . Map . Graphics . Device , WorldVertex . Stride * verts . Length , Usage . WriteOnly | Usage . Dynamic , VertexFormat . None , Pool . Default ) ;
DataStream s = vb . Lock ( 0 , WorldVertex . Stride * verts . Length , LockFlags . Discard ) ;
2014-12-03 23:15:26 +00:00
s . WriteRange ( verts ) ;
2013-09-11 09:47:53 +00:00
vb . Unlock ( ) ;
s . Dispose ( ) ;
//begin rendering
graphics . Device . SetRenderState ( RenderState . AlphaBlendEnable , true ) ;
graphics . Device . SetRenderState ( RenderState . AlphaTestEnable , false ) ;
graphics . Device . SetRenderState ( RenderState . ZWriteEnable , false ) ;
graphics . Device . SetRenderState ( RenderState . SourceBlend , Blend . SourceAlpha ) ;
graphics . Device . SetRenderState ( RenderState . DestinationBlend , Blend . SourceAlpha ) ;
2015-08-08 21:56:43 +00:00
graphics . Shaders . World3D . BeginPass ( 15 ) ;
2013-09-11 09:47:53 +00:00
world = Matrix . Identity ;
ApplyMatrices3D ( ) ;
//render
graphics . Shaders . World3D . ApplySettings ( ) ;
graphics . Device . SetStreamSource ( 0 , vb , 0 , WorldVertex . Stride ) ;
2015-08-08 21:56:43 +00:00
graphics . Device . DrawPrimitives ( PrimitiveType . LineList , 0 , pointscount / 2 ) ;
2012-09-17 15:41:18 +00:00
2013-09-11 09:47:53 +00:00
// Done
graphics . Shaders . World3D . EndPass ( ) ;
graphics . Device . SetRenderState ( RenderState . TextureFactor , - 1 ) ;
2012-09-17 21:57:08 +00:00
vb . Dispose ( ) ;
2013-09-11 09:47:53 +00:00
}
2009-04-19 18:07:22 +00:00
// This performs a single render pass
2015-09-27 21:09:14 +00:00
private void RenderSinglePass ( Dictionary < ImageData , List < VisualGeometry > > geopass , Dictionary < ImageData , List < VisualThing > > thingspass )
2009-04-19 18:07:22 +00:00
{
2015-09-27 21:09:14 +00:00
//mxd. Anything to render?
if ( geopass . Count = = 0 & & thingspass . Count = = 0 ) return ;
2013-09-11 09:47:53 +00:00
int currentshaderpass = shaderpass ;
2009-05-01 20:31:17 +00:00
int highshaderpass = shaderpass + 2 ;
2009-04-19 18:07:22 +00:00
// Begin rendering with this shader
graphics . Shaders . World3D . BeginPass ( shaderpass ) ;
2012-04-17 19:13:47 +00:00
2009-04-19 18:07:22 +00:00
// Render the geometry collected
2015-09-27 21:09:14 +00:00
foreach ( KeyValuePair < ImageData , List < VisualGeometry > > group in geopass )
2009-04-19 18:07:22 +00:00
{
ImageData curtexture ;
// What texture to use?
if ( group . Key is UnknownImage )
curtexture = General . Map . Data . UnknownTexture3D ;
2015-09-27 21:09:14 +00:00
else if ( group . Key . IsImageLoaded & & ! group . Key . IsDisposed )
2009-04-19 18:07:22 +00:00
curtexture = group . Key ;
else
curtexture = General . Map . Data . Hourglass3D ;
// Create Direct3D texture if still needed
if ( ( curtexture . Texture = = null ) | | curtexture . Texture . Disposed )
curtexture . CreateTexture ( ) ;
// Apply texture
2009-05-04 06:13:56 +00:00
if ( ! graphics . Shaders . Enabled ) graphics . Device . SetTexture ( 0 , curtexture . Texture ) ;
2009-04-19 18:07:22 +00:00
graphics . Shaders . World3D . Texture1 = curtexture . Texture ;
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 )
{
// Changing sector?
if ( ! object . ReferenceEquals ( g . Sector , sector ) )
{
// Update the sector if needed
if ( g . Sector . NeedsUpdateGeo ) g . Sector . Update ( ) ;
// Only do this sector when a vertexbuffer is created
2013-09-11 09:47:53 +00:00
//mxd. no Map means that sector was deleted recently, I suppose
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
graphics . Device . SetStreamSource ( 0 , sector . GeometryBuffer , 0 , WorldVertex . Stride ) ;
}
else
{
sector = null ;
}
2012-06-03 15:13:22 +00:00
}
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 ( 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
2009-07-07 14:52:39 +00:00
int 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?
2013-12-23 08:00:19 +00:00
if ( ! ( ! General . Settings . GZDrawFog | | fullbrightness | | sector . Sector . Brightness > 247 ) )
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
{
graphics . Shaders . World3D . EndPass ( ) ;
2009-05-01 20:31:17 +00:00
graphics . Shaders . World3D . BeginPass ( wantedshaderpass ) ;
currentshaderpass = wantedshaderpass ;
2009-04-19 18:07:22 +00:00
}
2009-05-04 06:13:56 +00:00
// Set the colors to use
if ( ! graphics . Shaders . Enabled )
{
2009-07-07 14:52:39 +00:00
graphics . Device . SetTexture ( 2 , ( g . Selected & & showselection ) ? selectionimage . Texture : null ) ;
graphics . Device . SetTexture ( 3 , ( ( g = = highlighted ) & & showhighlight ) ? highlightimage . Texture : null ) ;
2009-05-04 06:13:56 +00:00
}
else
{
2013-09-11 09:47:53 +00:00
//mxd. set variables for fog rendering
2014-12-03 23:15:26 +00:00
if ( wantedshaderpass > 7 )
{
2013-09-11 09:47:53 +00:00
graphics . Shaders . World3D . World = world ;
2013-09-11 08:49:45 +00:00
graphics . Shaders . World3D . LightColor = sector . Sector . FogColor ;
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
graphics . Shaders . World3D . CameraPosition = new Vector4 ( cameraposition . x , cameraposition . y , cameraposition . z , sector . FogDistance ) ;
2013-09-11 09:47:53 +00:00
}
graphics . Shaders . World3D . SetHighlightColor ( CalculateHighlightColor ( ( g = = highlighted ) & & showhighlight , ( g . Selected & & showselection ) ) . ToArgb ( ) ) ;
2009-05-04 06:13:56 +00:00
graphics . Shaders . World3D . ApplySettings ( ) ;
}
2009-05-01 20:31:17 +00:00
2009-04-19 18:07:22 +00:00
// Render!
graphics . Device . DrawPrimitives ( PrimitiveType . TriangleList , g . VertexOffset , g . Triangles ) ;
}
}
}
// Get things for this pass
2009-04-26 20:20:40 +00:00
if ( thingspass . Count > 0 )
2009-04-19 18:07:22 +00:00
{
2009-04-26 20:20:40 +00:00
// Texture addressing
graphics . Device . SetSamplerState ( 0 , SamplerState . AddressU , TextureAddress . Clamp ) ;
graphics . Device . SetSamplerState ( 0 , SamplerState . AddressV , TextureAddress . Clamp ) ;
graphics . Device . SetSamplerState ( 0 , SamplerState . AddressW , TextureAddress . Clamp ) ;
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
graphics . Device . SetRenderState ( RenderState . CullMode , 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
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 ;
ImageData curtexture ;
2013-12-23 08:00:19 +00:00
2015-09-27 21:09:14 +00:00
// What texture to use?
if ( ! group . Key . IsImageLoaded | | group . Key . IsDisposed )
curtexture = General . Map . Data . Hourglass3D ;
else
curtexture = group . Key ;
// Create Direct3D texture if still needed
if ( ( curtexture . Texture = = null ) | | curtexture . Texture . Disposed )
curtexture . CreateTexture ( ) ;
// Apply texture
if ( ! graphics . Shaders . Enabled ) graphics . Device . SetTexture ( 0 , curtexture . Texture ) ;
graphics . Shaders . World3D . Texture1 = curtexture . Texture ;
// Render all things with this texture
foreach ( VisualThing t in group . Value )
{
//mxd
if ( t . Thing . IsModel & &
( General . Settings . GZDrawModelsMode = = ModelRenderMode . ALL | |
General . Settings . GZDrawModelsMode = = ModelRenderMode . ACTIVE_THINGS_FILTER | |
( General . Settings . GZDrawModelsMode = = ModelRenderMode . SELECTION & & t . Selected ) ) )
continue ;
// Update buffer if needed
t . Update ( ) ;
// Only do this sector when a vertexbuffer is created
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
int wantedshaderpass = ( ( ( t = = highlighted ) & & showhighlight ) | | ( t . Selected & & showselection ) ) ? highshaderpass : shaderpass ;
2012-04-17 19:13:47 +00:00
2015-09-27 21:09:14 +00:00
//mxd. if fog is enagled, switch to shader, which calculates it
if ( General . Settings . GZDrawFog & & ! fullbrightness & & t . Thing . Sector ! = null & & ( t . Thing . Sector . HasFogColor | | t . Thing . Sector . Brightness < 248 ) )
wantedshaderpass + = 8 ;
2013-09-11 09:47:53 +00:00
2015-09-27 21:09:14 +00:00
//mxd. if current thing is light - set it's color to light color
Color4 litcolor = new Color4 ( ) ;
if ( Array . IndexOf ( GZBuilder . GZGeneral . GZ_LIGHTS , t . Thing . Type ) ! = - 1 & & ! fullbrightness )
{
wantedshaderpass + = 4 ; //render using one of passes, which uses World3D.VertexColor
graphics . Shaders . World3D . VertexColor = t . LightColor ;
litcolor = t . LightColor ;
}
//mxd. check if Thing is affected by dynamic lights and set color accordingly
else if ( General . Settings . GZDrawLightsMode ! = LightRenderMode . NONE & & ! fullbrightness & & lightthings . Count > 0 )
{
litcolor = GetLitColorForThing ( t ) ;
if ( litcolor . ToArgb ( ) ! = 0 )
2014-10-20 12:16:51 +00:00
{
2013-09-11 09:47:53 +00:00
wantedshaderpass + = 4 ; //render using one of passes, which uses World3D.VertexColor
2015-09-27 21:09:14 +00:00
graphics . Shaders . World3D . VertexColor = new Color4 ( t . VertexColor ) + litcolor ;
2013-09-11 09:47:53 +00:00
}
2015-09-27 21:09:14 +00:00
}
2013-09-11 09:47:53 +00:00
2015-09-27 21:09:14 +00:00
// Switch shader pass?
if ( currentshaderpass ! = wantedshaderpass )
{
graphics . Shaders . World3D . EndPass ( ) ;
graphics . Shaders . World3D . BeginPass ( wantedshaderpass ) ;
currentshaderpass = wantedshaderpass ;
}
2013-09-11 09:47:53 +00:00
2015-09-27 21:09:14 +00:00
// Set the colors to use
if ( ! graphics . Shaders . Enabled )
{
graphics . Device . SetTexture ( 2 , ( t . Selected & & showselection ) ? selectionimage . Texture : null ) ;
graphics . Device . SetTexture ( 3 , ( ( t = = highlighted ) & & showhighlight ) ? highlightimage . Texture : null ) ;
}
else
{
graphics . Shaders . World3D . SetHighlightColor ( CalculateHighlightColor ( ( t = = highlighted ) & & showhighlight , ( t . Selected & & showselection ) ) . ToArgb ( ) ) ;
}
2013-09-11 09:47:53 +00:00
2015-09-27 21:09:14 +00:00
//mxd. Create the matrix for positioning
if ( t . Info . RenderMode = = Thing . SpriteRenderMode . NORMAL ) // Apply billboarding?
{
if ( t . Info . XYBillboard )
Fixed, Draw Lines/Rectangle/Circle/Curve modes: line length labels displayed incorrect length.
Changed, Drag Linedefs/Vertices/Sectors/Things modes: line length labels are now displayed the same way as in Draw modes.
Changed, Drag Linedefs/Vertices/Sectors/Things modes: "lock movement to cardinal directions" mode (Alt-Shift-Drag) now locks movement in 4 directions instead of 8 and doesn't snap map elements to nearest grid intersections when they are not aligned to it.
Added, Visual mode, GZDoom, DECORATE: FORCEXYBILLBOARD flag is now supported.
Added, Visual mode, GLOOME, DECORATE: FLOORSPRITE, CEILSPRITE, WALLSPRITE, ROLLSPRITE and STICKTOPLANE flags are now supported (implementation is somewhat broken ATM and probably doesn't work the same way as in GLOOME, because Windows build with most these features is nowhere to be found...).
Fixed, Visual mode: in some cases Thing brightness was calculated incorrectly.
Updated ZDoom_DECORATE.cfg.
2015-08-25 22:05:14 +00:00
{
2015-09-27 21:09:14 +00:00
world = Matrix . Translation ( 0f , 0f , - t . LocalCenterZ )
* Matrix . RotationX ( Angle2D . PI - General . Map . VisualCamera . AngleZ )
* Matrix . Translation ( 0f , 0f , t . LocalCenterZ )
* billboard
* Matrix . Scaling ( t . Thing . ScaleX , t . Thing . ScaleX , t . Thing . ScaleY )
* t . Position ;
Fixed, Draw Lines/Rectangle/Circle/Curve modes: line length labels displayed incorrect length.
Changed, Drag Linedefs/Vertices/Sectors/Things modes: line length labels are now displayed the same way as in Draw modes.
Changed, Drag Linedefs/Vertices/Sectors/Things modes: "lock movement to cardinal directions" mode (Alt-Shift-Drag) now locks movement in 4 directions instead of 8 and doesn't snap map elements to nearest grid intersections when they are not aligned to it.
Added, Visual mode, GZDoom, DECORATE: FORCEXYBILLBOARD flag is now supported.
Added, Visual mode, GLOOME, DECORATE: FLOORSPRITE, CEILSPRITE, WALLSPRITE, ROLLSPRITE and STICKTOPLANE flags are now supported (implementation is somewhat broken ATM and probably doesn't work the same way as in GLOOME, because Windows build with most these features is nowhere to be found...).
Fixed, Visual mode: in some cases Thing brightness was calculated incorrectly.
Updated ZDoom_DECORATE.cfg.
2015-08-25 22:05:14 +00:00
}
else
{
2015-09-27 21:09:14 +00:00
world = billboard
* Matrix . Scaling ( t . Thing . ScaleX , t . Thing . ScaleX , t . Thing . ScaleY )
* t . Position ;
Fixed, Draw Lines/Rectangle/Circle/Curve modes: line length labels displayed incorrect length.
Changed, Drag Linedefs/Vertices/Sectors/Things modes: line length labels are now displayed the same way as in Draw modes.
Changed, Drag Linedefs/Vertices/Sectors/Things modes: "lock movement to cardinal directions" mode (Alt-Shift-Drag) now locks movement in 4 directions instead of 8 and doesn't snap map elements to nearest grid intersections when they are not aligned to it.
Added, Visual mode, GZDoom, DECORATE: FORCEXYBILLBOARD flag is now supported.
Added, Visual mode, GLOOME, DECORATE: FLOORSPRITE, CEILSPRITE, WALLSPRITE, ROLLSPRITE and STICKTOPLANE flags are now supported (implementation is somewhat broken ATM and probably doesn't work the same way as in GLOOME, because Windows build with most these features is nowhere to be found...).
Fixed, Visual mode: in some cases Thing brightness was calculated incorrectly.
Updated ZDoom_DECORATE.cfg.
2015-08-25 22:05:14 +00:00
}
2015-09-27 21:09:14 +00:00
}
else
{
world = Matrix . Scaling ( t . Thing . ScaleX , t . Thing . ScaleX , t . Thing . ScaleY )
* t . Position ;
}
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-09-27 21:09:14 +00:00
ApplyMatrices3D ( ) ;
2013-09-11 09:47:53 +00:00
2015-09-27 21:09:14 +00:00
//mxd. Set variables for fog rendering
if ( wantedshaderpass > 7 )
{
graphics . Shaders . World3D . World = world ;
graphics . Shaders . World3D . LightColor = t . Thing . Sector . FogColor ;
float fogdistance = ( litcolor . ToArgb ( ) ! = 0 ? VisualSector . MAXIMUM_FOG_DISTANCE : t . FogDistance ) ;
graphics . Shaders . World3D . CameraPosition = new Vector4 ( cameraposition . x , cameraposition . y , cameraposition . z , fogdistance ) ;
}
2012-05-20 00:56:59 +00:00
2015-09-27 21:09:14 +00:00
graphics . Shaders . World3D . ApplySettings ( ) ;
2012-04-17 19:13:47 +00:00
2015-09-27 21:09:14 +00:00
// Apply buffer
graphics . Device . SetStreamSource ( 0 , t . GeometryBuffer , 0 , WorldVertex . Stride ) ;
2012-04-17 19:13:47 +00:00
2015-09-27 21:09:14 +00:00
// Render!
graphics . Device . DrawPrimitives ( PrimitiveType . TriangleList , 0 , t . Triangles ) ;
2009-04-19 18:07:22 +00:00
}
}
}
2012-04-17 19:13:47 +00:00
2013-09-11 09:47:53 +00:00
// Texture addressing
graphics . Device . SetSamplerState ( 0 , SamplerState . AddressU , TextureAddress . Wrap ) ;
graphics . Device . SetSamplerState ( 0 , SamplerState . AddressV , TextureAddress . Wrap ) ;
graphics . Device . SetSamplerState ( 0 , SamplerState . AddressW , TextureAddress . Wrap ) ;
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
graphics . Device . SetRenderState ( RenderState . CullMode , Cull . Counterclockwise ) ; //mxd
2009-04-19 18:07:22 +00:00
}
// Done rendering with this shader
graphics . Shaders . World3D . EndPass ( ) ;
}
2009-05-05 21:13:50 +00:00
2015-09-27 21:09:14 +00:00
//mxd
private void RenderTranslucentPass ( List < VisualGeometry > geopass , List < VisualThing > thingspass )
{
// Anything to render?
if ( geopass . Count = = 0 & & thingspass . Count = = 0 ) return ;
int currentshaderpass = shaderpass ;
int highshaderpass = shaderpass + 2 ;
// Sort geometry by camera distance. First vertex of the BoundingBox is it's center
if ( General . Map . VisualCamera . Sector ! = null )
{
// If the camera is inside a sector, compare z coordinates
translucentgeo . Sort ( delegate ( VisualGeometry vg1 , VisualGeometry vg2 )
{
float camdist1 , camdist2 ;
if ( ( vg1 . GeometryType = = VisualGeometryType . FLOOR | | vg1 . GeometryType = = VisualGeometryType . CEILING )
& & General . Map . VisualCamera . Sector . Index = = vg1 . Sector . Sector . Index )
{
camdist1 = Math . Abs ( General . Map . VisualCamera . Position . z - vg1 . BoundingBox [ 0 ] . z ) ;
}
else
{
camdist1 = ( General . Map . VisualCamera . Position - vg1 . BoundingBox [ 0 ] ) . GetLengthSq ( ) ;
}
if ( ( vg2 . GeometryType = = VisualGeometryType . FLOOR | | vg2 . GeometryType = = VisualGeometryType . CEILING )
& & General . Map . VisualCamera . Sector . Index = = vg2 . Sector . Sector . Index )
{
camdist2 = Math . Abs ( General . Map . VisualCamera . Position . z - vg2 . BoundingBox [ 0 ] . z ) ;
}
else
{
camdist2 = ( General . Map . VisualCamera . Position - vg2 . BoundingBox [ 0 ] ) . GetLengthSq ( ) ;
}
return ( int ) ( camdist2 - camdist1 ) ;
} ) ;
}
else
{
translucentgeo . Sort ( ( vg1 , vg2 ) = > ( int ) ( ( General . Map . VisualCamera . Position - vg2 . 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
- ( General . Map . VisualCamera . Position - vg1 . BoundingBox [ 0 ] ) . GetLengthSq ( ) ) ) ;
2015-09-27 21:09:14 +00:00
}
// Begin rendering with this shader
graphics . Shaders . World3D . BeginPass ( shaderpass ) ;
VisualSector sector = null ;
RenderPass currentpass = RenderPass . Solid ;
long curtexturename = 0 ;
ImageData curtexture ;
// Go for all geometry
foreach ( VisualGeometry g in geopass )
{
// Change blend mode?
if ( g . RenderPass ! = currentpass )
{
switch ( g . RenderPass )
{
case RenderPass . Additive :
graphics . Device . SetRenderState ( RenderState . DestinationBlend , Blend . One ) ;
break ;
case RenderPass . Alpha :
graphics . Device . SetRenderState ( RenderState . DestinationBlend , Blend . InverseSourceAlpha ) ;
break ;
}
currentpass = g . RenderPass ;
}
// Change texture?
if ( g . Texture . LongName ! = curtexturename )
{
// What texture to use?
if ( g . Texture is UnknownImage )
curtexture = General . Map . Data . UnknownTexture3D ;
else if ( g . Texture . IsImageLoaded & & ! g . Texture . IsDisposed )
curtexture = g . Texture ;
else
curtexture = General . Map . Data . Hourglass3D ;
// Create Direct3D texture if still needed
if ( ( curtexture . Texture = = null ) | | curtexture . Texture . Disposed )
curtexture . CreateTexture ( ) ;
// Apply texture
if ( ! graphics . Shaders . Enabled ) graphics . Device . SetTexture ( 0 , curtexture . Texture ) ;
graphics . Shaders . World3D . Texture1 = curtexture . Texture ;
curtexturename = g . Texture . LongName ;
}
// Changing sector?
if ( ! object . ReferenceEquals ( g . Sector , sector ) )
{
// Update the sector if needed
if ( g . Sector . NeedsUpdateGeo ) g . Sector . Update ( ) ;
// 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
graphics . Device . SetStreamSource ( 0 , sector . GeometryBuffer , 0 , WorldVertex . Stride ) ;
}
else
{
sector = null ;
}
}
if ( sector ! = null )
{
// Determine the shader pass we want to use for this object
int wantedshaderpass = ( ( ( g = = highlighted ) & & showhighlight ) | | ( g . Selected & & showselection ) ) ? highshaderpass : shaderpass ;
//mxd. Render fog?
if ( ! ( ! General . Settings . GZDrawFog | | fullbrightness | | sector . Sector . Brightness > 247 ) )
wantedshaderpass + = 8 ;
// Switch shader pass?
if ( currentshaderpass ! = wantedshaderpass )
{
graphics . Shaders . World3D . EndPass ( ) ;
graphics . Shaders . World3D . BeginPass ( wantedshaderpass ) ;
currentshaderpass = wantedshaderpass ;
}
// Set the colors to use
if ( ! graphics . Shaders . Enabled )
{
graphics . Device . SetTexture ( 2 , ( g . Selected & & showselection ) ? selectionimage . Texture : null ) ;
graphics . Device . SetTexture ( 3 , ( ( g = = highlighted ) & & showhighlight ) ? highlightimage . Texture : null ) ;
}
else
{
//mxd. set variables for fog rendering
if ( wantedshaderpass > 7 )
{
graphics . Shaders . World3D . World = world ;
graphics . Shaders . World3D . LightColor = sector . Sector . FogColor ;
graphics . Shaders . World3D . CameraPosition = new Vector4 ( cameraposition . x , cameraposition . y , cameraposition . z , sector . FogDistance ) ;
}
graphics . Shaders . World3D . SetHighlightColor ( CalculateHighlightColor ( ( g = = highlighted ) & & showhighlight , ( g . Selected & & showselection ) ) . ToArgb ( ) ) ;
graphics . Shaders . World3D . ApplySettings ( ) ;
}
// Render!
graphics . Device . DrawPrimitives ( PrimitiveType . TriangleList , g . VertexOffset , g . 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
// Get things for this pass
if ( thingspass . Count > 0 )
{
// Texture addressing
graphics . Device . SetSamplerState ( 0 , SamplerState . AddressU , TextureAddress . Clamp ) ;
graphics . Device . SetSamplerState ( 0 , SamplerState . AddressV , TextureAddress . Clamp ) ;
graphics . Device . SetSamplerState ( 0 , SamplerState . AddressW , TextureAddress . Clamp ) ;
graphics . Device . SetRenderState ( RenderState . CullMode , Cull . None ) ; //mxd. Disable backside culling, because otherwise sprites with positive ScaleY and negative ScaleX will be facing away from the camera...
// Sort geometry by camera distance. First vertex of the BoundingBox is it's center
thingspass . Sort ( ( vt1 , vt2 ) = > ( int ) ( ( General . Map . VisualCamera . Position - vt2 . BoundingBox [ 0 ] ) . GetLengthSq ( )
- ( General . Map . VisualCamera . Position - vt1 . BoundingBox [ 0 ] ) . GetLengthSq ( ) ) ) ;
// Reset vars
currentpass = RenderPass . Solid ;
curtexturename = 0 ;
// Render things collected
foreach ( VisualThing t in thingspass )
{
if ( t . Texture is UnknownImage ) continue ;
// Change blend mode?
if ( t . RenderPass ! = currentpass )
{
switch ( t . RenderPass )
{
case RenderPass . Additive :
graphics . Device . SetRenderState ( RenderState . DestinationBlend , Blend . One ) ;
break ;
case RenderPass . Alpha :
graphics . Device . SetRenderState ( RenderState . DestinationBlend , Blend . InverseSourceAlpha ) ;
break ;
}
currentpass = t . RenderPass ;
}
// Change texture?
if ( t . Texture . LongName ! = curtexturename )
{
// What texture to use?
if ( t . Texture . IsImageLoaded & & ! t . Texture . IsDisposed )
curtexture = t . Texture ;
else
curtexture = General . Map . Data . Hourglass3D ;
// Create Direct3D texture if still needed
if ( ( curtexture . Texture = = null ) | | curtexture . Texture . Disposed )
curtexture . CreateTexture ( ) ;
// Apply texture
if ( ! graphics . Shaders . Enabled )
graphics . Device . SetTexture ( 0 , curtexture . Texture ) ;
graphics . Shaders . World3D . Texture1 = curtexture . Texture ;
curtexturename = t . Texture . LongName ;
}
//mxd
if ( t . Thing . IsModel & &
( General . Settings . GZDrawModelsMode = = ModelRenderMode . ALL | |
General . Settings . GZDrawModelsMode = = ModelRenderMode . ACTIVE_THINGS_FILTER | |
( General . Settings . GZDrawModelsMode = = ModelRenderMode . SELECTION & & t . Selected ) ) )
continue ;
// Update buffer if needed
t . Update ( ) ;
// Only do this sector when a vertexbuffer is created
if ( t . GeometryBuffer ! = null )
{
// Determine the shader pass we want to use for this object
int wantedshaderpass = ( ( ( t = = highlighted ) & & showhighlight ) | | ( t . Selected & & showselection ) ) ? highshaderpass : shaderpass ;
//mxd. if fog is enagled, switch to shader, which calculates it
if ( General . Settings . GZDrawFog & & ! fullbrightness & & t . Thing . Sector ! = null & & ( t . Thing . Sector . HasFogColor | | t . Thing . Sector . Brightness < 248 ) )
wantedshaderpass + = 8 ;
//mxd. if current thing is light - set it's color to light color
Color4 litcolor = new Color4 ( ) ;
if ( Array . IndexOf ( GZBuilder . GZGeneral . GZ_LIGHTS , t . Thing . Type ) ! = - 1 & & ! fullbrightness )
{
wantedshaderpass + = 4 ; //render using one of passes, which uses World3D.VertexColor
graphics . Shaders . World3D . VertexColor = t . LightColor ;
litcolor = t . LightColor ;
}
//mxd. check if Thing is affected by dynamic lights and set color accordingly
else if ( General . Settings . GZDrawLightsMode ! = LightRenderMode . NONE & & ! fullbrightness & & lightthings . Count > 0 )
{
litcolor = GetLitColorForThing ( t ) ;
if ( litcolor . ToArgb ( ) ! = 0 )
{
wantedshaderpass + = 4 ; //render using one of passes, which uses World3D.VertexColor
graphics . Shaders . World3D . VertexColor = new Color4 ( t . VertexColor ) + litcolor ;
}
}
// Switch shader pass?
if ( currentshaderpass ! = wantedshaderpass )
{
graphics . Shaders . World3D . EndPass ( ) ;
graphics . Shaders . World3D . BeginPass ( wantedshaderpass ) ;
currentshaderpass = wantedshaderpass ;
}
// Set the colors to use
if ( ! graphics . Shaders . Enabled )
{
graphics . Device . SetTexture ( 2 , ( t . Selected & & showselection ) ? selectionimage . Texture : null ) ;
graphics . Device . SetTexture ( 3 , ( ( t = = highlighted ) & & showhighlight ) ? highlightimage . Texture : null ) ;
}
else
{
graphics . Shaders . World3D . SetHighlightColor ( CalculateHighlightColor ( ( t = = highlighted ) & & showhighlight , ( t . Selected & & showselection ) ) . ToArgb ( ) ) ;
}
//mxd. Create the matrix for positioning
if ( t . Info . RenderMode = = Thing . SpriteRenderMode . NORMAL ) // Apply billboarding?
{
if ( t . Info . XYBillboard )
{
world = Matrix . Translation ( 0f , 0f , - t . LocalCenterZ )
* Matrix . RotationX ( Angle2D . PI - General . Map . VisualCamera . AngleZ )
* Matrix . Translation ( 0f , 0f , t . LocalCenterZ )
* billboard
* Matrix . Scaling ( t . Thing . ScaleX , t . Thing . ScaleX , t . Thing . ScaleY )
* t . Position ;
}
else
{
world = billboard
* Matrix . Scaling ( t . Thing . ScaleX , t . Thing . ScaleX , t . Thing . ScaleY )
* t . Position ;
}
}
else
{
world = Matrix . Scaling ( t . Thing . ScaleX , t . Thing . ScaleX , t . Thing . ScaleY )
* t . Position ;
}
ApplyMatrices3D ( ) ;
//mxd. Set variables for fog rendering
if ( wantedshaderpass > 7 )
{
graphics . Shaders . World3D . World = world ;
graphics . Shaders . World3D . LightColor = t . Thing . Sector . FogColor ;
float fogdistance = ( litcolor . ToArgb ( ) ! = 0 ? VisualSector . MAXIMUM_FOG_DISTANCE : t . FogDistance ) ;
graphics . Shaders . World3D . CameraPosition = new Vector4 ( cameraposition . x , cameraposition . y , cameraposition . z , fogdistance ) ;
}
graphics . Shaders . World3D . ApplySettings ( ) ;
// Apply buffer
graphics . Device . SetStreamSource ( 0 , t . GeometryBuffer , 0 , WorldVertex . Stride ) ;
// Render!
graphics . Device . DrawPrimitives ( PrimitiveType . TriangleList , 0 , t . Triangles ) ;
}
}
// Texture addressing
graphics . Device . SetSamplerState ( 0 , SamplerState . AddressU , TextureAddress . Wrap ) ;
graphics . Device . SetSamplerState ( 0 , SamplerState . AddressV , TextureAddress . Wrap ) ;
graphics . Device . SetSamplerState ( 0 , SamplerState . AddressW , TextureAddress . Wrap ) ;
graphics . Device . SetRenderState ( RenderState . CullMode , Cull . Counterclockwise ) ; //mxd
}
2015-09-27 21:09:14 +00:00
// Done rendering with this shader
graphics . Shaders . World3D . EndPass ( ) ;
}
2013-09-11 09:47:53 +00:00
//mxd. Dynamic lights pass!
2015-09-27 21:09:14 +00:00
private void RenderLights ( Dictionary < ImageData , List < VisualGeometry > > geometrytolit , List < VisualThing > lights )
2014-12-03 23:15:26 +00:00
{
2015-09-27 21:09:14 +00:00
// Anything to do?
if ( geometrytolit . Count = = 0 ) return ;
2012-08-10 12:08:08 +00:00
graphics . Shaders . World3D . World = Matrix . Identity ;
2013-09-11 09:47:53 +00:00
graphics . Shaders . World3D . BeginPass ( 17 ) ;
2012-04-18 19:34:11 +00:00
2013-09-11 09:47:53 +00:00
int i , count ;
Vector4 lpr ;
2015-09-27 21:09:14 +00:00
VisualSector sector = null ;
2012-04-18 19:34:11 +00:00
2013-09-11 09:47:53 +00:00
graphics . Device . SetRenderState ( RenderState . SourceBlend , Blend . One ) ;
graphics . Device . SetRenderState ( RenderState . DestinationBlend , Blend . BlendFactor ) ;
2012-04-18 19:34:11 +00:00
2015-09-27 21:09:14 +00:00
foreach ( KeyValuePair < ImageData , List < VisualGeometry > > group in geometrytolit )
2014-12-03 23:15:26 +00:00
{
2015-06-08 09:48:25 +00:00
if ( group . Key . Texture = = null ) continue ;
graphics . Shaders . World3D . Texture1 = group . Key . Texture ;
2012-04-18 19:34:11 +00:00
2015-09-27 21:09:14 +00:00
foreach ( VisualGeometry g in group . Value )
2014-12-03 23:15:26 +00:00
{
2015-09-27 21:09:14 +00:00
// Changing sector?
if ( ! object . ReferenceEquals ( g . Sector , sector ) )
{
// 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
graphics . Device . SetStreamSource ( 0 , sector . GeometryBuffer , 0 , WorldVertex . Stride ) ;
}
else
{
sector = null ;
}
}
if ( sector = = null ) continue ;
2012-04-18 19:34:11 +00:00
2013-09-11 09:47:53 +00:00
//normal lights
count = lightOffsets [ 0 ] ;
2015-09-27 21:09:14 +00:00
if ( lightOffsets [ 0 ] > 0 )
2014-12-03 23:15:26 +00:00
{
2013-09-11 09:47:53 +00:00
graphics . Device . SetRenderState ( RenderState . BlendOperation , BlendOperation . Add ) ;
2012-04-18 19:34:11 +00:00
2014-12-03 23:15:26 +00:00
for ( i = 0 ; i < count ; i + + )
{
if ( BoundingBoxesIntersect ( g . BoundingBox , lights [ i ] . BoundingBox ) )
{
2012-08-10 12:08:08 +00:00
lpr = new Vector4 ( lights [ i ] . Center , lights [ i ] . LightRadius ) ;
2013-12-18 09:11:04 +00:00
if ( lpr . W = = 0 ) continue ;
2013-09-11 09:47:53 +00:00
graphics . Shaders . World3D . LightColor = lights [ i ] . LightColor ;
graphics . Shaders . World3D . LightPositionAndRadius = lpr ;
graphics . Shaders . World3D . ApplySettings ( ) ;
graphics . Device . DrawPrimitives ( PrimitiveType . TriangleList , g . VertexOffset , g . Triangles ) ;
}
}
}
2013-12-18 09:11:04 +00:00
//additive lights
2015-09-27 21:09:14 +00:00
if ( lightOffsets [ 1 ] > 0 )
2014-12-03 23:15:26 +00:00
{
2013-09-11 09:47:53 +00:00
count + = lightOffsets [ 1 ] ;
graphics . Device . SetRenderState ( RenderState . BlendOperation , BlendOperation . Add ) ;
2014-12-03 23:15:26 +00:00
for ( i = lightOffsets [ 0 ] ; i < count ; i + + )
{
if ( BoundingBoxesIntersect ( g . BoundingBox , lights [ i ] . BoundingBox ) )
{
2013-09-11 09:47:53 +00:00
lpr = new Vector4 ( lights [ i ] . Center , lights [ i ] . LightRadius ) ;
2013-12-18 09:11:04 +00:00
if ( lpr . W = = 0 ) continue ;
2013-09-11 09:47:53 +00:00
graphics . Shaders . World3D . LightColor = lights [ i ] . LightColor ;
graphics . Shaders . World3D . LightPositionAndRadius = lpr ;
graphics . Shaders . World3D . ApplySettings ( ) ;
graphics . Device . DrawPrimitives ( PrimitiveType . TriangleList , g . VertexOffset , g . Triangles ) ;
}
}
}
//negative lights
2015-09-27 21:09:14 +00:00
if ( lightOffsets [ 2 ] > 0 )
2014-12-03 23:15:26 +00:00
{
2013-09-11 09:47:53 +00:00
count + = lightOffsets [ 2 ] ;
graphics . Device . SetRenderState ( RenderState . BlendOperation , BlendOperation . ReverseSubtract ) ;
2014-12-03 23:15:26 +00:00
for ( i = lightOffsets [ 0 ] + lightOffsets [ 1 ] ; i < count ; i + + )
{
if ( BoundingBoxesIntersect ( g . BoundingBox , lights [ i ] . BoundingBox ) )
{
2013-09-11 09:47:53 +00:00
lpr = new Vector4 ( lights [ i ] . Center , lights [ i ] . LightRadius ) ;
2013-12-18 09:11:04 +00:00
if ( lpr . W = = 0 ) continue ;
2013-09-11 09:47:53 +00:00
Color4 lc = lights [ i ] . LightColor ;
graphics . Shaders . World3D . LightColor = new Color4 ( lc . Alpha , ( lc . Green + lc . Blue ) / 2 , ( lc . Red + lc . Blue ) / 2 , ( lc . Green + lc . Red ) / 2 ) ;
graphics . Shaders . World3D . LightPositionAndRadius = lpr ;
graphics . Shaders . World3D . ApplySettings ( ) ;
graphics . Device . DrawPrimitives ( PrimitiveType . TriangleList , g . VertexOffset , g . Triangles ) ;
}
}
}
}
}
graphics . Shaders . World3D . EndPass ( ) ;
graphics . Device . SetRenderState ( RenderState . BlendOperation , BlendOperation . Add ) ;
}
//mxd. render models
2014-10-20 12:16:51 +00:00
private void RenderModels ( )
{
2013-09-11 09:47:53 +00:00
int shaderpass = fullbrightness ? 1 : 4 ;
int currentshaderpass = shaderpass ;
int highshaderpass = shaderpass + 2 ;
// Begin rendering with this shader
graphics . Shaders . World3D . BeginPass ( currentshaderpass ) ;
2015-09-27 21:09:14 +00:00
foreach ( KeyValuePair < ModelData , List < VisualThing > > group in modelthings )
2014-10-20 12:16:51 +00:00
{
foreach ( VisualThing t in group . Value )
{
2013-09-11 09:47:53 +00:00
t . Update ( ) ;
2015-06-08 09:48:25 +00:00
Color4 vertexcolor = new Color4 ( t . VertexColor ) ;
vertexcolor . Alpha = 1.0f ;
2014-10-20 12:16:51 +00:00
2013-09-11 09:47:53 +00:00
//check if model is affected by dynamic lights and set color accordingly
2015-06-08 09:48:25 +00:00
Color4 litcolor = new Color4 ( ) ;
2015-09-27 21:09:14 +00:00
if ( General . Settings . GZDrawLightsMode ! = LightRenderMode . NONE & & ! fullbrightness & & lightthings . Count > 0 )
2014-10-20 12:16:51 +00:00
{
2015-06-08 09:48:25 +00:00
litcolor = GetLitColorForThing ( t ) ;
graphics . Shaders . World3D . VertexColor = vertexcolor + litcolor ;
2014-10-20 12:16:51 +00:00
}
else
{
2015-06-08 09:48:25 +00:00
graphics . Shaders . World3D . VertexColor = vertexcolor ;
litcolor = vertexcolor ;
2013-09-11 09:47:53 +00:00
}
// Determine the shader pass we want to use for this object
int wantedshaderpass = ( ( ( ( t = = highlighted ) & & showhighlight ) | | ( t . Selected & & showselection ) ) ? highshaderpass : shaderpass ) ;
//mxd. if fog is enagled, switch to shader, which calculates it
if ( General . Settings . GZDrawFog & & ! fullbrightness & & t . Thing . Sector ! = null & & ( t . Thing . Sector . HasFogColor | | t . Thing . Sector . Brightness < 248 ) )
wantedshaderpass + = 8 ;
// Switch shader pass?
2014-10-20 12:16:51 +00:00
if ( currentshaderpass ! = wantedshaderpass )
{
2013-09-11 09:47:53 +00:00
graphics . Shaders . World3D . EndPass ( ) ;
graphics . Shaders . World3D . BeginPass ( wantedshaderpass ) ;
currentshaderpass = wantedshaderpass ;
}
// Set the colors to use
2014-10-20 12:16:51 +00:00
if ( ! graphics . Shaders . Enabled )
{
2013-09-11 09:47:53 +00:00
graphics . Device . SetTexture ( 2 , ( t . Selected & & showselection ) ? selectionimage . Texture : null ) ;
graphics . Device . SetTexture ( 3 , ( ( t = = highlighted ) & & showhighlight ) ? highlightimage . Texture : null ) ;
2014-10-20 12:16:51 +00:00
}
else
{
2013-09-11 09:47:53 +00:00
graphics . Shaders . World3D . SetHighlightColor ( CalculateHighlightColor ( ( t = = highlighted ) & & showhighlight , ( t . Selected & & showselection ) ) . ToArgb ( ) ) ;
}
// Create the matrix for positioning / rotation
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
float sx = t . Thing . ScaleX * t . Thing . ActorScale . Width ;
2014-12-22 21:36:49 +00:00
float sy = t . Thing . ScaleY * t . Thing . ActorScale . Height ;
2014-12-11 12:55:35 +00:00
Matrix modelscale = Matrix . Scaling ( sx , sx , sy ) ;
2014-12-22 21:36:49 +00:00
Matrix modelrotation = Matrix . RotationY ( - t . Thing . RollRad ) * Matrix . RotationX ( - t . Thing . PitchRad ) * Matrix . RotationZ ( t . Thing . Angle ) ;
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-03-26 11:30:36 +00:00
world = General . Map . Data . ModeldefEntries [ t . Thing . Type ] . Transform * modelscale * modelrotation * t . Position ;
2013-09-11 09:47:53 +00:00
ApplyMatrices3D ( ) ;
2012-04-17 19:13:47 +00:00
2013-09-11 09:47:53 +00:00
//mxd. set variables for fog rendering
2014-10-20 12:16:51 +00:00
if ( wantedshaderpass > 7 )
{
2013-09-11 09:47:53 +00:00
graphics . Shaders . World3D . World = world ;
2013-09-11 08:49:45 +00:00
graphics . Shaders . World3D . LightColor = t . Thing . Sector . FogColor ;
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
float fogdistance = ( litcolor . ToArgb ( ) ! = 0 ? VisualSector . MAXIMUM_FOG_DISTANCE : t . FogDistance ) ;
graphics . Shaders . World3D . CameraPosition = new Vector4 ( cameraposition . x , cameraposition . y , cameraposition . z , fogdistance ) ;
2013-09-11 09:47:53 +00:00
}
2012-05-20 00:56:59 +00:00
2014-10-20 12:16:51 +00:00
for ( int i = 0 ; i < group . Key . Model . Meshes . Count ; i + + )
{
2013-09-11 09:47:53 +00:00
if ( ! graphics . Shaders . Enabled ) graphics . Device . SetTexture ( 0 , group . Key . Model . Textures [ i ] ) ;
graphics . Shaders . World3D . Texture1 = group . Key . Model . Textures [ i ] ;
graphics . Shaders . World3D . ApplySettings ( ) ;
// Render!
group . Key . Model . Meshes [ i ] . DrawSubset ( 0 ) ;
}
}
}
graphics . Shaders . World3D . EndPass ( ) ;
}
//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 ( ) ;
float radius , radiusSquared , distSquared , scaler ;
int sign ;
2015-09-27 21:09:14 +00:00
for ( int i = 0 ; i < lightthings . Count ; i + + )
2014-12-03 23:15:26 +00:00
{
2013-09-11 09:47:53 +00:00
//don't light self
2015-09-27 21:09:14 +00:00
if ( General . Map . Data . GldefsEntries . ContainsKey ( t . Thing . Type ) & & General . Map . Data . GldefsEntries [ t . Thing . Type ] . DontLightSelf & & t . Thing . Index = = lightthings [ i ] . Thing . Index )
2013-09-11 09:47:53 +00:00
continue ;
2015-09-27 21:09:14 +00:00
distSquared = Vector3 . DistanceSquared ( lightthings [ i ] . Center , t . PositionV3 ) ;
radius = lightthings [ i ] . LightRadius ;
2013-09-11 09:47:53 +00:00
radiusSquared = radius * radius ;
2015-09-27 21:09:14 +00:00
if ( distSquared < radiusSquared )
2014-12-03 23:15:26 +00:00
{
2015-09-27 21:09:14 +00:00
sign = lightthings [ i ] . LightRenderStyle = = DynamicLightRenderStyle . NEGATIVE ? - 1 : 1 ;
scaler = 1 - distSquared / radiusSquared * lightthings [ i ] . LightColor . Alpha ;
litColor . Red + = lightthings [ i ] . LightColor . Red * scaler * sign ;
litColor . Green + = lightthings [ i ] . LightColor . Green * scaler * sign ;
litColor . Blue + = lightthings [ i ] . LightColor . Blue * scaler * sign ;
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
{
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
{
2015-09-27 21:09:14 +00:00
switch ( g . RenderPass )
2009-04-19 18:07:22 +00:00
{
2015-09-27 21:09:14 +00:00
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 )
{
2013-09-11 09:47:53 +00:00
//mxd. gater lights
2015-06-22 19:52:23 +00:00
if ( General . Settings . GZDrawLightsMode ! = LightRenderMode . NONE & & ! fullbrightness & & t . LightType ! = DynamicLightType . NONE )
2014-10-20 12:16:51 +00:00
{
2013-09-11 09:47:53 +00:00
t . UpdateLightRadius ( ) ;
2015-09-27 21:09:14 +00:00
if ( t . LightRadius > 0 )
2014-10-20 12:16:51 +00:00
{
2015-09-27 21:09:14 +00:00
if ( Array . IndexOf ( GZBuilder . GZGeneral . GZ_ANIMATED_LIGHT_TYPES , t . LightType ) ! = - 1 )
2015-06-22 19:52:23 +00:00
t . UpdateBoundingBox ( ) ;
2015-09-27 21:09:14 +00:00
lightthings . Add ( t ) ;
2013-09-11 09:47:53 +00:00
}
}
//mxd. gather models
2015-06-29 08:15:07 +00:00
if ( t . Thing . IsModel & &
( 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
{
2013-09-11 09:47:53 +00:00
ModelData mde = General . Map . Data . ModeldefEntries [ t . Thing . Type ] ;
2015-09-27 21:09:14 +00:00
if ( ! modelthings . ContainsKey ( mde ) )
modelthings . Add ( mde , new List < VisualThing > { t } ) ;
2013-07-29 08:50:50 +00:00
else
2015-09-27 21:09:14 +00:00
modelthings [ mde ] . Add ( t ) ;
2013-09-11 09:47:53 +00:00
}
2015-09-27 21:09:14 +00:00
//mxd. Add to the plain list
allthings . Add ( t ) ;
2013-09-11 09:47:53 +00:00
// Must have a texture!
if ( t . Texture ! = null )
2009-04-19 18:07:22 +00:00
{
2015-09-27 21:09:14 +00:00
//mxd
switch ( t . RenderPass )
2009-04-19 18:07:22 +00:00
{
2015-09-27 21:09:14 +00:00
case RenderPass . Solid :
if ( ! solidthings . ContainsKey ( t . Texture ) ) solidthings . Add ( t . Texture , new List < VisualThing > ( ) ) ;
solidthings [ t . Texture ] . Add ( t ) ;
break ;
case RenderPass . Mask :
if ( ! maskedthings . ContainsKey ( t . Texture ) ) maskedthings . Add ( t . Texture , new List < VisualThing > ( ) ) ;
maskedthings [ t . Texture ] . Add ( t ) ;
break ;
case RenderPass . Additive : case RenderPass . Alpha :
translucentthings . Add ( t ) ;
break ;
2009-04-19 18:07:22 +00:00
2015-09-27 21:09:14 +00:00
default :
throw new NotImplementedException ( "Thing rendering of " + t . RenderPass + " render pass is not implemented!" ) ;
}
2009-04-19 18:07:22 +00:00
}
}
2013-03-18 13:52:27 +00:00
//mxd
2014-10-20 12:16:51 +00:00
public void AddVisualVertices ( VisualVertex [ ] verts )
{
2013-03-18 13:52:27 +00:00
visualvertices = verts ;
}
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 ;
ApplyMatrices3D ( ) ;
2009-04-19 18:07:22 +00:00
// Set renderstates
2013-09-11 09:47:53 +00:00
graphics . Device . SetRenderState ( RenderState . CullMode , Cull . None ) ;
graphics . Device . SetRenderState ( RenderState . ZEnable , false ) ;
graphics . Device . SetRenderState ( RenderState . AlphaBlendEnable , true ) ;
graphics . Device . SetRenderState ( RenderState . AlphaTestEnable , false ) ;
graphics . Device . SetRenderState ( RenderState . SourceBlend , Blend . SourceAlpha ) ;
graphics . Device . SetRenderState ( RenderState . DestinationBlend , Blend . InverseSourceAlpha ) ;
graphics . Device . SetRenderState ( RenderState . TextureFactor , - 1 ) ;
graphics . Device . SetTransform ( TransformState . World , Matrix . Identity ) ;
graphics . Device . SetTransform ( TransformState . Projection , Matrix . Identity ) ;
ApplyMatrices2D ( ) ;
2009-04-19 18:07:22 +00:00
2013-09-11 09:47:53 +00:00
// Texture
if ( crosshairbusy )
{
if ( General . Map . Data . CrosshairBusy3D . Texture = = null ) General . Map . Data . CrosshairBusy3D . CreateTexture ( ) ;
graphics . Device . SetTexture ( 0 , General . Map . Data . CrosshairBusy3D . Texture ) ;
graphics . Shaders . Display2D . Texture1 = General . Map . Data . CrosshairBusy3D . Texture ;
}
else
{
if ( General . Map . Data . Crosshair3D . Texture = = null ) General . Map . Data . Crosshair3D . CreateTexture ( ) ;
graphics . Device . SetTexture ( 0 , General . Map . Data . Crosshair3D . Texture ) ;
graphics . Shaders . Display2D . Texture1 = General . Map . Data . Crosshair3D . Texture ;
}
2009-04-19 18:07:22 +00:00
2013-09-11 09:47:53 +00:00
// Draw
graphics . Shaders . Display2D . Begin ( ) ;
graphics . Shaders . Display2D . SetSettings ( 1.0f , 1.0f , 0.0f , 1.0f , true ) ;
graphics . Shaders . Display2D . BeginPass ( 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
graphics . Device . DrawUserPrimitives ( PrimitiveType . TriangleStrip , 0 , 2 , crosshairverts ) ;
2013-09-11 09:47:53 +00:00
graphics . Shaders . Display2D . EndPass ( ) ;
graphics . Shaders . Display2D . End ( ) ;
}
2009-04-19 18:07:22 +00:00
// This switches fog on and off
public void SetFogMode ( bool usefog )
{
graphics . Device . SetRenderState ( RenderState . FogEnable , usefog ) ;
}
// This siwtches crosshair busy icon on and off
public void SetCrosshairBusy ( bool busy )
{
crosshairbusy = busy ;
}
#endregion
}
}