Exemple #1
0
        /// <summary>
        /// This function encodes a new texture based on the list of key frame matrices
        /// </summary>
        /// <param name="keyFrameMatrices"></param>
        /// <returns></returns>
        static private PixelBitmapContent <Vector4> GetEncodedTexture(List <Matrix[]> keyFrameMatrices, int bones)
        {
            //We need 4 pixels per bone. We can store each row of the transform matrix in one pixel.
            int width = bones * 4;

            //Create a new bitmap content object
            PixelBitmapContent <Vector4> animationTexture = new PixelBitmapContent <Vector4>(width, keyFrameMatrices.Count);

            int y = 0;

            //Now, we'll write all the rows
            foreach (Matrix[] animationRow in keyFrameMatrices)
            {
                int x = 0;
                foreach (Matrix transform in animationRow)
                {
                    // Pretty trivial - we just right out the matrix data as pixels. Instead of R, G, B, and A, we write matrix values.

                    // However, as mentioned in the article, this could be optimized. We really only need 3 pixels to describe a matrix,
                    // because in a transform matrix, the fourth row is always (0, 0, 0, 1). Thus, we could use the RGB values to describe the 3x3
                    // matrix, and then use the A values to describe the translation values in the 4th column. During runtime, this would save
                    // us a vertex texture fetch per transform!

                    animationTexture.SetPixel(x + 0, y, new Vector4(transform.M11, transform.M12, transform.M13, transform.M14));
                    animationTexture.SetPixel(x + 1, y, new Vector4(transform.M21, transform.M22, transform.M23, transform.M24));
                    animationTexture.SetPixel(x + 2, y, new Vector4(transform.M31, transform.M32, transform.M33, transform.M34));
                    animationTexture.SetPixel(x + 3, y, new Vector4(transform.M41, transform.M42, transform.M43, transform.M44));
                    x += 4;
                }

                y++;
            }

            return(animationTexture);
        }
Exemple #2
0
        public override TextureContent Import(string filename, ContentImporterContext context)
        {
            using (FileStream file = new FileStream(filename, FileMode.Open))
            {
                byte[] bytes = new byte[file.Length];

                file.Read(bytes, 0, (int)file.Length);


                bool bit16 = false;

                // Figure out file size
                if (Width <= 0 || Height <= 0)
                {
                    Width  = (int)Math.Sqrt(file.Length);
                    Height = (int)(file.Length / Width);

                    if (Width * Height != file.Length)
                    {
                        Width  = (int)Math.Sqrt(file.Length / 2);
                        Height = (int)(file.Length / 2 / Width);

                        bit16 = true;
                    }

                    if (Width * Height * 2 == file.Length)
                    {
                        context.Logger.LogWarning(null, new ContentIdentity(filename),
                                                  "Input texture not a raw grayscale texture, or the specified width and height do not match.");
                    }
                }

                // Create texture
                int i = 0;
                PixelBitmapContent <float> bitmap = new PixelBitmapContent <float>(Width, Height);

                for (int y = 0; y < Height; ++y)
                {
                    for (int x = 0; x < Width; ++x)
                    {
                        if (bit16)
                        {
                            bitmap.SetPixel(x, y, 1.0f * (ushort)((bytes[i++] | bytes[i++] << 8)) / ushort.MaxValue);
                        }
                        else
                        {
                            bitmap.SetPixel(x, y, 1.0f * bytes[i++] / byte.MaxValue);
                        }
                    }
                }

                Texture2DContent result = new Texture2DContent();

                result.Mipmaps = new MipmapChain(bitmap);

                return(result);
            }
        }
        /// <summary>
        /// Using height data stored in the alpha channel, computes normalmap
        /// vectors and stores them in the RGB portion of the bitmap.
        /// </summary>
        static void ConvertAlphaToNormals(PixelBitmapContent <Vector4> bitmap)
        {
            for (int y = 0; y < bitmap.Height; y++)
            {
                for (int x = 0; x < bitmap.Width; x++)
                {
                    // Look up the heights to either side of this pixel.
                    float left  = GetHeight(bitmap, x - 1, y);
                    float right = GetHeight(bitmap, x + 1, y);

                    float top    = GetHeight(bitmap, x, y - 1);
                    float bottom = GetHeight(bitmap, x, y + 1);

                    // Compute gradient vectors, then cross them to get the normal.
                    Vector3 dx = new Vector3(1, 0, (right - left) * bumpSize);
                    Vector3 dy = new Vector3(0, 1, (bottom - top) * bumpSize);

                    Vector3 normal = Vector3.Cross(dx, dy);

                    normal.Normalize();

                    // Store the result.
                    float alpha = GetHeight(bitmap, x, y);

                    bitmap.SetPixel(x, y, new Vector4(normal, alpha));
                }
            }
        }
        /// <summary>
        /// Process converts the encoded normals to the NormalizedByte4 format and
        /// generates mipmaps.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public override TextureContent Process(TextureContent input, ContentProcessorContext context)
        {
            Texture2DContent result = new Texture2DContent();

            if (input.Faces[0][0] is PixelBitmapContent <Alpha8> )
            {
                return(input);
            }

            input.ConvertBitmapType(typeof(PixelBitmapContent <Vector3>));

            PixelBitmapContent <Vector3> source = input.Faces[0][0] as PixelBitmapContent <Vector3>;
            PixelBitmapContent <Alpha8>  bitmap = new PixelBitmapContent <Alpha8>(source.Width, source.Height);

            for (int y = 0; y < source.Height; ++y)
            {
                for (int x = 0; x < source.Width; ++x)
                {
                    Vector3 src = source.GetPixel(x, y);

                    bitmap.SetPixel(x, y, new Alpha8(
                                        0.3f * src.X + 0.59f * src.Y + 0.11f * src.Z));
                }
            }

            result.Mipmaps.Add(bitmap);

            return(result);
        }
