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 void addPhysicalPage(PTexPage pTexPage) { #if !DEBUG_MIP_LEVELS //Store 1x1 as mip 0, 2x2 as 1 4x4 as 2 etc, this way we can directly shift the decimal place //Then we will take fract from that //Store the page address as bytes var vTextPage = pTexPage.VirtualTexturePage; IntColor color = new IntColor(); color.A = 255; //Reverse the mip level (0 becomes highest level (least texels) and highesetMip becomes the lowest level (most texels, full size) color.B = (byte)(highestMip - vTextPage.mip - 1); //Typecast bad, try changing the type in the struct to byte color.R = (byte)pTexPage.pageX; color.G = (byte)pTexPage.pageY; fiBitmap[vTextPage.mip].setColorAtARGB(color.ARGB, vTextPage.x, vTextPage.y, 0); fillOutLowerMips(vTextPage, color, (c1, c2) => c1.B - c2.B >= 0); #endif }
internal void removePhysicalPage(PTexPage pTexPage) { #if !DEBUG_MIP_LEVELS var vTextPage = pTexPage.VirtualTexturePage; //Replace color with the one on the higher mip level IntColor color; if (vTextPage.mip + 1 < highestMip) { color = new IntColor(fiBitmap[vTextPage.mip + 1].getColorAtARGB((uint)vTextPage.x >> 1, (uint)vTextPage.y >> 1, 0)); } else { color = new IntColor(); color.B = (byte)(highestMip - vTextPage.mip - 1); } byte replacementMipLevel = (byte)(highestMip - vTextPage.mip - 1); fiBitmap[vTextPage.mip].setColorAtARGB(color.ARGB, vTextPage.x, vTextPage.y, 0); fillOutLowerMips(vTextPage, color, (c1, c2) => c2.B == replacementMipLevel); #endif }
/// <summary> /// Load the given image. Note that pTexPage is constant for the duration of this function call /// </summary> /// <param name="page"></param> /// <param name="pTexPage"></param> /// <returns></returns> private bool loadImages(VTexPage page, PTexPage pTexPage, StagingBufferSet stagingBuffers) { int stagingImageIndex = 0; bool usedPhysicalPage = false; IndirectionTexture indirectionTexture; if (virtualTextureManager.getIndirectionTexture(page.indirectionTexId, out indirectionTexture)) { //Fire off image loading and blitting tasks foreach (var textureUnit in indirectionTexture.OriginalTextures) { copyTostagingImageTasks[stagingImageIndex] = fireCopyToStaging(page, stagingBuffers, indirectionTexture, textureUnit); ++stagingImageIndex; } //Wait for results for (int i = 0; i < stagingImageIndex; ++i) { copyTostagingImageTasks[i].Wait(); if (copyTostagingImageTasks[i].Result) { usedPhysicalPage = true; } } //Single threaded //foreach (var textureUnit in indirectionTexture.OriginalTextures) //{ // if (copyToStaging(page, stagingBuffers, indirectionTexture, textureUnit)) // { // usedPhysicalPage = true; // } //} //Update staging buffer info stagingBuffers.Dest = new IntRect(pTexPage.x, pTexPage.y, textelsPerPhysicalPage, textelsPerPhysicalPage); } return(usedPhysicalPage); }