コード例 #1
0
        ///<summary>
        ///    Internal implementation of <see cref="HardwareBuffer.Lock"/>.
        ///</summary>
        protected override PixelBox LockImpl(BasicBox lockBox, BufferLocking options)
        {
            _lockedBox = lockBox;
            // Set extents and format
            var rval        = new PixelBox(lockBox, Format);
            var sizeInBytes = PixelUtil.GetMemorySize(lockBox.Width, lockBox.Height, lockBox.Depth,
                                                      XnaHelper.Convert(surface.Format));

            if (_bufferBytes == null || _bufferBytes.Length != sizeInBytes)
            {
                _bufferBytes = new byte[sizeInBytes];
#if !SILVERLIGHT
                if (surface != null)
                {
                    surface.GetData(mipLevel, XnaHelper.ToRectangle(lockBox), _bufferBytes, 0, _bufferBytes.Length);
                }
                else if (cube != null)
                {
                    cube.GetData(face, mipLevel, XnaHelper.ToRectangle(lockBox), _bufferBytes, 0, _bufferBytes.Length);
                }
                else
                {
                    volume.GetData(mipLevel, lockBox.Left, lockBox.Top, lockBox.Right, lockBox.Bottom,
                                   lockBox.Front, lockBox.Back, _bufferBytes, 0, _bufferBytes.Length);
                }
#endif
            }

            rval.Data = BufferBase.Wrap(_bufferBytes);

            return(rval);
        }
コード例 #2
0
ファイル: Texture.cs プロジェクト: bostich83/axiom
        public virtual void ConvertToImage(out Image destImage, bool includeMipMaps)
#endif
        {
            var numMips  = includeMipMaps ? MipmapCount + 1 : 1;
            var dataSize = Image.CalculateSize(numMips, FaceCount, Width, Height, Depth, Format);

            var pixData = new byte[dataSize];
            // if there are multiple faces and mipmaps we must pack them into the data
            // faces, then mips
            var currentPixData = BufferBase.Wrap(pixData);

            for (var face = 0; face < FaceCount; ++face)
            {
                for (var mip = 0; mip < numMips; ++mip)
                {
                    var mipDataSize = PixelUtil.GetMemorySize(Width, Height, Depth, Format);

                    var pixBox = new PixelBox(Width, Height, Depth, Format, currentPixData);
                    GetBuffer(face, mip).BlitToMemory(pixBox);

                    currentPixData += mipDataSize;
                }
            }

            currentPixData.Dispose();

            // load, and tell Image to delete the memory when it's done.
            destImage = (new Image()).FromDynamicImage(pixData, Width, Height, Depth, Format, true, FaceCount, numMips - 1);
        }
コード例 #3
0
ファイル: GLESTextureBuffer.cs プロジェクト: bostich83/axiom
        protected static void BuildMipmaps(PixelBox data)
        {
            int      width  = 0;
            int      height = 0;
            int      logW   = 0;
            int      logH   = 0;
            int      level  = 0;
            PixelBox scaled = data;

            scaled.Data   = data.Data;
            scaled.Left   = data.Left;
            scaled.Right  = data.Right;
            scaled.Top    = data.Top;
            scaled.Bottom = data.Bottom;
            scaled.Front  = data.Front;
            scaled.Back   = data.Back;

            All format   = GLESPixelUtil.GetGLOriginFormat(data.Format);
            All dataType = GLESPixelUtil.GetGLOriginDataType(data.Format);

            width  = data.Width;
            height = data.Height;

            logW  = ComputeLog(width);
            logH  = ComputeLog(height);
            level = (logW > logH ? logW : logH);

            for (int mip = 0; mip <= level; mip++)
            {
                format   = GLESPixelUtil.GetGLOriginFormat(scaled.Format);
                dataType = GLESPixelUtil.GetGLOriginDataType(scaled.Format);

                OpenGL.TexImage2D(All.Texture2D, mip, (int)format, width, height, 0, format, dataType, scaled.Data);

                GLESConfig.GlCheckError(null);

                if (mip != 0)
                {
                    scaled.Data = IntPtr.Zero;
                }

                if (width > 1)
                {
                    width = width / 2;
                }
                if (height > 1)
                {
                    height = height / 2;
                }

                int sizeInBytes = PixelUtil.GetMemorySize(width, height, 1, data.Format);
                scaled = new PixelBox(width, height, 1, data.Format);
                var dataarr = new byte[sizeInBytes];
                scaled.Data = Memory.PinObject(dataarr);
                Image.Scale(data, scaled, ImageFilter.Linear);
            }
        }
コード例 #4
0
        public void Bind(D3D9.Device dev, D3D9.Volume volume, D3D9.BaseTexture mipTex)
        {
            //Entering critical section
            LockDeviceAccess();

            var bufferResources = GetBufferResources(dev);
            var isNewBuffer     = false;

            if (bufferResources == null)
            {
                bufferResources = new BufferResources();
                this.mapDeviceToBufferResources.Add(dev, bufferResources);
                isNewBuffer = true;
            }

            bufferResources.MipTex = mipTex;
            bufferResources.Volume = volume;

            var desc = volume.Description;

            width  = desc.Width;
            height = desc.Height;
            depth  = desc.Depth;
            format = D3D9Helper.ConvertEnum(desc.Format);
            // Default
            rowPitch    = Width;
            slicePitch  = Height * Width;
            sizeInBytes = PixelUtil.GetMemorySize(Width, Height, Depth, Format);

            if (isNewBuffer && this.ownerTexture.IsManuallyLoaded)
            {
                foreach (var it in this.mapDeviceToBufferResources)
                {
                    if (it.Value != bufferResources && it.Value.Volume != null && it.Key.TestCooperativeLevel().Success&&
                        dev.TestCooperativeLevel().Success)
                    {
                        var fullBufferBox = new BasicBox(0, 0, 0, Width, Height, Depth);
                        var dstBox        = new PixelBox(fullBufferBox, Format);

                        var data = new byte[sizeInBytes];
                        using (var d = BufferBase.Wrap(data))
                        {
                            dstBox.Data = d;
                            BlitToMemory(fullBufferBox, dstBox, it.Value, it.Key);
                            BlitFromMemory(dstBox, fullBufferBox, bufferResources);
                            Array.Clear(data, 0, sizeInBytes);
                        }
                        break;
                    }
                }
            }

            //Leaving critical section
            UnlockDeviceAccess();
        }
コード例 #5
0
ファイル: GLES2TextureBuffer.cs プロジェクト: bostich83/axiom
        private void BuildMipmaps(PixelBox data)
        {
            int width, height, logW, logH, level;

            PixelBox scaled = data;

            scaled.Data   = data.Data;
            scaled.Left   = data.Left;
            scaled.Right  = data.Right;
            scaled.Top    = data.Top;
            scaled.Bottom = data.Bottom;
            scaled.Front  = data.Front;
            scaled.Back   = data.Back;

            width  = data.Width;
            height = data.Height;

            logW  = (int)System.Math.Log(width);
            logH  = (int)System.Math.Log(height);
            level = (logW > logH ? logW : logH);

            for (int mip = 0; mip < level; mip++)
            {
                All glFormat = GLES2PixelUtil.GetGLOriginFormat(scaled.Format);
                All dataType = GLES2PixelUtil.GetGLOriginDataType(scaled.Format);

                GL.TexImage2D(this.faceTarget, mip, (int)glFormat, width, height, 0, glFormat, dataType, scaled.Data.Pin());
                GLES2Config.GlCheckError(this);

                if (mip != 0)
                {
                    scaled.Data = null;
                }

                if (width > 1)
                {
                    width /= 2;
                }
                if (height > 1)
                {
                    height /= 2;
                }

                int sizeInBytes = PixelUtil.GetMemorySize(width, height, 1, data.Format);
                scaled      = new PixelBox(width, height, 1, data.Format);
                scaled.Data = BufferBase.Wrap(new byte[sizeInBytes]);
                Image.Scale(data, scaled, ImageFilter.Linear);
            }

            //Delete the scaled data for the last level
            if (level > 0)
            {
                scaled.Data = null;
            }
        }