Exemple #5
0
        public override TextureContent Import(string filename, ContentImporterContext context)
        {
            // load raw data
            FileStream reader = File.OpenRead(filename);

            int width  = 257;
            int height = 257;

            byte[] bytes = new byte[reader.Length];
            reader.Read(bytes, 0, bytes.Length);
            reader.Close();

            // import into standard XNA bitmap container
            PixelBitmapContent <Color> bitmapContent = new PixelBitmapContent <Color>(width, height);

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    bitmapContent.SetPixel(x, y, new Color(bytes[(y * width) + x], 0, 0));
                }
            }

            // create and return one-mipmap-level
            Texture2DContent content = new Texture2DContent
            {
                Identity = new ContentIdentity(filename)
            };

            content.Mipmaps.Add(bitmapContent);
            return(content);
        }
Exemple #6
0
        protected string BuildTexture(Color color, IDictionary <string, object> processorParameters = null)
        {
            PixelBitmapContent <Color> bitmap = new PixelBitmapContent <Color>(1, 1);

            bitmap.SetPixel(0, 0, color);
            return(BuildTexture(bitmap, processorParameters));
        }
        /// <summary>
        /// Applies a single pass of a separable box filter, blurring either
        /// along the x or y axis. This could give much higher quality results
        /// if we used a gaussian filter kernel rather than this simplistic box,
        /// but this is good enough to get the job done.
        /// </summary>
        static void ApplyBlurPass(PixelBitmapContent <Vector4> source,
                                  PixelBitmapContent <Vector4> destination,
                                  int dx, int dy)
        {
            int cubemapCenter = cubemapSize / 2;

            for (int y = 0; y < cubemapSize; y++)
            {
                for (int x = 0; x < cubemapSize; x++)
                {
                    // How far is this texel from the center of the image?
                    int xDist = cubemapCenter - x;
                    int yDist = cubemapCenter - y;

                    int distance = (int)Math.Sqrt(xDist * xDist + yDist * yDist);

                    // Blur more in the center, less near the edges.
                    int blurAmount = Math.Max(cubemapCenter - distance, 0) / 8;

                    // Accumulate source texel values.
                    Vector4 blurredValue = Vector4.Zero;

                    for (int i = -blurAmount; i <= blurAmount; i++)
                    {
                        blurredValue += source.GetPixel(x + dx * i, y + dy * i);
                    }

                    // Average them to calculate a blurred result.
                    blurredValue /= blurAmount * 2 + 1;

                    destination.SetPixel(x, y, blurredValue);
                }
            }
        }
Exemple #8
0
        static PixelBitmapContent <Color> CreateAlphaChannel(PixelBitmapContent <Color> input)
        {
            int width  = input.Width;
            int height = input.Height;

            PixelBitmapContent <Color> result = new PixelBitmapContent <Color>(width, height);

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    Color color = input.GetPixel(x, y);

                    // Adds/Replaces Alpha channel with the "Brightest color channel value
                    // A better way would be to average all three colors and use that for alpha.
                    // This will work just fine for grey scale textures and is simpler...
                    byte resultAlpha1 = (byte)(color.PackedValue & 0xff);
                    byte resultAlpha2 = (byte)(color.PackedValue & 0xff00);
                    byte resultAlpha3 = (byte)(color.PackedValue & 0xff0000);

                    byte resultAlpha = Math.Max(Math.Max(resultAlpha1, resultAlpha2), resultAlpha3);
                    color.PackedValue = (uint)(resultAlpha << 24) + (0x00ffffff);

                    result.SetPixel(x, y, color);
                }
            }

            return(result);
        }
Exemple #9
0
        unsafe private static BitmapContent ConvertToColor(BitmapContent input)
        {
            var width  = input.Width;
            var height = input.Height;

            SurfaceFormat format;

            input.TryGetFormat(out format);
            var formatSize = DDSImporter.GetBitmapSize(format, width, height);
            var blocks     = formatSize;
            var inData     = input.GetPixelData();

            var output = new PixelBitmapContent <Color>(width, height);

            fixed(byte *p = &inData[0])
            {
                DXT1Block *block = (DXT1Block *)p;

                //convert DXT1 to color
                for (int y = 0; y < height; ++y)
                {
                    for (int x = 0; x < width; ++x)
                    {
                        int blockIdx   = (x / 4) + (y / 4) * (width / 4);
                        int colorIndex = x % 4 + (y % 4) * 4;

                        Color color = block[blockIdx].GetColor(colorIndex);
                        output.SetPixel(x, y, color);
                    }
                }
            }

            return(output);
        }
