Exemplo n.º 1
0
        private void ApplyNewData(Context context, RasterDataDetails details)
        {
            // This is the start of a new frame, so the next request goes at the end
            details.RequestInsertionPoint = null;

#if SingleThreaded
            details.RequestQueue.ProcessQueue();
#endif

            List <TileLoadRequest> tiles = new List <TileLoadRequest>();
            EventHandler <MessageQueueEventArgs> handler = delegate(object sender, MessageQueueEventArgs e)
            {
                TileLoadRequest tile = (TileLoadRequest)e.Message;
                details.LoadedTiles[tile.Tile.Identifier] = tile.Texture;
                details.LoadingTiles.Remove(tile.Tile.Identifier);
                tiles.Add(tile);
            };
            details.DoneQueue.MessageReceived += handler;
            details.DoneQueue.ProcessQueue();
            details.DoneQueue.MessageReceived -= handler;

            foreach (TileLoadRequest tile in tiles)
            {
                ApplyNewTile(context, details, tile.Level, tile.Tile);
            }
        }
Exemplo n.º 2
0
        private void ApplyIfNotLoaded(Context context, RasterDataDetails details, ClipmapLevel level, RasterTile tile)
        {
            Texture2D texture;

            if (!details.LoadedTiles.TryGetValue(tile.Identifier, out texture) || texture == null)
            {
                ApplyNewTile(context, details, level, tile);
            }
        }
Exemplo n.º 3
0
 private void RequestTileResidency(Context context, ClipmapLevel level, RasterDataDetails details, RasterLevel rasterLevel, ClipmapLevel.Extent nextExtent)
 {
     RasterTileRegion[] tileRegions = rasterLevel.GetTilesInExtent(nextExtent.West, nextExtent.South, nextExtent.East, nextExtent.North);
     foreach (RasterTileRegion region in tileRegions)
     {
         if (!details.LoadedTiles.ContainsKey(region.Tile.Identifier))
         {
             RequestTileLoad(details, level, region.Tile);
         }
     }
 }
Exemplo n.º 4
0
        private void RequestTileLoad(RasterDataDetails details, ClipmapLevel level, RasterTile tile)
        {
            LinkedListNode <TileLoadRequest> requestNode;
            bool exists = details.LoadingTiles.TryGetValue(tile.Identifier, out requestNode);

            if (!exists)
            {
                // Create a new request.
                TileLoadRequest request = new TileLoadRequest();
                request.Level = level;
                request.Tile  = tile;
                requestNode   = new LinkedListNode <TileLoadRequest>(request);
            }

            lock (details.RequestList)
            {
                if (exists)
                {
                    // Remove the existing request from the queue so we can re-insert it
                    // in its new location.
                    if (requestNode.List == null)
                    {
                        // Request was in the queue at one point, but it's not anymore.
                        // That means it's been loaded,  so we don't need to do anything.
                        return;
                    }
                    details.RequestList.Remove(requestNode);
                }

                if (details.RequestInsertionPoint == null || details.RequestInsertionPoint.List == null)
                {
                    details.RequestList.AddLast(requestNode);
                }
                else
                {
                    details.RequestList.AddBefore(details.RequestInsertionPoint, requestNode);
                }
                details.RequestInsertionPoint = requestNode;

                // If the request list has too many entries, delete from the beginning
                const int MaxRequests = 500;
                while (details.RequestList.Count > MaxRequests)
                {
                    LinkedListNode <TileLoadRequest> nodeToRemove = details.RequestList.First;
                    details.RequestList.RemoveFirst();
                    details.LoadingTiles.Remove(nodeToRemove.Value.Tile.Identifier);
                }

                Monitor.Pulse(details.RequestList);
            }

            details.LoadingTiles[tile.Identifier] = requestNode;
        }
