static void BitmapAssert(BitmapContent bitmap, Color color, int range)
        {
            byte[] rgba;
            if (bitmap is Dxt1BitmapContent)
            {
                rgba = DxtUtil.DecompressDxt1(bitmap.GetPixelData(), bitmap.Width, bitmap.Height);
            }
            else if (bitmap is Dxt3BitmapContent)
            {
                rgba = DxtUtil.DecompressDxt3(bitmap.GetPixelData(), bitmap.Width, bitmap.Height);
            }
            else if (bitmap is Dxt5BitmapContent)
            {
                rgba = DxtUtil.DecompressDxt5(bitmap.GetPixelData(), bitmap.Width, bitmap.Height);
            }
            else
            {
                rgba = bitmap.GetPixelData();
            }

            for (var p = 0; p < rgba.Length; p += 4)
            {
                Assert.That(rgba[p + 0], Is.EqualTo(color.R).Within(range));
                Assert.That(rgba[p + 1], Is.EqualTo(color.G).Within(range));
                Assert.That(rgba[p + 2], Is.EqualTo(color.B).Within(range));
                Assert.That(rgba[p + 3], Is.EqualTo(color.A).Within(range));
            }
        }
        /// <summary>
        /// Construye el mapa de alturas a partir de la textura especificada
        /// </summary>
        /// <param name="terrain">Textura con el mapa de alturas del terreno</param>
        /// <param name="cellScale">Escala de alturas</param>
        /// <param name="context">Contexto</param>
        /// <returns>Devuelve el mapa de alturas generado</returns>
        private HeightMap BuildHeightMap(Texture2DContent terrain, float cellScale, ContentProcessorContext context)
        {
            if (terrain.Mipmaps.Count > 0)
            {
                BitmapContent heightMapContent = terrain.Mipmaps[0];

                // Sólo se soportan texturas cuadradas
                if (heightMapContent.Width == heightMapContent.Height)
                {
                    byte[] pixelData = heightMapContent.GetPixelData();

                    // Construir el mapa de alturas
                    return(HeightMap.FromData(
                               pixelData,
                               heightMapContent.Height,
                               heightMapContent.Width,
                               cellScale));
                }
                else
                {
                    //Sólo se soportan texturas cuadradas
                    throw new NotImplementedException();
                }
            }
            else
            {
                throw new PipelineException("El archivo de mapa de alturas no tiene el formato correcto. No se encuentra la imagen");
            }
        }
예제 #3
0
        public static SpriteFont Compile(GraphicsDevice g, string file, out IDisposable gR)
        {
            FontDescriptionImporter  ei = new FontDescriptionImporter();
            FontDescription          ec = ei.Import(file, new XNADynImporterContext());
            FontDescriptionProcessor ep = new FontDescriptionProcessor();
            var cec = ep.Process(ec, new XNADynProcessorContext());

            // Get Private Texture
            Texture2DContent texC   = sfcTexture.GetValue(cec) as Texture2DContent;
            MipmapChain      o      = txcMipmaps.GetValue(texC, null) as MipmapChain;
            BitmapContent    texBMP = o[0];
            SurfaceFormat    sf;

            if (!texBMP.TryGetFormat(out sf))
            {
                throw new InvalidContentException("Could Not Obtain The Surface Format Of The SpriteFont");
            }
            Texture2D texture = new Texture2D(g, texBMP.Width, texBMP.Height, false, sf);

            texture.SetData(texBMP.GetPixelData());

            // Get Private Glyph Data
            List <Rectangle> glyphs    = sfcGlyphs.GetValue(cec) as List <Rectangle>;
            List <Rectangle> cropping  = sfcCropping.GetValue(cec) as List <Rectangle>;
            List <char>      charMap   = sfcCharMap.GetValue(cec) as List <char>;
            int            lineSpacing = (int)sfcLineSpacing.GetValue(cec);
            float          spacing     = (float)sfcSpacing.GetValue(cec);
            List <Vector3> kerning     = sfcKerning.GetValue(cec) as List <Vector3>;
            char?          defaultChar = sfcDefaultChar.GetValue(cec) as char?;

            // Invoke Private SpriteFont Constructor
            gR = texture;
            return(sfConstructor.Invoke(new object[] { texture, glyphs, cropping, charMap, lineSpacing, spacing, kerning, defaultChar }) as SpriteFont);
        }
예제 #4
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);
        }
예제 #5
0
        public override List <Vertices> Process(TextureContent input, ContentProcessorContext context)
        {
            BitmapContent bitmap = input.Faces[0][0];

            byte[] bytes = bitmap.GetPixelData();
            Debug.Assert(bytes.Length % 4 == 0);

            // Note(manu): If this were C/C++, we could simply reinterpret the byte-array as a uint-array...
            uint[] data = new uint[bytes.Length / 4];
            for (int dataIndex = 0; dataIndex < data.Length; dataIndex++)
            {
                int byteIndex = dataIndex * 4;
                data[dataIndex] = BitConverter.ToUInt32(bytes, byteIndex);
            }

            DateTime         vertStart        = DateTime.Now;
            TextureConverter textureConverter = new TextureConverter(data, bitmap.Width)
            {
                PolygonDetectionType    = PolygonDetectionType,
                HoleDetection           = HoleDetection,
                MultipartDetection      = MultipartDetection,
                PixelOffsetOptimization = PixelOffsetOptimization,
                Transform      = Matrix.CreateScale(UniformScale * Conversion.RenderScale), // TODO(manu): Use z=1 instead?
                AlphaTolerance = (byte)AlphaTolerance,
                HullTolerance  = HullTolerance,
            };
            List <Vertices> vertices     = textureConverter.DetectVertices();
            TimeSpan        vertDuration = DateTime.Now - vertStart;

            Diagnostic(context.Logger, $"Parsing vertices took {vertDuration.TotalSeconds.ToString("0.000")} seconds (VelcroPhysics).");

            return(vertices);
        }
예제 #6
0
    public override List<ScreenLayoutInfo> Process(TextureContent input, ContentProcessorContext context)
    {
      BitmapContent bitmap = input.Faces[0][0];
      byte[] bytes = bitmap.GetPixelData();

      Debug.Assert(bytes.Length % 4 == 0);

      int mapWidth = bitmap.Width;
      int mapHeight = bitmap.Height;
      int numJobs = Environment.ProcessorCount;
      int numLinesPerJob = mapHeight / numJobs;
      JobInfo[] jobInfos = new JobInfo[numJobs];
      for(int jobIndex = 0; jobIndex < numJobs; jobIndex++)
      {
        // Example: Assume numLinesPerJob = 10:
        jobInfos[jobIndex].rowOffset = jobIndex * numLinesPerJob; // 0, 10, 20, ...
        jobInfos[jobIndex].rowCount = numLinesPerJob; // 10, 10, 10, ...
        jobInfos[jobIndex].infos = new List<ScreenLayoutInfo>();
        jobInfos[jobIndex].warnings = new List<string>();
      }

      DateTime start = DateTime.Now;

#if PARALLEL
      Parallel.ForEach(Enumerable.Range(0, numJobs), (jobIndex) =>
#else
      for(int jobIndex = 0; jobIndex < numJobs; jobIndex++)
#endif
      {
        int numRowsToProcess = jobInfos[jobIndex].rowCount;
        for(int localRow = 0; localRow < numRowsToProcess; localRow++)
        {
          int row = localRow + jobInfos[jobIndex].rowOffset;
          ParseLayoutInfos(bytes, row, mapWidth, jobInfos[jobIndex].infos, jobInfos[jobIndex].warnings);
        }
      }
예제 #7
0
        internal static void WriteUncompressed(string filename, BitmapContent bitmapContent)
        {
            using (var fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write))
                using (var writer = new BinaryWriter(fileStream))
                {
                    // Signature ("DDS ")
                    writer.Write((byte)0x44);
                    writer.Write((byte)0x44);
                    writer.Write((byte)0x53);
                    writer.Write((byte)0x20);

                    var header = new DdsHeader
                    {
                        dwSize              = 124,
                        dwFlags             = Ddsd.Caps | Ddsd.Width | Ddsd.Height | Ddsd.Pitch | Ddsd.PixelFormat,
                        dwWidth             = (uint)bitmapContent.Width,
                        dwHeight            = (uint)bitmapContent.Height,
                        dwPitchOrLinearSize = (uint)(bitmapContent.Width * 4),
                        dwDepth             = 0,
                        dwMipMapCount       = 0
                    };

                    writer.Write(header.dwSize);
                    writer.Write((uint)header.dwFlags);
                    writer.Write(header.dwHeight);
                    writer.Write(header.dwWidth);
                    writer.Write(header.dwPitchOrLinearSize);
                    writer.Write(header.dwDepth);
                    writer.Write(header.dwMipMapCount);

                    // 11 unused and reserved DWORDS.
                    for (int i = 0; i < 11; i++)
                    {
                        writer.Write((uint)0);
                    }

                    if (!bitmapContent.TryGetFormat(out SurfaceFormat format) || format != SurfaceFormat.Rgba32)
                    {
                        throw new NotSupportedException("Unsupported bitmap content!");
                    }

                    header.ddspf.dwSize        = 32;
                    header.ddspf.dwFlags       = Ddpf.AlphaPixels | Ddpf.Rgb;
                    header.ddspf.dwFourCC      = 0;
                    header.ddspf.dwRgbBitCount = 32;
                    header.ddspf.dwRBitMask    = 0x000000ff;
                    header.ddspf.dwGBitMask    = 0x0000ff00;
                    header.ddspf.dwBBitMask    = 0x00ff0000;
                    header.ddspf.dwABitMask    = 0xff000000;

                    // Write the DDS_PIXELFORMAT
                    writer.Write(header.ddspf.dwSize);
                    writer.Write((uint)header.ddspf.dwFlags);
                    writer.Write((uint)header.ddspf.dwFourCC);
                    writer.Write(header.ddspf.dwRgbBitCount);
                    writer.Write(header.ddspf.dwRBitMask);
                    writer.Write(header.ddspf.dwGBitMask);
                    writer.Write(header.ddspf.dwBBitMask);
                    writer.Write(header.ddspf.dwABitMask);

                    header.dwCaps  = DdsCaps.Texture;
                    header.dwCaps2 = 0;

                    // Continue reading DDS_HEADER
                    writer.Write((uint)header.dwCaps);
                    writer.Write((uint)header.dwCaps2);

                    // More reserved unused DWORDs.
                    for (int i = 0; i < 3; i++)
                    {
                        writer.Write((uint)0);
                    }

                    // Write out the face data.
                    writer.Write(bitmapContent.GetPixelData());
                }
        }
예제 #8
0
        public override TextureContent Process(TextureContent input, ContentProcessorContext context)
        {
            //System.Diagnostics.Debugger.Launch();

            input.Validate();

            try
            {
                using (CompressorOptionsBundle compressor = new CompressorOptionsBundle())
                {
                    compressor.InputOptions.ResetTextureLayout();

                    TextureType textureType = FindTextureType(input);

                    /*
                     * Set options
                     */

                    compressor.InputOptions.SetTextureLayout(textureType, input.Faces[0][0].Width, input.Faces[0][0].Height, 1);
                    compressor.InputOptions.SetFormat(InputFormat.BGRA_8UB);
                    compressor.InputOptions.SetAlphaMode(AlphaMode);
                    compressor.InputOptions.SetMipmapFilter(MipMapFilter);
                    compressor.InputOptions.SetMipmapGeneration(GenerateMipmaps, MaxMipMapLevel);
                    compressor.InputOptions.SetRoundMode(TextureRoundingMode);
                    compressor.InputOptions.SetWrapMode(WrapMode);

                    compressor.InputOptions.SetGamma(InputGamma, OutputGamma);
                    compressor.InputOptions.SetNormalizeMipmaps(false);
                    compressor.InputOptions.SetNormalMap(false);
                    compressor.InputOptions.SetConvertToNormalMap(false);

                    compressor.CompressionOptions.SetQuality(Quality);

                    GeneralOutputHandler outputHandler;

                    switch (TextureFormat)
                    {
                    case TextureOutputFormat.Colour:
                        compressor.CompressionOptions.SetFormat(Format.RGBA);
                        outputHandler = new PixelOutputHandler <Color>(textureType);
                        break;

                    case TextureOutputFormat.Normals:
                        compressor.CompressionOptions.SetFormat(Format.RGBA);
                        outputHandler = new PixelOutputHandler <Color>(textureType);

                        compressor.InputOptions.SetNormalizeMipmaps(true);
                        compressor.InputOptions.SetNormalMap(true);
                        compressor.InputOptions.SetConvertToNormalMap(ConvertToNormalMap);
                        compressor.InputOptions.SetGamma(1.0f, 1.0f);
                        break;

                    case TextureOutputFormat.DXT1:
                        compressor.CompressionOptions.SetFormat(Format.DXT1);
                        outputHandler = new Dxt1OutputHandler(textureType);
                        break;

                    case TextureOutputFormat.DXT1a:
                        compressor.CompressionOptions.SetFormat(Format.DXT1a);
                        outputHandler = new Dxt1OutputHandler(textureType);
                        break;

                    case TextureOutputFormat.DXT3:
                        compressor.CompressionOptions.SetFormat(Format.DXT3);
                        outputHandler = new Dxt3OutputHandler(textureType);
                        break;

                    case TextureOutputFormat.DXT5:
                        compressor.CompressionOptions.SetFormat(Format.DXT5);
                        outputHandler = new Dxt5OutputHandler(textureType);
                        break;

                    case TextureOutputFormat.DXT5n:
                        //FIXME: We force fastest quality since the normal compression mode is _very_ slow.
                        compressor.CompressionOptions.SetQuality(Quality.Fastest);

                        compressor.CompressionOptions.SetFormat(Format.DXT5n);

                        compressor.InputOptions.SetNormalizeMipmaps(true);
                        compressor.InputOptions.SetNormalMap(true);
                        compressor.InputOptions.SetConvertToNormalMap(ConvertToNormalMap);
                        compressor.InputOptions.SetGamma(1.0f, 1.0f);

                        outputHandler = new Dxt5OutputHandler(textureType);
                        break;

                    default:
                        throw new NotSupportedException("Unknown texture output format: " + TextureFormat);
                    }

                    /*
                     * Set input data
                     */

                    //TODO: Use a float format when texture tools support it.
                    input.ConvertBitmapType(typeof(PixelBitmapContent <Color>));

                    for (int i = 0; i < input.Faces.Count; i++)
                    {
                        MipmapChain mipChain = input.Faces[i];

                        for (int j = 0; j < mipChain.Count; j++)
                        {
                            BitmapContent bitmap = mipChain[j];

                            byte[] bitmapData = bitmap.GetPixelData();

                            //FIXME: When we move to XNA 4 the layout of Color will change, hence we need to swizzle the input.
                            compressor.InputOptions.SetMipmapData(bitmapData, bitmap.Width, bitmap.Height, 1, i, j);
                        }
                    }

                    /*
                     * Setup output
                     */


                    compressor.OutputOptions.SetOutputHandler(outputHandler);
                    compressor.OutputOptions.SetOutputHeader(false);

                    /*
                     * Go!
                     */
                    compressor.Compressor.SetEnableCuda(EnableCuda);

                    compressor.Compress();

                    /*
                     * Check the output makes sense.
                     */

                    outputHandler.OutputTextureContent.Validate();

                    return(outputHandler.OutputTextureContent);
                }
            }
            catch (TextureToolsException ttexcept)
            {
                throw ConvertException(ttexcept);
            }
        }