public override TexturePageHandle createTexturePageHandle(VTexPage page, IndirectionTexture indirectionTexture, int padding, int padding2, int textelsPerPage, int mipOffset)
        {
            PixelBox sourceBox;
            int      mipCount = image.NumMipmaps;

            if (mipCount == 0) //We always have to take from the largest size
            {
                sourceBox = image.getPixelBox(0, 0);
            }
            else
            {
                sourceBox = image.getPixelBox(0, (uint)(page.mip - mipOffset));
            }

            IntSize2 largestSupportedPageIndex = indirectionTexture.NumPages;

            largestSupportedPageIndex.Width  >>= page.mip;
            largestSupportedPageIndex.Height >>= page.mip;
            if (page.x != 0 && page.y != 0 && page.x + 1 != largestSupportedPageIndex.Width && page.y + 1 != largestSupportedPageIndex.Height)
            {
                //Can grab a complete page from the texture
                sourceBox.Rect = new IntRect(page.x * textelsPerPage - padding, page.y * textelsPerPage - padding, textelsPerPage + padding2, textelsPerPage + padding2);
            }
            else
            {
                //Have to get a partial page
                sourceBox.Rect = new IntRect(page.x * textelsPerPage, page.y * textelsPerPage, textelsPerPage, textelsPerPage);
            }

            return(new TexturePageHandle(sourceBox, this));
        }
        public override TexturePageHandle createTexturePageHandle(VTexPage page, IndirectionTexture indirectionTexture, int padding, int padding2, int textelsPerPage, int mipOffset)
        {
            int  mip           = page.mip;
            int  x             = page.x;
            int  y             = page.y;
            bool halfSizePages = textelsPerPage != pagedImage.PageSize;

            if (halfSizePages)
            {
                x /= 2;
                y /= 2;
            }

            var image    = pagedImage.getImage(x, y, mip - mipOffset);
            var pixelBox = image.getPixelBox();

            if (halfSizePages && image.Width == pagedImage.PageSize + padding2)
            {
                int subpageX       = page.x % 2;
                int subpageY       = page.y % 2;
                int offsetMultiple = (int)image.Width / 2 - padding;
                int halfSize       = textelsPerPage + padding2;

                pixelBox.Rect = new Engine.IntRect(offsetMultiple * subpageX, offsetMultiple * subpageY, halfSize, halfSize);
            }

            return(new TexturePageHandle(pixelBox, this, image));
        }
Beispiel #3
0
        private bool copyToStaging(VTexPage page, StagingBufferSet buffers, IndirectionTexture indirectionTexture, OriginalTextureInfo textureUnit)
        {
            bool usedPhysicalPage = false;

            try
            {
                if (page.mip >= textureUnit.MipOffset)
                {
                    //Load or grab from cache
                    using (var pageHandle = textureCache.getImage(page, indirectionTexture, textureUnit, textelsPerPage, padding, padding2))
                    {
                        buffers.setPhysicalPage(pageHandle.PixelBox, virtualTextureManager.getPhysicalTexture(textureUnit.TextureUnit), padding);
                        usedPhysicalPage = true;
                    }
                }
                else
                {
                    Logging.Log.Warning("Unable to load mip map level {0} for texture {1}", page.mip - textureUnit.MipOffset, textureUnit.TextureFileName);
                }
            }
            catch (Exception ex)
            {
                Logging.Log.Error("{0} loading image {1}. Message: {2}", ex.GetType().Name, textureUnit.TextureFileName, ex.Message);
            }
            return(usedPhysicalPage);
        }
Beispiel #4
0
 public void destroyIndirectionTexture(IndirectionTexture indirectionTex)
 {
     lock (newIndirectionTextures)
     {
         //Make sure we aren't waiting to be activated as a new texture
         newIndirectionTextures.Remove(indirectionTex);
     }
     lock (retiredIndirectionTextures)
     {
         retiredIndirectionTextures.Add(indirectionTex);
         indirectionTextures.Remove(indirectionTex.MaterialSetKey);
     }
 }