コード例 #6
0
ファイル: GLESTextureBuffer.cs プロジェクト: bostich83/axiom
        /// <summary>
        /// </summary>
        /// <param name="name"> </param>
        /// <param name="target"> </param>
        /// <param name="id"> </param>
        /// <param name="width"> </param>
        /// <param name="height"> </param>
        /// <param name="format"> </param>
        /// <param name="face"> </param>
        /// <param name="level"> </param>
        /// <param name="usage"> </param>
        /// <param name="crappyCard"> </param>
        /// <param name="writeGamma"> </param>
        /// <param name="fsaa"> </param>
        public GLESTextureBuffer(string basename, All targetfmt, int id, int width, int height, int format, int face, int level, BufferUsage usage, bool crappyCard, bool writeGamma, int fsaa)
            : base(0, 0, 0, Media.PixelFormat.Unknown, usage)
        {
            this._target         = targetfmt;
            this._textureId      = id;
            this._face           = face;
            this._level          = level;
            this._softwareMipmap = crappyCard;

            GLESConfig.GlCheckError(this);
            OpenGL.BindTexture(All.Texture2D, this._textureId);
            GLESConfig.GlCheckError(this);

            // Get face identifier
            this._faceTarget = this._target;

            // TODO verify who get this
            Width  = width;
            Height = height;
            Depth  = 1;

            _glInternalFormat = (All)format;
            Format            = GLESPixelUtil.GetClosestAxiomFormat(_glInternalFormat);

            RowPitch    = Width;
            SlicePitch  = Height * Width;
            sizeInBytes = PixelUtil.GetMemorySize(Width, Height, Depth, Format);

            // Set up a pixel box
            _buffer = new PixelBox(Width, Height, Depth, Format);
            if (Width == 0 || Height == 0 || Depth == 0)
            {
                /// We are invalid, do not allocate a buffer
                return;
            }

            // Is this a render target?
            if (((int)Usage & (int)TextureUsage.RenderTarget) != 0)
            {
                // Create render target for each slice
                for (int zoffset = 0; zoffset < Depth; zoffset++)
                {
                    string name = string.Empty;
                    name = "rtt/" + GetHashCode() + "/" + basename;
                    var target = new GLESSurfaceDescription();
                    target.Buffer  = this;
                    target.ZOffset = zoffset;
                    RenderTexture trt = GLESRTTManager.Instance.CreateRenderTexture(name, target, writeGamma, fsaa);
                    this._sliceTRT.Add(trt);
                    Root.Instance.RenderSystem.AttachRenderTarget(this._sliceTRT[zoffset]);
                }
            }
        }
コード例 #7
0
        ///<summary>
        ///    Copies a region from normal memory to a region of this pixelbuffer. The source
        ///    image can be in any pixel format supported by Axiom, and in any size.
        ///</summary>
        ///<param name="src">PixelBox containing the source pixels and format in memory</param>
        ///<param name="dstBox">Image.BasicBox describing the destination region in this buffer</param>
        ///<remarks>
        ///    The source and destination regions dimensions don't have to match, in which
        ///    case scaling is done. This scaling is generally done using a bilinear filter in hardware,
        ///    but it is faster to pass the source image in the right dimensions.
        ///    Only call this function when both buffers are unlocked.
        ///</remarks>
        public override void BlitFromMemory(PixelBox src, BasicBox dstBox)
        {
            var converted   = src;
            var bufGCHandle = new GCHandle();
            var bufSize     = 0;

            // Get src.Data as byte[]
            bufSize = PixelUtil.GetMemorySize(src.Width, src.Height, src.Depth, Format);
            var newBuffer = new byte[bufSize];

            //bufGCHandle = GCHandle.Alloc( newBuffer, GCHandleType.Pinned );
            //XnaHelper.Convert(XFG.SurfaceFormat) would never have returned SurfaceFormat.Unknown anyway...
            //if (XnaHelper.Convert(src.Format) != XFG.SurfaceFormat.Unknown)
            {
                converted = new PixelBox(src.Width, src.Height, src.Depth, Format, BufferBase.Wrap(newBuffer));
                PixelConverter.BulkPixelConversion(src, converted);
            }
            //else
            //{
            //    Memory.Copy(converted.Data, BufferBase.Wrap(newBuffer), bufSize);
            //}

            if (surface != null)
            {
                surface.SetData(mipLevel, XnaHelper.ToRectangle(dstBox), newBuffer, 0, bufSize);
            }
            else if (cube != null)
            {
                cube.SetData(face, mipLevel, XnaHelper.ToRectangle(dstBox), newBuffer, 0, bufSize);
            }
            else
            {
                throw new NotSupportedException("BlitFromMemory on Volume Textures not supported.");
            }

            // If we allocated a buffer for the temporary conversion, free it here
            if (bufGCHandle.IsAllocated)
            {
                bufGCHandle.Free();
            }

            if (doMipmapGen)
            {
                GenMipmaps();
            }
        }
コード例 #8
0
        public void Bind(GraphicsDevice device, RenderTarget2D surface, bool update)
        {
            this.device  = device;
            renderTarget = surface;

            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;
            slicePitch  = Height * Width;
            sizeInBytes = PixelUtil.GetMemorySize(Width, Height, Depth, Format);

            if (((int)usage & (int)TextureUsage.RenderTarget) != 0)
            {
                CreateRenderTextures(update);
            }
        }
コード例 #9
0
        ///<summary>
        ///    Call this to associate a Xna Texture3D with this pixel buffer
        ///</summary>
        public void Bind(GraphicsDevice device, Texture3D volume, bool update)
        {
            this.device = device;
            this.volume = volume;

            width  = volume.Width;
            height = volume.Height;
            depth  = volume.Depth;
            format = XnaHelper.Convert(volume.Format);
            // Default
            rowPitch    = Width;
            slicePitch  = Height * Width;
            sizeInBytes = PixelUtil.GetMemorySize(Width, Height, Depth, Format);

            if (((int)usage & (int)TextureUsage.RenderTarget) != 0)
            {
                CreateRenderTextures(update);
            }
        }
コード例 #10
0
        ///<summary>
        ///    Call this to associate a D3D volume with this pixel buffer
        ///</summary>
        public void Bind(D3D.Device device, D3D.Volume volume, bool update)
        {
            this.device = device;
            this.volume = volume;

            D3D.VolumeDescription desc = volume.Description;
            width  = desc.Width;
            height = desc.Height;
            depth  = desc.Depth;
            format = D3DHelper.ConvertEnum(desc.Format);
            // Default
            rowPitch    = width;
            slicePitch  = height * width;
            sizeInBytes = PixelUtil.GetMemorySize(width, height, depth, format);

            if (((int)usage & (int)TextureUsage.RenderTarget) != 0)
            {
                CreateRenderTextures(update);
            }
        }
コード例 #11
0
        public void Bind(GraphicsDevice device, TextureCube cube, ushort face, ushort miplevel, bool update)
        {
            this.device = device;
            this.cube   = cube;
            this.face   = (CubeMapFace)face;
            mipLevel    = miplevel;

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

            if (((int)usage & (int)TextureUsage.RenderTarget) != 0)
            {
                CreateRenderTextures(update);
            }
        }