Exemplo n.º 5
0
        private void RenderTileToLevelTexture(Context context, ClipmapLevel level, RasterDataDetails details, RasterTileRegion region, Texture2D tileTexture)
        {
            Texture2D levelTexture;
            Vector2I  originInTextures;

            ClipmapLevel.Extent nextExtent;

            if (details.Type == RasterType.Terrain)
            {
                levelTexture     = level.HeightTexture;
                originInTextures = level.OriginInTextures;
                nextExtent       = level.NextExtent;
            }
            else
            {
                levelTexture     = level.ImageryTexture;
                originInTextures = level.OriginInImagery;
                nextExtent       = level.NextImageryExtent;
            }

            context.TextureUnits[0].Texture        = tileTexture;
            context.TextureUnits[0].TextureSampler = Device.TextureSamplers.NearestClamp;

            _framebuffer.ColorAttachments[_updateTexelOutput] = levelTexture;

            int clipmapSize = nextExtent.East - nextExtent.West + 1;
            int destWest    = (originInTextures.X + (region.Tile.West + region.West - nextExtent.West)) % clipmapSize;
            int destSouth   = (originInTextures.Y + (region.Tile.South + region.South - nextExtent.South)) % clipmapSize;

            int width  = region.East - region.West + 1;
            int height = region.North - region.South + 1;

            _updateSourceOrigin.Value      = new Vector2F(region.West, region.South);
            _updateUpdateSize.Value        = new Vector2F(width, height);
            _updateDestinationOffset.Value = new Vector2F(destWest, destSouth);

            // Save the current state of the context
            Rectangle   oldViewport    = context.Viewport;
            Framebuffer oldFramebuffer = context.Framebuffer;

            // Update the context and draw
            context.Viewport    = new Rectangle(0, 0, levelTexture.Description.Width, levelTexture.Description.Height);
            context.Framebuffer = _framebuffer;
            context.Draw(_unitQuadPrimitiveType, _updateDrawState, _sceneState);

            // Restore the context to its original state
            context.Framebuffer = oldFramebuffer;
            context.Viewport    = oldViewport;
        }
Exemplo n.º 6
0
        private void InitializeRequestThreads(Context context, RasterDataDetails details, ClipmapLevel clipmapLevelZero, RasterLevel rasterLevelZero)
        {
            details.WorkerWindow = Device.CreateWindow(1, 1);
            context.MakeCurrent();

#if !SingleThreaded
            Thread requestThread = new Thread(RequestThreadEntryPoint);
            requestThread.IsBackground = true;
            requestThread.Start(details);
#endif

            // Preload the entire world at level 0
            RasterTileRegion[] regions = rasterLevelZero.GetTilesInExtent(0, 0, rasterLevelZero.LongitudePosts - 1, rasterLevelZero.LatitudePosts - 1);
            foreach (RasterTileRegion region in regions)
            {
                RequestTileLoad(details, clipmapLevelZero, region.Tile);
            }
        }
Exemplo n.º 7
0
        private void InitializeRequestThreads(Context context, RasterDataDetails details, ClipmapLevel clipmapLevelZero, RasterLevel rasterLevelZero)
        {
            details.WorkerWindow = Device.CreateWindow(1, 1);
            context.MakeCurrent();

#if !SingleThreaded
            Thread requestThread = new Thread(RequestThreadEntryPoint);
            requestThread.IsBackground = true;
            requestThread.Start(details);
#endif

            // Preload the entire world at level 0
            RasterTileRegion[] regions = rasterLevelZero.GetTilesInExtent(0, 0, rasterLevelZero.LongitudePosts - 1, rasterLevelZero.LatitudePosts - 1);
            foreach (RasterTileRegion region in regions)
            {
                RequestTileLoad(details, clipmapLevelZero, region.Tile);
            }
        }
Exemplo n.º 8
0
        private void RequestThreadEntryPoint(object state)
        {
            RasterDataDetails details = (RasterDataDetails)state;

            details.WorkerWindow.Context.MakeCurrent();

            while (true)
            {
                TileLoadRequest request = null;
                lock (details.RequestList)
                {
                    LinkedListNode <TileLoadRequest> lastNode = details.RequestList.Last;
                    if (lastNode != null)
                    {
                        request = lastNode.Value;
                        details.RequestList.RemoveLast();
                    }
                    else
                    {
                        Monitor.Wait(details.RequestList);

                        lastNode = details.RequestList.Last;
                        if (lastNode != null)
                        {
                            request = lastNode.Value;
                            details.RequestList.RemoveLast();
                        }
                    }
                }

                if (request != null)
                {
                    RasterTile tile = request.Tile;
                    request.Texture = tile.LoadTexture();

                    Fence fence = Device.CreateFence();
                    fence.ClientWait();

                    details.DoneQueue.Post(request);
                }
            }
        }