Beispiel #5
0
 /// <summary>
 /// Create or retrieve an indirection texture, will return true if the texture was just created. Useful
 /// for filling out other info on the texture if needed.
 /// </summary>
 /// <param name="materialSetKey">The key to use to search for this texture.</param>
 /// <param name="textureSize">The size of the virtual texture this indirection texture needs to remap.</param>
 /// <param name="indirectionTex">An out variable for the results.</param>
 /// <returns>True if the texture was just created, false if not.</returns>
 public bool createOrRetrieveIndirectionTexture(String materialSetKey, IntSize2 textureSize, bool keepHighestMip, out IndirectionTexture indirectionTex)
 {
     if (!indirectionTextures.TryGetValue(materialSetKey, out indirectionTex))
     {
         indirectionTex = new IndirectionTexture(materialSetKey, textureSize, texelsPerPage, this, keepHighestMip);
         indirectionTextures.Add(indirectionTex.MaterialSetKey, indirectionTex);
         lock (newIndirectionTextures)
         {
             newIndirectionTextures.Add(indirectionTex);
         }
         return(true);
     }
     return(false);
 }
Beispiel #6
0
 public void setIndirectionTextures(IndirectionTexture oldIndirectionTexture, IndirectionTexture newIndirectionTexture)
 {
     updateOldIndirectionTexture = oldIndirectionTexture != null;
     updateNewIndirectionTexture = oldIndirectionTexture != newIndirectionTexture;
     if (updateOldIndirectionTexture)
     {
         oldIndirectionTextureStaging.setData(oldIndirectionTexture);
         oldIndirectionId = oldIndirectionTexture.Id;
     }
     if (updateNewIndirectionTexture)
     {
         newIndirectionTextureStaging.setData(newIndirectionTexture);
         newIndirectionId = newIndirectionTexture.Id;
     }
 }