コード例 #12
0
        /// <summary>
        ///   Save our texture to a stream
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="requestedFormat"></param>
        public override void Save(System.IO.Stream stream, PixelFormat requestedFormat)
        {
            // First try to see if we can use the fast method to save this image.
            // TODO: I should be able to make the common path closer to this in performance ([email protected])
            if (pixelBuffer.Format == PixelFormat.A8R8G8B8)
            {
                if (requestedFormat == PixelFormat.A8B8G8R8 || requestedFormat == PixelFormat.B8G8R8)
                {
                    SimpleSave(stream, requestedFormat);
                    return;
                }
            }
            int bufSize = PixelUtil.GetMemorySize(pixelBuffer.Width, pixelBuffer.Height, pixelBuffer.Depth, requestedFormat);

            byte[] buffer = new byte[bufSize];
            // Pin down the byte array
            GCHandle handle  = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            IntPtr   address = handle.AddrOfPinnedObject();
            PixelBox box     =
                new PixelBox(pixelBuffer.Width, pixelBuffer.Height, pixelBuffer.Depth, requestedFormat, address);

            pixelBuffer.BlitToMemory(box);
            handle.Free();

            // I need to flip this image, since it was upside down in the
            // internal buffers.  I could do this in the save pass, which
            // would make this more efficient, but I don't currently think
            // that efficiency is that important.
            Image image = Image.FromDynamicImage(buffer, pixelBuffer.Width, pixelBuffer.Height,
                                                 pixelBuffer.Depth, requestedFormat);

            image.FlipAroundX();
            // Ok, now the data in buffer has been flipped.
            // Go ahead and discard the image
            image.Dispose();

            // write the data to the stream provided
            stream.Write(buffer, 0, bufSize);
        }
コード例 #13
0
        protected void BlitFromMemoryImpl(PixelBox src, BasicBox dstBox)
        {
            // TODO: This currently does way too many copies.  We copy
            // from src to a converted buffer (if needed), then from
            // converted to a byte array, then into the temporary surface,
            // and finally from the temporary surface to the real surface.
            PixelBox converted   = src;
            IntPtr   bufPtr      = IntPtr.Zero;
            GCHandle bufGCHandle = new GCHandle();

            // convert to pixelbuffer's native format if necessary
            if (D3DHelper.ConvertEnum(src.Format) == D3D.Format.Unknown)
            {
                int    bufSize   = PixelUtil.GetMemorySize(src.Width, src.Height, src.Depth, format);
                byte[] newBuffer = new byte[bufSize];
                bufGCHandle = GCHandle.Alloc(newBuffer, GCHandleType.Pinned);
                bufPtr      = bufGCHandle.AddrOfPinnedObject();
                converted   = new PixelBox(src.Width, src.Height, src.Depth, format, bufPtr);
                PixelUtil.BulkPixelConversion(src, converted);
            }

            // int formatBytes = PixelUtil.GetNumElemBytes(converted.Format);
            Surface tmpSurface = device.CreateOffscreenPlainSurface(converted.Width, converted.Height, D3DHelper.ConvertEnum(converted.Format), Pool.Scratch);
            int     pitch;
            // Ideally I would be using the Array mechanism here, but that doesn't seem to work
            GraphicsStream buf = tmpSurface.LockRectangle(LockFlags.NoSystemLock, out pitch);

            buf.Position = 0;
            unsafe {
                int    bufSize = PixelUtil.GetMemorySize(converted.Width, converted.Height, converted.Depth, converted.Format);
                byte * srcPtr  = (byte *)converted.Data.ToPointer();
                byte[] ugh     = new byte[bufSize];
                for (int i = 0; i < bufSize; ++i)
                {
                    ugh[i] = srcPtr[i];
                }
                buf.Write(ugh);
            }
            tmpSurface.UnlockRectangle();
            buf.Dispose();

            //ImageInformation imageInfo = new ImageInformation();
            //imageInfo.Format = D3DHelper.ConvertEnum(converted.Format);
            //imageInfo.Width = converted.Width;
            //imageInfo.Height = converted.Height;
            //imageInfo.Depth = converted.Depth;
            if (surface != null)
            {
                // I'm trying to write to surface using the data in converted
                Rectangle srcRect  = ToD3DRectangleExtent(converted);
                Rectangle destRect = ToD3DRectangle(dstBox);
                SurfaceLoader.FromSurface(surface, destRect, tmpSurface, srcRect, Filter.None, 0);
            }
            else
            {
                D3D.Box srcBox  = ToD3DBoxExtent(converted);
                D3D.Box destBox = ToD3DBox(dstBox);
                Debug.Assert(false, "Volume textures not yet supported");
                // VolumeLoader.FromStream(volume, destBox, converted.Data, converted.RowPitch * converted.SlicePitch * formatBytes, srcBox, Filter.None, 0);
                VolumeLoader.FromStream(volume, destBox, buf, srcBox, Filter.None, 0);
            }

            tmpSurface.Dispose();

            // If we allocated a buffer for the temporary conversion, free it here
            // If I used bufPtr to store my temporary data while I converted
            // it, I need to free it here.  This invalidates converted.
            // My data has already been copied to tmpSurface and then to the
            // real surface.
            if (bufGCHandle.IsAllocated)
            {
                bufGCHandle.Free();
            }

            if (doMipmapGen)
            {
                GenMipmaps();
            }
        }
コード例 #14
0
ファイル: GLESTexture.cs プロジェクト: bostich83/axiom
        /// <summary>
        /// </summary>
        protected override void createInternalResources()
        {
            // Convert to nearest power-of-two size if required
            Width  = GLESPixelUtil.OptionalPO2(Width);
            Height = GLESPixelUtil.OptionalPO2(Height);
            Depth  = GLESPixelUtil.OptionalPO2(Depth);

            //adjust format if required
            Format = TextureManager.Instance.GetNativeFormat(Graphics.TextureType.TwoD, Format, Usage);
            // Check requested number of mipmaps
            int maxMips = GLESPixelUtil.GetMaxMipmaps(Width, Height, Depth, Format);

            if (PixelUtil.IsCompressed(Format) && _mipmapCount == 0)
            {
                RequestedMipmapCount = 0;
            }

            _mipmapCount = RequestedMipmapCount;
            if (_mipmapCount > maxMips)
            {
                _mipmapCount = maxMips;
            }

            // Generate texture name
            OpenGL.GenTextures(1, ref this._textureID);
            GLESConfig.GlCheckError(this);
            // Set texture type
            OpenGL.BindTexture(All.Texture2D, this._textureID);
            GLESConfig.GlCheckError(this);
            // Set some misc default parameters, these can of course be changed later
            OpenGL.TexParameter(All.Texture2D, All.TextureMinFilter, (int)All.LinearMipmapNearest);
            GLESConfig.GlCheckError(this);
            OpenGL.TexParameter(All.Texture2D, All.TextureMagFilter, (int)All.Nearest);
            GLESConfig.GlCheckError(this);
            OpenGL.TexParameter(All.Texture2D, All.TextureWrapS, (int)All.ClampToEdge);
            GLESConfig.GlCheckError(this);
            OpenGL.TexParameter(All.Texture2D, All.TextureWrapT, (int)All.ClampToEdge);
            GLESConfig.GlCheckError(this);
            // If we can do automip generation and the user desires this, do so
            MipmapsHardwareGenerated = Root.Instance.RenderSystem.HardwareCapabilities.HasCapability(Capabilities.HardwareMipMaps) && !PixelUtil.IsCompressed(Format);

            if ((Usage & TextureUsage.AutoMipMap) == TextureUsage.AutoMipMap && RequestedMipmapCount > 0 && MipmapsHardwareGenerated)
            {
                OpenGL.TexParameter(All.Texture2D, All.GenerateMipmap, (int)All.True);
                GLESConfig.GlCheckError(this);
            }

            // Allocate internal buffer so that TexSubImageXD can be used
            // Internal format
            All format = GLESPixelUtil.GetClosestGLInternalFormat(Format, HardwareGammaEnabled);
            int width  = Width;
            int height = Height;
            int depth  = Depth;

            if (PixelUtil.IsCompressed(Format))
            {
                // Compressed formats
                int size = PixelUtil.GetMemorySize(Width, Height, Depth, Format);

                // Provide temporary buffer filled with zeroes as glCompressedTexImageXD does not
                // accept a 0 pointer like normal glTexImageXD
                // Run through this process for every mipmap to pregenerate mipmap pyramid

                var    tmpData    = new byte[size];
                IntPtr tmpDataptr = Memory.PinObject(tmpData);
                for (int mip = 0; mip <= MipmapCount; mip++)
                {
                    size = PixelUtil.GetMemorySize(Width, Height, Depth, Format);
                    OpenGL.CompressedTexImage2D(All.Texture2D, mip, format, width, height, 0, size, tmpDataptr);

                    GLESConfig.GlCheckError(this);

                    if (width > 1)
                    {
                        width = width / 2;
                    }
                    if (height > 1)
                    {
                        height = height / 2;
                    }
                    if (depth > 1)
                    {
                        depth = depth / 2;
                    }
                }
                Memory.UnpinObject(tmpData);
            }
            else
            {
                // Run through this process to pregenerate mipmap pyramid
                for (int mip = 0; mip <= MipmapCount; mip++)
                {
                    OpenGL.TexImage2D(All.Texture2D, mip, (int)format, width, height, 0, format, All.UnsignedByte, IntPtr.Zero);
                    GLESConfig.GlCheckError(this);

                    if (width > 1)
                    {
                        width = width / 2;
                    }
                    if (height > 1)
                    {
                        height = height / 2;
                    }
                }
            }

            CreateSurfaceList();

            // Get final internal format
            Format = GetBuffer(0, 0).Format;
        }