Exemplo n.º 9
0
        private void ApplyNewTile(Context context, RasterDataDetails details, ClipmapLevel level, RasterTile tile)
        {
            ClipmapLevel.Extent nextExtent  = details.Type == RasterType.Terrain ? level.NextExtent : level.NextImageryExtent;
            RasterLevel         rasterLevel = details.Type == RasterType.Terrain ? level.Terrain : level.Imagery;

            ClipmapUpdate entireLevel = new ClipmapUpdate(
                level,
                nextExtent.West,
                nextExtent.South,
                nextExtent.East,
                nextExtent.North);

            ClipmapUpdate thisTile = new ClipmapUpdate(
                level,
                tile.West - 1,
                tile.South - 1,
                tile.East + 1,
                tile.North + 1);

            ClipmapUpdate intersection = IntersectUpdates(entireLevel, thisTile);

            if (intersection.Width > 0 && intersection.Height > 0)
            {
                Update(context, intersection, level, details, rasterLevel);

                // Recurse on child tiles if they're NOT loaded.  Unloaded children will use data from this tile.
                ClipmapLevel finer = level.FinerLevel;
                if (finer != null)
                {
                    ApplyIfNotLoaded(context, details, finer, tile.SouthwestChild);
                    ApplyIfNotLoaded(context, details, finer, tile.SoutheastChild);
                    ApplyIfNotLoaded(context, details, finer, tile.NorthwestChild);
                    ApplyIfNotLoaded(context, details, finer, tile.NortheastChild);
                }
            }
        }
Exemplo n.º 10
0
        private void ApplyNewData(Context context, RasterDataDetails details)
        {
            // This is the start of a new frame, so the next request goes at the end
            details.RequestInsertionPoint = null;

#if SingleThreaded
            details.RequestQueue.ProcessQueue();
#endif

            List<TileLoadRequest> tiles = new List<TileLoadRequest>();
            EventHandler<MessageQueueEventArgs> handler = delegate(object sender, MessageQueueEventArgs e)
            {
                TileLoadRequest tile = (TileLoadRequest)e.Message;
                details.LoadedTiles[tile.Tile.Identifier] = tile.Texture;
                details.LoadingTiles.Remove(tile.Tile.Identifier);
                tiles.Add(tile);
            };
            details.DoneQueue.MessageReceived += handler;
            details.DoneQueue.ProcessQueue();
            details.DoneQueue.MessageReceived -= handler;

            foreach (TileLoadRequest tile in tiles)
            {
                ApplyNewTile(context, details, tile.Level, tile.Tile);
            }
        }
Exemplo n.º 11
0
 private void ApplyIfNotLoaded(Context context, RasterDataDetails details, ClipmapLevel level, RasterTile tile)
 {
     Texture2D texture;
     if (!details.LoadedTiles.TryGetValue(tile.Identifier, out texture) || texture == null)
     {
         ApplyNewTile(context, details, level, tile);
     }
 }