Exemple #10
0
        public override TextureContent Import(string filename, ContentImporterContext context)
        {
            // load tiff data
            m_pReader = new BinaryReader(File.OpenRead(filename));
            int nOffsetFirstIFD = ReadHeader();

            ReadAllIfds(nOffsetFirstIFD);
            m_pReader.Close();

            // import into standard XNA bitmap container
            PixelBitmapContent <float> bitmapContent = new PixelBitmapContent <float>(m_nWidth, m_nHeight);

            for (int y = 0; y < m_nHeight; y++)
            {
                for (int x = 0; x < m_nWidth; x++)
                {
                    bitmapContent.SetPixel(x, y, m_pImageData[(y * m_nWidth) + x]);
                }
            }

            // create and return one-mipmap-level
            Texture2DContent content = new Texture2DContent();

            content.Mipmaps.Add(bitmapContent);
            return(content);
        }
Exemple #11
0
 protected virtual void BuildNormalMap(PixelBitmapContent <Single> bm, PixelBitmapContent <Color> n)
 {
     unchecked
     {
         int ww = n.Width;
         int hh = n.Height;
         for (int y = 0; y < hh; ++y)
         {
             for (int x = 0; x < ww; ++x)
             {
                 float v00 = bm.GetPixel(x, y);
                 float v01 = bm.GetPixel(x, y + 1);
                 float v10 = bm.GetPixel(x + 1, y);
                 float v11 = bm.GetPixel(x + 1, y + 1);
                 //  80 meters up/down for the renderer
                 //  two dx-es means divide by 2 (to average)
                 //  two meters per triangle side means divide by 2 to normalize to meters
                 //  That is crappy resolution. I should probably use floats instead of bytes
                 //  for the underlying storage pixmap...
                 float   ddx = (v10 + v11 - v00 - v01) * Page.DynamicRange * 0.5f * 0.5f;
                 float   ddy = (v01 + v11 - v00 - v10) * Page.DynamicRange * 0.5f * 0.5f;
                 Vector3 v   = new Vector3(-ddx, -ddy, 1.0f);
                 v.Normalize();
                 v = v * 0.5f + new Vector3(0.5f, 0.5f, 0.5f);
                 Color c = new Color(v);
                 n.SetPixel(x, y, c);
             }
         }
     }
 }
        /// <summary>
        /// Flattens vectors from a normal map into a 2D displacement map
        /// and stores them in the RG portion of the bitmap.
        /// </summary>
        public static void ConvertNormalsToDisplacement(
            PixelBitmapContent <NormalizedByte4> bitmap, float distortionScale)
        {
            for (int y = 0; y < bitmap.Height; y++)
            {
                for (int x = 0; x < bitmap.Width; x++)
                {
                    // Get the normal from the normal map
                    Vector4 normal4 = bitmap.GetPixel(x, y).ToVector4();
                    Vector3 normal3 = new Vector3(normal4.X, normal4.Y, normal4.Z);

                    // Determine the magnitude of the distortion at this pixel
                    float amount = Vector3.Dot(normal3, Vector3.Backward) *
                                   distortionScale;

                    // Create a displacement vector of that magnitude in the direction
                    // of the normal projected onto the plane of the texture.
                    Vector2 normal2      = new Vector2(normal3.X, normal3.Y);
                    Vector2 displacement = normal2 * amount + new Vector2(.5f, .5f);

                    // Store the result
                    bitmap.SetPixel(x, y,
                                    new NormalizedByte4(displacement.X, displacement.Y, 0, 0));
                }
            }
        }
        public override TOutput Process(TInput input, ContentProcessorContext context)
        {
            input.ConvertBitmapType(typeof(PixelBitmapContent <Vector4>));
            PixelBitmapContent <Vector4> bm = (PixelBitmapContent <Vector4>)(((Texture2DContent)input).Mipmaps[0]);

            for (int y = 0, ym = bm.Height; y != ym; ++y)
            {
                for (int x = 0, xm = bm.Width; x != xm; ++x)
                {
                    Vector4 v = bm.GetPixel(x, y);
                    float   w = 1 - v.W;
                    if (v.Z > w)
                    {
                        v.Z = w;
                    }
                    w -= v.Z;
                    if (v.Y > w)
                    {
                        v.Y = w;
                    }
                    w -= v.Y;
                    if (v.X > w)
                    {
                        v.X = w;
                    }
                    System.Diagnostics.Debug.Assert(v.X + v.Y + v.Z + v.W <= 1.001f);
                    //  it's OK for w to be > 0 here, as that means the base layer weight
                    bm.SetPixel(x, y, v);
                }
            }
            input.ConvertBitmapType(typeof(PixelBitmapContent <Color>));
            input.GenerateMipmaps(true);
            return(input);
        }
        public static void setData(this PixelBitmapContent <Color> self, Color[] data)
        {
            var i = 0;

            for (var y = 0; y < self.Height; y++)
            {
                for (var x = 0; x < self.Width; x++)
                {
                    self.SetPixel(x, y, data[i++]);
                }
            }
        }
        /// <summary>
        /// Our source data is just a regular 2D image, but to make a good
        /// cubemap we need this to wrap on all sides without any visible seams.
        /// An easy way of making an image wrap from left to right is simply to
        /// put a mirrored copy of the image next to the original. The point
        /// where the image mirrors is still pretty obvious, but for a reflection
        /// map this will be good enough.
        /// </summary>
        static PixelBitmapContent <Color> MirrorBitmap(PixelBitmapContent <Color> source)
        {
            int width = source.Width * 2;

            PixelBitmapContent <Color> mirrored;

            mirrored = new PixelBitmapContent <Color>(width, source.Height);

            for (int y = 0; y < source.Height; y++)
            {
                for (int x = 0; x < source.Width; x++)
                {
                    Color color = source.GetPixel(x, y);

                    mirrored.SetPixel(x, y, color);
                    mirrored.SetPixel(width - x - 1, y, color);
                }
            }

            return(mirrored);
        }
        /// <summary>
        /// Worker function for folding and stretching a flap from the source
        /// image to make up one quarter of the top or bottom cubemap faces.
        /// </summary>
        static void ScaleTrapezoid(PixelBitmapContent <Color> source,
                                   int cubeSide, int cubeY,
                                   PixelBitmapContent <Color> destination,
                                   int destinationX, int destinationY,
                                   int xDirection1, int yDirection1,
                                   int xDirection2, int yDirection2)
        {
            int size = destination.Width;

            // Compute the source x location.
            int baseSourceX = cubeSide * source.Width / 4;

            // Copy the image data one row at a time.
            for (int row = 0; row < size / 2; row++)
            {
                // Compute the source y location.
                int sourceY;

                if (cubeY < 0)
                {
                    sourceY = source.Height / 3;
                }
                else
                {
                    sourceY = source.Height * 2 / 3;
                }

                sourceY += cubeY * row * source.Height / 3 / (size / 2);

                // Stretch this row from the source to destination.
                int x = destinationX;
                int y = destinationY;

                int rowLength = size - row * 2;

                for (int i = 0; i < rowLength; i++)
                {
                    int sourceX = baseSourceX + i * source.Width / 4 / rowLength;

                    Color color = source.GetPixel(sourceX, sourceY);

                    destination.SetPixel(x, y, color);

                    x += xDirection1;
                    y += yDirection1;
                }

                // Advance to the start of the next row.
                destinationX += xDirection1 + xDirection2;
                destinationY += yDirection1 + yDirection2;
            }
        }
        /// <summary>
        /// Process converts the encoded normals to the NormalizedByte4 format and
        /// generates mipmaps.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public override TextureContent Process(TextureContent input,
                                               ContentProcessorContext context)
        {
            // convert to vector4 format, so that we know what kind of data we're
            // working with.
            input.ConvertBitmapType(typeof(PixelBitmapContent <Vector4>));

            Texture2DContent output = new Texture2DContent();

            // expand the encoded normals; values ranging from 0 to 1 should be
            // expanded to range to -1 to 1.
            // NOTE: in almost all cases, the input normalmap will be a
            // Texture2DContent, and will only have one face.  just to be safe,
            // we'll do the conversion for every face in the texture.

            int mmIndex = 0;

            foreach (MipmapChain mipmapChain in input.Faces)
            {
                int bmpIndex = 0;

                foreach (PixelBitmapContent <Vector4> bitmap in mipmapChain)
                {
                    // Copy original bitmap to the new texture
                    output.Faces[mmIndex].Add(bitmap);

                    PixelBitmapContent <NormalizedByte4> normalizedBitmap =
                        new PixelBitmapContent <NormalizedByte4>(bitmap.Width, bitmap.Height);

                    for (int x = 0; x < bitmap.Width; x++)
                    {
                        for (int y = 0; y < bitmap.Height; y++)
                        {
                            Vector4 encoded = 2 * bitmap.GetPixel(x, y) - Vector4.One;
                            normalizedBitmap.SetPixel(x, y, new NormalizedByte4(encoded));
                        }
                    }
                    // now that the conversion to -1 to 1 ranges is finished, convert to the
                    // runtime-ready format NormalizedByte4.
                    output.Faces[mmIndex][bmpIndex++] = normalizedBitmap;
                }
                mmIndex++;
            }
            // Overwriting mipmaps isn't needed here.
            output.GenerateMipmaps(false);
            return(output);
        }
        /// <summary>
        /// Copies greyscale color information into the alpha channel.
        /// </summary>
        static void ConvertGreyToAlpha(PixelBitmapContent <Vector4> bitmap)
        {
            for (int y = 0; y < bitmap.Height; y++)
            {
                for (int x = 0; x < bitmap.Width; x++)
                {
                    Vector4 value = bitmap.GetPixel(x, y);

                    // Copy a greyscale version of the RGB data into the alpha channel.
                    float greyscale = (value.X + value.Y + value.Z) / 3;

                    value.W = greyscale;

                    bitmap.SetPixel(x, y, value);
                }
            }
        }
