예제 #1
0
        private static TextureFilter RenderBrushToTextureFilter(SolidColorBrush brush)
        {
            // Account for Opacity
            Color color = brush.Color;

            color = ColorOperations.Blend(
                color,
                Color.FromArgb(0, color.R, color.G, color.B),
                Math.Max(Math.Min(brush.Opacity, 1.0), 0.0));

            // We don't want to rely on RenderTargetBitmap for SolidColorBrush
            return(new SolidColorTextureFilter(color));
        }
예제 #2
0
        public override Color FilteredErrorLookup(Point uvLow, Point uvHigh, Color computedColor)
        {
            int lowerIndex = 0;
            int upperIndex = 0;

            Color computedError;

            // look for appropriate levels
            while (upperIndex < levels.Count && mipmapFactor > levels[upperIndex].PixelSize)
            {
                upperIndex++;
            }
            upperIndex = Math.Min(upperIndex, levels.Count - 1);
            lowerIndex = Math.Max(upperIndex - 1, 0);

            // Now perform error lookup on the mipmap levels
            if (lowerIndex == upperIndex)
            {
                // no need to blend, clear case of too near (pure bilinear mag)
                // or too far (1 pixel last level)
                computedError = levels[lowerIndex].FilteredErrorLookup(uvLow, uvHigh, computedColor);
            }
            else
            {
                // Find the colors of the adjacent levels
                Color lowerLevel = levels[lowerIndex].FilteredErrorLookup(uvLow, uvHigh, computedColor);
                Color upperLevel = levels[upperIndex].FilteredErrorLookup(uvLow, uvHigh, computedColor);

                // Find a suitable blend factor
                double lowerPixelSize = levels[lowerIndex].PixelSize;
                double upperPixelSize = levels[upperIndex].PixelSize;
                // upper pixel is 2x larger than lower pixel
                double blendFactor = (mipmapFactor / lowerPixelSize) - 1;

                // return the mix
                computedError = ColorOperations.Blend(upperLevel, lowerLevel, blendFactor);
            }

            // Compare against bilinear error
            Color baseError = base.FilteredErrorLookup(uvLow, uvHigh, computedColor);

            computedError = ColorOperations.Max(computedError, baseError);

            return(computedError);
        }
예제 #3
0
        public override Color FilteredTextureLookup(Point uv)
        {
            int lowerIndex = 0;
            int upperIndex = 0;

            // look for appropriate levels
            while (upperIndex < levels.Count && mipmapFactor > levels[upperIndex].PixelSize)
            {
                upperIndex++;
            }
            upperIndex = Math.Min(upperIndex, levels.Count - 1);
            lowerIndex = Math.Max(upperIndex - 1, 0);

            // Now perform texture lookup on the mipmap levels
            if (lowerIndex == upperIndex)
            {
                // no need to blend, clear case of too near (pure bilinear mag)
                // or too far (1 pixel last level)
                return(levels[lowerIndex].FilteredTextureLookup(uv));
            }
            else
            {
                // Find the colors of the adjacent levels
                Color lowerLevel = levels[lowerIndex].FilteredTextureLookup(uv);;
                Color upperLevel = levels[upperIndex].FilteredTextureLookup(uv);;

                // Find a suitable blend factor
                double lowerPixelSize = levels[lowerIndex].PixelSize;
                double upperPixelSize = levels[upperIndex].PixelSize;
                // upper pixel is 2x larger than lower pixel
                double blendFactor = (mipmapFactor / lowerPixelSize) - 1;

                // return the mix
                return(ColorOperations.Blend(upperLevel, lowerLevel, blendFactor));
            }
        }
예제 #4
0
        /// <summary>
        /// Get the pixel from the FrameBuffer at the specified Point.
        /// This method uses Bilinear interpolation to determine the Color value.
        /// If the Point is outside the bounds of the FrameBuffer, return null.
        /// </summary>
        private Color?GetPixel(Point point)
        {
            // point is somewhere in a pixel:
            // pixel center is at ( 0.5, 0.5 ) and is already factored into this point.
            // we need to find the weights of the surrounding pixel centers and interpolate to find the value
            //
            //  x   x'      x"
            //  +-------+-------+ y
            //  |       |       |
            //  |   1.......2   | y'
            //  |   : o |   :   |   // o is at ( point.X, point.Y )
            //  +---:---+---:---+
            //  |   :   |   :   |
            //  |   3.......4   | y"
            //  |       |       |
            //  +-------+-------+
            //
            // x  = floor( point.X - 0.5 )
            // x' = x + 0.5
            // x" = x + 1.5
            // y  = floor( point.Y - 0.5 )
            // y' = y + 0.5
            // y" = y + 1.5
            // leftWeight   = 1 - (point.X - x')
            // rightWeight  =     (point.X - x')
            // topWeight    = 1 - (point.Y - y')
            // bottomWeight =     (point.Y - y')

            //
            //  +-------+-------+
            //  |       |       |
            //  |   1.5.....2   | // 5 is the interpolated color at (point.X,y')
            //  |   : o |   :   |
            //  +---:-|-+---:---+
            //  |   : | |   :   |
            //  |   3.6.....4   | // 6 is the interpolated color at (point.X,y")
            //  |       |       |
            //  +-------+-------+
            // p5 = p1*leftWeight + p2*rightWeight
            // p6 = p3*leftWeight + p4*rightWeight
            // o = p5*topWeight + p6*bottomWeight

            int    x            = (int)Math.Floor(point.X - Const.pixelCenterX);
            int    y            = (int)Math.Floor(point.Y - Const.pixelCenterY);
            double xPrime       = x + Const.pixelCenterX;
            double yPrime       = y + Const.pixelCenterY;
            double rightWeight  = (point.X - xPrime);
            double bottomWeight = (point.Y - yPrime);

            Color?p1 = SafeGetPixel(x, y);
            Color?p2 = SafeGetPixel(x + 1, y);
            Color?p3 = SafeGetPixel(x, y + 1);
            Color?p4 = SafeGetPixel(x + 1, y + 1);

            // Never blend with something outside the framebuffer

            Color?p5 = ColorOperations.Blend(p2, p1, rightWeight);
            Color?p6 = ColorOperations.Blend(p4, p3, rightWeight);

            return(ColorOperations.Blend(p6, p5, bottomWeight));
        }