Beispiel #7
0
        private bool loadPage(VTexPage page, StagingBufferSet stagingBuffers)
        {
            bool added = false;

            try
            {
                //First see if we still have that page in our virtual texture pool, possible optimization to sort these to the front of the list
                if (physicalPageQueue.Count > 0)              //Do we have pages available
                {
                    PTexPage pTexPage = physicalPageQueue[0]; //The physical page candidate, do not modify before usedPhysicalPages if statement below
                    if (loadImages(page, pTexPage, stagingBuffers))
                    {
                        //Alert old texture of removal if there was one, Do not modify pTexPage above this if block, we need the old data
                        IndirectionTexture oldIndirectionTexture = null;
                        if (pTexPage.VirtualTexturePage != null)
                        {
                            if (virtualTextureManager.getIndirectionTexture(pTexPage.VirtualTexturePage.indirectionTexId, out oldIndirectionTexture))
                            {
                                oldIndirectionTexture.removePhysicalPage(pTexPage);
                            }

                            physicalPagePool.Remove(pTexPage.VirtualTexturePage); //Be sure to remove the page from the pool if it was used previously
                        }

                        physicalPageQueue.RemoveAt(0);
                        pTexPage.VirtualTexturePage = page;
                        usedPhysicalPages.Add(page, pTexPage);

                        //Add to new indirection texture
                        IndirectionTexture newIndirectionTex;
                        if (virtualTextureManager.getIndirectionTexture(page.indirectionTexId, out newIndirectionTex))
                        {
                            newIndirectionTex.addPhysicalPage(pTexPage);
                            stagingBuffers.setIndirectionTextures(oldIndirectionTexture, newIndirectionTex);
                        }
                        added = true;
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.Log.Debug("{0} loading page {1}. Message: {2}", ex.GetType().Name, page.ToString(), ex.Message);
            }
            return(added);
        }
        internal TexturePageHandle getImage(VTexPage page, IndirectionTexture indirectionTexture, OriginalTextureInfo textureUnit, int textelsPerPage, int padding, int padding2)
        {
            String textureName;

            if (texturesArePaged)
            {
                textureName = textureUnit.TextureFileName;
            }
            else
            {
                textureName = String.Format("{0}_{1}", textureUnit.TextureFileName, indirectionTexture.RealTextureSize.Width >> page.mip);
            }
            TextureCacheHandle cacheHandle;

            if (!this.TryGetValue(textureName, out cacheHandle))
            {
                String file = textureUnit.TextureFileName;
                if (texturesArePaged) //Paged Images
                {
                    //using (var perfMon = new LogPerformanceBlock(String.Format("Loaded image {0} in {{0}} ms", file), Logging.LogLevel.Info, "TextureCache"))
                    //{
                    PagedImage pagedImage = new PagedImage();
                    pagedImage.load(() => VirtualFileSystem.Instance.openStream(file, Engine.Resources.FileMode.Open, Engine.Resources.FileAccess.Read));
                    cacheHandle = this.Add(textureName, pagedImage);
                    //}
                }
                else //Normal Images
                {
                    String extension  = Path.GetExtension(file);
                    String directFile = textureUnit.TextureFileName.Substring(0, file.Length - extension.Length);
                    directFile = String.Format("{0}_{1}{2}", directFile, indirectionTexture.RealTextureSize.Width >> page.mip, extension);
                    if (VirtualFileSystem.Instance.exists(directFile))
                    {
                        var image = doLoadImage(extension, directFile);
                        cacheHandle = this.Add(textureName, image);
                    }
                    else
                    {
                        //Not using cache for full size images, this is a rare case that we are not really supporting right now
                        Image image = doLoadImage(extension, textureUnit.TextureFileName);

                        //If we aren't mip 0 resize accordingly
                        if (page.mip > image.NumMipmaps && page.mip != 0)
                        {
                            using (Image original = image)
                            {
                                image = new Image(original.Width >> page.mip, original.Height >> page.mip, original.Depth, original.Format, original.NumFaces, original.NumMipmaps);
                                using (var src = original.getPixelBox())
                                {
                                    using (var dest = image.getPixelBox())
                                    {
                                        Image.Scale(src, dest, Image.Filter.FILTER_BILINEAR);
                                    }
                                }
                            }
                        }
                        cacheHandle = this.Add(textureName, image);
                    }
                }
            }
            return(cacheHandle.createTexturePageHandle(page, indirectionTexture, padding, padding2, textelsPerPage, textureUnit.MipOffset));
        }
Beispiel #9
0
 public void setupVirtualTextureFragmentParams(GpuProgramParametersSharedPtr gpuParams, IndirectionTexture indirectionTexture)
 {
     if (gpuParams.Value.hasNamedConstant("physicalSizeRecip"))
     {
         gpuParams.Value.setNamedConstant("physicalSizeRecip", PhysicalSizeRecrip);
         var realSize = indirectionTexture.RealTextureSize;
         gpuParams.Value.setNamedConstant("mipBiasSize", new Vector2(realSize.Width, realSize.Height));
         gpuParams.Value.setNamedConstant("pagePaddingScale", TextureLoader.PagePaddingScale);
         gpuParams.Value.setNamedConstant("pagePaddingOffset", TextureLoader.PagePaddingOffset);
         if (gpuParams.Value.hasNamedConstant("pageSizeLog2"))
         {
             gpuParams.Value.setNamedConstant("pageSizeLog2", pageSizeLog2);
         }
     }
     else
     {
         Logging.Log.Error("physicalSizeRecip varaible missing");
     }
 }
Beispiel #10
0
 internal bool getIndirectionTexture(int id, out IndirectionTexture tex)
 {
     return(indirectionTexturesById.TryGetValue(id, out tex));
 }
 public void setData(IndirectionTexture indirectionTexture)
 {
     this.indirectionTexture = indirectionTexture;
     indirectionTexture.copyToStaging(pixelBox);
 }
Beispiel #12
0
 private Task <bool> fireCopyToStaging(VTexPage page, StagingBufferSet buffers, IndirectionTexture indirectionTexture, OriginalTextureInfo textureUnit)
 {
     return(Task.Run(() => copyToStaging(page, buffers, indirectionTexture, textureUnit)));
 }
Beispiel #13
0
 /// <summary>
 /// Create a texture page handle for this cache handle, the page will be selected from the given info.
 /// You must dispose the handle that is returned.
 /// </summary>
 /// <param name="page"></param>
 /// <param name="indirectionTexture"></param>
 /// <param name="padding"></param>
 /// <param name="padding2"></param>
 /// <param name="textelsPerPage"></param>
 /// <returns></returns>
 public abstract TexturePageHandle createTexturePageHandle(VTexPage page, IndirectionTexture indirectionTexture, int padding, int padding2, int textelsPerPage, int mipOffset);