Exemplo n.º 1
0
        protected static void FromD3DLock(PixelBox rval, DX.DataBox lbox)
        {
            var bpp  = PixelUtil.GetNumElemBytes(rval.Format);
            var size = 0;

            if (bpp != 0)
            {
                rval.RowPitch   = lbox.RowPitch / bpp;
                rval.SlicePitch = lbox.SlicePitch / bpp;
                Debug.Assert((lbox.RowPitch % bpp) == 0);
                Debug.Assert((lbox.SlicePitch % bpp) == 0);
                size = lbox.RowPitch * rval.Height;
            }
            else if (PixelUtil.IsCompressed(rval.Format))
            {
                rval.RowPitch   = rval.Width;
                rval.SlicePitch = rval.Width * rval.Height;
                size            = rval.Width * rval.Height;
            }
            else
            {
                throw new AxiomException("Invalid pixel format");
            }

            rval.Data = BufferBase.Wrap(lbox.DataPointer, size);
        }
Exemplo n.º 2
0
 ///<summary>
 ///    Util functions to convert a D3D locked rectangle to a pixel box
 ///</summary>
 protected static void FromD3DLock(PixelBox rval, int pitch, GraphicsStream stream)
 {
     rval.RowPitch   = pitch / PixelUtil.GetNumElemBytes(rval.Format);
     rval.SlicePitch = rval.RowPitch * rval.Height;
     Debug.Assert((pitch % PixelUtil.GetNumElemBytes(rval.Format)) == 0);
     rval.Data = stream.InternalData;
 }
Exemplo n.º 3
0
        protected void Download()
        {
#if !AXIOM_SAFE_ONLY
            unsafe
#endif
            {
                using (var pDst = BufferBase.Wrap(this.mData, mData.Length * sizeof(float)))
                {
                    var pDstPtr = pDst.ToFloatPointer();
                    var pDstIdx = 0;
                    //download data
                    var box     = new BasicBox(0, 0, this.mBuffer.Width, this.mBuffer.Height);
                    var pBox    = this.mBuffer.Lock(box, BufferLocking.ReadOnly);
                    var pSrc    = pBox.Data.ToBytePointer();
                    var pSrcIdx = (int)this.mChannelOffset;
                    var srcInc  = PixelUtil.GetNumElemBytes(this.mBuffer.Format);
                    for (var y = box.Top; y < box.Bottom; ++y)
                    {
                        for (var x = box.Left; x < box.Right; ++x)
                        {
                            pDstPtr[pDstIdx++] = (float)((pSrc[pSrcIdx]) / 255.0f);
                            pSrcIdx           += srcInc;
                        }
                    }
                    this.mBuffer.Unlock();
                }
            }
        }
Exemplo n.º 4
0
        public override void CopyContentsToMemory(PixelBox dst, FrameBuffer buffer)
        {
            if ((dst.Left < 0) || (dst.Right > Width) ||
                (dst.Top < 0) || (dst.Bottom > Height) ||
                (dst.Front != 0) || (dst.Back != 1))
            {
                throw new Exception("Invalid box.");
            }
            if (buffer == RenderTarget.FrameBuffer.Auto)
            {
                buffer = IsFullScreen ? RenderTarget.FrameBuffer.Front : RenderTarget.FrameBuffer.Back;
            }

            int format = GLPixelUtil.GetGLOriginFormat(dst.Format);
            int type   = GLPixelUtil.GetGLOriginDataType(dst.Format);

            if ((format == Gl.GL_NONE) || (type == 0))
            {
                throw new Exception("Unsupported format.");
            }


            // Switch context if different from current one
            RenderSystem rsys = Root.Instance.RenderSystem;

            rsys.Viewport = this.GetViewport(0);

            // Must change the packing to ensure no overruns!
            Gl.glPixelStorei(Gl.GL_PACK_ALIGNMENT, 1);

            Gl.glReadBuffer((buffer == RenderTarget.FrameBuffer.Front) ? Gl.GL_FRONT : Gl.GL_BACK);
            Gl.glReadPixels(dst.Left, dst.Top, dst.Width, dst.Height, format, type, dst.Data);

            // restore default alignment
            Gl.glPixelStorei(Gl.GL_PACK_ALIGNMENT, 4);

            //vertical flip

            {
                int    rowSpan = dst.Width * PixelUtil.GetNumElemBytes(dst.Format);
                int    height  = dst.Height;
                byte[] tmpData = new byte[rowSpan * height];
                unsafe
                {
                    var dataPtr = dst.Data.ToBytePointer();
                    //int *srcRow = (uchar *)dst.data, *tmpRow = tmpData + (height - 1) * rowSpan;

                    for (int row = height - 1, tmpRow = 0; row >= 0; row--, tmpRow++)
                    {
                        for (int col = 0; col < rowSpan; col++)
                        {
                            tmpData[tmpRow * rowSpan + col] = dataPtr[row * rowSpan + col];
                        }
                    }
                }
                var tmpDataHandle = BufferBase.Wrap(tmpData);
                Memory.Copy(tmpDataHandle, dst.Data, rowSpan * height);
            }
        }
Exemplo n.º 5
0
        public virtual void SetFormat(PixelFormat pf)
        {
            this.format        = pf;
            this.desiredFormat = pf;
            this.srcFormat     = pf;

            srcBpp = PixelUtil.GetNumElemBytes(pf);
        }
Exemplo n.º 6
0
 ///<summary>
 ///    Util functions to convert a D3D LockedBox to a pixel box
 ///</summary>
 protected static void FromD3DLock(PixelBox rval, D3D.LockedBox lbox, GraphicsStream stream)
 {
     rval.RowPitch   = lbox.RowPitch / PixelUtil.GetNumElemBytes(rval.Format);
     rval.SlicePitch = lbox.SlicePitch / PixelUtil.GetNumElemBytes(rval.Format);
     Debug.Assert((lbox.RowPitch % PixelUtil.GetNumElemBytes(rval.Format)) == 0);
     Debug.Assert((lbox.SlicePitch % PixelUtil.GetNumElemBytes(rval.Format)) == 0);
     rval.Data = stream.InternalData;
 }
Exemplo n.º 7
0
        public XnaImageCodecStream(WriteableBitmap texture)
        {
            ImageData.width  = texture.PixelWidth;
            ImageData.height = texture.PixelHeight;
            ImageData.format = PixelFormat.A8B8G8R8;
            var buffer = new byte[ImageData.width * ImageData.height * PixelUtil.GetNumElemBytes(ImageData.format)];

            Buffer.BlockCopy(texture.Pixels, 0, buffer, 0, buffer.Length);
            _stream = new MemoryStream(buffer);
            ImageData.numMipMaps = 1;
            ImageData.size       = buffer.Length;
        }
Exemplo n.º 8
0
        public XnaImageCodecStream(Texture2D texture)
        {
            ImageData.width  = texture.Width;
            ImageData.height = texture.Height;
            ImageData.format = XnaHelper.Convert(texture.Format);
            var buffer = new byte[ImageData.width * ImageData.height * PixelUtil.GetNumElemBytes(ImageData.format)];

            texture.GetData(buffer);
            _stream = new MemoryStream(buffer);
            ImageData.numMipMaps = 1;
            ImageData.size       = buffer.Length;
        }
Exemplo n.º 9
0
        public void WriteContentsToFile(string fileName)
        {
            var pf = SuggestPixelFormat();

            var data = new byte[Width * Height * PixelUtil.GetNumElemBytes(pf)];
            var buf  = BufferBase.Wrap(data);
            var pb   = new PixelBox(Width, Height, 1, pf, buf);

            CopyContentsToMemory(pb);

            (new Image()).FromDynamicImage(data, Width, Height, 1, pf, false, 1, 0).Save(fileName);
            buf.Dispose();
        }
