Пример #1
0
        /// <summary>
        /// Convienence method for setting the AiString string (and length).
        /// </summary>
        /// <param name="data">String data to set</param>
        /// <returns>True if the operation was successful, false otherwise.</returns>
        public unsafe bool SetString(String data)
        {
            if (String.IsNullOrEmpty(data))
            {
                Length = new UIntPtr(0);

                fixed(byte *bytePtr = Data)
                MemoryHelper.ClearMemory(new IntPtr(bytePtr), 0, AiDefines.MAX_LENGTH);

                return(true);
            }

            //Note: aiTypes.h specifies aiString is UTF-8 encoded string.
            if (Encoding.UTF8.GetByteCount(data) <= AiDefines.MAX_LENGTH)
            {
                byte[] copy = Encoding.UTF8.GetBytes(data);

                //Write bytes to data field
                if (copy.Length > 0)
                {
                    fixed(byte *bytePtr = Data)
                    MemoryHelper.Write <byte>(new IntPtr(bytePtr), copy, 0, copy.Length);
                }

                Length = new UIntPtr((uint)copy.Length);

                return(true);
            }

            return(false);
        }
Пример #2
0
        /// <summary>
        /// Writes DDS formatted data to a stream. Image data is expected to be DXGI-compliant data, but an effort is made to write out D3D9-compatible headers when possible.
        /// </summary>
        /// <param name="output">Output stream.</param>
        /// <param name="mipChains">Mipmap chains to write. Each mipmap chain represents a single face (so > 1 represents an array texture or a Cubemap). All faces must have
        /// equivalent dimensions and each chain must have the same number of mipmaps.</param>
        /// <param name="format">DXGI format the image data is stored as.</param>
        /// <param name="texDim">Dimension of the texture to write.</param>
        /// <param name="flags">Flags to control how the DDS data is saved.</param>
        /// <returns>True if writing the data was successful, false if otherwise.</returns>
        public static bool Write(Stream output, List <MipChain> mipChains, DXGIFormat format, TextureDimension texDim, DDSFlags flags = DDSFlags.None)
        {
            if (output == null || !output.CanWrite || mipChains == null || mipChains.Count == 0 || mipChains[0].Count == 0 || format == DXGIFormat.Unknown)
            {
                return(false);
            }

            //Extract details
            int     width, height, depth, arrayCount, mipCount;
            MipData firstMip = mipChains[0][0];

            width      = firstMip.Width;
            height     = firstMip.Height;
            depth      = firstMip.Depth;
            arrayCount = mipChains.Count;
            mipCount   = mipChains[0].Count;

            if (!ValidateInternal(mipChains, format, texDim))
            {
                return(false);
            }

            //Setup a transfer buffer
            StreamTransferBuffer buffer = new StreamTransferBuffer(firstMip.RowPitch, false);

            //Write out header
            if (!WriteHeader(output, buffer, texDim, format, width, height, depth, arrayCount, mipCount, flags))
            {
                return(false);
            }

            //Iterate over each array face...
            for (int i = 0; i < arrayCount; i++)
            {
                MipChain mipChain = mipChains[i];

                //Iterate over each mip face...
                for (int mipLevel = 0; mipLevel < mipCount; mipLevel++)
                {
                    MipData mip = mipChain[mipLevel];

                    //Compute pitch, based on MSDN programming guide. We will write out these pitches rather than the supplied in order to conform to the recomendation
                    //that we compute pitch based on format
                    int realMipWidth, realMipHeight, dstRowPitch, dstSlicePitch, bytesPerPixel;
                    ImageHelper.ComputePitch(format, mip.Width, mip.Height, out dstRowPitch, out dstSlicePitch, out realMipWidth, out realMipHeight, out bytesPerPixel);

                    //Ensure write buffer is sufficiently sized for a single scanline
                    if (buffer.Length < dstRowPitch)
                    {
                        buffer.Resize(dstRowPitch, false);
                    }

                    //Sanity check
                    if (dstRowPitch < mip.RowPitch)
                    {
                        return(false);
                    }

                    IntPtr srcPtr = mip.Data;

                    //Advance stream one slice at a time...
                    for (int slice = 0; slice < mip.Depth; slice++)
                    {
                        int    bytesToWrite = dstSlicePitch;
                        IntPtr sPtr         = srcPtr;

                        //Copy scanline into temp buffer, write to output
                        for (int row = 0; row < realMipHeight; row++)
                        {
                            MemoryHelper.CopyMemory(buffer.Pointer, sPtr, dstRowPitch);
                            buffer.WriteBytes(output, dstRowPitch);
                            bytesToWrite -= dstRowPitch;

                            //Advance to next scanline in source data
                            sPtr = MemoryHelper.AddIntPtr(sPtr, mip.RowPitch);
                        }

                        //Pad slice if necessary
                        if (bytesToWrite > 0)
                        {
                            MemoryHelper.ClearMemory(buffer.Pointer, 0, bytesToWrite);
                            buffer.WriteBytes(output, bytesToWrite);
                        }

                        //Advance source pointer to next slice
                        srcPtr = MemoryHelper.AddIntPtr(srcPtr, mip.SlicePitch);
                    }
                }
            }

            return(true);
        }