예제 #1
0
        /// <summary>
        /// Detect allowed FBO formats
        /// </summary>
        private void _detectFBOFormats()
        {
            // Try all formats, and report which ones work as target
            int fb, tid;
            int old_drawbuffer, old_readbuffer;
            int target = Gl.GL_TEXTURE_2D;

            Gl.glGetIntegerv(Gl.GL_DRAW_BUFFER, out old_drawbuffer);
            Gl.glGetIntegerv(Gl.GL_READ_BUFFER, out old_readbuffer);

            for (int x = 0; x < (int)PixelFormat.Count; ++x)
            {
                this._props[x].Valid = false;

                // Fetch GL format token
                int fmt = GLPixelUtil.GetGLInternalFormat((PixelFormat)x);
                if (fmt == Gl.GL_NONE && x != 0)
                {
                    continue;
                }

                // No test for compressed formats
                if (PixelUtil.IsCompressed((PixelFormat)x))
                {
                    continue;
                }

                // Buggy ATI cards *crash* on non-RGB(A) formats
                int[] depths = PixelUtil.GetBitDepths((PixelFormat)x);
                if (fmt != Gl.GL_NONE && this._atiMode && (depths[0] == 0 || depths[1] == 0 || depths[2] == 0))
                {
                    continue;
                }

                // Buggy NVidia Drivers fail on 32Bit FP formats on Windows.
                if (PixelUtil.IsFloatingPoint((PixelFormat)x) && PlatformManager.IsWindowsOS && !this._atiMode)
                {
                    continue;
                }

                // Create and attach framebuffer
                Gl.glGenFramebuffersEXT(1, out fb);
                Gl.glBindFramebufferEXT(Gl.GL_FRAMEBUFFER_EXT, fb);
                if (fmt != Gl.GL_NONE)
                {
                    // Create and attach texture
                    Gl.glGenTextures(1, out tid);
                    Gl.glBindTexture(target, tid);

                    // Set some default parameters so it won't fail on NVidia cards
                    Gl.glTexParameteri(target, Gl.GL_TEXTURE_MAX_LEVEL, 0);
                    Gl.glTexParameteri(target, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST);
                    Gl.glTexParameteri(target, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);
                    Gl.glTexParameteri(target, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP_TO_EDGE);
                    Gl.glTexParameteri(target, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP_TO_EDGE);

                    Gl.glTexImage2D(target, 0, fmt, PROBE_SIZE, PROBE_SIZE, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, IntPtr.Zero);
                    Gl.glFramebufferTexture2DEXT(Gl.GL_FRAMEBUFFER_EXT, Gl.GL_COLOR_ATTACHMENT0_EXT, target, tid, 0);
                }
                else
                {
                    // Draw to nowhere -- stencil/depth only
                    tid = 0;
                    Gl.glDrawBuffer(Gl.GL_NONE);
                    Gl.glReadBuffer(Gl.GL_NONE);
                }
                // Check status
                int status = Gl.glCheckFramebufferStatusEXT(Gl.GL_FRAMEBUFFER_EXT);

                // Ignore status in case of fmt==GL_NONE, because no implementation will accept
                // a buffer without *any* attachment. Buffers with only stencil and depth attachment
                // might still be supported, so we must continue probing.
                if (fmt == Gl.GL_NONE || status == Gl.GL_FRAMEBUFFER_COMPLETE_EXT)
                {
                    this._props[x].Valid = true;
                    var str = new StringBuilder();
                    str.AppendFormat("\tFBO {0} depth/stencil support: ", PixelUtil.GetFormatName((PixelFormat)x));

                    // For each depth/stencil formats
                    for (int depth = 0; depth < this._depthFormats.GetLength(0); ++depth)
                    {
                        if (this._depthFormats[depth] != GL_DEPTH24_STENCIL8_EXT)
                        {
                            // General depth/stencil combination

                            for (int stencil = 0; stencil < this._stencilFormats.GetLength(0); ++stencil)
                            {
                                //LogManager.Instance.Write( "Trying {0} D{1}S{2} ", PixelUtil.GetFormatName( (PixelFormat)x ), _depthBits[ depth ], _stencilBits[ stencil ] );

                                if (_tryFormat(this._depthFormats[depth], this._stencilFormats[stencil]))
                                {
                                    /// Add mode to allowed modes
                                    str.AppendFormat("D{0}S{1} ", this._depthBits[depth], this._stencilBits[stencil]);
                                    FormatProperties.Mode mode;
                                    mode.Depth   = depth;
                                    mode.Stencil = stencil;
                                    this._props[x].Modes.Add(mode);
                                }
                            }
                        }
                        else
                        {
                            // Packed depth/stencil format
#if false
                            // Only query packed depth/stencil formats for 32-bit
                            // non-floating point formats (ie not R32!)
                            // Linux nVidia driver segfaults if you query others
                            if (!PlatformManager.IsWindowsOS &&
                                (PixelUtil.GetNumElemBits((PixelFormat)x) != 32 ||
                                 PixelUtil.IsFloatingPoint((PixelFormat)x)))
                            {
                                continue;
                            }
#endif
                            if (_tryPackedFormat(this._depthFormats[depth]))
                            {
                                /// Add mode to allowed modes
                                str.AppendFormat("Packed-D{0}S8 ", this._depthBits[depth]);
                                FormatProperties.Mode mode;
                                mode.Depth   = depth;
                                mode.Stencil = 0; // unuse
                                this._props[x].Modes.Add(mode);
                            }
                        }
                    }

                    LogManager.Instance.Write(str.ToString());
                }
                // Delete texture and framebuffer
                Gl.glBindFramebufferEXT(Gl.GL_FRAMEBUFFER_EXT, 0);
                Gl.glDeleteFramebuffersEXT(1, ref fb);

                // Workaround for NVIDIA / Linux 169.21 driver problem
                // see http://www.ogre3d.org/phpBB2/viewtopic.php?t=38037&start=25
                Gl.glFinish();

                Gl.glDeleteTextures(1, ref tid);
            }

            // It seems a bug in nVidia driver: glBindFramebufferEXT should restore
            // draw and read buffers, but in some unclear circumstances it won't.
            Gl.glDrawBuffer(old_drawbuffer);
            Gl.glReadBuffer(old_readbuffer);

            string fmtstring = "";
            for (int x = 0; x < (int)PixelFormat.Count; ++x)
            {
                if (this._props[x].Valid)
                {
                    fmtstring += PixelUtil.GetFormatName((PixelFormat)x) + " ";
                }
            }
            LogManager.Instance.Write("[GL] : Valid FBO targets " + fmtstring);
        }
