// This adds or updates sector geometry into a buffer. // Modiies the list of SurfaceEntries with the new surface entry for the stored geometry. public void UpdateSurfaces(SurfaceEntryCollection entries, SurfaceUpdate update) { // Free entries when number of vertices has changed if ((entries.Count > 0) && (entries.totalvertices != update.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; e.desaturation = update.desaturation; 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; } e.desaturation = update.desaturation; 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 e.UpdateBBox(); if (!resourcesunloaded) { VertexBuffer vb = set.buffers[e.bufferindex]; General.Map.Graphics.SetBufferSubdata(vb, e.vertexoffset, e.floorvertices); General.Map.Graphics.SetBufferSubdata(vb, e.vertexoffset + e.floorvertices.Length, e.ceilvertices); } } }
// This adds or updates sector geometry into a buffer. // Modiies the list of SurfaceEntries with the new surface entry for the stored geometry. public void UpdateSurfaces(SurfaceEntryCollection entries, SurfaceUpdate update) { // Free entries when number of vertices has changed if ((entries.Count > 0) && (entries.totalvertices != update.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 e.UpdateBBox(); if (!resourcesunloaded) { // Lock the buffer DataStream bstream; VertexBuffer vb = set.buffers[e.bufferindex]; if (vb.Tag == null) { // Note: DirectX warns me that I am not using LockFlags.Discard or LockFlags.NoOverwrite here, // 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[e.bufferindex] * FlatVertex.Stride, LockFlags.None); vb.Tag = bstream; lockedbuffers.Add(vb); } else { bstream = (DataStream)vb.Tag; } // Write the vertices to buffer bstream.Seek(e.vertexoffset * FlatVertex.Stride, SeekOrigin.Begin); bstream.WriteRange(e.floorvertices); bstream.WriteRange(e.ceilvertices); } } }