Exemplo n.º 10
0
 public HardwarePixelBuffer(int width, int height, int depth, Axiom.Media.PixelFormat format, BufferUsage usage,
                            bool useSystemMemory, bool useShadowBuffer)
     : base(usage, useSystemMemory, useShadowBuffer)
 {
     this.width  = width;
     this.height = height;
     this.depth  = depth;
     this.format = format;
     // Default
     this.rowPitch   = width;
     this.slicePitch = height * width;
     sizeInBytes     = height * width * PixelUtil.GetNumElemBytes(format);
 }
Exemplo n.º 11
0
        protected override void download(PixelBox data)
        {
            if (data.Width != Width || data.Height != Height || data.Depth != Depth)
            {
                throw new ArgumentException("only download of entire buffer is supported by GL");
            }

            Gl.glBindTexture(this._target, this._textureId);
            if (PixelUtil.IsCompressed(data.Format))
            {
                if (data.Format != Format || !data.IsConsecutive)
                {
                    throw new ArgumentException("Compressed images must be consecutive, in the source format");
                }
                // Data must be consecutive and at beginning of buffer as PixelStorei not allowed
                // for compressed formate
                Gl.glGetCompressedTexImageARB(this._faceTarget, this._level, data.Data.Pin());
                data.Data.UnPin();
            }
            else
            {
                if (data.Width != data.RowPitch)
                {
                    Gl.glPixelStorei(Gl.GL_PACK_ROW_LENGTH, data.RowPitch);
                }
                if (data.Height * data.Width != data.SlicePitch)
                {
                    Gl.glPixelStorei(Gl.GL_PACK_IMAGE_HEIGHT, (data.SlicePitch / data.Width));
                }
                if (((data.Width * PixelUtil.GetNumElemBytes(data.Format)) & 3) != 0)
                {
                    // Standard alignment of 4 is not right
                    Gl.glPixelStorei(Gl.GL_PACK_ALIGNMENT, 1);
                }
                // We can only get the entire texture
                Gl.glGetTexImage(this._faceTarget, this._level, GLPixelUtil.GetGLOriginFormat(data.Format),
                                 GLPixelUtil.GetGLOriginDataType(data.Format), data.Data.Pin());
                data.Data.UnPin();
                // Restore defaults
                Gl.glPixelStorei(Gl.GL_PACK_ROW_LENGTH, 0);
                Gl.glPixelStorei(Gl.GL_PACK_IMAGE_HEIGHT, 0);
                Gl.glPixelStorei(Gl.GL_PACK_ALIGNMENT, 4);
            }
        }
Exemplo n.º 12
0
        public void Update()
        {
            if (this.mData != null && this.mDirty)
            {
                using (var mDataBuf = BufferBase.Wrap(this.mData, mData.Length * sizeof(float)))
                {
                    var pSrcBase = mDataBuf + (this.mDirtyBox.Top * this.mBuffer.Width + this.mDirtyBox.Left);
                    var pDstBase = this.mBuffer.Lock(this.mDirtyBox, BufferLocking.Normal).Data;
                    pDstBase += this.mChannelOffset;
                    var dstInc = PixelUtil.GetNumElemBytes(this.mBuffer.Format);

#if !AXIOM_SAFE_ONLY
                    unsafe
#endif
                    {
                        for (int y = 0; y < this.mDirtyBox.Height; ++y)
                        {
                            var pSrc = (pSrcBase + (y * this.mBuffer.Width) * sizeof(float)).ToFloatPointer();
                            var pDst = pDstBase + (y * this.mBuffer.Width * dstInc);
                            for (int x = 0; x < this.mDirtyBox.Width; ++x)
                            {
                                pDst.ToBytePointer()[0] = (byte)(pSrc[x] * 255);
                                pDst += dstInc;
                            }
                        }
                    }

                    this.mBuffer.Unlock();
                    this.mDirty = false;
                }

                // make sure composite map is updated
                // mDirtyBox is in image space, convert to terrain units
                var compositeMapRect = new Rectangle();
                var blendToTerrain   = (float)this.mParent.Size / (float)this.mBuffer.Width;
                compositeMapRect.Left   = (long)(this.mDirtyBox.Left * blendToTerrain);
                compositeMapRect.Right  = (long)(this.mDirtyBox.Right * blendToTerrain + 1);
                compositeMapRect.Top    = (long)((this.mBuffer.Height - this.mDirtyBox.Bottom) * blendToTerrain);
                compositeMapRect.Bottom = (long)((this.mBuffer.Height - this.mDirtyBox.Top) * blendToTerrain + 1);
                this.mParent.DirtyCompositeMapRect(compositeMapRect);
                this.mParent.UpdateCompositeMapWithDelay();
            }
        }
Exemplo n.º 13
0
        public EditableImage(string name, int width, int height, PixelFormat format, ColorEx color, int numMipMaps, bool isAlpha)
        {
            this.width       = width;
            this.height      = height;
            this.format      = format;
            this.textureName = name;
            this.numMipMaps  = numMipMaps;
            this.isAlpha     = isAlpha;

            bytesPerPixel = PixelUtil.GetNumElemBytes(format);
            stride        = bytesPerPixel * width;

            pixelData = new byte[width * height * bytesPerPixel];

            // this will pin the buffer
            image = Image.FromDynamicImage(pixelData, width, height, format);

            Fill(0, 0, width, height, color);
        }
Exemplo n.º 14
0
        ///<summary>
        ///    Call this to associate a Xna Texture2D with this pixel buffer
        ///</summary>
        public void Bind(GraphicsDevice device, Texture2D surface, ushort miplevel, bool update)
        {
            this.device  = device;
            this.surface = surface;
            mipLevel     = miplevel;

            width  = surface.Width / (int)Utility.Pow(2, mipLevel);
            height = surface.Height / (int)Utility.Pow(2, mipLevel);
            depth  = 1;
            format = XnaHelper.Convert(surface.Format);
            // Default
            rowPitch    = Width * PixelUtil.GetNumElemBytes(Format);
            slicePitch  = Height * RowPitch;
            sizeInBytes = PixelUtil.GetMemorySize(Width, Height, Depth, Format);

            if (((int)usage & (int)TextureUsage.RenderTarget) != 0)
            {
                CreateRenderTextures(update);
            }
        }
Exemplo n.º 15
0
        public TerrainLayerBlendMap(Terrain parent, byte layerIdx, HardwarePixelBuffer buf)
        {
            this.mParent   = parent;
            this.mLayerIdx = layerIdx;
            this.mChannel  = (byte)((this.mLayerIdx - 1) % 4);
            this.mDirty    = false;
            this.mBuffer   = buf;
            this.mData     = new float[this.mBuffer.Width * this.mBuffer.Height * sizeof(float)];

            // we know which of RGBA we need to look at, now find it in the format
            // because we can't guarantee what precise format the RS gives us
            PixelFormat fmt       = this.mBuffer.Format;
            var         rgbaShift = PixelUtil.GetBitShifts(fmt);

            this.mChannelOffset = (byte)(rgbaShift[this.mChannel] / 8); // /8 convert to bytes
#if AXIOM_BIG_ENDIAN
            // invert (dealing bytewise)
            mChannelOffset = (byte)(PixelUtil.GetNumElemBytes(fmt) - mChannelOffset - 1);
#endif
            Download();
        }
        /// <summary>
        ///     Get an appropriately defined 'null' texture, ie one which will always
        ///     result in no shadows.
        /// </summary>
        public Texture GetNullShadowTexture(PixelFormat format)
        {
            foreach (Texture tex in nullTextureList)
            {
                if (format == tex.Format)
                {
                    // Ok, a match
                    return(tex);
                }
            }

            // not found, create a new one
            // A 1x1 texture of the correct format, not a render target
            string  baseName  = "Axiom/ShadowTextureNull";
            string  targName  = baseName + count++;
            Texture shadowTex = TextureManager.Instance.CreateManual(
                targName,
                TextureType.TwoD, 1, 1, 1, 0, format, TextureUsage.Default);

            nullTextureList.Add(shadowTex);

            // Populate the texture based on format
            int byteCount = PixelUtil.GetNumElemBytes(format);

            unsafe {
                byte [] bytes = new byte[byteCount];
                for (int i = 0; i < byteCount; i++)
                    bytes[i] = 0xff;
                fixed(byte *fixedBytes = &bytes[0])
                {
                    PixelBox bytesPixelBox = new PixelBox(1, 1, 1, format, new IntPtr(fixedBytes));

                    shadowTex.GetBuffer().BlitFromMemory(bytesPixelBox);
                }
            }
            return(shadowTex);
        }
