Пример #1
0
 public void Dispose()
 {
     KeyboardBitmap.Dispose();
     MouseBitmap.Dispose();
     HeadsetBitmap.Dispose();
     GenericBitmap.Dispose();
 }
Пример #2
0
        private void renderBucket(IDisplay display, int bx, int by, int threadID, IntersectionState istate)
        {
            // pixel sized extents
            int x0 = bx * bucketSize;
            int y0 = by * bucketSize;
            int bw = Math.Min(bucketSize, imageWidth - x0);
            int bh = Math.Min(bucketSize, imageHeight - y0);

            // prepare bucket
            display.imagePrepare(x0, y0, bw, bh, threadID);

            Color[] bucketRGB   = new Color[bw * bh];
            float[] bucketAlpha = new float[bw * bh];

            // subpixel extents
            int sx0 = x0 * subPixelSize - fs;
            int sy0 = y0 * subPixelSize - fs;
            int sbw = bw * subPixelSize + fs * 2;
            int sbh = bh * subPixelSize + fs * 2;

            // round up to align with maximum step size
            sbw = (sbw + (maxStepSize - 1)) & (~(maxStepSize - 1));
            sbh = (sbh + (maxStepSize - 1)) & (~(maxStepSize - 1));
            // extra padding as needed
            if (maxStepSize > 1)
            {
                sbw++;
                sbh++;
            }
            // allocate bucket memory
            ImageSample[] samples = new ImageSample[sbw * sbh];
            // allocate samples and compute jitter offsets
            float invSubPixelSize = 1.0f / subPixelSize;

            for (int y = 0, index = 0; y < sbh; y++)
            {
                for (int x = 0; x < sbw; x++, index++)
                {
                    int   sx = sx0 + x;
                    int   sy = sy0 + y;
                    int   j  = sx & (sigmaLength - 1);
                    int   k  = sy & (sigmaLength - 1);
                    int   i  = (j << sigmaOrder) + QMC.sigma(k, sigmaOrder);
                    float dx = useJitter ? (float)QMC.halton(0, k) : 0.5f;
                    float dy = useJitter ? (float)QMC.halton(0, j) : 0.5f;
                    float rx = (sx + dx) * invSubPixelSize;
                    float ry = (sy + dy) * invSubPixelSize;
                    ry             = imageHeight - ry;
                    samples[index] = new ImageSample(rx, ry, i);
                }
            }
            for (int x = 0; x < sbw - 1; x += maxStepSize)
            {
                for (int y = 0; y < sbh - 1; y += maxStepSize)
                {
                    refineSamples(samples, sbw, x, y, maxStepSize, thresh, istate);
                }
            }
            if (dumpBuckets)
            {
                UI.printInfo(UI.Module.BCKT, "Dumping bucket [{0}, {1}] to file ...", bx, by);
                GenericBitmap bitmap = new GenericBitmap(sbw, sbh);
                for (int y = sbh - 1, index = 0; y >= 0; y--)
                {
                    for (int x = 0; x < sbw; x++, index++)
                    {
                        bitmap.writePixel(x, y, samples[index].c, samples[index].alpha);
                    }
                }
                bitmap.save(string.Format("bucket_{0}_{1}.png", bx, by));
            }
            if (displayAA)
            {
                // color coded image of what is visible
                float invArea = invSubPixelSize * invSubPixelSize;
                for (int y = 0, index = 0; y < bh; y++)
                {
                    for (int x = 0; x < bw; x++, index++)
                    {
                        int sampled = 0;
                        for (int i = 0; i < subPixelSize; i++)
                        {
                            for (int j = 0; j < subPixelSize; j++)
                            {
                                int sx = x * subPixelSize + fs + i;
                                int sy = y * subPixelSize + fs + j;
                                int s  = sx + sy * sbw;
                                sampled += samples[s].sampled() ? 1 : 0;
                            }
                        }
                        bucketRGB[index]   = new Color(sampled * invArea);
                        bucketAlpha[index] = 1.0f;
                    }
                }
            }
            else
            {
                // filter samples into pixels
                float cy = imageHeight - (y0 + 0.5f);
                for (int y = 0, index = 0; y < bh; y++, cy--)
                {
                    float cx = x0 + 0.5f;
                    for (int x = 0; x < bw; x++, index++, cx++)
                    {
                        Color c      = Color.black();
                        float a      = 0.0f;
                        float weight = 0.0f;
                        for (int j = -fs, sy = y * subPixelSize; j <= fs; j++, sy++)
                        {
                            for (int i = -fs, sx = x * subPixelSize, s = sx + sy * sbw; i <= fs; i++, sx++, s++)
                            {
                                float dx = samples[s].rx - cx;
                                if (Math.Abs(dx) > fhs)
                                {
                                    continue;
                                }
                                float dy = samples[s].ry - cy;
                                if (Math.Abs(dy) > fhs)
                                {
                                    continue;
                                }
                                float f = filter.get(dx, dy);
                                c.madd(f, samples[s].c);
                                a      += f * samples[s].alpha;
                                weight += f;
                            }
                        }
                        float invWeight = 1.0f / weight;
                        c.mul(invWeight);
                        a *= invWeight;
                        bucketRGB[index]   = c;
                        bucketAlpha[index] = a;
                    }
                }
            }
            // update pixels
            display.imageUpdate(x0, y0, bw, bh, bucketRGB, bucketAlpha);
        }