Exemple #19
0
        PixelBitmapContent <Rgba1010102> Encode2(PixelBitmapContent <Rgba1010102> bmpMipMap)
        {
            // Create Color Bitmap of Equal Size
            PixelBitmapContent <Rgba1010102> bmpColor = new PixelBitmapContent <Rgba1010102>(bmpMipMap.Width, bmpMipMap.Height);

            // Convert each pixel to gamma encoded color
            for (int y = 0; y < bmpMipMap.Height; y++)
            {
                for (int x = 0; x < bmpMipMap.Width; x++)
                {
                    // Get Input Pixel
                    Rgba1010102 CmipMap = bmpMipMap.GetPixel(x, y);

                    // Set Output Pixel
                    bmpColor.SetPixel(x, y, GammaEncodeColor2(CmipMap.ToVector4()));
                } //for (x)
            }     //for (y)

            return(bmpColor);
        }//method
Exemple #20
0
        public override Texture2DContent Import(string filename, ContentImporterContext context)
        {
            Bitmap bitmap        = Image.FromFile(filename) as Bitmap;
            var    bitmapContent = new PixelBitmapContent <Microsoft.Xna.Framework.Color>(bitmap.Width, bitmap.Height);

            for (int i = 0; i < bitmap.Width; i++)
            {
                for (int j = 0; j < bitmap.Height; j++)
                {
                    System.Drawing.Color          from = bitmap.GetPixel(i, j);
                    Microsoft.Xna.Framework.Color to   = new Microsoft.Xna.Framework.Color(from.R, from.G, from.B, from.A);
                    bitmapContent.SetPixel(i, j, to);
                }
            }

            return(new Texture2DContent()
            {
                Mipmaps = new MipmapChain(bitmapContent)
            });
        }