Exemplo n.º 12
0
        private void UpsampleTileData(Context context, ClipmapLevel level, RasterDataDetails details, RasterTileRegion region)
        {
            ClipmapLevel coarserLevel = level.CoarserLevel;

            if (coarserLevel == null)
            {
                return;
            }

            Texture2D levelTexture;
            Texture2D coarserLevelTexture;
            Vector2I  originInTextures;
            Vector2I  coarserOriginInTextures;

            ClipmapLevel.Extent nextExtent;
            ClipmapLevel.Extent coarserNextExtent;

            if (details.Type == RasterType.Terrain)
            {
                levelTexture            = level.HeightTexture;
                coarserLevelTexture     = coarserLevel.HeightTexture;
                originInTextures        = level.OriginInTextures;
                coarserOriginInTextures = coarserLevel.OriginInTextures;
                nextExtent        = level.NextExtent;
                coarserNextExtent = coarserLevel.NextExtent;
            }
            else
            {
                levelTexture            = level.ImageryTexture;
                coarserLevelTexture     = coarserLevel.ImageryTexture;
                originInTextures        = level.OriginInImagery;
                coarserOriginInTextures = coarserLevel.OriginInImagery;
                nextExtent        = level.NextImageryExtent;
                coarserNextExtent = coarserLevel.NextImageryExtent;
            }

            context.TextureUnits[0].Texture        = coarserLevelTexture;
            context.TextureUnits[0].TextureSampler = Device.TextureSamplers.LinearRepeat;

            _framebuffer.ColorAttachments[_upsampleTexelOutput] = levelTexture;

            int fineClipmapSize = nextExtent.East - nextExtent.West + 1;
            int destWest        = (originInTextures.X + (region.Tile.West + region.West - nextExtent.West)) % fineClipmapSize;
            int destSouth       = (originInTextures.Y + (region.Tile.South + region.South - nextExtent.South)) % fineClipmapSize;

            int    coarseClipmapSize = coarserNextExtent.East - coarserNextExtent.West + 1;
            double sourceWest        = (coarserOriginInTextures.X + ((region.Tile.West + region.West) / 2.0 - coarserNextExtent.West)) % coarseClipmapSize;
            double sourceSouth       = (coarserOriginInTextures.Y + ((region.Tile.South + region.South) / 2.0 - coarserNextExtent.South)) % coarseClipmapSize;

            int width  = region.East - region.West + 1;
            int height = region.North - region.South + 1;

            _upsampleSourceOrigin.Value       = new Vector2F((float)sourceWest, (float)sourceSouth);
            _upsampleUpdateSize.Value         = new Vector2F(width, height);
            _upsampleDestinationOffset.Value  = new Vector2F(destWest, destSouth);
            _upsampleOneOverTextureSize.Value = new Vector2F(1.0f / coarserLevelTexture.Description.Width, 1.0f / coarserLevelTexture.Description.Height);

            // Save the current state of the context
            Rectangle   oldViewport    = context.Viewport;
            Framebuffer oldFramebuffer = context.Framebuffer;

            // Update the context and draw
            context.Viewport    = new Rectangle(0, 0, levelTexture.Description.Width, levelTexture.Description.Height);
            context.Framebuffer = _framebuffer;
            context.Draw(_unitQuadPrimitiveType, _upsampleDrawState, _sceneState);

            // Restore the context to its original state
            context.Framebuffer = oldFramebuffer;
            context.Viewport    = oldViewport;
        }
Exemplo n.º 13
0
 private void RequestTileResidency(Context context, ClipmapLevel level, RasterDataDetails details, RasterLevel rasterLevel, ClipmapLevel.Extent nextExtent)
 {
     RasterTileRegion[] tileRegions = rasterLevel.GetTilesInExtent(nextExtent.West, nextExtent.South, nextExtent.East, nextExtent.North);
     foreach (RasterTileRegion region in tileRegions)
     {
         if (!details.LoadedTiles.ContainsKey(region.Tile.Identifier))
         {
             RequestTileLoad(details, level, region.Tile);
         }
     }
 }