コード例 #15
0
ファイル: GLES2TextureBuffer.cs プロジェクト: bostich83/axiom
        public override void BlitFromMemory(PixelBox src, BasicBox dstBox)
        {
            // Fall back to normal GLHardwarePixelBuffer::blitFromMemory in case
            // - FBO is not supported
            // - Either source or target is luminance due doesn't looks like supported by hardware
            // - the source dimensions match the destination ones, in which case no scaling is needed
            //Ogre TODO: Check that extension is NOT available
            if (PixelUtil.IsLuminance(src.Format) || PixelUtil.IsLuminance(this.format) || (src.Width == dstBox.Width && src.Height == dstBox.Height && src.Depth == dstBox.Depth))
            {
                base.BlitFromMemory(src, dstBox);
                return;
            }

            if (!Buffer.Contains(dstBox))
            {
                throw new ArgumentOutOfRangeException("dstBox", "Destination box out of range");
            }

            //For scoped deletion of conversion buffer

            PixelBox   srcPB;
            BufferBase buf;

            //first, convert the srcbox to a OpenGL compatible pixel format
            if (GLES2PixelUtil.GetGLOriginFormat(src.Format) == 0)
            {
                //Conver to buffer intenral format
                buf = BufferBase.Wrap(new byte[PixelUtil.GetMemorySize(src.Width, src.Height, src.Depth, this.format)]);

                srcPB = new PixelBox(src.Width, src.Height, src.Depth, this.format, buf);
                PixelConverter.BulkPixelConversion(src, srcPB);
            }
            else
            {
                //No conversion needed
                srcPB = src;
            }

            //Create temporary texture to store source data
            int id       = 0;
            All target   = All.Texture2D;
            int width    = GLES2PixelUtil.OptionalPO2(src.Width);
            int height   = GLES2PixelUtil.OptionalPO2(src.Height);
            All format   = GLES2PixelUtil.GetClosestGLInternalFormat(src.Format);
            All datatype = GLES2PixelUtil.GetGLOriginDataType(src.Format);

            //Generate texture name
            GL.GenTextures(1, ref id);
            GLES2Config.GlCheckError(this);

            //Set texture type
            GL.BindTexture(target, id);
            GLES2Config.GlCheckError(this);

            //Allocate texture memory
            GL.TexImage2D(target, 0, (int)format, width, height, 0, format, datatype, IntPtr.Zero);
            GLES2Config.GlCheckError(this);

            var tex = new GLES2TextureBuffer(string.Empty, target, id, width, height, format, (All)src.Format, 0, 0, BufferUsage.StaticWriteOnly, false, false, 0);

            //Upload data to 0,0,0 in temprary texture
            var tempTarget = new BasicBox(0, 0, 0, srcPB.Width, srcPB.Height, srcPB.Depth);

            tex.Upload(srcPB, tempTarget);

            //Blit
            this.BlitFromTexture(tex, tempTarget, dstBox);
            GLES2Config.GlCheckError(this);
        }
コード例 #16
0
ファイル: GLES2TextureBuffer.cs プロジェクト: bostich83/axiom
        public GLES2TextureBuffer(string baseName, All target, int id, int width, int height, All internalFormat, All format, int face, int level, BufferUsage usage, bool crappyCard, bool writeGamma, int fsaa)
            : base(0, 0, 0, PixelFormat.Unknown, usage)
        {
            this.target         = target;
            this.textureID      = id;
            this.face           = face;
            this.level          = level;
            this.softwareMipmap = crappyCard;

            GLES2Config.GlCheckError(this);
            GL.BindTexture(target, this.textureID);
            GLES2Config.GlCheckError(this);

            //Get face identifier
            this.faceTarget = this.target;
            if (this.target == All.TextureCubeMap)
            {
                this.faceTarget = All.TextureCubeMapPositiveX + face;
            }
            //Calculate the width and height of the texture at this mip level
            this.width  = this.level == 0 ? width : (int)(width / Math.Utility.Pow(2, level));
            this.height = this.level == 0 ? height : (int)(height / Math.Utility.Pow(2, level));

            if (this.width < 1)
            {
                this.width = 1;
            }
            if (this.height < 1)
            {
                this.height = 1;
            }

            //Only 2D is supporte so depth is always 1
            depth = 1;

            GlInternalFormat = internalFormat;
            this.format      = GLES2PixelUtil.GetClosestAxiomFormat(internalFormat, format);

            rowPitch    = this.width;
            slicePitch  = this.height * this.width;
            sizeInBytes = PixelUtil.GetMemorySize(this.width, this.height, depth, this.format);
            //Setup a pixel box
            Buffer = new PixelBox(this.width, this.height, depth, this.format);

            if (this.width == 0 || this.height == 0 || depth == 0)
            {
                //We are invalid, do not allocat a buffer
                return;
            }

            if (((TextureUsage)usage & TextureUsage.RenderTarget) == TextureUsage.RenderTarget)
            {
                //Create render target for each slice

                for (int zoffset = 0; zoffset < depth; zoffset++)
                {
                    var name    = "rtt/ " + GetHashCode() + "/" + baseName;
                    var rtarget = new GLES2SurfaceDesc {
                        buffer = this, zoffset = zoffset
                    };
                    var trt = GLES2RTTManager.Instance.CreateRenderTexture(name, rtarget, writeGamma, fsaa);
                    this.sliceTRT.Add(trt);
                    Core.Root.Instance.RenderSystem.AttachRenderTarget(this.sliceTRT[zoffset]);
                }
            }
        }
