// 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);
                }
            }
        }
Example #2
0
        // 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);
                }
            }
        }