Exemplo n.º 17
0
        protected override void Download(PixelBox data)
        {
#if GL_NV_get_tex_image
            if (data.Width != Width || data.Height != Height || data.Depth != Depth)
            {
                throw new Core.AxiomException("only download of entire buffer is supported by GL");
            }

            GL.BindTexture(this.target, this.textureID);
            if (PixelUtil.IsCompressed(data.Format))
            {
                if (data.Format != format || !data.IsConsecutive)
                {
                    throw new Core.AxiomException("Compressed images must be consecutive, in the source format");
                }

                GL.GetCompressedTexImageNV(this.faceTarget, this.level, data.Data);
            }
            else
            {
                if ((data.Width * PixelUtil.GetNumElemBytes(data.Format) & 3) != 0)
                {
                    //Standard alignment of 4 is not right
                    GL.PixelStore(Glenum.PackAlignment, 1);
                }

                //We can only get the entire texture
                GL.GetTexImageNV(this.faceTarget, this.level, GLES2PixelUtil.GetGLOriginFormat(data.Format), GLES2PixelUtil.GetGLOriginDataType(data.Format), data.Data);

                //Restore defaults
                GL.PixelStore(Glenum.PackAlignment, 4);
            }
#else
            throw new Core.AxiomException("Downloading texture buffers is not supported by OpenGL ES");
#endif
        }
Exemplo n.º 18
0
        internal static unsafe void ClearTexture(Texture texture, Colour colour)
        {
            using (HardwarePixelBufferSharedPtr hbuf = texture.GetBuffer())
            {
                hbuf.Lock(HardwareBuffer.LockOptions.HBL_NORMAL);
                PixelBox pb = hbuf.CurrentLock;

                byte *destData          = (byte *)pb.data;
                uint  destPixelSize     = PixelUtil.GetNumElemBytes(pb.format);
                uint  destRowPitchBytes = pb.rowPitch * destPixelSize;

                ColourValue cv = new ColourValue(colour.Red / 255f, colour.Green / 255f, colour.Blue / 255f, colour.Alpha / 255f);
                for (uint i = 0; i < texture.Height; i++)
                {
                    for (uint j = 0; j < texture.Width; j++)
                    {
                        uint offset = (i * destRowPitchBytes) + (j * destPixelSize);
                        PixelUtil.PackColour(cv, pb.format, &destData[offset]);
                    }
                }

                hbuf.Unlock();
            }
        }
Exemplo n.º 19
0
        public override Codec.DecodeResult Decode(Stream input)
        {
            // Buffer stream into memory (TODO: override IO functions instead?)
            var data = new byte[(int)input.Length];

            input.Read(data, 0, data.Length);
            FI.FIMEMORY          fiMem;
            FI.FREE_IMAGE_FORMAT ff;
            FI.FIBITMAP          fiBitmap;
            using (var datPtr = BufferBase.Wrap(data))
            {
                fiMem = FI.FreeImage.OpenMemory(datPtr.Pin(), (uint)data.Length);
                datPtr.UnPin();
                ff       = (FI.FREE_IMAGE_FORMAT) this._freeImageType;
                fiBitmap = FI.FreeImage.LoadFromMemory((FI.FREE_IMAGE_FORMAT) this._freeImageType, fiMem,
                                                       FI.FREE_IMAGE_LOAD_FLAGS.DEFAULT);
            }

            if (fiBitmap.IsNull)
            {
                throw new AxiomException("Error decoding image");
            }

            var imgData = new ImageData();

            imgData.depth      = 1; // only 2D formats handled by this codec
            imgData.width      = (int)FI.FreeImage.GetWidth(fiBitmap);
            imgData.height     = (int)FI.FreeImage.GetHeight(fiBitmap);
            imgData.numMipMaps = 0; // no mipmaps in non-DDS

            // Must derive format first, this may perform conversions
            var imageType = FI.FreeImage.GetImageType(fiBitmap);
            var colorType = FI.FreeImage.GetColorType(fiBitmap);
            var bpp       = (int)FI.FreeImage.GetBPP(fiBitmap);

            switch (imageType)
            {
            case FI.FREE_IMAGE_TYPE.FIT_UNKNOWN:
            case FI.FREE_IMAGE_TYPE.FIT_COMPLEX:
            case FI.FREE_IMAGE_TYPE.FIT_UINT32:
            case FI.FREE_IMAGE_TYPE.FIT_INT32:
            case FI.FREE_IMAGE_TYPE.FIT_DOUBLE:
            default:
                throw new AxiomException("Unknown or unsupported image format");

            case FI.FREE_IMAGE_TYPE.FIT_BITMAP:
                // Standard image type
                // Perform any colour conversions for greyscale
                if (colorType == FI.FREE_IMAGE_COLOR_TYPE.FIC_MINISWHITE || colorType == FI.FREE_IMAGE_COLOR_TYPE.FIC_MINISBLACK)
                {
                    var newBitmap = FI.FreeImage.ConvertToGreyscale(fiBitmap);
                    // free old bitmap and replace
                    FI.FreeImage.Unload(fiBitmap);
                    fiBitmap = newBitmap;
                    // get new formats
                    bpp       = (int)FI.FreeImage.GetBPP(fiBitmap);
                    colorType = FI.FreeImage.GetColorType(fiBitmap);
                }
                // Perform any colour conversions for RGB
                else if (bpp < 8 || colorType == FI.FREE_IMAGE_COLOR_TYPE.FIC_PALETTE ||
                         colorType == FI.FREE_IMAGE_COLOR_TYPE.FIC_CMYK)
                {
                    var newBitmap = FI.FreeImage.ConvertTo24Bits(fiBitmap);
                    // free old bitmap and replace
                    FI.FreeImage.Unload(fiBitmap);
                    fiBitmap = newBitmap;
                    // get new formats
                    bpp       = (int)FI.FreeImage.GetBPP(fiBitmap);
                    colorType = FI.FreeImage.GetColorType(fiBitmap);
                }

                // by this stage, 8-bit is greyscale, 16/24/32 bit are RGB[A]
                switch (bpp)
                {
                case 8:
                    imgData.format = PixelFormat.L8;
                    break;

                case 16:
                    // Determine 555 or 565 from green mask
                    // cannot be 16-bit greyscale since that's FIT_UINT16
                    if (FI.FreeImage.GetGreenMask(fiBitmap) == FI.FreeImage.FI16_565_GREEN_MASK)
                    {
                        imgData.format = PixelFormat.R5G6B5;
                    }
                    else
                    {
                        // FreeImage doesn't support 4444 format so must be 1555
                        imgData.format = PixelFormat.A1R5G5B5;
                    }
                    break;

                case 24:
                    // FreeImage differs per platform
                    //     PixelFormat.BYTE_BGR[A] for little endian (== PixelFormat.ARGB native)
                    //     PixelFormat.BYTE_RGB[A] for big endian (== PixelFormat.RGBA native)
                    if (FI.FreeImage.IsLittleEndian())
                    {
                        imgData.format = PixelFormat.BYTE_BGR;
                    }
                    else
                    {
                        imgData.format = PixelFormat.BYTE_RGB;
                    }
                    break;

                case 32:
                    if (FI.FreeImage.IsLittleEndian())
                    {
                        imgData.format = PixelFormat.BYTE_BGRA;
                    }
                    else
                    {
                        imgData.format = PixelFormat.BYTE_RGBA;
                    }
                    break;
                }
                ;
                break;

            case FI.FREE_IMAGE_TYPE.FIT_UINT16:
            case FI.FREE_IMAGE_TYPE.FIT_INT16:
                // 16-bit greyscale
                imgData.format = PixelFormat.L16;
                break;

            case FI.FREE_IMAGE_TYPE.FIT_FLOAT:
                // Single-component floating point data
                imgData.format = PixelFormat.FLOAT32_R;
                break;

            case FI.FREE_IMAGE_TYPE.FIT_RGB16:
                imgData.format = PixelFormat.SHORT_RGB;
                break;

            case FI.FREE_IMAGE_TYPE.FIT_RGBA16:
                imgData.format = PixelFormat.SHORT_RGBA;
                break;

            case FI.FREE_IMAGE_TYPE.FIT_RGBF:
                imgData.format = PixelFormat.FLOAT32_RGB;
                break;

            case FI.FREE_IMAGE_TYPE.FIT_RGBAF:
                imgData.format = PixelFormat.FLOAT32_RGBA;
                break;
            }

            var srcPitch = (int)FI.FreeImage.GetPitch(fiBitmap);

            // Final data - invert image and trim pitch at the same time
            var dstPitch = imgData.width * PixelUtil.GetNumElemBytes(imgData.format);

            imgData.size = dstPitch * imgData.height;
            // Bind output buffer
            var outputData = new byte[imgData.size];

            using (var srcData = BufferBase.Wrap(FI.FreeImage.GetBits(fiBitmap), imgData.height * srcPitch))
            {
                var pDst = BufferBase.Wrap(outputData);

                for (var y = 0; y < imgData.height; ++y)
                {
                    using (var pSrc = srcData + (imgData.height - y - 1) * srcPitch)
                    {
                        Memory.Copy(pSrc, pDst, dstPitch);
                        pDst += dstPitch;
                    }
                }

                pDst.Dispose();
            }

            FI.FreeImage.Unload(fiBitmap);
            FI.FreeImage.CloseMemory(fiMem);

            return(new Codec.DecodeResult(new MemoryStream(outputData), imgData));
        }