コード例 #17
0
ファイル: Texture.cs プロジェクト: bostich83/axiom
        public virtual void LoadImages(Image[] images)
        {
            if (images.Length < 1)
            {
                throw new AxiomException("Cannot load empty vector of images");
            }

            // Set desired texture size and properties from images[0]
            this.srcWidth  = this.width = images[0].Width;
            this.srcHeight = this.height = images[0].Height;
            this.srcDepth  = this.depth = images[0].Depth;

            // Get source image format and adjust if required
            this.srcFormat = images[0].Format;
            if (this.treatLuminanceAsAlpha && this.srcFormat == PixelFormat.L8)
            {
                this.srcFormat = PixelFormat.A8;
            }

            if (this.desiredFormat != PixelFormat.Unknown)
            {
                // If have desired format, use it
                this.format = this.desiredFormat;
            }
            else
            {
                // Get the format according with desired bit depth
                this.format = PixelUtil.GetFormatForBitDepths(this.srcFormat, this.desiredIntegerBitDepth,
                                                              this.desiredFloatBitDepth);
            }

            // The custom mipmaps in the image have priority over everything
            var imageMips = images[0].NumMipMaps;

            if (imageMips > 0)
            {
                this.mipmapCount = this.requestedMipmapCount = imageMips;
                // Disable flag for auto mip generation
                this.usage &= ~TextureUsage.AutoMipMap;
            }

            // Create the texture
            CreateInternalResources();

            // Check if we're loading one image with multiple faces
            // or a vector of images representing the faces
            int  faces;
            bool multiImage;             // Load from multiple images?

            if (images.Length > 1)
            {
                faces      = images.Length;
                multiImage = true;
            }
            else
            {
                faces      = images[0].NumFaces;
                multiImage = false;
            }

            // Check wether number of faces in images exceeds number of faces
            // in this texture. If so, clamp it.
            if (faces > FaceCount)
            {
                faces = FaceCount;
            }

            // Say what we're doing
            if (TextureManager.Instance.Verbose)
            {
                var msg = new StringBuilder();
                msg.AppendFormat("Texture: {0}: Loading {1} faces( {2}, {3}x{4}x{5} ) with", _name, faces,
                                 PixelUtil.GetFormatName(images[0].Format), images[0].Width, images[0].Height,
                                 images[0].Depth);
                if (!(this.mipmapsHardwareGenerated && this.mipmapCount == 0))
                {
                    msg.AppendFormat(" {0}", this.mipmapCount);
                }

                if ((this.usage & TextureUsage.AutoMipMap) == TextureUsage.AutoMipMap)
                {
                    msg.AppendFormat("{0} generated mipmaps", this.mipmapsHardwareGenerated ? " hardware" : string.Empty);
                }
                else
                {
                    msg.Append(" custom mipmaps");
                }

                msg.AppendFormat(" from {0}.\n\t", multiImage ? "multiple Images" : "an Image");

                // Print data about first destination surface
                var buf = GetBuffer(0, 0);
                msg.AppendFormat(" Internal format is {0} , {1}x{2}x{3}.", PixelUtil.GetFormatName(buf.Format), buf.Width,
                                 buf.Height, buf.Depth);

                LogManager.Instance.Write(msg.ToString());
            }

            // Main loading loop
            // imageMips == 0 if the image has no custom mipmaps, otherwise contains the number of custom mips
            for (var mip = 0; mip <= imageMips; ++mip)
            {
                for (var i = 0; i < faces; ++i)
                {
                    PixelBox src;
                    if (multiImage)
                    {
                        // Load from multiple images
                        src = images[i].GetPixelBox(0, mip);
                    }
                    else
                    {
                        // Load from faces of images[0]
                        src = images[0].GetPixelBox(i, mip);
                    }

                    // Sets to treated format in case is difference
                    src.Format = this.srcFormat;

                    if (this.gamma != 1.0f)
                    {
                        // Apply gamma correction
                        // Do not overwrite original image but do gamma correction in temporary buffer
                        var bufSize = PixelUtil.GetMemorySize(src.Width, src.Height, src.Depth, src.Format);
                        var buff    = new byte[bufSize];
                        var buffer  = BufferBase.Wrap(buff);

                        var corrected = new PixelBox(src.Width, src.Height, src.Depth, src.Format, buffer);
                        PixelConverter.BulkPixelConversion(src, corrected);

                        Image.ApplyGamma(corrected.Data, this.gamma, corrected.ConsecutiveSize, PixelUtil.GetNumElemBits(src.Format));

                        // Destination: entire texture. BlitFromMemory does
                        // the scaling to a power of two for us when needed
                        GetBuffer(i, mip).BlitFromMemory(corrected);
                    }
                    else
                    {
                        // Destination: entire texture. BlitFromMemory does
                        // the scaling to a power of two for us when needed
                        GetBuffer(i, mip).BlitFromMemory(src);
                    }
                }
            }

            // Update size (the final size, not including temp space)
            Size = FaceCount * PixelUtil.GetMemorySize(this.width, this.height, this.depth, this.format);
        }
コード例 #18
0
        // create the texture and call the callback
        public void Notify()
        {
            Debug.Assert(Done);

            bool loaded = false;

            // need these in the callback for scaling images into picture frames (friendworld)
            int initialWidth  = 0;
            int initialHeight = 0;

            try
            {
                if (sourceBuffer != null)
                {
                    int imageID;

                    // create and bind a new image
                    Il.ilGenImages(1, out imageID);
                    Il.ilBindImage(imageID);

                    // Put it right side up
                    Il.ilEnable(Il.IL_ORIGIN_SET);
                    Il.ilSetInteger(Il.IL_ORIGIN_MODE, Il.IL_ORIGIN_UPPER_LEFT);

                    // Keep DXTC(compressed) data if present
                    Il.ilSetInteger(Il.IL_KEEP_DXTC_DATA, Il.IL_TRUE);

                    // load the data into DevIL
                    Il.ilLoadL(this.ilImageType, sourceBuffer, sourceBuffer.Length);

                    // check for an error
                    int ilError = Il.ilGetError();

                    if (ilError != Il.IL_NO_ERROR)
                    {
                        log.ErrorFormat("TextureFetcher: Error while decoding image data: '{0}'", Ilu.iluErrorString(ilError));
                        throw new Exception("TextureFetcher: Error while decoding image data: " + Ilu.iluErrorString(ilError));
                    }

                    int ilFormat  = Il.ilGetInteger(Il.IL_IMAGE_FORMAT);
                    int imageType = Il.ilGetInteger(Il.IL_IMAGE_TYPE);

                    // force conversion to 24-bit RGB image
                    if ((imageType != Il.IL_BYTE && imageType != Il.IL_UNSIGNED_BYTE) || ilFormat != Il.IL_BGR)
                    {
                        ilFormat  = Il.IL_BGR;
                        imageType = Il.IL_UNSIGNED_BYTE;

                        Il.ilConvertImage(ilFormat, imageType);
                    }

                    PixelFormat format     = PixelFormat.R8G8B8;
                    int         width      = Il.ilGetInteger(Il.IL_IMAGE_WIDTH);
                    int         height     = Il.ilGetInteger(Il.IL_IMAGE_HEIGHT);
                    int         depth      = Il.ilGetInteger(Il.IL_IMAGE_DEPTH);
                    int         numMipMaps = Il.ilGetInteger(Il.IL_NUM_MIPMAPS) + 1;
                    int         numFaces   = Il.ilGetInteger(Il.IL_NUM_IMAGES) + 1;

                    initialWidth  = width;
                    initialHeight = height;

                    if (numFaces > 1 || numMipMaps > 1)
                    {
                        log.WarnFormat("TextureFetcher: ignoring extra faces or mipmaps: faces={0}: mipmaps={1}", numFaces, numMipMaps);
                    }

                    if (destHeight == 0)
                    {
                        destHeight = height;
                    }
                    if (destWidth == 0)
                    {
                        destWidth = width;
                    }

                    int scaleX;
                    int scaleY;
                    int topFill    = 0;
                    int bottomFill = 0;
                    int leftFill   = 0;
                    int rightFill  = 0;

                    if (keepAspect)
                    {
                        float scaleWidthFactor  = (float)width / (float)destWidth;
                        float scaleHeightFactor = (float)height / (float)destHeight;
                        if (scaleWidthFactor > scaleHeightFactor)
                        {
                            scaleX     = destWidth;
                            scaleY     = (int)(height / scaleWidthFactor);
                            topFill    = (destHeight - scaleY) / 2;
                            bottomFill = destHeight - scaleY - topFill;
                        }
                        else
                        {
                            scaleX    = (int)(width / scaleHeightFactor);
                            scaleY    = destHeight;
                            leftFill  = (destWidth - scaleX) / 2;
                            rightFill = destWidth - scaleX - leftFill;
                        }
                    }
                    else
                    {
                        scaleX = destWidth;
                        scaleY = destWidth;
                    }

                    // scale the image
                    if ((scaleX != width) || (scaleY != height))
                    {
                        DoScale(scaleX, scaleY);

                        width  = scaleX;
                        height = scaleY;
                    }

                    int imageSize = PixelUtil.GetMemorySize(destWidth, destHeight, depth, format);

                    // set up buffer for the decoded data
                    byte[] buffer = new byte[imageSize];

                    byte fillRed   = (byte)(fillColor.r * 255.0);
                    byte fillGreen = (byte)(fillColor.g * 255.0);
                    byte fillBlue  = (byte)(fillColor.b * 255.0);

                    if (keepAspect)
                    {
                        // fill top
                        for (int y = 0; y < topFill; y++)
                        {
                            int offset = y * destWidth * 3;
                            for (int x = 0; x < destWidth; x++)
                            {
                                buffer[offset++] = fillBlue;
                                buffer[offset++] = fillGreen;
                                buffer[offset++] = fillRed;
                            }
                        }

                        // copy the data
                        IntPtr srcPtr    = Il.ilGetData();
                        int    srcOffset = 0;
                        unsafe
                        {
                            byte *srcBytes = (byte *)srcPtr.ToPointer();

                            for (int y = topFill; y < topFill + height; y++)
                            {
                                int offset = y * destWidth * 3;
                                for (int x = 0; x < leftFill; x++)
                                {
                                    buffer[offset++] = fillBlue;
                                    buffer[offset++] = fillGreen;
                                    buffer[offset++] = fillRed;
                                }

                                for (int x = 0; x < width; x++)
                                {
                                    buffer[offset++] = srcBytes[srcOffset++];
                                    buffer[offset++] = srcBytes[srcOffset++];
                                    buffer[offset++] = srcBytes[srcOffset++];
                                }

                                for (int x = 0; x < rightFill; x++)
                                {
                                    buffer[offset++] = fillBlue;
                                    buffer[offset++] = fillGreen;
                                    buffer[offset++] = fillRed;
                                }
                            }
                        }

                        // fill bottom
                        for (int y = topFill + height; y < destHeight; y++)
                        {
                            int offset = y * destWidth * 3;
                            for (int x = 0; x < destWidth; x++)
                            {
                                buffer[offset++] = fillBlue;
                                buffer[offset++] = fillGreen;
                                buffer[offset++] = fillRed;
                            }
                        }
                    }
                    else
                    {
                        // copy the data
                        IntPtr srcPtr = Il.ilGetData();
                        unsafe
                        {
                            byte *srcBytes = (byte *)srcPtr.ToPointer();
                            for (int i = 0; i < imageSize; i++)
                            {
                                buffer[i] = srcBytes[i];
                            }
                        }
                    }

                    // Restore IL state
                    Il.ilDisable(Il.IL_ORIGIN_SET);
                    Il.ilDisable(Il.IL_FORMAT_SET);

                    // we won't be needing this anymore
                    Il.ilDeleteImages(1, ref imageID);

                    Image resultImage = Image.FromDynamicImage(buffer, destWidth, destHeight, depth, format);

                    TextureManager.Instance.LoadImage(textureName, resultImage);
                    loaded = true;
                    resultImage.Dispose();
                }
            }
            catch (Exception ex)
            {
                LogUtil.LogUtil.ExceptionLog.ErrorFormat("TextureFetcher: exception while decoding image: {0}", ex);
            }
            finally
            {
                doneHandler(textureName, initialWidth, initialHeight, loaded);
            }
            return;
        }