Exemple #21
0
        }//method

        public PixelBitmapContent <Rgba1010102> Decode2(PixelBitmapContent <Color> bmpInput)
        {
            // Decoded Bitmap
            PixelBitmapContent <Rgba1010102> bmpDecoded = new PixelBitmapContent <Rgba1010102>(bmpInput.Width, bmpInput.Height);

            // Convert each pixel to gamma decoded float
            for (int y = 0; y < bmpInput.Height; y++)
            {
                for (int x = 0; x < bmpInput.Width; x++)
                {
                    // Get Input Pixel
                    Color Cinput = bmpInput.GetPixel(x, y);

                    // Set Output Pixel
                    bmpDecoded.SetPixel(x, y, GammaDecodeColor2(Cinput.ToVector4()));
                } //for (x)
            }     //for (y)

            return(bmpDecoded);
        }
        private Texture2DContent BuildTextureContent(byte[] buffer)
        {
            var bitmap = new Bitmap(new MemoryStream(buffer));

            var bitmapContent = new PixelBitmapContent <Color>(bitmap.Width, bitmap.Height);

            for (int i = 0; i < bitmap.Width; i++)
            {
                for (int j = 0; j < bitmap.Height; j++)
                {
                    System.Drawing.Color from = bitmap.GetPixel(i, j);

                    //System.Drawing.Color to Microsoft.Xna.Framework.Color
                    var to = new Color(from.R, from.G, from.B, from.A);
                    bitmapContent.SetPixel(i, j, to);
                }
            }

            return(new Texture2DContent {
                Mipmaps = new MipmapChain(bitmapContent)
            });
        }
        public override TextureContent Process(TextureContent input, ContentProcessorContext context)
        {
            input.ConvertBitmapType(typeof(PixelBitmapContent<Color>));
            foreach (var mipmapChain in input.Faces)
            {
                for (int i = 0; i < mipmapChain.Count; i++)
                {
                    var bitmap = mipmapChain[i] as PixelBitmapContent<Color>;

                    int newWidth = (int) ((float) bitmap.Width * Scale);
                    int newHeight = (int) ((float) bitmap.Height * Scale);

                    var newBitmap = new PixelBitmapContent<Color>(newWidth, newHeight);

                    for (int y = 0; y < bitmap.Height; y++)
                    {
                        for (int x = 0; x < bitmap.Width; x++)
                        {
                            for (int scaleY = 0; scaleY < Scale; scaleY++)
                            {
                                for (int scaleX = 0; scaleX < Scale; scaleX++)
                                {
                                    newBitmap.SetPixel(
                                        (int) (x * Scale) + scaleX,
                                        (int) (y * Scale) + scaleY,
                                        bitmap.GetPixel(x, y));
                                }
                            }
                        }
                    }

                    mipmapChain[i] = newBitmap;
                }
            }

            return base.Process(input, context);
        }