Exemplo n.º 20
0
        private FI.FIBITMAP _encode(Stream input, CodecData codecData)
        {
            var ret = new FI.FIBITMAP();

            ret.SetNull();
            var imgData = codecData as ImageData;

            if (imgData != null)
            {
                var data = new byte[(int)input.Length];
                input.Read(data, 0, data.Length);
                var dataPtr = BufferBase.Wrap(data);
                var src     = new PixelBox(imgData.width, imgData.height, imgData.depth, imgData.format, dataPtr);

                // The required format, which will adjust to the format
                // actually supported by FreeImage.
                var requiredFormat = imgData.format;

                // determine the settings
                var imageType         = FI.FREE_IMAGE_TYPE.FIT_UNKNOWN;
                var determiningFormat = imgData.format;

                switch (determiningFormat)
                {
                case PixelFormat.R5G6B5:
                case PixelFormat.B5G6R5:
                case PixelFormat.R8G8B8:
                case PixelFormat.B8G8R8:
                case PixelFormat.A8R8G8B8:
                case PixelFormat.X8R8G8B8:
                case PixelFormat.A8B8G8R8:
                case PixelFormat.X8B8G8R8:
                case PixelFormat.B8G8R8A8:
                case PixelFormat.R8G8B8A8:
                case PixelFormat.A4L4:
                case PixelFormat.BYTE_LA:
                case PixelFormat.R3G3B2:
                case PixelFormat.A4R4G4B4:
                case PixelFormat.A1R5G5B5:
                case PixelFormat.A2R10G10B10:
                case PixelFormat.A2B10G10R10:
                    // I'd like to be able to use r/g/b masks to get FreeImage to load the data
                    // in it's existing format, but that doesn't work, FreeImage needs to have
                    // data in RGB[A] (big endian) and BGR[A] (little endian), always.
                    if (PixelUtil.HasAlpha(determiningFormat))
                    {
                        if (FI.FreeImageEngine.IsLittleEndian)
                        {
                            requiredFormat = PixelFormat.BYTE_BGRA;
                        }
                        else
                        {
                            requiredFormat = PixelFormat.BYTE_RGBA;
                        }
                    }
                    else
                    {
                        if (FI.FreeImageEngine.IsLittleEndian)
                        {
                            requiredFormat = PixelFormat.BYTE_BGR;
                        }
                        else
                        {
                            requiredFormat = PixelFormat.BYTE_RGB;
                        }
                    }
                    imageType = FI.FREE_IMAGE_TYPE.FIT_BITMAP;
                    break;

                case PixelFormat.L8:
                case PixelFormat.A8:
                    imageType = FI.FREE_IMAGE_TYPE.FIT_BITMAP;
                    break;

                case PixelFormat.L16:
                    imageType = FI.FREE_IMAGE_TYPE.FIT_UINT16;
                    break;

                case PixelFormat.SHORT_GR:
                    requiredFormat = PixelFormat.SHORT_RGB;
                    break;

                case PixelFormat.SHORT_RGB:
                    imageType = FI.FREE_IMAGE_TYPE.FIT_RGB16;
                    break;

                case PixelFormat.SHORT_RGBA:
                    imageType = FI.FREE_IMAGE_TYPE.FIT_RGBA16;
                    break;

                case PixelFormat.FLOAT16_R:
                    requiredFormat = PixelFormat.FLOAT32_R;
                    break;

                case PixelFormat.FLOAT32_R:
                    imageType = FI.FREE_IMAGE_TYPE.FIT_FLOAT;
                    break;

                case PixelFormat.FLOAT16_GR:
                case PixelFormat.FLOAT16_RGB:
                case PixelFormat.FLOAT32_GR:
                    requiredFormat = PixelFormat.FLOAT32_RGB;
                    break;

                case PixelFormat.FLOAT32_RGB:
                    imageType = FI.FREE_IMAGE_TYPE.FIT_RGBF;
                    break;

                case PixelFormat.FLOAT16_RGBA:
                    requiredFormat = PixelFormat.FLOAT32_RGBA;
                    break;

                case PixelFormat.FLOAT32_RGBA:
                    imageType = FI.FREE_IMAGE_TYPE.FIT_RGBAF;
                    break;

                default:
                    throw new AxiomException("Not Supported image format :{0}", determiningFormat.ToString());
                } //end switch

                // Check support for this image type & bit depth
                if (!FI.FreeImage.FIFSupportsExportType((FI.FREE_IMAGE_FORMAT) this._freeImageType, imageType) ||
                    !FI.FreeImage.FIFSupportsExportBPP((FI.FREE_IMAGE_FORMAT) this._freeImageType,
                                                       PixelUtil.GetNumElemBits(requiredFormat)))
                {
                    // Ok, need to allocate a fallback
                    // Only deal with RGBA . RGB for now
                    switch (requiredFormat)
                    {
                    case PixelFormat.BYTE_RGBA:
                        requiredFormat = PixelFormat.BYTE_RGB;
                        break;

                    case PixelFormat.BYTE_BGRA:
                        requiredFormat = PixelFormat.BYTE_BGR;
                        break;

                    default:
                        break;
                    }
                }

                var conversionRequired = false;
                input.Position = 0;
                var srcData = new byte[(int)input.Length];
                input.Read(srcData, 0, srcData.Length);
                var srcDataPtr = BufferBase.Wrap(srcData);

                // Check BPP
                var bpp = PixelUtil.GetNumElemBits(requiredFormat);
                if (!FI.FreeImage.FIFSupportsExportBPP((FI.FREE_IMAGE_FORMAT) this._freeImageType, bpp))
                {
                    if (bpp == 32 && PixelUtil.HasAlpha(imgData.format) &&
                        FI.FreeImage.FIFSupportsExportBPP((FI.FREE_IMAGE_FORMAT) this._freeImageType, 24))
                    {
                        // drop to 24 bit (lose alpha)
                        if (FI.FreeImage.IsLittleEndian())
                        {
                            requiredFormat = PixelFormat.BYTE_BGR;
                        }
                        else
                        {
                            requiredFormat = PixelFormat.BYTE_RGB;
                        }

                        bpp = 24;
                    }
                    else if (bpp == 128 && PixelUtil.HasAlpha(imgData.format) &&
                             FI.FreeImage.FIFSupportsExportBPP((FI.FREE_IMAGE_FORMAT) this._freeImageType, 96))
                    {
                        // drop to 96-bit floating point
                        requiredFormat = PixelFormat.FLOAT32_RGB;
                    }
                }

                var convBox = new PixelBox(imgData.width, imgData.height, 1, requiredFormat);
                if (requiredFormat != imgData.format)
                {
                    conversionRequired = true;
                    // Allocate memory
                    var convData = new byte[convBox.ConsecutiveSize];
                    convBox.Data = BufferBase.Wrap(convData);
                    // perform conversion and reassign source
                    var newSrc = new PixelBox(imgData.width, imgData.height, 1, imgData.format, dataPtr);
                    PixelConverter.BulkPixelConversion(newSrc, convBox);
                    srcDataPtr = convBox.Data;
                }

                ret = FI.FreeImage.AllocateT(imageType, imgData.width, imgData.height, bpp);
                if (ret.IsNull)
                {
                    if (conversionRequired)
                    {
                        srcDataPtr.SafeDispose();
                        convBox = null;
                    }

                    throw new AxiomException("FreeImage.AllocateT failed - possibly out of memory. ");
                }

                if (requiredFormat == PixelFormat.L8 || requiredFormat == PixelFormat.A8)
                {
                    // Must explicitly tell FreeImage that this is greyscale by setting
                    // a "grey" palette (otherwise it will save as a normal RGB
                    // palettized image).
                    var tmp = FI.FreeImage.ConvertToGreyscale(ret);
                    FI.FreeImage.Unload(ret);
                    ret = tmp;
                }

                var dstPitch = (int)FI.FreeImage.GetPitch(ret);
                var srcPitch = imgData.width * PixelUtil.GetNumElemBytes(requiredFormat);

                // Copy data, invert scanlines and respect FreeImage pitch
                var pSrc = srcDataPtr;
                using (var pDest = BufferBase.Wrap(FI.FreeImage.GetBits(ret), imgData.height * srcPitch))
                {
                    var byteSrcData = pSrc;
                    var byteDstData = pDest;
                    for (var y = 0; y < imgData.height; ++y)
                    {
                        byteSrcData += (imgData.height - y - 1) * srcPitch;
                        Memory.Copy(pSrc, pDest, srcPitch);
                        byteDstData += dstPitch;
                    }
                }

                if (conversionRequired)
                {
                    // delete temporary conversion area
                    srcDataPtr.SafeDispose();
                    convBox = null;
                }
            }
            return(ret);
        }