コード例 #19
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);
            }
        }
コード例 #20
0
        protected override void createInternalResources()
        {
            //Conver to nearest power of two size if require
            this.width  = GLES2PixelUtil.OptionalPO2(Width);
            this.height = GLES2PixelUtil.OptionalPO2(Height);
            this.depth  = GLES2PixelUtil.OptionalPO2(Depth);

            //Adjust format if required
            format = TextureManager.Instance.GetNativeFormat(textureType, Format, usage);

            //Check requested number of mipmaps
            int maxMips = GLES2PixelUtil.GetMaxMipmaps(this.width, this.height, this.depth, format);

            if (PixelUtil.IsCompressed(format) && (mipmapCount == 0))
            {
                requestedMipmapCount = 0;
            }

            mipmapCount = requestedMipmapCount;
            if (mipmapCount > maxMips)
            {
                mipmapCount = maxMips;
            }

            //Generate texture name
            GL.GenTextures(1, ref this.textureID);
            GLES2Config.GlCheckError(this);

            //Set texture name
            GL.BindTexture(this.GLES2TextureTarget, this.textureID);
            GLES2Config.GlCheckError(this);

            //Set some misc default parameters, tehse can of course be changed later
            GL.TexParameter(this.GLES2TextureTarget, GLenum.TextureMinFilter, (int)GLenum.Nearest);
            GLES2Config.GlCheckError(this);

            GL.TexParameter(this.GLES2TextureTarget, GLenum.TextureMagFilter, (int)GLenum.Nearest);
            GLES2Config.GlCheckError(this);

            GL.TexParameter(this.GLES2TextureTarget, GLenum.TextureWrapS, (int)GLenum.ClampToEdge);
            GLES2Config.GlCheckError(this);

            GL.TexParameter(this.GLES2TextureTarget, GLenum.TextureWrapT, (int)GLenum.ClampToEdge);
            GLES2Config.GlCheckError(this);

            //If we can do automip generation and the user desires this, do so
            mipmapsHardwareGenerated = Root.Instance.RenderSystem.Capabilities.HasCapability(Capabilities.HardwareMipMaps) && !PixelUtil.IsCompressed(format);

            //Ogre FIXME: For some reason this is crashing on iOS 5
#if !MONOTOUCH && ANDROID
            if ((usage & TextureUsage.AutoMipMap) == TextureUsage.AutoMipMap && requestedMipmapCount > 0 && mipmapsHardwareGenerated && (textureType != Graphics.TextureType.CubeMap))
            {
                GL.GenerateMipmap(this.GLES2TextureTarget);
                GLES2Config.GlCheckError(this);
            }
#endif
            //Allocate internal buffer so that glTexSubImageXD can be used
            //INternal format
            GLenum glformat = GLES2PixelUtil.GetClosestGLInternalFormat(format, hwGamma);

            GLenum dataType = GLES2PixelUtil.GetGLOriginDataType(format);
            int    width    = Width;
            int    height   = Height;
            int    depth    = Depth;

            if (PixelUtil.IsCompressed(format))
            {
                //Compressed formats
                int size = PixelUtil.GetMemorySize(Width, Height, Depth, Format);

                // Provide temporary buffer filled with zeroes as glCompressedTexImageXD does not
                // accept a 0 pointer like normal glTexImageXD
                // Run through this process for every mipmap to pregenerate mipmap pyramid


                var tmpData = new IntPtr();

                for (int mip = 0; mip < mipmapCount; mip++)
                {
                    size = PixelUtil.GetMemorySize(width, height, depth, Format);

                    switch (textureType)
                    {
                    case TextureType.OneD:
                    case TextureType.TwoD:
                        GL.CompressedTexImage2D(GLenum.Texture2D, mip, glformat, width, height, 0, size, tmpData);
                        GLES2Config.GlCheckError(this);

                        break;

                    case TextureType.CubeMap:
                        for (int face = 0; face < 6; face++)
                        {
                            GL.CompressedTexImage2D((GLenum)((int)GLenum.TextureCubeMapPositiveX + face), mip, glformat, width, height, 0, size, tmpData);
                            GLES2Config.GlCheckError(this);
                        }
                        break;

                    case TextureType.ThreeD:
                        break;

                    default:
                        break;
                    }

                    if (width > 1)
                    {
                        width = width / 2;
                    }
                    if (height > 1)
                    {
                        height = height / 2;
                    }
                    if (depth > 1)
                    {
                        depth = depth / 2;
                    }
                }
                tmpData = IntPtr.Zero;
            }
            else
            {
                //Run through this process to pregenerate mipmap pyramid
                for (int mip = 0; mip < mipmapCount; mip++)
                {
                    //Normal formats
                    switch (textureType)
                    {
                    case TextureType.OneD:
                    case TextureType.TwoD:
                        GL.TexImage2D(GLenum.Texture2D, mip, (int)glformat, width, height, 0, glformat, dataType, new IntPtr());
                        GLES2Config.GlCheckError(this);

                        break;

                    case TextureType.CubeMap:
                        for (int face = 0; face < 6; face++)
                        {
                            GL.TexImage2D(GLenum.TextureCubeMapPositiveX + face, mip, (int)glformat, width, height, 0, glformat, dataType, new IntPtr());
                            GLES2Config.GlCheckError(this);
                        }
                        break;

                    case TextureType.ThreeD:
                    default:
                        break;
                    }
                    if (width > 1)
                    {
                        width /= 2;
                    }
                    if (height > 1)
                    {
                        height /= 2;
                    }
                }
            }

            this.CreateSurfaceList();

            //Get final internal format
            base.format = this.GetBuffer(0, 0).Format;
        }