Exemple #24
0
        public override TextureContent Process(TextureContent input, ContentProcessorContext context)
        {
            input.ConvertBitmapType(typeof(PixelBitmapContent <Color>));
            foreach (var mipmapChain in input.Faces)
            {
                for (int i = 0; i < mipmapChain.Count; i++)
                {
                    var bitmap = mipmapChain[i] as PixelBitmapContent <Color>;

                    int newWidth  = (int)((float)bitmap.Width * Scale);
                    int newHeight = (int)((float)bitmap.Height * Scale);

                    var newBitmap = new PixelBitmapContent <Color>(newWidth, newHeight);

                    for (int y = 0; y < bitmap.Height; y++)
                    {
                        for (int x = 0; x < bitmap.Width; x++)
                        {
                            for (int scaleY = 0; scaleY < Scale; scaleY++)
                            {
                                for (int scaleX = 0; scaleX < Scale; scaleX++)
                                {
                                    newBitmap.SetPixel(
                                        (int)(x * Scale) + scaleX,
                                        (int)(y * Scale) + scaleY,
                                        bitmap.GetPixel(x, y));
                                }
                            }
                        }
                    }

                    mipmapChain[i] = newBitmap;
                }
            }

            return(base.Process(input, context));
        }
        public override TextureContent Process(TextureContent input, ContentProcessorContext context)
        {
            TextureContent texContent = base.Process(input, context);

            texContent.ConvertBitmapType(typeof(PixelBitmapContent <Color>));

            for (int face = 0; face < input.Faces.Count; face++)
            {
                MipmapChain mipChain = input.Faces[face];
                for (int mipLevel = 0; mipLevel < mipChain.Count; mipLevel++)
                {
                    PixelBitmapContent <Color> oldImage  = (PixelBitmapContent <Color>)input.Faces[face][mipLevel];
                    PixelBitmapContent <Color> grayImage = new PixelBitmapContent <Color>(oldImage.Width, oldImage.Height);

                    for (int x = 0; x < oldImage.Width; x++)
                    {
                        for (int y = 0; y < oldImage.Height; y++)
                        {
                            Color oldColor  = oldImage.GetPixel(x, y);
                            float grayValue = oldColor.R * 0.299f / 255.0f;
                            grayValue += oldColor.G * 0.596f / 255.0f;
                            grayValue += oldColor.B * 0.211f / 255.0f;
                            float alpha = oldColor.A / 255.0f;

                            Color grayColor = new Color(grayValue, grayValue, grayValue, alpha);
                            Color newColor  = Color.Lerp(oldColor, grayColor, interpolation);
                            grayImage.SetPixel(x, y, newColor);
                        }
                    }

                    input.Faces[face][mipLevel] = grayImage;
                }
            }

            return(texContent);
        }
        public override TextureContent Process(TextureContent input, ContentProcessorContext context)
        {
            string[] strs = context.OutputFilename.Split('\\');

            /* // If assigning this processor to all textures, use something like this to only apply to certain folders
             * if (strs.Length > 2 && strs[strs.Length - 2] == "Animations")
             * { } */
            //write_debug(context.OutputDirectory);
            //write_debug(context.OutputFilename);

            Dictionary <Color, int> palette = new Dictionary <Color, int>();

            Dictionary <string, Color[]> palette_data = context.BuildAndLoadAsset <string, Dictionary <string, Color[]> >(
                new ExternalReference <string>(@"Face_Palette_Data.xml"), "");
            string filename = Path.GetFileNameWithoutExtension(context.OutputFilename);
            string doop     = filename;

            // If palette data for the face exists
            if (palette_data.ContainsKey(filename) && palette_data[filename].Length > 0)
            {
                // Add the colors to a dictionary
                for (int i = 0; i < palette_data[filename].Length; i++)
                {
                    if (!palette.ContainsKey(palette_data[filename][i]))
                    {
                        palette.Add(palette_data[filename][i], i);
                    }
                }
            }
            // The process for getting to this point has changed, so now if there is no palette entry for a texture it shouldn't be edited at all
            else
            {
                return(base.Process(input, context));
            }

            // Otherwise we have palette data and the image will be remapped to color indices on the red channel
            input.ConvertBitmapType(typeof(PixelBitmapContent <Color>));
            int base_count = palette.Count;
            int new_colors = 0;

            foreach (MipmapChain image_face in input.Faces)
            {
                for (int i = 0; i < image_face.Count; i++)
                {
                    PixelBitmapContent <Color> mip = (PixelBitmapContent <Color>)image_face[i];
                    Color original, edited;

                    for (int y = 0; y < mip.Height; y++)
                    {
                        for (int x = 0; x < mip.Width; x++)
                        {
                            original = mip.GetPixel(x, y);
                            // Checks for new colors not in the palette data
                            // Why would those exist? //Yeti
                            if (!palette.ContainsKey(original))
                            {
                                // Gets the smallest whole number that is not already in the palette values
                                int index = 0;
                                while (palette.Values.ToList().Contains(index))
                                {
                                    index++;
                                }
                                // Adds a new color
                                palette.Add(original, index);
                                // Keeps track of how many new colors have been added
                                new_colors++;
                            }
                            edited = new Color((palette[original] * 1) % 256, 0, 0, original.A);
                            mip.SetPixel(x, y, edited);
                        }
                    }
                }
            }

            if (false)
            {
                //write_debug(doop + ", " + palette.Count.ToString());
                write_debug(doop + ", " + new_colors.ToString() + "/" + palette.Count.ToString());
                for (int i = base_count; i < palette.Count; i++)
                {
                    foreach (KeyValuePair <Color, int> entry in palette)
                    {
                        if (entry.Value == i)
                        {
                            if (entry.Key.A > 0)
                            {
                                write_debug(entry.Key.ToString());
                            }
                            break;
                        }
                    }
                }
            }

            return(base.Process(input, context));
        }
        public override Texture2DContent Process(Splatter splatter, ContentProcessorContext context)
        {
            var input = splatter.Layers.Select(layer => layer != null ? layer.Filename : null).ToArray();

            if (input.Length > 4)
            {
                context.Logger.LogWarning(null, null, "SplatterTextureProcessor supports at most 4 textures. Additional textures will be discarded");
            }

            int width  = 0;
            int height = 0;

            Texture2DContent texture = null;

            PixelBitmapContent <float> bitmapR = null;
            PixelBitmapContent <float> bitmapG = null;
            PixelBitmapContent <float> bitmapB = null;
            PixelBitmapContent <float> bitmapA = null;

            if (input.Length > 0 && !string.IsNullOrEmpty(input[0]))
            {
                texture = context.BuildAndLoadAsset <TextureContent, Texture2DContent>(
                    new ExternalReference <TextureContent>(input[0]), null);

                texture.ConvertBitmapType(typeof(PixelBitmapContent <float>));
                bitmapR = (PixelBitmapContent <float>)texture.Mipmaps[0];

                width  = bitmapR.Width;
                height = bitmapR.Height;
            }

            if (input.Length > 1 && !string.IsNullOrEmpty(input[1]))
            {
                texture = context.BuildAndLoadAsset <TextureContent, Texture2DContent>(
                    new ExternalReference <TextureContent>(input[1]), null);

                texture.ConvertBitmapType(typeof(PixelBitmapContent <float>));
                bitmapG = (PixelBitmapContent <float>)texture.Mipmaps[0];

                width  = bitmapG.Width;
                height = bitmapG.Height;
            }

            if (input.Length > 2 && !string.IsNullOrEmpty(input[2]))
            {
                texture = context.BuildAndLoadAsset <TextureContent, Texture2DContent>(
                    new ExternalReference <TextureContent>(input[2]), null);

                texture.ConvertBitmapType(typeof(PixelBitmapContent <float>));
                bitmapB = (PixelBitmapContent <float>)texture.Mipmaps[0];

                width  = bitmapB.Width;
                height = bitmapB.Height;
            }

            if (input.Length > 3 && !string.IsNullOrEmpty(input[3]))
            {
                texture = context.BuildAndLoadAsset <TextureContent, Texture2DContent>(
                    new ExternalReference <TextureContent>(input[3]), null);

                texture.ConvertBitmapType(typeof(PixelBitmapContent <float>));
                bitmapA = (PixelBitmapContent <float>)texture.Mipmaps[0];

                width  = bitmapA.Width;
                height = bitmapA.Height;
            }

            // In case no alpha texture is specified.
            width  = Math.Max(1, width);
            height = Math.Max(1, height);

            PixelBitmapContent <Vector4> bitmap = new PixelBitmapContent <Vector4>(width, height);

            for (int y = 0; y < height; ++y)
            {
                for (int x = 0; x < width; ++x)
                {
                    var color = new Vector4(
                        bitmapR != null ? bitmapR.GetPixel(x, y) : GenerateBaseLayer ? 1 : 0,
                        bitmapG != null ? bitmapG.GetPixel(x, y) : 0,
                        bitmapB != null ? bitmapB.GetPixel(x, y) : 0,
                        bitmapA != null ? bitmapA.GetPixel(x, y) : 0);

                    color.Z = Math.Min(color.Z, 1 - color.W);
                    color.Y = Math.Min(color.Y, 1 - color.W - color.Z);
                    color.X = Math.Min(color.X, 1 - color.W - color.Z - color.Y);

                    bitmap.SetPixel(x, y, color);
                }
            }

            Texture2DContent result = new Texture2DContent();

            result.Mipmaps = new MipmapChain(bitmap);
            result.ConvertBitmapType(typeof(PixelBitmapContent <Color>));

            return(result);
        }