Exemplo n.º 21
0
        protected override void upload(PixelBox box)
        {
            Gl.glBindTexture(this._target, this._textureId);
            if (PixelUtil.IsCompressed(box.Format))
            {
                if (box.Format != Format || !box.IsConsecutive)
                {
                    throw new ArgumentException("Compressed images must be consecutive, in the source format");
                }

                int format = GLPixelUtil.GetClosestGLInternalFormat(Format);
                // Data must be consecutive and at beginning of buffer as PixelStorei not allowed
                // for compressed formats
                switch (this._target)
                {
                case Gl.GL_TEXTURE_1D:
                    Gl.glCompressedTexSubImage1DARB(Gl.GL_TEXTURE_1D, this._level, box.Left, box.Width, format, box.ConsecutiveSize,
                                                    box.Data.Pin());
                    box.Data.UnPin();
                    break;

                case Gl.GL_TEXTURE_2D:
                case Gl.GL_TEXTURE_CUBE_MAP:
                    Gl.glCompressedTexSubImage2DARB(this._faceTarget, this._level, box.Left, box.Top, box.Width, box.Height, format,
                                                    box.ConsecutiveSize, box.Data.Pin());
                    box.Data.UnPin();
                    break;

                case Gl.GL_TEXTURE_3D:
                    Gl.glCompressedTexSubImage3DARB(Gl.GL_TEXTURE_3D, this._level, box.Left, box.Top, box.Front, box.Width,
                                                    box.Height,
                                                    box.Depth, format, box.ConsecutiveSize, box.Data.Pin());
                    box.Data.UnPin();
                    break;
                }
            }
            else if (this._softwareMipmap)
            {
                int internalFormat;
                Gl.glGetTexLevelParameteriv(this._target, this._level, Gl.GL_TEXTURE_INTERNAL_FORMAT, out internalFormat);
                if (box.Width != box.RowPitch)
                {
                    Gl.glPixelStorei(Gl.GL_UNPACK_ROW_LENGTH, box.RowPitch);
                }
                if (box.Height * box.Width != box.SlicePitch)
                {
                    Gl.glPixelStorei(Gl.GL_UNPACK_IMAGE_HEIGHT, (box.SlicePitch / box.Width));
                }
                Gl.glPixelStorei(Gl.GL_UNPACK_ALIGNMENT, 1);

                switch (this._target)
                {
                case Gl.GL_TEXTURE_1D:
                    Glu.gluBuild1DMipmaps(Gl.GL_TEXTURE_1D, internalFormat, box.Width, GLPixelUtil.GetGLOriginFormat(box.Format),
                                          GLPixelUtil.GetGLOriginDataType(box.Format), box.Data.Pin());
                    box.Data.UnPin();
                    break;

                case Gl.GL_TEXTURE_2D:
                case Gl.GL_TEXTURE_CUBE_MAP:
                    Glu.gluBuild2DMipmaps(this._faceTarget, internalFormat, box.Width, box.Height,
                                          GLPixelUtil.GetGLOriginFormat(box.Format), GLPixelUtil.GetGLOriginDataType(box.Format),
                                          box.Data.Pin());
                    box.Data.UnPin();
                    break;

                case Gl.GL_TEXTURE_3D:
                    /* Requires GLU 1.3 which is harder to come by than cards doing hardware mipmapping
                     *                              Most 3D textures don't need mipmaps?
                     *                      Gl.gluBuild3DMipmaps(
                     *                              Gl.GL_TEXTURE_3D, internalFormat,
                     *                              box.getWidth(), box.getHeight(), box.getDepth(),
                     *                              GLPixelUtil.getGLOriginFormat(box.format), GLPixelUtil.getGLOriginDataType(box.format),
                     *                              box.box);
                     */
                    Gl.glTexImage3D(Gl.GL_TEXTURE_3D, 0, internalFormat, box.Width, box.Height, box.Depth, 0,
                                    GLPixelUtil.GetGLOriginFormat(box.Format), GLPixelUtil.GetGLOriginDataType(box.Format),
                                    box.Data.Pin());
                    box.Data.UnPin();
                    break;
                }
            }
            else
            {
                if (box.Width != box.RowPitch)
                {
                    Gl.glPixelStorei(Gl.GL_UNPACK_ROW_LENGTH, box.RowPitch);
                }
                if (box.Height * box.Width != box.SlicePitch)
                {
                    Gl.glPixelStorei(Gl.GL_UNPACK_IMAGE_HEIGHT, (box.SlicePitch / box.Width));
                }
                if (((box.Width * PixelUtil.GetNumElemBytes(box.Format)) & 3) != 0)
                {
                    // Standard alignment of 4 is not right
                    Gl.glPixelStorei(Gl.GL_UNPACK_ALIGNMENT, 1);
                }
                switch (this._target)
                {
                case Gl.GL_TEXTURE_1D:
                    Gl.glTexSubImage1D(Gl.GL_TEXTURE_1D, this._level, box.Left, box.Width,
                                       GLPixelUtil.GetGLOriginFormat(box.Format),
                                       GLPixelUtil.GetGLOriginDataType(box.Format), box.Data.Pin());
                    box.Data.UnPin();
                    break;

                case Gl.GL_TEXTURE_2D:
                case Gl.GL_TEXTURE_CUBE_MAP:
                    Gl.glTexSubImage2D(this._faceTarget, this._level, box.Left, box.Top, box.Width, box.Height,
                                       GLPixelUtil.GetGLOriginFormat(box.Format), GLPixelUtil.GetGLOriginDataType(box.Format),
                                       box.Data.Pin());
                    box.Data.UnPin();
                    break;

                case Gl.GL_TEXTURE_3D:
                    Gl.glTexSubImage3D(Gl.GL_TEXTURE_3D, this._level, box.Left, box.Top, box.Front, box.Width, box.Height, box.Depth,
                                       GLPixelUtil.GetGLOriginFormat(box.Format), GLPixelUtil.GetGLOriginDataType(box.Format),
                                       box.Data.Pin());
                    box.Data.UnPin();
                    break;
                }
            }
            // Restore defaults
            Gl.glPixelStorei(Gl.GL_UNPACK_ROW_LENGTH, 0);
            Gl.glPixelStorei(Gl.GL_UNPACK_IMAGE_HEIGHT, 0);
            Gl.glPixelStorei(Gl.GL_UNPACK_ALIGNMENT, 4);
        }
        private void CreateTileData()
        {
            if (textureName.Equals("zero.png"))
            {
                textureName = string.Format("{0}_x{1}y{2}.{3}", parent.BaseName, m_tileLocationX, m_loadTileZ,
                                            parent.MosaicDesc.FileExt);
            }

            Image   textureImage;
            Texture texture = TextureManager.Instance.GetByName(textureName);

            if (ResourceManager.HasCommonResourceData(textureName))
            {
                Stream s = ResourceManager.FindCommonResourceData(textureName);
                textureImage = Image.FromStream(s, parent.MosaicDesc.FileExt);
                s.Close();
            }
            else
            {
                // Create a new image
                int    bpp    = PixelUtil.GetNumElemBytes(DEFAULT_IMAGE_FORMAT);
                byte[] buffer = new byte[tileSizeSamples * tileSizeSamples * bpp];
                textureImage = Image.FromDynamicImage(buffer, tileSizeSamples, tileSizeSamples, DEFAULT_IMAGE_FORMAT);
                Modified     = true;
            }

            // Cause the texture image to get refreshed
            dirtyImage       = true;
            dirtyArea.X      = 0;
            dirtyArea.Y      = 0;
            dirtyArea.Width  = textureImage.Width;
            dirtyArea.Height = textureImage.Height;

            // Popupate the tileData from the image
            switch (textureImage.Format)
            {
            case PixelFormat.A8:
            case PixelFormat.L8:
                tileData = new TileData8(textureImage);
                break;

            case PixelFormat.L16:
                tileData = new TileData16(textureImage);
                break;

            case PixelFormat.R8G8B8:
            case PixelFormat.B8G8R8:
                tileData = new TileData24(textureImage);
                break;

            case PixelFormat.A8B8G8R8:
            case PixelFormat.A8R8G8B8:
            case PixelFormat.B8G8R8A8:
            case PixelFormat.R8G8B8A8:
            case PixelFormat.X8R8G8B8:
            case PixelFormat.X8B8G8R8:
                tileData = new TileData32(textureImage);
                break;

            default:
                throw new InvalidDataException("Unexpected pixel format: " + textureImage.Format);
            }
        }
        public void RefreshTexture()
        {
            if (tileData != null && dirtyImage)
            {
                EnsureTextureIsDynamic(); // Unload texture & recreate if needed

                Texture texture = TextureManager.Instance.GetByName(textureName);
                if (texture == null)
                {
                    // We couldn't find the texture.  It might be that we're in
                    // the midst of swapping them at the DirectX level (this is
                    // only speculation)
                    return;
                }

                if (texture is D3DTexture)
                {
                    // Turns out that to get performance, not only did I have to go
                    // straight to DirectX, unsafe code is much faster as well.  What
                    // we're doing here is keeping a temporary surface around that we
                    // can lock and draw to at our leisure, then copying the surface
                    // over to the correct texture data when we're done.  To do this,
                    // the easiest way is to lock the desired rectangle on the temp
                    // surface, and get a graphics stream object back from it.  You
                    // might think you could then use byte arrays, or even ask for
                    // an Array of bytes back from LockRectangle, but not only was
                    // that slower, it also produced unpredictable results, possibly
                    // due to storing the array in row order vs. column order in the
                    // native vs. managed areas.
                    //
                    // The temporary surface is necessary because, well, I could
                    // never seem to acquire the lock on the real surface.  However,
                    // an offscreen plain surface (as used above) seems to lock fine.
                    //
                    // Next caveat: The pointer on the graphics stream points to the
                    // start of the row of the locked rectangle.  You'd be surprised
                    // how long it took me to figure that one out.  Further, it's
                    // important to use the pitch returned by LockRectangle to adjust
                    // your row array position, as the pitch may or may not be your
                    // surface width in bytes.  (Some drivers store extra data on the
                    // ends of the rows, it seems.)
                    Rectangle lockRect = new Rectangle();
                    lockRect.X      = dirtyArea.X;
                    lockRect.Y      = dirtyArea.Y;
                    lockRect.Width  = dirtyArea.Width;
                    lockRect.Height = dirtyArea.Height;

                    D3D.Texture       t = (texture as D3DTexture).DXTexture as D3D.Texture;
                    int               pitch;
                    int               bpp = PixelUtil.GetNumElemBytes(texture.Format);
                    D3D.Surface       dst = t.GetSurfaceLevel(0);
                    DX.GraphicsStream g   = dynamicSurface.LockRectangle(lockRect, D3D.LockFlags.NoSystemLock, out pitch);
                    unsafe
                    {
                        uint *dstArray = (uint *)g.InternalDataPointer;
                        pitch /= sizeof(uint);
                        for (int z = 0; z < lockRect.Height; z++)
                        {
                            for (int x = 0; x < lockRect.Width; x++)
                            {
                                uint data      = GetData(x + lockRect.X, z + lockRect.Y);
                                uint converted = ConvertPixel(data, INTERNAL_DATA_FORMAT, texture.Format);
                                dstArray[z * pitch + x] = converted;
                            }
                        }
                    }
                    dynamicSurface.UnlockRectangle();
                    D3D.SurfaceLoader.FromSurface(dst, dynamicSurface, D3D.Filter.None, 0);
                }
                else
                {
#if false
                    // following code is for blitting only the dirty rectangle
                    BasicBox destBox = new BasicBox(dirtyArea.X, dirtyArea.Y, dirtyArea.X + dirtyArea.Width,
                                                    dirtyArea.Y + dirtyArea.Height);
                    PixelBox srcPixel        = textureImage.GetPixelBox(0, 0);
                    BasicBox srcBox          = new BasicBox(0, 0, dirtyArea.Width, dirtyArea.Height);
                    PixelBox trimmedSrcPixel = srcPixel.GetSubVolume(srcBox);
                    buffer.BlitFromMemory(trimmedSrcPixel, destBox);
#endif
                }

                // Clean up dirty bit
                dirtyImage       = false;
                dirtyArea.X      = 0;
                dirtyArea.Y      = 0;
                dirtyArea.Width  = 0;
                dirtyArea.Height = 0;
            }
        }
