Example #1
0
        private KTXError ReadHeader(byte[] headerChunk, out KTXHeader header)
        {
            KTXError errorCode = KTXError.Success;

            header = new KTXHeader();
            header.Populate(headerChunk);
            if (header.Instructions.Result != KTXError.Success)
            {
                return(header.Instructions.Result);
            }
            header.KeyValueData = new byte[header.BytesOfKeyValueData];
            if (header.KeyValueData == null)
            {
                return(KTXError.OutOfMemory);
            }
            return(errorCode);
        }
Example #2
0
        KTXTextureOutput LoadTexture(
            Stream src,
            KTXHeader header)
        {
            // default out values
            KTXError errorCode = KTXError.Success;

            bool isFirstTime     = true;
            int  previousLodSize = 0;

            byte[] data = null;

            var faces = new KTXFaceData[header.NumberOfFaces];

            for (var i = 0; i < faces.Length; ++i)
            {
                faces[i] = new KTXFaceData((uint)i, header.NumberOfMipmapLevels);
            }

            using (var dest = new MemoryStream())
            {
                for (int level = 0; level < header.NumberOfMipmapLevels; ++level)
                {
                    UInt32 faceLodSize;
                    if (!header.ExtractUInt32(src, out faceLodSize))
                    {
                        errorCode = KTXError.InvalidOperation;
                        break;
                    }

                    int faceLodSizeRounded = ((int)faceLodSize + 3) & ~3;

                    // array texture is this correct ?
                    if (isFirstTime)
                    {
                        isFirstTime     = false;
                        previousLodSize = faceLodSizeRounded;

                        /* allocate memory sufficient for the first level */
                        data = new byte[faceLodSizeRounded];
                        if (data == null)
                        {
                            errorCode = KTXError.OutOfMemory;
                            break;
                        }
                    }
                    else
                    {
                        if (previousLodSize < faceLodSizeRounded)
                        {
                            /* subsequent levels cannot be larger than the first level */
                            errorCode = KTXError.InvalidValue;
                            break;
                        }
                    }

                    var mipmap = new KTXMipmapData();
                    mipmap.Common.Level = level;
                    mipmap.Common.Data  = data;
                    mipmap.Common.Size  = faceLodSize;
                    mipmap.SizeRounded  = faceLodSizeRounded;

                    var loadError = ExtractFace(src, dest, header, mipmap, data, faces);
                    if (loadError != KTXError.Success)
                    {
                        errorCode = loadError;
                        break;
                    }
                }

                var format = DetermineFormat(header.GlType, header.GlFormat, header.GlInternalFormat);

                // MgImageOptimizer takes
                // 1. byte array
                // 2. image source

                var output = new KTXTextureOutput();

                // one face at a time
                var face = faces[0];

                output.Source = new MgImageSource
                {
                    Format  = format,
                    Height  = header.PixelHeight,
                    Width   = header.PixelWidth,
                    Mipmaps = face.Mipmaps,
                    Size    = (uint)dest.Length,
                };

                output.TextureInfo = mTextureOptimizer.Load(dest.ToArray(), output.Source, null, null);

                // QUEUE WAIT ON
                var err = mGraphicsConfiguration.Queue.QueueWaitIdle();
                Debug.Assert(err == Result.SUCCESS);
                mGraphicsConfiguration.Device.FreeCommandBuffers(
                    mGraphicsConfiguration.Partition.CommandPool,
                    new[] { output.TextureInfo.Command });

                return(output);
            }
        }