Exemple #28
0
        PixelBitmapContent <Color> CreateNormalMap(PixelBitmapContent <Color> input)
        {
            int width  = input.Width;
            int height = input.Height;

            PixelBitmapContent <Color> result = new PixelBitmapContent <Color>(width, height);

            float h1, h2, h3, h4;

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    if (x < width - 1)
                    {
                        h1 = ((float)input.GetPixel(x + 1, y).R / 255.0f);
                    }
                    else // wrap x to other side of texture.
                    {
                        h1 = ((float)input.GetPixel(0, y).R / 255.0f);
                    }

                    if (x > 0)
                    {
                        h3 = ((float)input.GetPixel(x - 1, y).R / 255.0f);
                    }
                    else // Wrap x to other side of texture.
                    {
                        h3 = ((float)input.GetPixel((width - 1), y).R / 255.0f);
                    }

                    if (y < height - 1)
                    {
                        h2 = ((float)input.GetPixel(x, y + 1).R / 255.0f);
                    }
                    else // Wrap y to other side of texture
                    {
                        h2 = ((float)input.GetPixel(x, 0).R / 255.0f);
                    }

                    if (y > 0)
                    {
                        h4 = (float)(input.GetPixel(x, y - 1).R / 255.0f);
                    }
                    else // Wrap y to other side of texture
                    {
                        h4 = (float)(input.GetPixel(x, (height - 1)).R / 255.0f);
                    }

                    Vector3 v1 = new Vector3(1.0f, 0.0f, (h1 - h3));
                    Vector3 v2 = new Vector3(0.0f, 1.0f, (h2 - h4));

                    Vector3 normal = Vector3.Cross(v1, v2);
                    normal.Normalize();

                    normal.X = (normal.X + 1.0f) * 0.5f;
                    normal.Y = (normal.Y + 1.0f) * 0.5f;
                    normal.Z = (normal.Z + 1.0f) * 0.5f;

                    result.SetPixel(x, y, new Color(normal));
                }
            }

            return(result);
        }
        public override TextureContent Process(TextureContent input, ContentProcessorContext context)
        {
            string[] strs = context.OutputFilename.Split('\\');

            /* // If assigning this processor to all textures, use something like this to only apply to certain folders
             * if (strs.Length > 2 && strs[strs.Length - 2] == "Animations")
             * { } */
            //write_debug(context.OutputDirectory);
            //write_debug(context.OutputFilename);

            bool battler = (strs.Length > 2 && strs[strs.Length - 2] == "Battlers");

            Dictionary <Color, int> palette = new Dictionary <Color, int>();

            Dictionary <string, Color[]> palette_data = context.BuildAndLoadAsset <string, Dictionary <string, Color[]> >(new ExternalReference <string>(@"BattlerPalettes.xml"), "");
            string filename = Path.GetFileNameWithoutExtension(context.OutputFilename);

            if (!palette_data.ContainsKey(filename))
            {
                filename = filename.Split('-')[0];
            }
            if (palette_data.ContainsKey(filename))
            {
                for (int i = 0; i < palette_data[filename].Length; i++)
                {
                    if (!palette.ContainsKey(palette_data[filename][i]))
                    {
                        palette.Add(palette_data[filename][i], i);
                    }
                }
            }
            // The process for getting to this point has changed, so now if there is no palette entry for a texture it shouldn't be edited at all
            else
            {
                return(base.Process(input, context));
            }

            // Otherwise we have palette data and the image will be remapped to color indices on the red channel
            input.ConvertBitmapType(typeof(PixelBitmapContent <Color>));
            foreach (MipmapChain image_face in input.Faces)
            {
                for (int i = 0; i < image_face.Count; i++)
                {
                    PixelBitmapContent <Color> mip = (PixelBitmapContent <Color>)image_face[i];
                    Color original, edited;

                    // Go through the whole image
                    for (int y = 0; y < mip.Height; y++)
                    {
                        for (int x = 0; x < mip.Width; x++)
                        {
                            original = mip.GetPixel(x, y);
                            // If this color isn't already in the palette, /leave the color alone/
                            // This is a new change to leave unpaletted colors alone
                            if (original.A > 0 && palette.ContainsKey(original))
                            {
                                edited = new Color((palette[original] * 1) % 256, 0, 0, original.A);
                                mip.SetPixel(x, y, edited);
                            }
                        }
                    }
                }
            }

            /*
             * if (false)
             * {
             *  //write_debug(originalFilename + ", " + palette.Count.ToString());
             *  write_debug(originalFilename + ", " + new_colors.ToString() + "/" + palette.Count.ToString());
             *  for (int i = base_count; i < palette.Count; i++)
             *      foreach (KeyValuePair<Color, int> entry in palette)
             *          if (entry.Value == i)
             *          {
             *              if (entry.Key.A > 0)
             *                  write_debug(entry.Key.ToString());
             *              break;
             *          }
             * }*/

            return(base.Process(input, context));
        }