コード例 #21
0
ファイル: Texture.cs プロジェクト: bostich83/axiom
 protected override int calculateSize()
 {
     return(FaceCount * PixelUtil.GetMemorySize(Width, Height, Depth, Format));
 }
コード例 #22
0
        protected virtual void LoadImages(List <Image> images)
        {
            Debug.Assert(images.Count >= 1);
            if (isLoaded)
            {
                log.InfoFormat("Unloading image: {0}", name);
                Unload();
            }
            srcWidth  = width = images[0].Width;
            srcHeight = height = images[0].Height;
            srcDepth  = depth = images[0].Depth;
            if (hasAlpha && images[0].Format == PixelFormat.L8)
            {
                format = PixelFormat.A8;
                srcBpp = 8;
            }
            else
            {
                this.Format = images[0].Format;
            }
            if (finalBpp == 16)
            {
                switch (format)
                {
                case PixelFormat.R8G8B8:
                case PixelFormat.X8R8G8B8:
                    format = PixelFormat.R5G6B5;
                    break;

                case PixelFormat.B8G8R8:
                case PixelFormat.X8B8G8R8:
                    format = PixelFormat.B5G6R5;
                    break;

                case PixelFormat.A8R8G8B8:
                case PixelFormat.R8G8B8A8:
                case PixelFormat.A8B8G8R8:
                case PixelFormat.B8G8R8A8:
                    format = PixelFormat.A4R4G4B4;
                    break;

                default:
                    // use the original format
                    break;
                }
            }

            // The custom mipmaps in the image have priority over everything
            int imageMips = images[0].NumMipMaps;

            if (imageMips > 0)
            {
                numMipmaps = imageMips;
                usage     &= ~TextureUsage.AutoMipMap;
            }

            // Create the texture
            CreateInternalResources();

            // Check if we're loading one image with multiple faces
            // or a vector of images representing the faces
            int  faces;
            bool multiImage;         // Load from multiple images?

            if (images.Count > 1)
            {
                faces      = images.Count;
                multiImage = true;
            }
            else
            {
                faces      = images[0].NumFaces;
                multiImage = false;
            }

            // Check wether number of faces in images exceeds number of faces
            // in this texture. If so, clamp it.
            if (faces > this.NumFaces)
            {
                faces = this.NumFaces;
            }

            // Say what we're doing
            log.InfoFormat("Texture: {0}: Loading {1} faces({2},{3}x{4}x{5})",
                           name, faces, PixelUtil.GetFormatName(images[0].Format),
                           images[0].Width, images[0].Height, images[0].Depth);
#if NOT // crazy ogre logging
            if (!(mMipmapsHardwareGenerated && mNumMipmaps == 0))
            {
                str << mNumMipmaps;
            }
            if (mUsage & TU_AUTOMIPMAP)
            {
                if (mMipmapsHardwareGenerated)
                {
                    str << " hardware";
                }

                str << " generated mipmaps";
            }
            else
            {
                str << " custom mipmaps";
            }
            if (multiImage)
            {
                str << " from multiple Images.";
            }
            else
            {
                str << " from Image.";
            }
            // Scoped
            {
                // Print data about first destination surface
                HardwarePixelBufferSharedPtr buf = getBuffer(0, 0);
                str << " Internal format is " << PixelUtil::getFormatName(buf->getFormat()) <<
                    "," << buf->getWidth() << "x" << buf->getHeight() << "x" << buf->getDepth() << ".";
            }
            LogManager::getSingleton().logMessage(
                LML_NORMAL, str.str());
#endif
            // Main loading loop
            // imageMips == 0 if the image has no custom mipmaps, otherwise contains the number of custom mips
            for (int mip = 0; mip <= imageMips; ++mip)
            {
                for (int i = 0; i < faces; ++i)
                {
                    PixelBox src;
                    if (multiImage)
                    {
                        // Load from multiple images
                        src = images[i].GetPixelBox(0, mip);
                    }
                    else
                    {
                        // Load from faces of images[0]
                        src = images[0].GetPixelBox(i, mip);

                        if (hasAlpha && src.Format == PixelFormat.L8)
                        {
                            src.Format = PixelFormat.A8;
                        }
                    }

                    if (gamma != 1.0f)
                    {
                        // Apply gamma correction
                        // Do not overwrite original image but do gamma correction in temporary buffer
                        IntPtr buffer = Marshal.AllocHGlobal(PixelUtil.GetMemorySize(src.Width, src.Height, src.Depth, src.Format));
                        try {
                            PixelBox corrected = new PixelBox(src.Width, src.Height, src.Depth, src.Format, buffer);
                            PixelUtil.BulkPixelConversion(src, corrected);

                            Image.ApplyGamma(corrected.Data, gamma, corrected.ConsecutiveSize, PixelUtil.GetNumElemBits(src.Format));

                            // Destination: entire texture. BlitFromMemory does the scaling to
                            // a power of two for us when needed
                            GetBuffer(i, mip).BlitFromMemory(corrected);
                        } finally {
                            Marshal.FreeHGlobal(buffer);
                        }
                    }
                    else
                    {
                        // Destination: entire texture. BlitFromMemory does the scaling to
                        // a power of two for us when needed
                        GetBuffer(i, mip).BlitFromMemory(src);
                    }
                }
            }
            // Update size (the final size, not including temp space)
            size = this.NumFaces * PixelUtil.GetMemorySize(width, height, depth, format);

            isLoaded = true;
        }
コード例 #23
0
ファイル: GLTextureBuffer.cs プロジェクト: axiom3d/axiom
        public GLTextureBuffer(string baseName, int target, int id, int face, int level, BufferUsage usage,
                               bool softwareMipmap, BaseGLSupport glSupport, bool writeGamma, int fsaa)
            : base(0, 0, 0, PixelFormat.Unknown, usage)
        {
            int value;

            this._glSupport = glSupport;

            this._target         = target;
            this._textureId      = id;
            this._face           = face;
            this._level          = level;
            this._softwareMipmap = softwareMipmap;

            Gl.glBindTexture(this._target, this._textureId);

            // Get face identifier
            this._faceTarget = this._target;
            if (this._target == Gl.GL_TEXTURE_CUBE_MAP)
            {
                this._faceTarget = Gl.GL_TEXTURE_CUBE_MAP_POSITIVE_X + this._face;
            }

            // Get width
            Gl.glGetTexLevelParameteriv(this._faceTarget, this._level, Gl.GL_TEXTURE_WIDTH, out value);
            width = value;

            // Get height
            if (this._target == Gl.GL_TEXTURE_1D)
            {
                value = 1; // Height always 1 for 1D textures
            }
            else
            {
                Gl.glGetTexLevelParameteriv(this._faceTarget, this._level, Gl.GL_TEXTURE_HEIGHT, out value);
            }
            height = value;

            // Get depth
            if (this._target != Gl.GL_TEXTURE_3D)
            {
                value = 1; // Depth always 1 for non-3D textures
            }
            else
            {
                Gl.glGetTexLevelParameteriv(this._faceTarget, this._level, Gl.GL_TEXTURE_DEPTH, out value);
            }
            depth = value;

            // Get format
            Gl.glGetTexLevelParameteriv(this._faceTarget, this._level, Gl.GL_TEXTURE_INTERNAL_FORMAT, out value);
            GLFormat = value;
            format   = GLPixelUtil.GetClosestPixelFormat(value);

            // Default
            rowPitch    = Width;
            slicePitch  = Height * Width;
            sizeInBytes = PixelUtil.GetMemorySize(Width, Height, Depth, Format);

            // Set up pixel box
            buffer = new PixelBox(Width, Height, Depth, Format);

            if (Width == 0 || Height == 0 || Depth == 0)
            {
                /// We are invalid, do not allocate a buffer
                return;
            }

            // Is this a render target?
            if (((TextureUsage)Usage & TextureUsage.RenderTarget) == TextureUsage.RenderTarget)
            {
                // Create render target for each slice
                this._sliceTRT.Capacity = Depth;
                for (int zoffset = 0; zoffset < Depth; ++zoffset)
                {
                    String name;
                    name = String.Format("{0}/{1}/{2}/{3}", baseName, face, this._level, zoffset);

                    GLSurfaceDesc renderTarget;
                    renderTarget.Buffer  = this;
                    renderTarget.ZOffset = zoffset;
                    RenderTexture trt = GLRTTManager.Instance.CreateRenderTexture(name, renderTarget, writeGamma, fsaa);
                    this._sliceTRT.Add(trt);
                    Root.Instance.RenderSystem.AttachRenderTarget(this._sliceTRT[zoffset]);
                }
            }
        }