Exemplo n.º 14
0
        private ClipmapUpdate[] SplitUpdateToAvoidWrapping(ClipmapUpdate update, RasterDataDetails details)
        {
            ClipmapLevel level  = update.Level;
            Vector2I     origin = details.Type == RasterType.Terrain ? level.OriginInTextures : level.OriginInImagery;

            ClipmapLevel.Extent extent = details.Type == RasterType.Terrain ? level.NextExtent : level.NextImageryExtent;

            int clipmapSizeX = extent.East - extent.West + 1;
            int clipmapSizeY = extent.North - extent.South + 1;

            int west  = (origin.X + (update.West - extent.West)) % clipmapSizeX;
            int east  = (origin.X + (update.East - extent.West)) % clipmapSizeX;
            int south = (origin.Y + (update.South - extent.South)) % clipmapSizeY;
            int north = (origin.Y + (update.North - extent.South)) % clipmapSizeY;

            if (east < west && north < south)
            {
                // Horizontal AND vertical wrap
                ClipmapUpdate bottomLeftUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    update.South,
                    extent.West + (clipmapSizeX - origin.X - 1),
                    extent.South + (clipmapSizeY - origin.Y - 1));

                ClipmapUpdate bottomRightUpdate = new ClipmapUpdate(
                    level,
                    extent.West + clipmapSizeX - origin.X,
                    update.South,
                    update.East,
                    extent.South + (clipmapSizeY - origin.Y - 1));

                ClipmapUpdate topLeftUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    extent.South + clipmapSizeY - origin.Y,
                    extent.West + (clipmapSizeX - origin.X - 1),
                    update.North);

                ClipmapUpdate topRightUpdate = new ClipmapUpdate(
                    level,
                    extent.West + clipmapSizeX - origin.X,
                    extent.South + clipmapSizeY - origin.Y,
                    update.East,
                    update.North);

                ClipmapUpdate[] result = new ClipmapUpdate[4];
                result[0] = bottomLeftUpdate;
                result[1] = bottomRightUpdate;
                result[2] = topLeftUpdate;
                result[3] = topRightUpdate;
                return(result);
            }
            else if (east < west)
            {
                // Horizontal wrap
                ClipmapUpdate leftUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    update.South,
                    extent.West + (clipmapSizeX - origin.X - 1),
                    update.North);

                ClipmapUpdate rightUpdate = new ClipmapUpdate(
                    level,
                    extent.West + clipmapSizeX - origin.X,
                    update.South,
                    update.East,
                    update.North);

                ClipmapUpdate[] result = new ClipmapUpdate[2];
                result[0] = leftUpdate;
                result[1] = rightUpdate;
                return(result);
            }
            else if (north < south)
            {
                // Vertical wrap
                ClipmapUpdate bottomUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    update.South,
                    update.East,
                    extent.South + (clipmapSizeY - origin.Y - 1));

                ClipmapUpdate topUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    extent.South + clipmapSizeY - origin.Y,
                    update.East,
                    update.North);

                ClipmapUpdate[] result = new ClipmapUpdate[2];
                result[0] = bottomUpdate;
                result[1] = topUpdate;
                return(result);
            }
            else
            {
                // No wrap
                ClipmapUpdate[] result = new ClipmapUpdate[1];
                result[0] = update;
                return(result);
            }
        }
Exemplo n.º 15
0
        private void Update(Context context, ClipmapUpdate update, ClipmapLevel level, RasterDataDetails details, RasterLevel rasterLevel)
        {
            ClipmapUpdate[] updates = SplitUpdateToAvoidWrapping(update, details);
            foreach (ClipmapUpdate nonWrappingUpdate in updates)
            {
                RasterTileRegion[] tileRegions = rasterLevel.GetTilesInExtent(nonWrappingUpdate.West, nonWrappingUpdate.South, nonWrappingUpdate.East, nonWrappingUpdate.North);
                foreach (RasterTileRegion region in tileRegions)
                {
                    Texture2D tileTexture;
                    bool      loaded = details.LoadedTiles.TryGetValue(region.Tile.Identifier, out tileTexture);
                    if (loaded)
                    {
                        RenderTileToLevelTexture(context, level, details, region, tileTexture);
                    }
                    else
                    {
                        UpsampleTileData(context, level, details, region);
                    }
                }
            }

            if (details.Type == RasterType.Terrain)
            {
                // Normals at edges are incorrect, so include a one-post buffer around the update region
                // when updating normals in order to update normals that were previously at the edge.
                ClipmapUpdate   updateWithBuffer = update.AddBufferWithinLevelNextExtent();
                ClipmapUpdate[] normalUpdates    = SplitUpdateToAvoidWrapping(updateWithBuffer, details);
                foreach (ClipmapUpdate normalUpdate in normalUpdates)
                {
                    UpdateNormals(context, normalUpdate);
                }
            }
        }
Exemplo n.º 16
0
        private void Update(Context context, ClipmapUpdate update, ClipmapLevel level, RasterDataDetails details, RasterLevel rasterLevel)
        {
            ClipmapUpdate[] updates = SplitUpdateToAvoidWrapping(update, details);
            foreach (ClipmapUpdate nonWrappingUpdate in updates)
            {
                RasterTileRegion[] tileRegions = rasterLevel.GetTilesInExtent(nonWrappingUpdate.West, nonWrappingUpdate.South, nonWrappingUpdate.East, nonWrappingUpdate.North);
                foreach (RasterTileRegion region in tileRegions)
                {
                    Texture2D tileTexture;
                    bool loaded = details.LoadedTiles.TryGetValue(region.Tile.Identifier, out tileTexture);
                    if (loaded)
                    {
                        RenderTileToLevelTexture(context, level, details, region, tileTexture);
                    }
                    else
                    {
                        UpsampleTileData(context, level, details, region);
                    }
                }
            }

            if (details.Type == RasterType.Terrain)
            {
                // Normals at edges are incorrect, so include a one-post buffer around the update region
                // when updating normals in order to update normals that were previously at the edge.
                ClipmapUpdate updateWithBuffer = update.AddBufferWithinLevelNextExtent();
                ClipmapUpdate[] normalUpdates = SplitUpdateToAvoidWrapping(updateWithBuffer, details);
                foreach (ClipmapUpdate normalUpdate in normalUpdates)
                {
                    UpdateNormals(context, normalUpdate);
                }
            }
        }
Exemplo n.º 17
0
        private ClipmapUpdate[] SplitUpdateToAvoidWrapping(ClipmapUpdate update, RasterDataDetails details)
        {
            ClipmapLevel level = update.Level;
            Vector2I origin = details.Type == RasterType.Terrain ? level.OriginInTextures : level.OriginInImagery;
            ClipmapLevel.Extent extent = details.Type == RasterType.Terrain ? level.NextExtent : level.NextImageryExtent;

            int clipmapSizeX = extent.East - extent.West + 1;
            int clipmapSizeY = extent.North - extent.South + 1;

            int west = (origin.X + (update.West - extent.West)) % clipmapSizeX;
            int east = (origin.X + (update.East - extent.West)) % clipmapSizeX;
            int south = (origin.Y + (update.South - extent.South)) % clipmapSizeY;
            int north = (origin.Y + (update.North - extent.South)) % clipmapSizeY;

            if (east < west && north < south)
            {
                // Horizontal AND vertical wrap
                ClipmapUpdate bottomLeftUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    update.South,
                    extent.West + (clipmapSizeX - origin.X - 1),
                    extent.South + (clipmapSizeY - origin.Y - 1));

                ClipmapUpdate bottomRightUpdate = new ClipmapUpdate(
                    level,
                    extent.West + clipmapSizeX - origin.X,
                    update.South,
                    update.East,
                    extent.South + (clipmapSizeY - origin.Y - 1));

                ClipmapUpdate topLeftUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    extent.South + clipmapSizeY - origin.Y,
                    extent.West + (clipmapSizeX - origin.X - 1),
                    update.North);

                ClipmapUpdate topRightUpdate = new ClipmapUpdate(
                    level,
                    extent.West + clipmapSizeX - origin.X,
                    extent.South + clipmapSizeY - origin.Y,
                    update.East,
                    update.North);

                ClipmapUpdate[] result = new ClipmapUpdate[4];
                result[0] = bottomLeftUpdate;
                result[1] = bottomRightUpdate;
                result[2] = topLeftUpdate;
                result[3] = topRightUpdate;
                return result;
            }
            else if (east < west)
            {
                // Horizontal wrap
                ClipmapUpdate leftUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    update.South,
                    extent.West + (clipmapSizeX - origin.X - 1),
                    update.North);

                ClipmapUpdate rightUpdate = new ClipmapUpdate(
                    level,
                    extent.West + clipmapSizeX - origin.X,
                    update.South,
                    update.East,
                    update.North);

                ClipmapUpdate[] result = new ClipmapUpdate[2];
                result[0] = leftUpdate;
                result[1] = rightUpdate;
                return result;
            }
            else if (north < south)
            {
                // Vertical wrap
                ClipmapUpdate bottomUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    update.South,
                    update.East,
                    extent.South + (clipmapSizeY - origin.Y - 1));

                ClipmapUpdate topUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    extent.South + clipmapSizeY - origin.Y,
                    update.East,
                    update.North);

                ClipmapUpdate[] result = new ClipmapUpdate[2];
                result[0] = bottomUpdate;
                result[1] = topUpdate;
                return result;
            }
            else
            {
                // No wrap
                ClipmapUpdate[] result = new ClipmapUpdate[1];
                result[0] = update;
                return result;
            }
        }
Exemplo n.º 18
0
        private void ApplyNewTile(Context context, RasterDataDetails details, ClipmapLevel level, RasterTile tile)
        {
            ClipmapLevel.Extent nextExtent = details.Type == RasterType.Terrain ? level.NextExtent : level.NextImageryExtent;
            RasterLevel rasterLevel = details.Type == RasterType.Terrain ? level.Terrain : level.Imagery;

            ClipmapUpdate entireLevel = new ClipmapUpdate(
                level,
                nextExtent.West,
                nextExtent.South,
                nextExtent.East,
                nextExtent.North);

            ClipmapUpdate thisTile = new ClipmapUpdate(
                level,
                tile.West - 1,
                tile.South - 1,
                tile.East + 1,
                tile.North + 1);

            ClipmapUpdate intersection = IntersectUpdates(entireLevel, thisTile);

            if (intersection.Width > 0 && intersection.Height > 0)
            {
                Update(context, intersection, level, details, rasterLevel);

                // Recurse on child tiles if they're NOT loaded.  Unloaded children will use data from this tile.
                ClipmapLevel finer = level.FinerLevel;
                if (finer != null)
                {
                    ApplyIfNotLoaded(context, details, finer, tile.SouthwestChild);
                    ApplyIfNotLoaded(context, details, finer, tile.SoutheastChild);
                    ApplyIfNotLoaded(context, details, finer, tile.NorthwestChild);
                    ApplyIfNotLoaded(context, details, finer, tile.NortheastChild);
                }
            }
        }
Exemplo n.º 19
0
        private void RequestTileLoad(RasterDataDetails details,  ClipmapLevel level, RasterTile tile)
        {
            LinkedListNode<TileLoadRequest> requestNode;
            bool exists = details.LoadingTiles.TryGetValue(tile.Identifier, out requestNode);

            if (!exists)
            {
                // Create a new request.
                TileLoadRequest request = new TileLoadRequest();
                request.Level = level;
                request.Tile = tile;
                requestNode = new LinkedListNode<TileLoadRequest>(request);
            }

            lock (details.RequestList)
            {
                if (exists)
                {
                    // Remove the existing request from the queue so we can re-insert it
                    // in its new location.
                    if (requestNode.List == null)
                    {
                        // Request was in the queue at one point, but it's not anymore.
                        // That means it's been loaded,  so we don't need to do anything.
                        return;
                    }
                    details.RequestList.Remove(requestNode);
                }

                if (details.RequestInsertionPoint == null || details.RequestInsertionPoint.List == null)
                {
                    details.RequestList.AddLast(requestNode);
                }
                else
                {
                    details.RequestList.AddBefore(details.RequestInsertionPoint, requestNode);
                }
                details.RequestInsertionPoint = requestNode;

                // If the request list has too many entries, delete from the beginning
                const int MaxRequests = 500;
                while (details.RequestList.Count > MaxRequests)
                {
                    LinkedListNode<TileLoadRequest> nodeToRemove = details.RequestList.First;
                    details.RequestList.RemoveFirst();
                    details.LoadingTiles.Remove(nodeToRemove.Value.Tile.Identifier);
                }

                Monitor.Pulse(details.RequestList);
            }

            details.LoadingTiles[tile.Identifier] = requestNode;
        }
Exemplo n.º 20
0
        private void UpsampleTileData(Context context, ClipmapLevel level, RasterDataDetails details, RasterTileRegion region)
        {
            ClipmapLevel coarserLevel = level.CoarserLevel;

            if (coarserLevel == null)
                return;

            Texture2D levelTexture;
            Texture2D coarserLevelTexture;
            Vector2I originInTextures;
            Vector2I coarserOriginInTextures;
            ClipmapLevel.Extent nextExtent;
            ClipmapLevel.Extent coarserNextExtent;

            if (details.Type == RasterType.Terrain)
            {
                levelTexture = level.HeightTexture;
                coarserLevelTexture = coarserLevel.HeightTexture;
                originInTextures = level.OriginInTextures;
                coarserOriginInTextures = coarserLevel.OriginInTextures;
                nextExtent = level.NextExtent;
                coarserNextExtent = coarserLevel.NextExtent;
            }
            else
            {
                levelTexture = level.ImageryTexture;
                coarserLevelTexture = coarserLevel.ImageryTexture;
                originInTextures = level.OriginInImagery;
                coarserOriginInTextures = coarserLevel.OriginInImagery;
                nextExtent = level.NextImageryExtent;
                coarserNextExtent = coarserLevel.NextImageryExtent;
            }

            context.TextureUnits[0].Texture = coarserLevelTexture;
            context.TextureUnits[0].TextureSampler = Device.TextureSamplers.LinearRepeat;

            _framebuffer.ColorAttachments[_upsampleTexelOutput] = levelTexture;

            int fineClipmapSize = nextExtent.East - nextExtent.West + 1;
            int destWest = (originInTextures.X + (region.Tile.West + region.West - nextExtent.West)) % fineClipmapSize;
            int destSouth = (originInTextures.Y + (region.Tile.South + region.South - nextExtent.South)) % fineClipmapSize;

            int coarseClipmapSize = coarserNextExtent.East - coarserNextExtent.West + 1;
            double sourceWest = (coarserOriginInTextures.X + ((region.Tile.West + region.West) / 2.0 - coarserNextExtent.West)) % coarseClipmapSize;
            double sourceSouth = (coarserOriginInTextures.Y + ((region.Tile.South + region.South) / 2.0 - coarserNextExtent.South)) % coarseClipmapSize;

            int width = region.East - region.West + 1;
            int height = region.North - region.South + 1;

            _upsampleSourceOrigin.Value = new Vector2F((float)sourceWest, (float)sourceSouth);
            _upsampleUpdateSize.Value = new Vector2F(width, height);
            _upsampleDestinationOffset.Value = new Vector2F(destWest, destSouth);
            _upsampleOneOverTextureSize.Value = new Vector2F(1.0f / coarserLevelTexture.Description.Width, 1.0f / coarserLevelTexture.Description.Height);

            // Save the current state of the context
            Rectangle oldViewport = context.Viewport;
            Framebuffer oldFramebuffer = context.Framebuffer;

            // Update the context and draw
            context.Viewport = new Rectangle(0, 0, levelTexture.Description.Width, levelTexture.Description.Height);
            context.Framebuffer = _framebuffer;
            context.Draw(_unitQuadPrimitiveType, _upsampleDrawState, _sceneState);

            // Restore the context to its original state
            context.Framebuffer = oldFramebuffer;
            context.Viewport = oldViewport;
        }
Exemplo n.º 21
0
        private void RenderTileToLevelTexture(Context context, ClipmapLevel level, RasterDataDetails details, RasterTileRegion region, Texture2D tileTexture)
        {
            Texture2D levelTexture;
            Vector2I originInTextures;
            ClipmapLevel.Extent nextExtent;

            if (details.Type == RasterType.Terrain)
            {
                levelTexture = level.HeightTexture;
                originInTextures = level.OriginInTextures;
                nextExtent = level.NextExtent;
            }
            else
            {
                levelTexture = level.ImageryTexture;
                originInTextures = level.OriginInImagery;
                nextExtent = level.NextImageryExtent;
            }

            context.TextureUnits[0].Texture = tileTexture;
            context.TextureUnits[0].TextureSampler = Device.TextureSamplers.NearestClamp;

            _framebuffer.ColorAttachments[_updateTexelOutput] = levelTexture;

            int clipmapSize = nextExtent.East - nextExtent.West + 1;
            int destWest = (originInTextures.X + (region.Tile.West + region.West - nextExtent.West)) % clipmapSize;
            int destSouth = (originInTextures.Y + (region.Tile.South + region.South - nextExtent.South)) % clipmapSize;

            int width = region.East - region.West + 1;
            int height = region.North - region.South + 1;

            _updateSourceOrigin.Value = new Vector2F(region.West, region.South);
            _updateUpdateSize.Value = new Vector2F(width, height);
            _updateDestinationOffset.Value = new Vector2F(destWest, destSouth);

            // Save the current state of the context
            Rectangle oldViewport = context.Viewport;
            Framebuffer oldFramebuffer = context.Framebuffer;

            // Update the context and draw
            context.Viewport = new Rectangle(0, 0, levelTexture.Description.Width, levelTexture.Description.Height);
            context.Framebuffer = _framebuffer;
            context.Draw(_unitQuadPrimitiveType, _updateDrawState, _sceneState);

            // Restore the context to its original state
            context.Framebuffer = oldFramebuffer;
            context.Viewport = oldViewport;
        }