Exemple #30
0
        /// <summary>
        /// 文字グリフからテクスチャを生成する
        /// </summary>
        /// <param name="layouter"></param>
        void ProcessTexture(BoxLayouter layouter)
        {
            // レイアウト、複数の矩形を1つの矩形内に並べる
            int width, height;

            layouter.Layout(out width, out height);

            // 配置後のグリフを画像へ書き込む
            var bitmap = new PixelBitmapContent <Color>(width, height);

            for (int i = 0; i < layouter.Items.Count; ++i)
            {
                // グリフ位置情報の追加
                var rc = fontContent.Glyphs[i];
                rc.X = layouter.Items[i].Bounds.X;
                rc.Y = layouter.Items[i].Bounds.Y;
                fontContent.Glyphs[i] = rc;

                // 個々のグリフ画像をひとつの画像へ追加する
                var pixels = layouter.Items[i].Tag as uint[];
                int idx    = 0;
                for (int y = 0; y < rc.Height; ++y)
                {
                    for (int x = 0; x < rc.Width; ++x)
                    {
                        int r = (int)((pixels[idx] & 0x00ff0000) >> 16);
                        int g = (int)((pixels[idx] & 0x0000ff00) >> 8);
                        int b = (int)((pixels[idx] & 0x000000ff) >> 0);
                        int a = (int)((pixels[idx] & 0xff000000) >> 24);
                        bitmap.SetPixel(rc.X + x, rc.Y + y, new Color(r, g, b, a));
                        ++idx;
                    }
                }
            }

            // 文字画像をまとめた画像をテクスチャへ変換する
            fontContent.Texture = new Texture2DContent();
            switch (TextureFormat)
            {
            case WpfTextureFormat.Auto:
                if (UseGradient)
                {
                    // グラデーション使用していればColorフォーマット
                    fontContent.Texture.Mipmaps = bitmap;
                }
                else if (OutlineThickness > 0)
                {
                    // アウトラインのみ使用していればBgra4444フォーマット
                    fontContent.Texture.Mipmaps = bitmap;
                    fontContent.Texture.ConvertBitmapType(
                        typeof(PixelBitmapContent <Bgra4444>));
                }
                else
                {
                    // それ以外の単色フォントであれば単色に特化したDXT3圧縮をする
                    fontContent.Texture.Mipmaps =
                        SingleColorDxtCompressor.Compress(bitmap, FontColor);
                }
                break;

            case WpfTextureFormat.Bgra4444:
                fontContent.Texture.Mipmaps = bitmap;
                fontContent.Texture.ConvertBitmapType(
                    typeof(PixelBitmapContent <Bgra4444>));
                break;

            case WpfTextureFormat.Color:
                fontContent.Texture.Mipmaps = bitmap;
                break;
            }
        }