Exemplo n.º 24
0
        protected override void Upload(PixelBox data, BasicBox dest)
        {
            GL.BindTexture(this.target, this.textureID);
            GLES2Config.GlCheckError(this);

            if (PixelUtil.IsCompressed(data.Format))
            {
                if (data.Format != format || !data.IsConsecutive)
                {
                    var glFormat = GLES2PixelUtil.GetClosestGLInternalFormat(format);
                    //Data must be consecutive and at beginning of buffer as PixelStore is not allowed
                    //for compressed formats
                    if (dest.Left == 0 && dest.Top == 0)
                    {
                        GL.CompressedTexImage2D(this.faceTarget, this.level, glFormat, dest.Width, dest.Height, 0, data.ConsecutiveSize, data.Data.Pin());
                        GLES2Config.GlCheckError(this);
                    }
                    else
                    {
                        GL.CompressedTexSubImage2D(this.faceTarget, this.level, dest.Left, dest.Top, dest.Width, dest.Height, glFormat, data.ConsecutiveSize, data.Data.Pin());
                        GLES2Config.GlCheckError(this);
                    }
                }
            }
            else if (this.softwareMipmap)
            {
                if (data.Width != data.RowPitch)
                {
                    //Ogre TODO
                    throw new Core.AxiomException("Unsupported texture format");
                }
                if (data.Height * data.Width != data.SlicePitch)
                {
                    //Ogre TODO
                    throw new Core.AxiomException("Unsupported texture format");
                }

                GL.PixelStore(All.UnpackAlignment, 1);
                GLES2Config.GlCheckError(this);

                this.BuildMipmaps(data);
            }
            else
            {
                if (data.Width != data.RowPitch)
                {
                    //Ogre TODO
                    throw new Core.AxiomException("Unsupported texture format");
                }
                if (data.Height * data.Width != data.SlicePitch)
                {
                    //Ogre TODO
                    throw new Core.AxiomException("Unsupported texture format");
                }

                if ((data.Width * PixelUtil.GetNumElemBytes(data.Format) & 3) != 0)
                {
                    //Standard alignment of 4 is not right
                    GL.PixelStore(All.UnpackAlignment, 1);
                    GLES2Config.GlCheckError(this);
                }
                var dataPtr = data.Data.Pin();
                GL.TexImage2D(this.faceTarget, this.level, (int)GLES2PixelUtil.GetClosestGLInternalFormat(data.Format), data.Width, data.Height, 0, GLES2PixelUtil.GetGLOriginFormat(data.Format), GLES2PixelUtil.GetGLOriginDataType(data.Format), dataPtr);
                //GL.TexSubImage2D( this.faceTarget, this.level, dest.Left, dest.Top, dest.Width, dest.Height, GLES2PixelUtil.GetGLOriginFormat( data.Format ), GLES2PixelUtil.GetGLOriginDataType( data.Format ), dataPtr );
                data.Data.UnPin();
                GLES2Config.GlCheckError(this);
            }
            GL.PixelStore(All.UnpackAlignment, 4);
            GLES2Config.GlCheckError(this);
        }
