Ejemplo n.º 1
0
        readonly int[] sizes; // This stores the sizes of various mip levels

        #endregion Fields

        #region Constructors

        public PageIndexer( VirtualTextureInfo info )
        {
            this.info = info;

            mipcount = MathExtensions.Log2(info.PageTableSize) + 1;

            sizes   = new int[mipcount];
            for( int i = 0; i < mipcount; ++i )
                sizes[i] = ( info.VirtualTextureSize / info.TileSize ) >> i;

            offsets = new int[mipcount];
            Count = 0;
            for( int i = 0; i < mipcount; ++i )
            {
                offsets[i] = Count;
                Count += sizes[i] * sizes[i];
            }

            // Calculate reverse mapping
            reverse = new Page[Count];
            for( int i = 0; i < mipcount; ++i )
            {
                int size = sizes[i];
                for( int y = 0; y < size; ++y )
                for( int x = 0; x < size; ++x )
                {
                    Page page = new Page( x, y, i );
                    reverse[this[page]] = page;
                }
            }
        }
Ejemplo n.º 2
0
        public void Add( Page request, Point mapping )
        {
            int scale = 1 << request.Mip; // Same as pow( 2, mip )
            int x = request.X * scale;
            int y = request.Y * scale;

            Quadtree node = this;

            while( request.Mip < node.Level )
            {
                for( int i = 0; i < 4; ++i )
                {
                    Rectangle rect = GetRectangle( node, i );
                    if( rect.Contains( x, y ) )
                    {
                        // Create a new one if needed
                        if( node.Children[i] == null )
                        {
                            node.Children[i] = new Quadtree( rect, node.Level-1 );
                            node = node.Children[i];
                            break;
                        }

                        // Otherwise traverse the tree
                        else
                        {
                            node = node.Children[i];
                            break;
                        }
                    }
                }
            }

            // We have created the correct node, now set the mapping
            node.Mapping = mapping;
        }
Ejemplo n.º 3
0
        public void Remove( Page request )
        {
            int index;
            Quadtree node = FindPage( this, request, out index );

            if( node != null )
                node.Children[index] = null;
        }
Ejemplo n.º 4
0
        static Quadtree FindPage( Quadtree node, Page request, out int index )
        {
            int scale = 1 << request.Mip; // Same as pow( 2, mip )
            int x = request.X * scale;
            int y = request.Y * scale;

            // Find the parent of the child we want to remove
            bool exitloop = false;
            while( !exitloop )
            {
                exitloop = true;

                for( int i = 0; i < 4; ++i )
                {
                    if( node.Children[i] != null && node.Children[i].Rectangle.Contains( x, y ) )
                    {
                        // We found it
                        if( request.Mip == node.Level-1 )
                        {
                            index = i;
                            return node;
                        }

                        // Check the children
                        else
                        {
                            node = node.Children[i];
                            exitloop = false;
                        }
                    }
                }
            }

            // We couldn't find it so it must not exist anymore
            index = -1;
            return null;
        }
Ejemplo n.º 5
0
        // Schedule a load if not already loaded or loading
        public bool Request( Page request )
        {
            if( !loading.Contains( request ) )
            {
                Point pt = Point.Empty;
                if( !lru.TryGetValue( request, false, out pt ) )
                {
                    loading.Add( request );
                    loader.Submit( request );
                    return true;
                }
            }

            return false;
        }
Ejemplo n.º 6
0
        void LoadComplete( Page page, byte[] data )
        {
            loading.Remove( page );

            // Find a place in the atlas for the data
            Point pt = Point.Empty;

            if( current == count*count )
                pt = lru.RemoveLast();
            else
            {
                pt = new Point( current % count, current / count );
                ++current;

                if( current == count * count )
                    Console.WriteLine("Atlas Full, using LRU");
            }

            atlas.UploadPage( pt, data );
            lru.Add( page, pt );

            // Signal that we added a page
            Added( page, pt );
        }
Ejemplo n.º 7
0
        // Update the pages's position in the lru
        public bool Touch( Page page )
        {
            if( !loading.Contains( page ) )
            {
                Point pt = Point.Empty;
                return lru.TryGetValue( page, true, out pt );
            }

            return false;
        }
Ejemplo n.º 8
0
        public int this[Page page]
        {
            get
            {
                if( page.Mip < 0 || page.Mip >= mipcount )
                    throw new Exception( "Page is not valid" );

                int offset = offsets[page.Mip];
                int stride = sizes[page.Mip];

                return offset + page.Y * stride + page.X;
            }
        }
Ejemplo n.º 9
0
        public bool IsValid( Page page )
        {
            if( page.Mip < 0 )
            {
                LastError = string.Format( "Mip level smaller than zero ({0}).", page );
                return false;
            }

            else if( page.Mip >= mipcount )
            {
                LastError = string.Format( "Mip level larger than max ({1}), ({0}).", page, mipcount );
                return false;
            }

            if( page.X < 0 )
            {
                LastError = string.Format( "X smaller than zero ({0}).", page );
                return false;
            }

            else if( page.X >= sizes[page.Mip] )
            {
                LastError = string.Format( "X larger than max ({1}), ({0}).", page, sizes[page.Mip] );
                return false;
            }

            if( page.Y < 0 )
            {
                LastError = string.Format( "Y smaller than zero ({0}).", page );
                return false;
            }

            else if( page.Y >= sizes[page.Mip] )
            {
                LastError = string.Format( "Y larger than max ({1}), ({0}).", page, sizes[page.Mip] );
                return false;
            }

            return true;
        }
Ejemplo n.º 10
0
        public void Submit( Page request )
        {
            ReadState state = new ReadState();
            state.Page = request;

            readthread.Enqueue( state );
            #if DEBUG
            //Console.WriteLine("Requested: {0}", state.Page );
            #endif
        }
Ejemplo n.º 11
0
        void CopyColor( byte[] image, Page request )
        {
            byte[][] colors =
            {
                new byte[] {   0,   0, 255, 255 },
                new byte[] {   0, 255, 255, 255 },
                new byte[] { 255,   0,   0, 255 },
                new byte[] { 255,   0, 255, 255 },
                new byte[] { 255, 255,   0, 255 },
                new byte[] {  64,  64, 192, 255 },

                new byte[] {  64, 192,  64, 255 },
                new byte[] {  64, 192, 192, 255 },
                new byte[] { 192,  64,  64, 255 },
                new byte[] { 192,  64, 192, 255 },
                new byte[] { 192, 192,  64, 255 },
                new byte[] {   0, 255,   0, 255 }
            };

            int pagesize = info.PageSize;

            for( int y = 0; y < pagesize; ++y )
            for( int x = 0; x < pagesize; ++x )
            {
                image[(y*pagesize+x)*VirtualTexture.ChannelCount+0] = colors[request.Mip][0];
                image[(y*pagesize+x)*VirtualTexture.ChannelCount+1] = colors[request.Mip][1];
                image[(y*pagesize+x)*VirtualTexture.ChannelCount+2] = colors[request.Mip][2];
                image[(y*pagesize+x)*VirtualTexture.ChannelCount+3] = colors[request.Mip][3];
            }
        }