mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-29 23:22:32 +00:00
Fixed crash when sectors with lots of sidedefs are created or loaded
This commit is contained in:
parent
d84312ea92
commit
89bf322a74
6 changed files with 264 additions and 91 deletions
|
@ -51,6 +51,7 @@ Global
|
||||||
{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||||
{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||||
{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Debug|x86.ActiveCfg = Debug|x86
|
{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Debug|x86.Build.0 = Debug|x86
|
||||||
{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Release|Any CPU.ActiveCfg = Release|x86
|
{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Release|Any CPU.ActiveCfg = Release|x86
|
||||||
{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||||
{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Release|Mixed Platforms.Build.0 = Release|x86
|
{FBC0A503-9152-4BE2-9B5C-128FFD0B0D3F}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||||
|
@ -59,6 +60,7 @@ Global
|
||||||
{A5F93B70-18D9-4F3C-9B72-BC8B5B13998E}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
{A5F93B70-18D9-4F3C-9B72-BC8B5B13998E}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||||
{A5F93B70-18D9-4F3C-9B72-BC8B5B13998E}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
{A5F93B70-18D9-4F3C-9B72-BC8B5B13998E}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||||
{A5F93B70-18D9-4F3C-9B72-BC8B5B13998E}.Debug|x86.ActiveCfg = Debug|x86
|
{A5F93B70-18D9-4F3C-9B72-BC8B5B13998E}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{A5F93B70-18D9-4F3C-9B72-BC8B5B13998E}.Debug|x86.Build.0 = Debug|x86
|
||||||
{A5F93B70-18D9-4F3C-9B72-BC8B5B13998E}.Release|Any CPU.ActiveCfg = Release|x86
|
{A5F93B70-18D9-4F3C-9B72-BC8B5B13998E}.Release|Any CPU.ActiveCfg = Release|x86
|
||||||
{A5F93B70-18D9-4F3C-9B72-BC8B5B13998E}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
{A5F93B70-18D9-4F3C-9B72-BC8B5B13998E}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||||
{A5F93B70-18D9-4F3C-9B72-BC8B5B13998E}.Release|Mixed Platforms.Build.0 = Release|x86
|
{A5F93B70-18D9-4F3C-9B72-BC8B5B13998E}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||||
|
@ -67,6 +69,7 @@ Global
|
||||||
{CBD14608-D467-458A-97B3-CA767CA85203}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
{CBD14608-D467-458A-97B3-CA767CA85203}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||||
{CBD14608-D467-458A-97B3-CA767CA85203}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
{CBD14608-D467-458A-97B3-CA767CA85203}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||||
{CBD14608-D467-458A-97B3-CA767CA85203}.Debug|x86.ActiveCfg = Debug|x86
|
{CBD14608-D467-458A-97B3-CA767CA85203}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{CBD14608-D467-458A-97B3-CA767CA85203}.Debug|x86.Build.0 = Debug|x86
|
||||||
{CBD14608-D467-458A-97B3-CA767CA85203}.Release|Any CPU.ActiveCfg = Release|x86
|
{CBD14608-D467-458A-97B3-CA767CA85203}.Release|Any CPU.ActiveCfg = Release|x86
|
||||||
{CBD14608-D467-458A-97B3-CA767CA85203}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
{CBD14608-D467-458A-97B3-CA767CA85203}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||||
{CBD14608-D467-458A-97B3-CA767CA85203}.Release|Mixed Platforms.Build.0 = Release|x86
|
{CBD14608-D467-458A-97B3-CA767CA85203}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||||
|
|
|
@ -703,7 +703,9 @@
|
||||||
<Compile Include="Map\MapElementCollection.cs" />
|
<Compile Include="Map\MapElementCollection.cs" />
|
||||||
<Compile Include="Rendering\SurfaceBufferSet.cs" />
|
<Compile Include="Rendering\SurfaceBufferSet.cs" />
|
||||||
<Compile Include="Rendering\SurfaceEntry.cs" />
|
<Compile Include="Rendering\SurfaceEntry.cs" />
|
||||||
|
<Compile Include="Rendering\SurfaceEntryCollection.cs" />
|
||||||
<Compile Include="Rendering\SurfaceManager.cs" />
|
<Compile Include="Rendering\SurfaceManager.cs" />
|
||||||
|
<Compile Include="Rendering\SurfaceUpdate.cs" />
|
||||||
<Compile Include="Types\ThingClassHandler.cs" />
|
<Compile Include="Types\ThingClassHandler.cs" />
|
||||||
<Compile Include="Types\ThingTypeHandler.cs" />
|
<Compile Include="Types\ThingTypeHandler.cs" />
|
||||||
<Compile Include="Windows\ErrorsForm.cs">
|
<Compile Include="Windows\ErrorsForm.cs">
|
||||||
|
|
|
@ -73,7 +73,7 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
private Triangulation triangles;
|
private Triangulation triangles;
|
||||||
private FlatVertex[] flatvertices;
|
private FlatVertex[] flatvertices;
|
||||||
private ReadOnlyCollection<LabelPositionInfo> labels;
|
private ReadOnlyCollection<LabelPositionInfo> labels;
|
||||||
private SurfaceEntry surfaceentry;
|
private SurfaceEntryCollection surfaceentries;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
this.longceiltexname = MapSet.EmptyLongName;
|
this.longceiltexname = MapSet.EmptyLongName;
|
||||||
this.updateneeded = true;
|
this.updateneeded = true;
|
||||||
this.triangulationneeded = true;
|
this.triangulationneeded = true;
|
||||||
this.surfaceentry = new SurfaceEntry(-1, -1, -1);
|
this.surfaceentries = new SurfaceEntryCollection();
|
||||||
|
|
||||||
if(map == General.Map.Map)
|
if(map == General.Map.Map)
|
||||||
General.Map.UndoRedo.RecAddSector(this);
|
General.Map.UndoRedo.RecAddSector(this);
|
||||||
|
@ -156,7 +156,7 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
map.AddSectorIndexHole(fixedindex);
|
map.AddSectorIndexHole(fixedindex);
|
||||||
|
|
||||||
// Free surface entry
|
// Free surface entry
|
||||||
General.Map.CRenderer2D.Surfaces.FreeSurfaces(surfaceentry);
|
General.Map.CRenderer2D.Surfaces.FreeSurfaces(surfaceentries);
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
sidedefs = null;
|
sidedefs = null;
|
||||||
|
@ -273,8 +273,8 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
labels = Array.AsReadOnly<LabelPositionInfo>(Tools.FindLabelPositions(this).ToArray());
|
labels = Array.AsReadOnly<LabelPositionInfo>(Tools.FindLabelPositions(this).ToArray());
|
||||||
|
|
||||||
// Number of vertices changed?
|
// Number of vertices changed?
|
||||||
if((surfaceentry != null) && (triangles.Vertices.Count != surfaceentry.numvertices))
|
if(triangles.Vertices.Count != surfaceentries.totalvertices)
|
||||||
General.Map.CRenderer2D.Surfaces.FreeSurfaces(surfaceentry);
|
General.Map.CRenderer2D.Surfaces.FreeSurfaces(surfaceentries);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,25 +302,17 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
// Create bounding box
|
// Create bounding box
|
||||||
bbox = CreateBBox();
|
bbox = CreateBBox();
|
||||||
|
|
||||||
// Make a dummy entry if we don't have one yet
|
// Make update info (this lets the plugin fill in texture coordinates and such)
|
||||||
if(surfaceentry == null) surfaceentry = new SurfaceEntry(-1, -1, -1);
|
SurfaceUpdate updateinfo = new SurfaceUpdate(flatvertices.Length, true, true);
|
||||||
|
flatvertices.CopyTo(updateinfo.floorvertices, 0);
|
||||||
|
General.Plugins.OnSectorFloorSurfaceUpdate(this, ref updateinfo.floorvertices);
|
||||||
|
flatvertices.CopyTo(updateinfo.ceilvertices, 0);
|
||||||
|
General.Plugins.OnSectorCeilingSurfaceUpdate(this, ref updateinfo.ceilvertices);
|
||||||
|
updateinfo.floortexture = longfloortexname;
|
||||||
|
updateinfo.ceiltexture = longceiltexname;
|
||||||
|
|
||||||
// Create floor vertices
|
// Update surfaces
|
||||||
FlatVertex[] floorvertices = new FlatVertex[flatvertices.Length];
|
General.Map.CRenderer2D.Surfaces.UpdateSurfaces(surfaceentries, updateinfo);
|
||||||
flatvertices.CopyTo(floorvertices, 0);
|
|
||||||
General.Plugins.OnSectorFloorSurfaceUpdate(this, ref floorvertices);
|
|
||||||
surfaceentry.floorvertices = floorvertices;
|
|
||||||
surfaceentry.floortexture = longfloortexname;
|
|
||||||
|
|
||||||
// Create ceiling vertices
|
|
||||||
FlatVertex[] ceilvertices = new FlatVertex[flatvertices.Length];
|
|
||||||
flatvertices.CopyTo(ceilvertices, 0);
|
|
||||||
General.Plugins.OnSectorCeilingSurfaceUpdate(this, ref ceilvertices);
|
|
||||||
surfaceentry.ceilvertices = ceilvertices;
|
|
||||||
surfaceentry.ceiltexture = longceiltexname;
|
|
||||||
|
|
||||||
// Update entry
|
|
||||||
surfaceentry = General.Map.CRenderer2D.Surfaces.UpdateSurfaces(surfaceentry);
|
|
||||||
|
|
||||||
// Updated
|
// Updated
|
||||||
updateneeded = false;
|
updateneeded = false;
|
||||||
|
@ -333,16 +325,13 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
if(flatvertices == null) return;
|
if(flatvertices == null) return;
|
||||||
|
|
||||||
// Create floor vertices
|
// Create floor vertices
|
||||||
FlatVertex[] floorvertices = new FlatVertex[flatvertices.Length];
|
SurfaceUpdate updateinfo = new SurfaceUpdate(flatvertices.Length, true, false);
|
||||||
flatvertices.CopyTo(floorvertices, 0);
|
flatvertices.CopyTo(updateinfo.floorvertices, 0);
|
||||||
General.Plugins.OnSectorFloorSurfaceUpdate(this, ref floorvertices);
|
General.Plugins.OnSectorFloorSurfaceUpdate(this, ref updateinfo.floorvertices);
|
||||||
surfaceentry.floorvertices = floorvertices;
|
updateinfo.floortexture = longfloortexname;
|
||||||
surfaceentry.floortexture = longfloortexname;
|
|
||||||
if(surfaceentry.ceilvertices == null)
|
|
||||||
surfaceentry.ceilvertices = floorvertices;
|
|
||||||
|
|
||||||
// Update entry
|
// Update entry
|
||||||
surfaceentry = General.Map.CRenderer2D.Surfaces.UpdateSurfaces(surfaceentry);
|
General.Map.CRenderer2D.Surfaces.UpdateSurfaces(surfaceentries, updateinfo);
|
||||||
General.Map.CRenderer2D.Surfaces.UnlockBuffers();
|
General.Map.CRenderer2D.Surfaces.UnlockBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,16 +341,13 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
if(flatvertices == null) return;
|
if(flatvertices == null) return;
|
||||||
|
|
||||||
// Create ceiling vertices
|
// Create ceiling vertices
|
||||||
FlatVertex[] ceilvertices = new FlatVertex[flatvertices.Length];
|
SurfaceUpdate updateinfo = new SurfaceUpdate(flatvertices.Length, false, true);
|
||||||
flatvertices.CopyTo(ceilvertices, 0);
|
flatvertices.CopyTo(updateinfo.ceilvertices, 0);
|
||||||
General.Plugins.OnSectorCeilingSurfaceUpdate(this, ref ceilvertices);
|
General.Plugins.OnSectorCeilingSurfaceUpdate(this, ref updateinfo.ceilvertices);
|
||||||
surfaceentry.ceilvertices = ceilvertices;
|
updateinfo.ceiltexture = longceiltexname;
|
||||||
surfaceentry.ceiltexture = longceiltexname;
|
|
||||||
if(surfaceentry.floorvertices == null)
|
|
||||||
surfaceentry.floorvertices = ceilvertices;
|
|
||||||
|
|
||||||
// Update entry
|
// Update entry
|
||||||
surfaceentry = General.Map.CRenderer2D.Surfaces.UpdateSurfaces(surfaceentry);
|
General.Map.CRenderer2D.Surfaces.UpdateSurfaces(surfaceentries, updateinfo);
|
||||||
General.Map.CRenderer2D.Surfaces.UnlockBuffers();
|
General.Map.CRenderer2D.Surfaces.UnlockBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
49
Source/Core/Rendering/SurfaceEntryCollection.cs
Normal file
49
Source/Core/Rendering/SurfaceEntryCollection.cs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
|
||||||
|
#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;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using CodeImp.DoomBuilder.Map;
|
||||||
|
using SlimDX.Direct3D9;
|
||||||
|
using SlimDX;
|
||||||
|
using CodeImp.DoomBuilder.Geometry;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using CodeImp.DoomBuilder.Data;
|
||||||
|
using CodeImp.DoomBuilder.Editing;
|
||||||
|
|
||||||
|
using Configuration = CodeImp.DoomBuilder.IO.Configuration;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
namespace CodeImp.DoomBuilder.Rendering
|
||||||
|
{
|
||||||
|
// This contains information to update surface entries with. This may exceed the maximum number
|
||||||
|
// of sector vertices, the surface manager will take care of splitting it up in several SurfaceEntries.
|
||||||
|
internal class SurfaceEntryCollection : List<SurfaceEntry>
|
||||||
|
{
|
||||||
|
public int totalvertices = 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,6 +48,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
// is a scary big number for a vertexbuffer.
|
// is a scary big number for a vertexbuffer.
|
||||||
private const int MAX_VERTICES_PER_BUFFER = 30000;
|
private const int MAX_VERTICES_PER_BUFFER = 30000;
|
||||||
|
|
||||||
|
// When a sector exceeds this number of vertices, it should split up it's triangles
|
||||||
|
// This number must be a multiple of 3.
|
||||||
|
public const int MAX_VERTICES_PER_SECTOR = 6000;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================== Variables
|
#region ================== Variables
|
||||||
|
@ -220,10 +224,19 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
{
|
{
|
||||||
if(s.Triangles != null)
|
if(s.Triangles != null)
|
||||||
{
|
{
|
||||||
// We count the number of sectors that have specific number of vertices
|
int numvertices = s.Triangles.Vertices.Count;
|
||||||
if(!sectorverts.ContainsKey(s.Triangles.Vertices.Count))
|
while(numvertices > 0)
|
||||||
sectorverts.Add(s.Triangles.Vertices.Count, 0);
|
{
|
||||||
sectorverts[s.Triangles.Vertices.Count]++;
|
// Determine for how many vertices in this entry
|
||||||
|
int vertsinentry = (numvertices > MAX_VERTICES_PER_SECTOR) ? MAX_VERTICES_PER_SECTOR : numvertices;
|
||||||
|
|
||||||
|
// We count the number of sectors that have specific number of vertices
|
||||||
|
if(!sectorverts.ContainsKey(vertsinentry))
|
||||||
|
sectorverts.Add(vertsinentry, 0);
|
||||||
|
sectorverts[vertsinentry]++;
|
||||||
|
|
||||||
|
numvertices -= vertsinentry;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,53 +398,95 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
}
|
}
|
||||||
|
|
||||||
// This adds or updates sector geometry into a buffer.
|
// This adds or updates sector geometry into a buffer.
|
||||||
// Always specify the entry when a previous entry was already given for that sector!
|
// Modiies the list of SurfaceEntries with the new surface entry for the stored geometry.
|
||||||
// Sector must set the floorvertices and ceilvertices members on the entry.
|
public void UpdateSurfaces(SurfaceEntryCollection entries, SurfaceUpdate update)
|
||||||
// Returns the new surface entry for the stored geometry, floorvertices and ceilvertices will be preserved.
|
|
||||||
public SurfaceEntry UpdateSurfaces(SurfaceEntry entry)
|
|
||||||
{
|
{
|
||||||
if(entry.floorvertices.Length != entry.ceilvertices.Length)
|
// Free entries when number of vertices has changed
|
||||||
General.Fail("Floor vertices has different length from ceiling vertices!");
|
if((entries.Count > 0) && (entries.totalvertices != update.numvertices))
|
||||||
|
|
||||||
int numvertices = entry.floorvertices.Length;
|
|
||||||
|
|
||||||
// Free entry when number of vertices have changed
|
|
||||||
if((entry.numvertices != numvertices) && (entry.numvertices != -1))
|
|
||||||
FreeSurfaces(entry);
|
|
||||||
|
|
||||||
// Check if we can render this at all
|
|
||||||
if(numvertices > 0)
|
|
||||||
{
|
{
|
||||||
SurfaceBufferSet set = GetSet(numvertices);
|
FreeSurfaces(entries);
|
||||||
|
entries.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if((entries.Count == 0) && (update.numvertices > 0))
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
if((update.floorvertices == null) || (update.ceilvertices == null))
|
||||||
|
General.Fail("We need both floor and ceiling vertices when the number of vertices changes!");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// If we have no entries yet, we have to make them now
|
||||||
|
int vertsremaining = update.numvertices;
|
||||||
|
while(vertsremaining > 0)
|
||||||
|
{
|
||||||
|
// Determine for how many vertices in this entry
|
||||||
|
int vertsinentry = (vertsremaining > MAX_VERTICES_PER_SECTOR) ? MAX_VERTICES_PER_SECTOR : vertsremaining;
|
||||||
|
|
||||||
|
// Lookup the set that holds entries for this number of vertices
|
||||||
|
SurfaceBufferSet set = GetSet(vertsinentry);
|
||||||
|
|
||||||
|
// Make sure we can get a new entry in this set
|
||||||
|
EnsureFreeBufferSpace(set, 1);
|
||||||
|
|
||||||
|
// Get a new entry in this set
|
||||||
|
SurfaceEntry e = set.holes[set.holes.Count - 1];
|
||||||
|
set.holes.RemoveAt(set.holes.Count - 1);
|
||||||
|
set.entries.Add(e);
|
||||||
|
|
||||||
|
// Fill the entry data
|
||||||
|
e.floorvertices = new FlatVertex[vertsinentry];
|
||||||
|
e.ceilvertices = new FlatVertex[vertsinentry];
|
||||||
|
Array.Copy(update.floorvertices, update.numvertices - vertsremaining, e.floorvertices, 0, vertsinentry);
|
||||||
|
Array.Copy(update.ceilvertices, update.numvertices - vertsremaining, e.ceilvertices, 0, vertsinentry);
|
||||||
|
e.floortexture = update.floortexture;
|
||||||
|
e.ceiltexture = update.ceiltexture;
|
||||||
|
|
||||||
|
entries.Add(e);
|
||||||
|
vertsremaining -= vertsinentry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We re-use the same entries, just copy over the updated data
|
||||||
|
int vertsremaining = update.numvertices;
|
||||||
|
foreach(SurfaceEntry e in entries)
|
||||||
|
{
|
||||||
|
if(update.floorvertices != null)
|
||||||
|
{
|
||||||
|
Array.Copy(update.floorvertices, update.numvertices - vertsremaining, e.floorvertices, 0, e.numvertices);
|
||||||
|
e.floortexture = update.floortexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(update.ceilvertices != null)
|
||||||
|
{
|
||||||
|
Array.Copy(update.ceilvertices, update.numvertices - vertsremaining, e.ceilvertices, 0, e.numvertices);
|
||||||
|
e.ceiltexture = update.ceiltexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
vertsremaining -= e.numvertices;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entries.totalvertices = update.numvertices;
|
||||||
|
|
||||||
|
// Time to update or create the buffers
|
||||||
|
foreach(SurfaceEntry e in entries)
|
||||||
|
{
|
||||||
|
SurfaceBufferSet set = GetSet(e.numvertices);
|
||||||
|
|
||||||
// Update bounding box
|
// Update bounding box
|
||||||
entry.UpdateBBox();
|
e.UpdateBBox();
|
||||||
|
|
||||||
// Check if we need a new entry
|
|
||||||
if(entry.numvertices == -1)
|
|
||||||
{
|
|
||||||
EnsureFreeBufferSpace(set, 1);
|
|
||||||
SurfaceEntry nentry = set.holes[set.holes.Count - 1];
|
|
||||||
set.holes.RemoveAt(set.holes.Count - 1);
|
|
||||||
nentry.ceilvertices = entry.ceilvertices;
|
|
||||||
nentry.floorvertices = entry.floorvertices;
|
|
||||||
nentry.floortexture = entry.floortexture;
|
|
||||||
nentry.ceiltexture = entry.ceiltexture;
|
|
||||||
nentry.bbox = entry.bbox;
|
|
||||||
set.entries.Add(nentry);
|
|
||||||
entry = nentry;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!resourcesunloaded)
|
if(!resourcesunloaded)
|
||||||
{
|
{
|
||||||
// Lock the buffer
|
// Lock the buffer
|
||||||
DataStream bstream;
|
DataStream bstream;
|
||||||
VertexBuffer vb = set.buffers[entry.bufferindex];
|
VertexBuffer vb = set.buffers[e.bufferindex];
|
||||||
if(vb.Tag == null)
|
if(vb.Tag == null)
|
||||||
{
|
{
|
||||||
// Note: DirectX warns me that I am not using LockFlags.Discard or LockFlags.NoOverwrite here,
|
// Note: DirectX warns me that I am not using LockFlags.Discard or LockFlags.NoOverwrite here,
|
||||||
// but we don't care (we don't have much of a choice since we want to update our data)
|
// but we don't have much of a choice since we want to update our data and not destroy other data
|
||||||
bstream = vb.Lock(0, set.buffersizes[entry.bufferindex] * FlatVertex.Stride, LockFlags.None);
|
bstream = vb.Lock(0, set.buffersizes[e.bufferindex] * FlatVertex.Stride, LockFlags.None);
|
||||||
vb.Tag = bstream;
|
vb.Tag = bstream;
|
||||||
lockedbuffers.Add(vb);
|
lockedbuffers.Add(vb);
|
||||||
}
|
}
|
||||||
|
@ -441,27 +496,28 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the vertices to buffer
|
// Write the vertices to buffer
|
||||||
bstream.Seek(entry.vertexoffset * FlatVertex.Stride, SeekOrigin.Begin);
|
bstream.Seek(e.vertexoffset * FlatVertex.Stride, SeekOrigin.Begin);
|
||||||
bstream.WriteRange(entry.floorvertices);
|
bstream.WriteRange(e.floorvertices);
|
||||||
bstream.WriteRange(entry.ceilvertices);
|
bstream.WriteRange(e.ceilvertices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This frees the given surface entry
|
// This frees the given surface entry
|
||||||
public void FreeSurfaces(SurfaceEntry entry)
|
public void FreeSurfaces(SurfaceEntryCollection entries)
|
||||||
{
|
{
|
||||||
if((entry.numvertices > 0) && (entry.bufferindex > -1))
|
foreach(SurfaceEntry e in entries)
|
||||||
{
|
{
|
||||||
SurfaceBufferSet set = sets[entry.numvertices];
|
if((e.numvertices > 0) && (e.bufferindex > -1))
|
||||||
set.entries.Remove(entry);
|
{
|
||||||
SurfaceEntry newentry = new SurfaceEntry(entry);
|
SurfaceBufferSet set = sets[e.numvertices];
|
||||||
set.holes.Add(newentry);
|
set.entries.Remove(e);
|
||||||
|
SurfaceEntry newentry = new SurfaceEntry(e);
|
||||||
|
set.holes.Add(newentry);
|
||||||
|
}
|
||||||
|
e.numvertices = -1;
|
||||||
|
e.bufferindex = -1;
|
||||||
}
|
}
|
||||||
entry.numvertices = -1;
|
|
||||||
entry.bufferindex = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This unlocks the locked buffers
|
// This unlocks the locked buffers
|
||||||
|
|
77
Source/Core/Rendering/SurfaceUpdate.cs
Normal file
77
Source/Core/Rendering/SurfaceUpdate.cs
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
|
||||||
|
#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;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using CodeImp.DoomBuilder.Map;
|
||||||
|
using SlimDX.Direct3D9;
|
||||||
|
using SlimDX;
|
||||||
|
using CodeImp.DoomBuilder.Geometry;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using CodeImp.DoomBuilder.Data;
|
||||||
|
using CodeImp.DoomBuilder.Editing;
|
||||||
|
|
||||||
|
using Configuration = CodeImp.DoomBuilder.IO.Configuration;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
namespace CodeImp.DoomBuilder.Rendering
|
||||||
|
{
|
||||||
|
// This contains information to update surface entries with. This may exceed the maximum number
|
||||||
|
// of sector vertices, the surface manager will take care of splitting it up in several SurfaceEntries.
|
||||||
|
internal class SurfaceUpdate
|
||||||
|
{
|
||||||
|
public int numvertices;
|
||||||
|
|
||||||
|
// Sector geometry (local copy used to quickly refill buffers)
|
||||||
|
// The sector must set these!
|
||||||
|
public FlatVertex[] floorvertices;
|
||||||
|
public FlatVertex[] ceilvertices;
|
||||||
|
|
||||||
|
// Sector images
|
||||||
|
// The sector must set these!
|
||||||
|
public long floortexture;
|
||||||
|
public long ceiltexture;
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
internal SurfaceUpdate(int numvertices, bool updatefloor, bool updateceiling)
|
||||||
|
{
|
||||||
|
this.numvertices = numvertices;
|
||||||
|
this.floortexture = 0;
|
||||||
|
this.ceiltexture = 0;
|
||||||
|
|
||||||
|
if(updatefloor)
|
||||||
|
this.floorvertices = new FlatVertex[numvertices];
|
||||||
|
else
|
||||||
|
this.floorvertices = null;
|
||||||
|
|
||||||
|
if(updateceiling)
|
||||||
|
this.ceilvertices = new FlatVertex[numvertices];
|
||||||
|
else
|
||||||
|
this.ceilvertices = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue