Ejemplo n.º 1
0
        private static Texture CreateTextureFromDds(
            GraphicsDevice graphicsDevice,
            DdsFile ddsFile)
        {
            var mipMapData = new TextureMipMapData[ddsFile.Header.MipMapCount];

            for (var i = 0; i < ddsFile.Header.MipMapCount; i++)
            {
                mipMapData[i] = new TextureMipMapData
                {
                    Data        = ddsFile.MipMaps[i].Data,
                    BytesPerRow = (int)ddsFile.MipMaps[i].RowPitch
                };
            }

            var width  = (int)ddsFile.Header.Width;
            var height = (int)ddsFile.Header.Height;

            // BC3 texture dimensions need to be aligned to a multiple of 4.
            if (ddsFile.ImageFormat == DdsImageFormat.Bc3)
            {
                width  = Math.Max(width, 4);
                height = Math.Max(height, 4);
            }

            return(Texture.CreateTexture2D(
                       graphicsDevice,
                       ddsFile.PixelFormat,
                       width,
                       height,
                       mipMapData));
        }
Ejemplo n.º 2
0
        public static TextureMipMapData[] GenerateMipMaps(
            int width,
            int height,
            byte[] rgbaData)
        {
            var numLevels = CalculateMipMapCount(width, height);

            var mipMapData = new TextureMipMapData[numLevels];

            int previousWidth = -1, previousHeight = -1;

            for (int level = 0; level < numLevels; level++)
            {
                if (level > 0)
                {
                    var levelData = new byte[width * height * ByteRgba.BytesPerPixel];

                    for (int y = 0; y < height; y++)
                    {
                        for (int x = 0; x < width; x++)
                        {
                            int previousLevelX = x * (previousWidth / width);
                            int previousLevelY = y * (previousHeight / height);

                            var moreDetailedMipLevel = mipMapData[level - 1];
                            var c00 = ByteRgba.FromByteArray(moreDetailedMipLevel.Data, previousLevelX, previousLevelY, previousWidth);
                            var c10 = ByteRgba.FromByteArray(moreDetailedMipLevel.Data, ClampToDimension(previousLevelX + 1, previousWidth), previousLevelY, previousWidth);
                            var c01 = ByteRgba.FromByteArray(moreDetailedMipLevel.Data, previousLevelX, ClampToDimension(previousLevelY + 1, previousHeight), previousWidth);
                            var c11 = ByteRgba.FromByteArray(moreDetailedMipLevel.Data, ClampToDimension(previousLevelX + 1, previousWidth), ClampToDimension(previousLevelY + 1, previousHeight), previousWidth);
                            var interpolatedColor = ByteRgba.Average(c00, c10, c01, c11);

                            interpolatedColor.CopyTo(levelData, x, y, width);
                        }
                    }

                    mipMapData[level] = new TextureMipMapData
                    {
                        Data        = levelData,
                        BytesPerRow = width * ByteRgba.BytesPerPixel
                    };
                }
                else
                {
                    mipMapData[level] = new TextureMipMapData
                    {
                        Data        = rgbaData,
                        BytesPerRow = width * ByteRgba.BytesPerPixel
                    };
                }

                previousWidth  = width;
                previousHeight = height;

                width  = Math.Max((int)Math.Floor(width / 2.0), 1);
                height = Math.Max((int)Math.Floor(height / 2.0), 1);
            }

            return(mipMapData);
        }
Ejemplo n.º 3
0
        private uint GetTextureIndex(Texture texture)
        {
            if (!_nameToTextureIndex.TryGetValue(texture, out var result))
            {
                if (_nextTextureIndex == MaxTextures ||
                    texture.Width != texture.Height ||
                    texture.Width != TextureSize)
                {
                    throw new InvalidOperationException();
                }

                result = _nextTextureIndex;

                _nameToTextureIndex.Add(texture, _nextTextureIndex);

                var commandList = _graphicsDevice.ResourceFactory.CreateCommandList();
                commandList.Begin();

                for (var mipLevel = 0u; mipLevel < TextureMipLevels; mipLevel++)
                {
                    var mipSize = TextureMipMapData.CalculateMipSize(mipLevel, TextureSize);

                    commandList.CopyTexture(
                        texture,
                        0, 0, 0,
                        mipLevel,
                        0,
                        TextureArray,
                        0, 0, 0,
                        mipLevel,
                        _nextTextureIndex,
                        mipSize,
                        mipSize,
                        1,
                        1);
                }

                commandList.End();

                _graphicsDevice.SubmitCommands(commandList);

                _graphicsDevice.DisposeWhenIdle(commandList);

                _graphicsDevice.WaitForIdle();

                _nextTextureIndex++;
            }

            return(result);
        }
Ejemplo n.º 4
0
        private static Texture CreateTextureFromDds(
            GraphicsDevice graphicsDevice,
            ResourceUploadBatch uploadBatch,
            DdsFile ddsFile)
        {
            var mipMapData = new TextureMipMapData[ddsFile.Header.MipMapCount];

            for (var i = 0; i < ddsFile.Header.MipMapCount; i++)
            {
                mipMapData[i] = new TextureMipMapData
                {
                    Data        = ddsFile.MipMaps[i].Data,
                    BytesPerRow = (int)ddsFile.MipMaps[i].RowPitch
                };
            }

            return(Texture.CreateTexture2D(
                       graphicsDevice,
                       uploadBatch,
                       ToPixelFormat(ddsFile.ImageFormat),
                       (int)ddsFile.Header.Width,
                       (int)ddsFile.Header.Height,
                       mipMapData));
        }
Ejemplo n.º 5
0
        public static DdsFile FromStream(Stream stream)
        {
            using (var reader = new BinaryReader(stream, Encoding.ASCII, true))
            {
                var magic = reader.ReadFourCc();
                if (magic != "DDS ")
                {
                    throw new InvalidDataException();
                }

                var header = DdsHeader.Parse(reader);

                DdsImageFormat imageFormat;
                if (header.PixelFormat.Flags.HasFlag(DdsPixelFormatFlags.FourCc))
                {
                    imageFormat = GetImageFormat(header.PixelFormat.FourCc);
                }
                else if (header.PixelFormat.Flags.HasFlag(DdsPixelFormatFlags.BumpDuDv))
                {
                    imageFormat = DdsImageFormat.Rg8SNorm;
                }
                else if (header.PixelFormat.Flags.HasFlag(DdsPixelFormatFlags.Rgb))
                {
                    imageFormat = DdsImageFormat.Rgba8;
                }
                else
                {
                    throw new InvalidDataException();
                }

                var dimension = DdsTextureDimension.Texture2D;
                var arraySize = 1u;
                if (header.Flags.HasFlag(DdsHeaderFlags.Depth) && header.Caps2.HasFlag(DdsCaps2.Volume))
                {
                    dimension = DdsTextureDimension.Texture3D;
                }
                else if (header.Caps2.HasFlag(DdsCaps2.CubeMap))
                {
                    dimension = DdsTextureDimension.TextureCube;
                    if (!header.Caps2.HasFlag(DdsCaps2.AllCubeMapFaces))
                    {
                        throw new InvalidDataException();
                    }
                    arraySize = 6;
                }

                var isCompressed = imageFormat == DdsImageFormat.Bc1 ||
                                   imageFormat == DdsImageFormat.Bc2 ||
                                   imageFormat == DdsImageFormat.Bc3;

                var mipMapCount = header.MipMapCount;
                if (mipMapCount == 0)
                {
                    mipMapCount = 1;
                }

                var mipMaps = new TextureMipMapData[mipMapCount * arraySize];

                for (var arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
                {
                    var width  = header.Width;
                    var height = header.Height;

                    if (isCompressed)
                    {
                        // Ensure width and height are multiple of 4.
                        width  = (width + 3) / 4 * 4;
                        height = (height + 3) / 4 * 4;
                    }

                    var depth = Math.Max(header.Depth, 1);

                    for (var i = 0; i < mipMapCount; i++)
                    {
                        var surfaceInfo = GetSurfaceInfo(width, height, imageFormat, header);

                        var numSurfaceBytes = surfaceInfo.NumBytes * depth;
                        var mipMapData      = reader.ReadBytes((int)numSurfaceBytes);
                        if (mipMapData.Length != numSurfaceBytes)
                        {
                            throw new InvalidDataException();
                        }

                        // Set alpha bytes for 32-bit rgb images that don't include alpha data.
                        if (imageFormat == DdsImageFormat.Rgba8 && !header.PixelFormat.Flags.HasFlag(DdsPixelFormatFlags.AlphaPixels))
                        {
                            for (var j = 0; j < mipMapData.Length; j += 4)
                            {
                                mipMapData[j + 3] = 255;
                            }
                        }

                        mipMaps[(arrayIndex * mipMapCount) + i] = new TextureMipMapData(
                            mipMapData,
                            surfaceInfo.RowBytes,
                            surfaceInfo.NumBytes,
                            width,
                            height);

                        width  >>= 1;
                        height >>= 1;
                        depth  >>= 1;

                        if (isCompressed)
                        {
                            // Round width and height down to multiple of 4.
                            width  -= width % 4;
                            height -= height % 4;

                            width  = Math.Max(width, 4);
                            height = Math.Max(height, 4);
                        }
                        else
                        {
                            width  = Math.Max(width, 1);
                            height = Math.Max(height, 1);
                        }

                        depth = Math.Max(depth, 1);
                    }
                }

                return(new DdsFile
                {
                    Header = header,
                    Dimension = dimension,
                    ImageFormat = imageFormat,
                    ArraySize = arraySize,
                    MipMapCount = mipMapCount,
                    MipMaps = mipMaps
                });
            }
        }