public PageTable( D3D10.Device device, PageCache cache, VirtualTextureInfo info, PageIndexer indexer ) { this.info = info; this.device = device; this.indexer = indexer; quadtree = new Quadtree(new Rectangle(0, 0, info.PageTableSize, info.PageTableSize), MathExtensions.Log2(info.PageTableSize)); int size = info.PageTableSize; texture = new Direct3D.Texture( device, size, size, DXGI.Format.R8G8B8A8_UNorm, D3D10.ResourceUsage.Default, 0 ); staging = new Direct3D.WriteTexture( device, size, size, DXGI.Format.R8G8B8A8_UNorm ); cache.Added += ( Page page, Point pt ) => quadtree.Add( page, pt ); cache.Removed += ( Page page, Point pt ) => quadtree.Remove( page ); SetupDataAndInfo(); }
// Static Functions static Rectangle GetRectangle( Quadtree node, int index ) { int x = node.Rectangle.X; int y = node.Rectangle.Y; int w = node.Rectangle.Width/2; int h = node.Rectangle.Height/2; switch( index ) { case 0: return new Rectangle( x, y, w, h ); case 1: return new Rectangle( x + w, y, w, h ); case 2: return new Rectangle( x + w, y + h, w, h ); case 3: return new Rectangle( x, y + h, w, h ); } throw new ArgumentOutOfRangeException( "index" ); }
static void Write( Quadtree node, SimpleImage image, int miplevel ) { if( node.Level >= miplevel ) { int rx = node.Rectangle.X >> miplevel; int ry = node.Rectangle.Y >> miplevel; int rw = node.Rectangle.Width >> miplevel; int rh = node.Rectangle.Height >> miplevel; SimpleImage.Fill( image, new Rectangle( rx, ry, rw, rh ), (byte)node.Mapping.X, (byte)node.Mapping.Y, (byte)node.Level, 255 ); foreach( Quadtree child in node.Children ) if( child != null ) Quadtree.Write( child, image, miplevel ); } }
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; }