예제 #2
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);
        }
        private bool _checkVertexTextureFormats(D3D9RenderWindow renderWindow)
        {
            var anySupported = false;

            var bbSurf     = (D3D9.Surface[])renderWindow["DDBACKBUFFER"];
            var bbSurfDesc = bbSurf[0].Description;

            for (var pf = PixelFormat.L8; pf < PixelFormat.Count; ++pf)
            {
                var fmt = D3D9Helper.ConvertEnum(D3D9Helper.GetClosestSupported(pf));
                if (
                    !this._pD3D.CheckDeviceFormat(this._activeD3DDriver.AdapterNumber, D3D9.DeviceType.Hardware, bbSurfDesc.Format,
                                                  D3D9.Usage.QueryVertexTexture, D3D9.ResourceType.Texture, fmt))
                {
                    continue;
                }

                // cool, at least one supported
                anySupported = true;
                LogManager.Instance.Write("D3D9: Vertex texture format supported - {0}", PixelUtil.GetFormatName(pf));
            }

            return(anySupported);
        }
예제 #4
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;
        }
예제 #5
0
        /// <summary>
        ///   Detect which internal formats are allowed as RTT Also detect what combinations of stencil and depth are allowed with this interal format.
        /// </summary>
        private void DetectFBOFormats()
        {
            //Try all formats, and report which ones work as target
            int    fb = 0, tid = 0;
            GLenum target = GLenum.Texture2D;

            for (int x = 0; x < (int)PixelFormat.Count; x++)
            {
                this.props[x].Valid = false;

                //Fetch gl format token
                var fmt = GLES2PixelUtil.GetGLInternalFormat((PixelFormat)x);

                if ((fmt == GLenum.None) && (x != 0))
                {
                    continue;
                }

                //No test for compressed formats
                if (PixelUtil.IsCompressed((PixelFormat)x))
                {
                    continue;
                }

                //Create and attach framebuffer
                GL.GenFramebuffers(1, ref fb);
                GL.BindFramebuffer(GLenum.Framebuffer, fb);
                if (fmt != GLenum.None)
                {
                    //Create and attach texture
                    GL.GenTextures(1, ref tid);
                    GL.BindTexture(target, tid);

                    //Set some default parameters
                    GL.TexParameter(target, GLenum.TextureMinFilter, (int)GLenum.Nearest);
                    GL.TexParameter(target, GLenum.TextureMagFilter, (int)GLenum.Nearest);
                    GL.TexParameter(target, GLenum.TextureWrapS, (int)GLenum.ClampToEdge);
                    GL.TexParameter(target, GLenum.TextureWrapT, (int)GLenum.ClampToEdge);

                    GL.TexImage2D(target, 0, (int)fmt, PROBE_SIZE, PROBE_SIZE, 0, fmt, GLES2PixelUtil.GetGLOriginDataType((PixelFormat)x), IntPtr.Zero);
                    GL.FramebufferTexture2D(GLenum.Framebuffer, GLenum.ColorAttachment0, target, tid, 0);
                }
                //Check status
                GLenum status = GL.CheckFramebufferStatus(GLenum.Framebuffer);
                // Ignore status in case of fmt==GL_NONE, because no implementation will accept
                // a buffer without *any* attachment. Buffers with only stencil and depth attachment
                // might still be supported, so we must continue probing.
                if (fmt == GLenum.None || status == GLenum.FramebufferComplete)
                {
                    this.props[x].Valid = true;
                    var sb = new StringBuilder();
                    sb.Append("FBO " + PixelUtil.GetFormatName((PixelFormat)x) + " depth/stencil support: ");

                    //For each depth/stencil formats
                    for (int depth = 0; depth < DepthFormatCount; depth++)
                    {
                        if (depthFormats[depth] != GLenum.Depth24Stencil8Oes)
                        {
                            //General depth/stencil combination

                            for (int stencil = 0; stencil < StencilFormatCount; stencil++)
                            {
                                if (this.TryFormat(depthFormats[depth], stencilFormats[stencil]))
                                {
                                    //Add mode to allowed modes
                                    sb.Append("D" + depthBits[depth] + "S" + stencilBits[stencil] + " ");
                                    var mode = new FormatProperties.Mode();
                                    mode.Depth   = depth;
                                    mode.Stencil = stencil;
                                    this.props[x].Modes.Add(mode);
                                }
                            }
                        }
                        else
                        {
                            //Packed depth/stencil format
                            if (this.TryPackedFormat(depthFormats[depth]))
                            {
                                //Add mode to allowed modes
                                sb.Append("Packed-D" + depthBits[depth] + "S" + 8 + " ");
                                var mode = new FormatProperties.Mode();
                                mode.Depth   = depth;
                                mode.Stencil = 0;                                 //unuse
                                this.props[x].Modes.Add(mode);
                            }
                        }
                    }
                    Core.LogManager.Instance.Write(sb.ToString());
                }
                //Delte texture and framebuffer
                GL.BindFramebuffer(GLenum.Framebuffer, 0);
                GL.DeleteFramebuffers(1, ref fb);

                if (fmt != GLenum.None)
                {
                    GL.DeleteTextures(1, ref tid);
                }
            }

            // Clear any errors
            GLES2Config.GlClearError();

            string fmtstring = string.Empty;

            for (int x = 0; x < (int)PixelFormat.Count; x++)
            {
                if (this.props[x].Valid)
                {
                    fmtstring += PixelUtil.GetFormatName((PixelFormat)x) + " ";
                }
                Core.LogManager.Instance.Write("[GLES2] : Valid FBO targets " + fmtstring);
            }
        }
