private void Allocate(int sizeX, out int textureIdx, out int x, out int y)
        {
            // Look for space in existing textures.
            for (int i = 0; i < cacheTextures.Count; i++)
            {
                if (TryAllocateFromTexture(cacheTextures[i], sizeX, out x, out y))
                {
                    textureIdx = i;
                    return;
                }
            }

            // Create new texture.
            var texture = new CacheTexture();

            texture.bmp = graphics.CreateEmptyBitmap(PatternCacheTextureSize, PatternCacheTextureSize);
            InitCacheRows(texture);
            textureIdx = cacheTextures.Count;
            cacheTextures.Add(texture);

            // Allocation cannot fail here.
            var allocated = TryAllocateFromTexture(texture, sizeX, out x, out y);

            Debug.Assert(allocated);
        }
        private bool TryAllocateFromTexture(CacheTexture texture, int sizeX, out int x, out int y)
        {
            Debug.Assert(texture.rows.Length == PatternCacheTextureSize / clampedPatternCacheSizeY);

            for (int j = 0; j < texture.rows.Length; j++)
            {
                var row = texture.rows[j];
                if (row.freeEntries.Count > 0)
                {
                    for (int k = 0; k < row.freeEntries.Count; k++)
                    {
                        var free = row.freeEntries[k];
                        if (free.sizeX >= sizeX)
                        {
                            CacheEntry node;

                            if (free.sizeX > sizeX)
                            {
                                // Create new node.
                                node        = new CacheEntry();
                                node.startX = free.startX;
                                node.sizeX  = sizeX;

                                // Shrink free node.
                                free.startX += sizeX;
                                free.sizeX  -= sizeX;
                            }
                            else // Perfect fit, use as is.
                            {
                                node = free;
                                row.freeEntries.RemoveAt(k);
                            }

                            x = node.startX;
                            y = j * clampedPatternCacheSizeY;

                            InsertAndMerge(row.usedEntries, node);

                            return(true);
                        }
                    }
                }
            }

            x = -1;
            y = -1;

            return(false);
        }
        private void InitCacheRows(CacheTexture texture)
        {
            var numRows = PatternCacheTextureSize / clampedPatternCacheSizeY;

            texture.rows = new CacheRow[numRows];

            for (int i = 0; i < numRows; i++)
            {
                texture.rows[i] = new CacheRow();
                texture.rows[i].freeEntries.Add(new CacheEntry()
                {
                    startX = 0, sizeX = PatternCacheTextureSize
                });
            }
        }
Beispiel #4
0
 private void fillMotionBlurCache(SceneDescription sd, Texture[] motionblurCache, CacheTexture sum, double t0, double dt)
 {
     double t = t0-dt;
     Texture tex;
     for(int i = motionblurCache.Length-0x02; i >= 0x00; i--) {
         tex = buildCameraCalculateAt(sd, t);
         motionblurCache[i] = tex;
         sum.AddTexture(tex);
         t -= dt;
     }
 }
Beispiel #5
0
 public void Execute(SceneDescription description)
 {
     double min = Math.Max(this.T0, description.SceneGraph.T0);
     double max = this.T1;
     double dt = (max-min)/this.TimeSamples;
     uint nDelta = (uint)Math.Round(this.ClosureTime/dt)+0x01;
     Texture[] motionblurCache = new Texture[nDelta];
     CacheTexture blurCache = new CacheTexture((int)description.CameraWrapper.Width, (int)description.CameraWrapper.Height);
     Texture tex;
     this.fillMotionBlurCache(description, motionblurCache, blurCache, min, dt);
     if(this.Task == SuperCameraTask.MakeImage) {
         blurCache.AddTexture(this.buildCameraCalculateAt(description, min));
         blurCache.MixWithAlpha(nDelta).Save(this.outputFile);
     }
     else if(this.Task == SuperCameraTask.MakeMovie) {
         this.clearTmpFolder();
         int index = 0;
         Process proc = new Process();
         proc.StartInfo.FileName = "convert";
         string imagename;
         string jpegname;
         uint j = nDelta-0x01;
         for(double t = min; t <= max; t += dt) {
             imagename = string.Format("/tmp/output{0}.png", index.ToString("00000"));
             jpegname = string.Format("{0} /tmp/output{1}.jpg", imagename, index.ToString("00000"));
             tex = this.buildCameraCalculateAt(description, t);
             blurCache.RemoveTexture(motionblurCache[j]);
             blurCache.AddTexture(tex);
             blurCache.MixWithAlpha(nDelta).Save(imagename);
             motionblurCache[j++] = tex;
             j %= nDelta;
             index++;
             proc.WaitForExit();
             proc.StartInfo.Arguments = jpegname;
             proc.Start();
         }
         proc.WaitForExit();
         this.convertToMovie();
         this.clearTmpFolder();
     }
 }
 private void PreDeviceReset_Atlas()
 {
     // when device is going to be reset, all render targets will lose their content;
     // so unload all glyphs here; they'll be reloaded if they are drawn again
     m_loadedGlyphs.Clear();
     for (int i = 0; i < m_cacheTextures.Count; ++i)
     {
         var tex = new CacheTexture();
         tex.m_physicalRTTexture = m_cacheTextures[i].m_physicalRTTexture;
         m_cacheTextures[i] = tex;
     }
 }
        private int RequestPage()
        {
            for (int i = 0; i < m_cacheTextures.Count; ++i)
            {
                var ct = m_cacheTextures[i];
                for (int j = 0; j < ct.m_pageOccupied.Length; ++j)
                {
                    if (!ct.m_pageOccupied[j])
                    {
                        ct.m_pageOccupied[j] = true;
                        return i * PagesInOneCacheTexture + j;
                    }
                }
            }

            // find the least used glyph
            KeyValuePair<uint, GlyphData> leastUsedGlyph = new KeyValuePair<uint,GlyphData>(0, null);
            foreach (var kvp in m_loadedGlyphs)
            {
                if (leastUsedGlyph.Value == null
                    || kvp.Value.m_timeStamp < leastUsedGlyph.Value.m_timeStamp)
                {
                    leastUsedGlyph = kvp;
                }
            }

            if (leastUsedGlyph.Value == null || leastUsedGlyph.Value.m_timeStamp >= m_timeStamp - MinimalPageLife)
            {
                var cacheTexture = new CacheTexture();
                cacheTexture.m_physicalRTTexture = m_cacheTextures.Count % 4 == 0
                                                   ? new RenderTarget2D(GameApp.Instance.GraphicsDevice, CacheTextureSize, CacheTextureSize, true, SurfaceFormat.Color, DepthFormat.None, 0, RenderTargetUsage.PreserveContents)
                                                   : m_cacheTextures.Last().m_physicalRTTexture;
                cacheTexture.m_pageOccupied[0] = true;
                m_cacheTextures.Add(cacheTexture);
                return (m_cacheTextures.Count - 1) * PagesInOneCacheTexture;
            }
            else
            {
                // release the glyph
                foreach (var pageIndex in leastUsedGlyph.Value.m_pageIndices)
                {
                    var textureIndex = pageIndex / PagesInOneCacheTexture;
                    var localIndex = pageIndex % PagesInOneCacheTexture;
                    m_cacheTextures[textureIndex].m_pageOccupied[localIndex] = false;
                }
                var retIndex = leastUsedGlyph.Value.m_pageIndices[0, 0];
                m_cacheTextures[retIndex / PagesInOneCacheTexture].m_pageOccupied[retIndex % PagesInOneCacheTexture] = true;
                m_loadedGlyphs.Remove(leastUsedGlyph.Key);
                return retIndex;
            }
        }