コード例 #24
0
ファイル: ILImageCodec.cs プロジェクト: bostich83/axiom
        public override Codec.DecodeResult Decode(Stream input)
        {
            var imgData = new ImageData();
            var output  = new MemoryStream();

            int imageID;
            int imageFormat, bytesPerPixel;

            // create and bind a new image
            Il.ilGenImages(1, out imageID);
            Il.ilBindImage(imageID);

            // create a temp buffer and write the stream into it
            var buffer = new byte[input.Length];

            input.Read(buffer, 0, buffer.Length);

            // Put it right side up
            Il.ilEnable(Il.IL_ORIGIN_SET);
            Il.ilSetInteger(Il.IL_ORIGIN_MODE, Il.IL_ORIGIN_UPPER_LEFT);

            // Keep DXTC(compressed) data if present
            Il.ilSetInteger(Il.IL_KEEP_DXTC_DATA, Il.IL_TRUE);

            // load the data into DevIL
            Il.ilLoadL(this._ilType, buffer, buffer.Length);

            // check for an error
            var ilError = Il.ilGetError();

            if (ilError != Il.IL_NO_ERROR)
            {
                throw new AxiomException("Error while decoding image data: '{0}'", Ilu.iluErrorString(ilError));
            }

            imageFormat = Il.ilGetInteger(Il.IL_IMAGE_FORMAT);
            var imageType = Il.ilGetInteger(Il.IL_IMAGE_TYPE);

            // Convert image if imageType is incompatible with us (double or long)
            if (imageType != Il.IL_BYTE && imageType != Il.IL_UNSIGNED_BYTE && imageType != Il.IL_FLOAT &&
                imageType != Il.IL_UNSIGNED_SHORT && imageType != Il.IL_SHORT)
            {
                Il.ilConvertImage(imageFormat, Il.IL_FLOAT);
                imageType = Il.IL_FLOAT;
            }

            // Converted paletted images
            if (imageFormat == Il.IL_COLOR_INDEX)
            {
                Il.ilConvertImage(Il.IL_BGRA, Il.IL_UNSIGNED_BYTE);
                imageFormat = Il.IL_BGRA;
                imageType   = Il.IL_UNSIGNED_BYTE;
            }

            // populate the image data
            bytesPerPixel = Il.ilGetInteger(Il.IL_IMAGE_BYTES_PER_PIXEL);

            imgData.format     = ILUtil.Convert(imageFormat, imageType);
            imgData.width      = Il.ilGetInteger(Il.IL_IMAGE_WIDTH);
            imgData.height     = Il.ilGetInteger(Il.IL_IMAGE_HEIGHT);
            imgData.depth      = Il.ilGetInteger(Il.IL_IMAGE_DEPTH);
            imgData.numMipMaps = Il.ilGetInteger(Il.IL_NUM_MIPMAPS);

            if (imgData.format == PixelFormat.Unknown)
            {
                throw new AxiomException("Unsupported devil format ImageFormat={0} ImageType={1}", imageFormat, imageType);
            }

            // Check for cubemap
            var numFaces = Il.ilGetInteger(Il.IL_NUM_IMAGES) + 1;

            if (numFaces == 6)
            {
                imgData.flags |= ImageFlags.CubeMap;
            }
            else
            {
                numFaces = 1;                 // Support only 1 or 6 face images for now
            }

            // Keep DXT data (if present at all and the GPU supports it)
            var dxtFormat = Il.ilGetInteger(Il.IL_DXTC_DATA_FORMAT);

            if (dxtFormat != Il.IL_DXT_NO_COMP &&
                Root.Instance.RenderSystem.Capabilities.HasCapability(Axiom.Graphics.Capabilities.TextureCompressionDXT))
            {
                imgData.format = ILUtil.Convert(dxtFormat, imageType);
                imgData.flags |= ImageFlags.Compressed;

                // Validate that this devil version loads DXT mipmaps
                if (imgData.numMipMaps > 0)
                {
                    Il.ilBindImage(imageID);
                    Il.ilActiveMipmap(1);
                    if ((uint)Il.ilGetInteger(Il.IL_DXTC_DATA_FORMAT) != dxtFormat)
                    {
                        imgData.numMipMaps = 0;
                        LogManager.Instance.Write(
                            "Warning: Custom mipmaps for compressed image were ignored because they are not loaded by this DevIL version.");
                    }
                }
            }

            // Calculate total size from number of mipmaps, faces and size
            imgData.size = Image.CalculateSize(imgData.numMipMaps, numFaces, imgData.width, imgData.height, imgData.depth,
                                               imgData.format);

            // get the decoded data
            BufferBase BufferHandle;

            // Dimensions of current mipmap
            var width  = imgData.width;
            var height = imgData.height;
            var depth  = imgData.depth;

            // Transfer data
            for (var mip = 0; mip <= imgData.numMipMaps; ++mip)
            {
                for (var i = 0; i < numFaces; ++i)
                {
                    Il.ilBindImage(imageID);
                    if (numFaces > 1)
                    {
                        Il.ilActiveImage(i);
                    }
                    if (imgData.numMipMaps > 0)
                    {
                        Il.ilActiveMipmap(mip);
                    }

                    // Size of this face
                    var imageSize = PixelUtil.GetMemorySize(width, height, depth, imgData.format);
                    buffer = new byte[imageSize];

                    if ((imgData.flags & ImageFlags.Compressed) != 0)
                    {
                        // Compare DXT size returned by DevIL with our idea of the compressed size
                        if (imageSize == Il.ilGetDXTCData(IntPtr.Zero, 0, dxtFormat))
                        {
                            // Retrieve data from DevIL
                            using (BufferHandle = BufferBase.Wrap(buffer))
                            {
                                Il.ilGetDXTCData(BufferHandle.Pin(), imageSize, dxtFormat);
                                BufferHandle.UnPin();
                            }
                        }
                        else
                        {
                            LogManager.Instance.Write("Warning: compressed image size mismatch, devilsize={0} oursize={1}",
                                                      Il.ilGetDXTCData(IntPtr.Zero, 0, dxtFormat), imageSize);
                        }
                    }
                    else
                    {
                        // Retrieve data from DevIL
                        using (BufferHandle = BufferBase.Wrap(buffer))
                        {
                            var dst = new PixelBox(width, height, depth, imgData.format, BufferHandle);
                            ILUtil.ConvertFromIL(dst);
                        }
                    }

                    // write the decoded data to the output stream
                    output.Write(buffer, 0, buffer.Length);
                }

                // Next mip
                if (width != 1)
                {
                    width /= 2;
                }

                if (height != 1)
                {
                    height /= 2;
                }

                if (depth != 1)
                {
                    depth /= 2;
                }
            }

            // Restore IL state
            Il.ilDisable(Il.IL_ORIGIN_SET);
            Il.ilDisable(Il.IL_FORMAT_SET);

            Il.ilDeleteImages(1, ref imageID);

            return(new DecodeResult(output, imgData));
        }