Exemplo n.º 25
0
        /// <summary>
        /// </summary>
        /// <param name="data"> </param>
        /// <param name="dest"> </param>
        protected override void Upload(PixelBox data, BasicBox dest)
        {
            OpenGL.BindTexture(this._target, this._textureId);
            GLESConfig.GlCheckError(this);

            if (PixelUtil.IsCompressed(data.Format))
            {
                if (data.Format != Format || !data.IsConsecutive)
                {
                    throw new AxiomException("Compressed images must be consecutive, in the source format");
                }

                if (data.Format != Format || !data.IsConsecutive)
                {
                    throw new AxiomException("Compressed images must be consecutive, in the source format.");
                }

                All format = GLESPixelUtil.GetClosestGLInternalFormat(Format);
                // Data must be consecutive and at beginning of buffer as PixelStorei not allowed
                // for compressed formats
                if (dest.Left == 0 && dest.Top == 0)
                {
                    OpenGL.CompressedTexImage2D(All.Texture2D, this._level, format, dest.Width, dest.Height, 0, data.ConsecutiveSize, data.Data);
                }
                else
                {
                    OpenGL.CompressedTexSubImage2D(All.Texture2D, this._level, dest.Left, dest.Top, dest.Width, dest.Height, format, data.ConsecutiveSize, data.Data);
                }
                GLESConfig.GlCheckError(this);
            }
            else if (this._softwareMipmap)
            {
                if (data.Width != data.RowPitch)
                {
                    //TODO
                    throw new AxiomException("Unsupported Texture format!");
                }
                if (data.Height * data.Width != data.SlicePitch)
                {
                    //TODO
                    throw new AxiomException("Unsupported Texture format!");
                }

                OpenGL.PixelStore(All.UnpackAlignment, 1);
                GLESConfig.GlCheckError(this);
                BuildMipmaps(data);
            }
            else
            {
                if (data.Width != data.RowPitch)
                {
                    //TODO
                    throw new AxiomException("Unsupported Texture format!");
                }
                if (data.Height * data.Width != data.SlicePitch)
                {
                    //TODO
                    throw new AxiomException("Unsupported Texture format!");
                }

                if (((data.Width * PixelUtil.GetNumElemBytes(data.Format)) & 3) != 0)
                {
                    // Standard alignment of 4 is not right
                    OpenGL.PixelStore(All.UnpackAlignment, 1);
                    GLESConfig.GlCheckError(this);
                }
                All form = GLESPixelUtil.GetGLOriginFormat(data.Format);
                All pix  = GLESPixelUtil.GetGLOriginDataType(data.Format);
                GLESConfig.GlCheckError(this);
                GL.TexSubImage2D(this._faceTarget, this._level, dest.Left, dest.Top, dest.Width, dest.Height, GLESPixelUtil.GetGLOriginFormat(data.Format), GLESPixelUtil.GetGLOriginDataType(data.Format), data.Data);
                GLESConfig.GlCheckError(this);
            }

            OpenGL.PixelStore(All.UnpackAlignment, 4);
            GLESConfig.GlCheckError(this);
        }
Exemplo n.º 26
0
        public override void CopyContentsToMemory(PixelBox dst, FrameBuffer buffer)
        {
            if ((dst.Left < 0) || (dst.Right > Width) ||
                (dst.Top < 0) || (dst.Bottom > Height) ||
                (dst.Front != 0) || (dst.Back != 1))
            {
                throw new Exception("Invalid box.");
            }

            var device = Driver.XnaDevice;
            //in 3.1, this was ResolveTexture2D, an actual RenderTarget provides the exact same
            //functionality, especially seeing as RenderTarget2D is a texture now.
            //the difference is surface is actually set on the device -DoubleA
            RenderTarget2D surface;
            var            data  = new byte[dst.ConsecutiveSize];
            var            pitch = 0;

            if (buffer == FrameBuffer.Auto)
            {
                buffer = FrameBuffer.Front;
            }

#if SILVERLIGHT
            var mode = ((XnaRenderSystem)Root.Instance.RenderSystem).DisplayMode;
            surface = new RenderTarget2D(device, mode.Width, mode.Height, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8);
#else
            var mode = device.DisplayMode;
            surface = new RenderTarget2D(device, mode.Width, mode.Height, false, SurfaceFormat.Rgba64, DepthFormat.Depth24Stencil8);
#endif
            //ResolveTexture2D( device, mode.Width, mode.Height, 0, SurfaceFormat.Rgba32 );

#if !SILVERLIGHT
            if (buffer == FrameBuffer.Front)
            {
                // get the entire front buffer.  This is SLOW!!
                device.SetRenderTarget(surface);

                if (IsFullScreen)
                {
                    if ((dst.Left == 0) && (dst.Right == Width) && (dst.Top == 0) && (dst.Bottom == Height))
                    {
                        surface.GetData(data);
                    }
                    else
                    {
                        var rect = new Rectangle();
                        rect.Left   = dst.Left;
                        rect.Right  = dst.Right;
                        rect.Top    = dst.Top;
                        rect.Bottom = dst.Bottom;

                        surface.GetData(0, XnaHelper.ToRectangle(rect), data, 0, 255);
                    }
                }
#if !(XBOX || XBOX360 || WINDOWS_PHONE)
                else
                {
                    var srcRect = new Rectangle();
                    srcRect.Left   = dst.Left;
                    srcRect.Right  = dst.Right;
                    srcRect.Top    = dst.Top;
                    srcRect.Bottom = dst.Bottom;
                    // Adjust Rectangle for Window Menu and Chrome
                    var point = new Point();
                    point.X = (int)srcRect.Left;
                    point.Y = (int)srcRect.Top;
                    var control = Control.FromHandle(_windowHandle);
                    point           = control.PointToScreen(point);
                    srcRect.Top     = (long)point.Y;
                    srcRect.Left    = (long)point.X;
                    srcRect.Bottom += (long)point.Y;
                    srcRect.Right  += (long)point.X;

                    surface.GetData(0, XnaHelper.ToRectangle(srcRect), data, 0, 255);
                }
#endif
            }
            else
            {
                device.SetRenderTarget(surface);

                if ((dst.Left == 0) && (dst.Right == Width) && (dst.Top == 0) && (dst.Bottom == Height))
                {
                    surface.GetData(data);
                }
                else
                {
                    var rect = new Rectangle();
                    rect.Left   = dst.Left;
                    rect.Right  = dst.Right;
                    rect.Top    = dst.Top;
                    rect.Bottom = dst.Bottom;

                    surface.GetData(0, XnaHelper.ToRectangle(rect), data, 0, 255);
                }
            }
#endif

            var format = XnaHelper.Convert(surface.Format);

            if (format == PixelFormat.Unknown)
            {
                throw new Exception("Unsupported format");
            }

            var dataPtr = Memory.PinObject(data);
            var src     = new PixelBox(dst.Width, dst.Height, 1, format, dataPtr);
            src.RowPitch   = pitch / PixelUtil.GetNumElemBytes(format);
            src.SlicePitch = surface.Height * src.RowPitch;

            PixelConverter.BulkPixelConversion(src, dst);

            Memory.UnpinObject(data);
            surface.Dispose();
        }