예제 #6
0
        /// <summary>
        ///   Detect which internal formats are allowed as RTT Also detect what combinations of stencil and depth are allowed with this internal format.
        /// </summary>
        private void DetectFBOFormats()
        {
            // Try all formats, and report which ones work as target
            int fb = 0, tid = 0;
            All target = All.Texture2D;

            for (int x = 0; x < (int)Media.PixelFormat.Count; x++)
            {
                LogManager.Instance.Write("[GLES] [DEBUG] testing PixelFormat : {0}", (Media.PixelFormat)x);

                this._props[x]         = new FormatProperties();
                this._props[x].Modes   = new List <FormatProperties.Mode>();
                this._props[x].IsValid = false;

                // Fetch GL format token
                All fmt = GLESPixelUtil.GetClosestGLInternalFormat((Media.PixelFormat)x);
                LogManager.Instance.Write("[GLES] [DEBUG] fmt={0}", fmt);
                if (fmt == All.Zero && x != 0)
                {
                    continue;
                }

                // No test for compressed formats
                if (PixelUtil.IsCompressed((Media.PixelFormat)x))
                {
                    continue;
                }

                // Create and attach framebuffer
                OpenGLOES.GenRenderbuffers(1, ref fb);
                GLESConfig.GlCheckError(this);
                OpenGLOES.BindFramebuffer(All.FramebufferOes, fb);
                GLESConfig.GlCheckError(this);

                if (fmt != All.Zero)
                {
                    // Create and attach texture
                    OpenGL.GenTextures(1, ref tid);
                    GLESConfig.GlCheckError(this);
                    OpenGL.BindTexture(target, tid);
                    GLESConfig.GlCheckError(this);

                    // Set some default parameters
                    OpenGL.TexParameterx(target, All.TextureMinFilter, (int)All.LinearMipmapNearest);
                    GLESConfig.GlCheckError(this);
                    OpenGL.TexParameterx(target, All.TextureMagFilter, (int)All.Nearest);
                    GLESConfig.GlCheckError(this);
                    OpenGL.TexParameterx(target, All.TextureWrapS, (int)All.ClampToEdge);
                    GLESConfig.GlCheckError(this);
                    OpenGL.TexParameterx(target, All.TextureWrapT, (int)All.ClampToEdge);
                    GLESConfig.GlCheckError(this);

                    OpenGL.TexImage2D(target, 0, (int)fmt, ProbeSize, ProbeSize, 0, fmt, All.UnsignedByte, IntPtr.Zero);
                    GLESConfig.GlCheckError(this);
                    OpenGLOES.FramebufferTexture2D(All.FramebufferOes, All.ColorAttachment0Oes, target, tid, 0);
                    GLESConfig.GlCheckError(this);
                }

                // Check status
                All status = OpenGLOES.CheckFramebufferStatus(All.FramebufferOes);
                GLESConfig.GlCheckError(this);
                LogManager.Instance.Write("[GLES] [DEBUG] status={0}", status);

                // Ignore status in case of fmt==GL_NONE, because no implementation will accept
                // a buffer without *any* attachment. Buffers with only stencil and depth attachment
                // might still be supported, so we must continue probing.
                if (fmt == 0 || status == All.FramebufferCompleteOes)
                {
                    this._props[x].IsValid = true;
                    var str = new StringBuilder();
                    str.Append("FBO " + PixelUtil.GetFormatName((Media.PixelFormat)x) + " depth/stencil support: ");

                    // For each depth/stencil formats
                    for (int depth = 0; depth < DepthFormats.Length; ++depth)
                    {
                        if (DepthFormats[depth] != All.Depth24Stencil8Oes)
                        {
                            // General depth/stencil combination
                            for (int stencil = 0; stencil < StencilFormats.Length; ++stencil)
                            {
                                if (TryFormat(DepthFormats[depth], StencilFormats[stencil]))
                                {
                                    /// Add mode to allowed modes
                                    str.Append("D" + DepthBits[depth] + "S" + StencilBits[stencil] + " ");
                                    var mode = new FormatProperties.Mode();
                                    mode.Depth   = depth;
                                    mode.Stencil = stencil;
                                    this._props[x].Modes.Add(mode);
                                }
                            }                     //end for stencil
                        }                         //end if
                        else
                        {
                            // Packed depth/stencil format
                            if (TryPacketFormat(DepthFormats[depth]))
                            {
                                /// Add mode to allowed modes
                                str.Append("Packed-D" + DepthBits[depth] + "S8" + " ");
                                var mode = new FormatProperties.Mode();
                                mode.Depth   = depth;
                                mode.Stencil = 0;                                 //unused
                                this._props[x].Modes.Add(mode);
                            }
                        }
                    }             //end for depth
                    LogManager.Instance.Write(str.ToString());
                }                 //end if
                                  // Delete texture and framebuffer
#if AXIOM_PLATFORM_IPHONE
                // The screen buffer is 1 on iPhone
                OpenGLOES.BindFramebuffer(All.FramebufferOes, 1);
#else
                OpenGLOES.BindFramebuffer(All.FramebufferOes, 0);
#endif
                GLESConfig.GlCheckError(this);
                OpenGLOES.DeleteFramebuffers(1, ref fb);
                GLESConfig.GlCheckError(this);
                if (fmt != 0)
                {
                    OpenGL.DeleteTextures(1, ref tid);
                }
            }             //end for pixelformat count

            string fmtstring = string.Empty;
            for (int x = 0; x < (int)Media.PixelFormat.Count; x++)
            {
                if (this._props[x].IsValid)
                {
                    fmtstring += PixelUtil.GetFormatName((Media.PixelFormat)x);
                }
            }
            LogManager.Instance.Write("[GLES] : Valid FBO targets " + fmtstring);
        }