Exemplo n.º 27
0
        private static void _ilToAxiomInternal <T>(BufferBase tar, PixelFormat fmt, T r, T g, T b, T a)
        {
            if (!typeof(T).IsPrimitive)
            {
                throw new AxiomException("Invalid type!");
            }

            var ilfmt    = Il.ilGetInteger(Il.IL_IMAGE_FORMAT);
            var src      = Il.ilGetData();
            var srcend   = Il.ilGetData().Offset(Il.ilGetInteger(Il.IL_IMAGE_SIZE_OF_DATA));
            var elemSize = PixelUtil.GetNumElemBytes(fmt);

            while ((int)src < (int)srcend)
            {
                using (var srcBuf = BufferBase.Wrap(src, (int)srcend - (int)src))
                {
                    var srcPtr = srcBuf as ITypePointer <T>;

                    switch (ilfmt)
                    {
                    case Il.IL_RGB:
                        r   = srcPtr[0];
                        g   = srcPtr[1];
                        b   = srcPtr[2];
                        src = src.Offset(3);
                        break;

                    case Il.IL_BGR:
                        b   = srcPtr[0];
                        g   = srcPtr[1];
                        r   = srcPtr[2];
                        src = src.Offset(3);
                        break;

                    case Il.IL_LUMINANCE:
                        r   = srcPtr[0];
                        g   = srcPtr[0];
                        b   = srcPtr[0];
                        src = src.Offset(1);
                        break;

                    case Il.IL_LUMINANCE_ALPHA:
                        r   = srcPtr[0];
                        g   = srcPtr[0];
                        b   = srcPtr[0];
                        a   = srcPtr[1];
                        src = src.Offset(2);
                        break;

                    case Il.IL_RGBA:
                        r   = srcPtr[0];
                        g   = srcPtr[1];
                        b   = srcPtr[2];
                        a   = srcPtr[3];
                        src = src.Offset(4);
                        break;

                    case Il.IL_BGRA:
                        b   = srcPtr[0];
                        g   = srcPtr[1];
                        r   = srcPtr[2];
                        a   = srcPtr[3];
                        src = src.Offset(4);
                        break;

                    default:
                        return;
                    }
                    ;

                    _packI <T>(r, g, b, a, fmt, tar);
                    tar += elemSize;
                }
            }
        }
Exemplo n.º 28
0
        protected void BlitFromMemory(PixelBox src, BasicBox dstBox, BufferResources dstBufferResources)
        {
            // for scoped deletion of conversion buffer
            var converted = src;
            var bufSize   = 0;

            // convert to pixelbuffer's native format if necessary
            if (D3D9Helper.ConvertEnum(src.Format) == D3D9.Format.Unknown)
            {
                bufSize = PixelUtil.GetMemorySize(src.Width, src.Height, src.Depth, Format);
                var newBuffer = new byte[bufSize];
                using (var data = BufferBase.Wrap(newBuffer))
                {
                    converted = new PixelBox(src.Width, src.Height, src.Depth, Format, data);
                }
                PixelConverter.BulkPixelConversion(src, converted);
            }

            int rowWidth = 0;

            if (PixelUtil.IsCompressed(converted.Format))
            {
                rowWidth = converted.RowPitch / 4;
                // D3D wants the width of one row of cells in bytes
                if (converted.Format == PixelFormat.DXT1)
                {
                    // 64 bits (8 bytes) per 4x4 block
                    rowWidth *= 8;
                }
                else
                {
                    // 128 bits (16 bytes) per 4x4 block
                    rowWidth *= 16;
                }
            }
            else
            {
                rowWidth = converted.RowPitch * PixelUtil.GetNumElemBytes(converted.Format);
            }

            if (dstBufferResources.Surface != null)
            {
                var srcRect  = ToD3DRectangle(converted);
                var destRect = ToD3DRectangle(dstBox);

                bufSize = PixelUtil.GetMemorySize(converted.Width, converted.Height, converted.Depth, converted.Format);
                var data = new byte[bufSize];
                using (var dest = BufferBase.Wrap(data))
                {
                    Memory.Copy(converted.Data, dest, bufSize);
                }

                try
                {
                    D3D9.Surface.FromMemory(dstBufferResources.Surface, data, D3D9.Filter.Default, 0,
                                            D3D9Helper.ConvertEnum(converted.Format), rowWidth, srcRect, destRect);
                }
                catch (Exception e)
                {
                    throw new AxiomException("D3D9.Surface.FromMemory failed in D3D9HardwarePixelBuffer.BlitFromMemory", e);
                }
            }
            else if (dstBufferResources.Volume != null)
            {
                var srcBox     = ToD3DBox(converted);
                var destBox    = ToD3DBox(dstBox);
                var sliceWidth = 0;
                if (PixelUtil.IsCompressed(converted.Format))
                {
                    sliceWidth = converted.SlicePitch / 16;
                    // D3D wants the width of one slice of cells in bytes
                    if (converted.Format == PixelFormat.DXT1)
                    {
                        // 64 bits (8 bytes) per 4x4 block
                        sliceWidth *= 8;
                    }
                    else
                    {
                        // 128 bits (16 bytes) per 4x4 block
                        sliceWidth *= 16;
                    }
                }
                else
                {
                    sliceWidth = converted.SlicePitch * PixelUtil.GetNumElemBytes(converted.Format);
                }

                bufSize = PixelUtil.GetMemorySize(converted.Width, converted.Height, converted.Depth, converted.Format);
                var data = new byte[bufSize];
                using (var dest = BufferBase.Wrap(data))
                {
                    Memory.Copy(converted.Data, dest, bufSize);
                }

                //TODO note sliceWidth and rowWidth are ignored..
                D3D9.ImageInformation info;
                try
                {
                    //D3D9.D3DX9.LoadVolumeFromMemory() not accessible 'cause D3D9.D3DX9 static class is not public
                    D3D9.Volume.FromFileInMemory(dstBufferResources.Volume, data, D3D9.Filter.Default, 0, srcBox, destBox, null,
                                                 out info);
                }
                catch (Exception e)
                {
                    throw new AxiomException("D3D9.Volume.FromFileInMemory failed in D3D9HardwarePixelBuffer.BlitFromMemory", e);
                }
            }

            if (this.doMipmapGen)
            {
                GenMipmaps(dstBufferResources.MipTex);
            }
        }