Exemplo n.º 1
0
        /// <summary>
        ///   Try a certain packed depth/stencil format, and return the status.
        /// </summary>
        /// <param name="packedFormat"> </param>
        /// <returns> true if this combo is supported, false if not </returns>
        private bool TryPacketFormat(All packedFormat)
        {
            int packedRB = 0;

            /// Generate renderbuffer
            OpenGLOES.GenRenderbuffers(1, ref packedRB);

            //bind it to FBO
            OpenGLOES.BindRenderbuffer(All.RenderbufferOes, packedRB);

            /// Allocate storage for buffer
            OpenGLOES.RenderbufferStorage(All.RenderbufferOes, packedFormat, ProbeSize, ProbeSize);

            /// Attach depth
            OpenGLOES.FramebufferRenderbuffer(All.FramebufferOes, All.DepthAttachmentOes, All.RenderbufferOes, packedRB);

            /// Attach stencil
            OpenGLOES.FramebufferRenderbuffer(All.FramebufferOes, All.StencilAttachmentOes, All.RenderbufferOes, packedRB);

            All status = OpenGLOES.CheckFramebufferStatus(All.FramebufferOes);

            /// Detach and destroy
            OpenGLOES.FramebufferRenderbuffer(All.FramebufferOes, All.DepthAttachmentOes, All.RenderbufferOes, 0);
            OpenGLOES.FramebufferRenderbuffer(All.FramebufferOes, All.StencilAttachmentOes, All.RenderbufferOes, 0);
            OpenGLOES.DeleteRenderbuffers(1, ref packedRB);

            return(status == All.FramebufferCompleteOes);
        }
Exemplo n.º 2
0
        /// <summary>
        ///   Bind FrameBufferObject
        /// </summary>
        public void Bind()
        {
            /// Bind it to FBO
            int fb = this._multiSampleFB != 0 ? this._multiSampleFB : this._fb;

            OpenGLOES.BindFramebuffer(All.FramebufferOes, fb);
            GLESConfig.GlCheckError(this);
        }
Exemplo n.º 3
0
        /// <summary>
        ///   Try a certain FBO format, and return the status. Also sets mDepthRB and mStencilRB.
        /// </summary>
        /// <param name="depthFormat"> </param>
        /// <param name="stencilFormat"> </param>
        /// <returns> true if this combo is supported, false if not </returns>
        private bool TryFormat(All depthFormat, All stencilFormat)
        {
            int status = 0, depthRB = 0, stencilRB = 0;

            if (depthFormat != 0)
            {
                /// Generate depth renderbuffer
                OpenGLOES.GenRenderbuffers(1, ref depthRB);

                /// Bind it to FBO;
                OpenGLOES.RenderbufferStorage(All.RenderbufferOes, depthFormat, ProbeSize, ProbeSize);

                /// Attach depth
                OpenGLOES.FramebufferRenderbuffer(All.FramebufferOes, All.DepthAttachmentOes, All.RenderbufferOes, depthRB);
            }
            // Stencil buffers aren't available on iPhone
            if (stencilFormat != 0)
            {
                /// Generate stencil renderbuffer
                OpenGLOES.GenRenderbuffers(1, ref stencilRB);

                //bind it to FBO
                OpenGLOES.BindRenderbuffer(All.RenderbufferOes, stencilRB);

                /// Allocate storage for stencil buffer
                OpenGLOES.RenderbufferStorage(All.RenderbufferOes, stencilFormat, ProbeSize, ProbeSize);

                /// Attach stencil
                OpenGLOES.FramebufferRenderbuffer(All.FramebufferOes, All.StencilAttachmentOes, All.RenderbufferOes, stencilRB);
            }

            status = (int)OpenGLOES.CheckFramebufferStatus(All.FramebufferOes);

            OpenGLOES.FramebufferRenderbuffer(All.FramebufferOes, All.DepthAttachmentOes, All.RenderbufferOes, depthRB);
            OpenGLOES.FramebufferRenderbuffer(All.FramebufferOes, All.StencilAttachmentOes, All.RenderbufferOes, stencilRB);

            if (depthRB != 0)
            {
                OpenGLOES.DeleteRenderbuffers(1, ref depthRB);
            }

            if (stencilRB != 0)
            {
                OpenGLOES.DeleteRenderbuffers(1, ref stencilRB);
            }

            //Clear OpenGL Errors create because of the evaluation
            while (OpenGL.GetError() != All.NoError)
            {
                ;
            }

            return(status == (int)All.FramebufferCompleteOes);
        }
Exemplo n.º 4
0
 /// <summary>
 /// </summary>
 public GLESFBORTTManager()
     : base()
 {
     LogManager.Instance.Write("FBO CTOR ENTER");
     this._renderBuffer = new Dictionary <RBFormat, RBRef>();
     TemporaryFBO       = 0;
     DetectFBOFormats();
     OpenGLOES.GenFramebuffers(1, ref this._tempFbo);
     GLESConfig.GlCheckError(this);
     LogManager.Instance.Write("FBO CTOR EXIT");
 }
Exemplo n.º 5
0
 /// <summary>
 /// </summary>
 /// <param name="manager"> </param>
 /// <param name="fsaa"> </param>
 public GLESFrameBufferObject(GLESFBORTTManager manager, int fsaa)
 {
     /// Generate framebuffer object
     OpenGLOES.GenFramebuffers(1, ref this._fb);
     GLESConfig.GlCheckError(this);
     this._depth   = new GLESSurfaceDescription();
     this._stencil = new GLESSurfaceDescription();
     for (int x = 0; x < Configuration.Config.MaxMultipleRenderTargets; x++)
     {
         this._color[x] = new GLESSurfaceDescription();
     }
 }
Exemplo n.º 6
0
        /// <summary>
        /// </summary>
        public void Dispose()
        {
            Manager.ReleaseRenderbuffer(this._depth);
            Manager.ReleaseRenderbuffer(this._stencil);
            Manager.ReleaseRenderbuffer(this._multisampleColorBuffer);

            /// Delete framebuffer object
            OpenGLOES.DeleteFramebuffers(1, ref this._fb);
            GLESConfig.GlCheckError(this);

            if (this._multiSampleFB != 0)
            {
                OpenGLOES.DeleteFramebuffers(1, ref this._multiSampleFB);
            }

            GLESConfig.GlCheckError(this);
        }
Exemplo n.º 7
0
        /// <summary>
        /// </summary>
        /// <param name="disposeManagedResources"> </param>
        protected override void dispose(bool disposeManagedResources)
        {
            if (!IsDisposed)
            {
                if (disposeManagedResources)
                {
                    if (data != null)
                    {
                        OpenGLOES.DeleteRenderbuffers(1, ref this._renderbufferID);
                        GLESConfig.GlCheckError(this);
                    }
                }
            }

            // If it is available, make the call to the
            // base class's Dispose(Boolean) method
            base.dispose(disposeManagedResources);
        }
Exemplo n.º 8
0
        /// <summary>
        /// </summary>
        /// <param name="format"> </param>
        /// <param name="width"> </param>
        /// <param name="height"> </param>
        /// <param name="numSamples"> </param>
        public GLESRenderBuffer(All format, int width, int height, int numSamples)
            : base(width, height, 1, GLESPixelUtil.GetClosestAxiomFormat(format), BufferUsage.WriteOnly)
        {
            _glInternalFormat = format;
            /// Generate renderbuffer
            OpenGLOES.GenRenderbuffers(1, ref this._renderbufferID);
            GLESConfig.GlCheckError(this);
            /// Bind it to FBO
            OpenGLOES.BindRenderbuffer(All.RenderbufferOes, this._renderbufferID);
            GLESConfig.GlCheckError(this);

            /// Allocate storage for depth buffer
            if (numSamples <= 0)
            {
                OpenGLOES.RenderbufferStorage(All.RenderbufferOes, format, width, height);
                GLESConfig.GlCheckError(this);
            }
        }
Exemplo n.º 9
0
        /// <summary>
        ///   Bind a certain render target if it is a FBO. If it is not a FBO, bind the main frame buffer.
        /// </summary>
        /// <param name="target"> </param>
        public override void Bind(Graphics.RenderTarget target)
        {
            /// Check if the render target is in the rendertarget->FBO map
            GLESFrameBufferObject fbo = null;

            fbo = target["FBO"] as GLESFrameBufferObject;
            if (fbo != null)
            {
                fbo.Bind();
            }
            else
            {
                // Old style context (window/pbuffer) or copying render texture
#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);
            }
        }
Exemplo n.º 10
0
 /// <summary>
 /// </summary>
 protected override void UnlockImpl()
 {
     if (this._lockedToScratch)
     {
         if (this._scratchUploadOnUnlock)
         {
             // have to write the data back to vertex buffer
             this.WriteData(this._scratchOffset, this._scratchSize, this._scratchPtr, this._scratchOffset == 0 && this._scratchSize == sizeInBytes);
         }
         // deallocate from scratch buffer
         ((GLESHardwareBufferManager)HardwareBufferManager.Instance).DeallocateScratch(this._scratchPtr);
         this._lockedToScratch = false;
     }
     else
     {
         OpenGL.BindBuffer(All.ElementArrayBuffer, this._bufferId);
         GLESConfig.GlCheckError(this);
         if (!OpenGLOES.UnmapBuffer(All.ElementArrayBuffer))
         {
             throw new AxiomException("Buffer data corrupted, please reload");
         }
     }
     isLocked = false;
 }
Exemplo n.º 11
0
        /// <summary>
        /// </summary>
        /// <param name="offset"> </param>
        /// <param name="length"> </param>
        /// <param name="locking"> </param>
        /// <returns> </returns>
        protected override BufferBase LockImpl(int offset, int length, BufferLocking locking)
        {
            All access = 0;

            if (isLocked)
            {
                throw new AxiomException("Invalid attempt to lock an index buffer that has already been locked");
            }

            BufferBase retPtr = null;

            if (length < MapBufferThreshold)
            {
                retPtr = ((GLESHardwareBufferManager)HardwareBufferManager.Instance).AllocateScratch(length);
                if (retPtr != null)
                {
                    this._lockedToScratch       = true;
                    this._scratchOffset         = offset;
                    this._scratchSize           = length;
                    this._scratchPtr            = retPtr;
                    this._scratchUploadOnUnlock = (locking != BufferLocking.ReadOnly);

                    if (locking != BufferLocking.Discard)
                    {
                        this.ReadData(offset, length, retPtr);
                    }
                }
            }
            else
            {
                throw new AxiomException("Invalid Buffer lockSize");
            }

            if (retPtr == null)
            {
                OpenGL.BindBuffer(All.ElementArrayBuffer, this._bufferId);
                GLESConfig.GlCheckError(this);
                // Use glMapBuffer
                if (locking == BufferLocking.Discard)
                {
                    OpenGL.BufferData(All.ElementArrayBuffer, new IntPtr(sizeInBytes), IntPtr.Zero, GLESHardwareBufferManager.GetGLUsage(usage));
                    GLESConfig.GlCheckError(this);
                }
                if ((usage & BufferUsage.WriteOnly) != 0)
                {
                    access = All.WriteOnlyOes;
                }

                IntPtr pBuffer = OpenGLOES.MapBuffer(All.ElementArrayBuffer, access);
                GLESConfig.GlCheckError(this);
                if (pBuffer == IntPtr.Zero)
                {
                    throw new AxiomException("Index Buffer: Out of memory");
                }
                unsafe
                {
                    // return offset
                    retPtr = BufferBase.Wrap(pBuffer, sizeInBytes);
                }

                this._lockedToScratch = false;
            }
            isLocked = true;

            return(retPtr);
        }
Exemplo n.º 12
0
 /// <summary>
 /// </summary>
 /// <param name="attachment"> </param>
 /// <param name="zOffset"> </param>
 public override void BindToFramebuffer(All attachment, int zOffset)
 {
     Utilities.Contract.Requires(zOffset < Depth);
     OpenGLOES.FramebufferRenderbuffer(All.FramebufferOes, attachment, All.RenderbufferOes, this._renderbufferID);
     GLESConfig.GlCheckError(this);
 }
Exemplo n.º 13
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);
        }
Exemplo n.º 14
0
        /// <summary>
        /// </summary>
        private void Intialize()
        {
            // Release depth and stencil, if they were bound
            Manager.ReleaseRenderbuffer(this._depth);
            Manager.ReleaseRenderbuffer(this._stencil);
            Manager.ReleaseRenderbuffer(this._multisampleColorBuffer);

            /// First buffer must be bound
            if (this._color[0].Buffer == null)
            {
                throw new AxiomException("Attachment 0 must have surface attached");
            }

            // If we're doing multisampling, then we need another FBO which contains a
            // renderbuffer which is set up to multisample, and we'll blit it to the final
            // FBO afterwards to perform the multisample resolve. In that case, the
            // mMultisampleFB is bound during rendering and is the one with a depth/stencil

            /// Store basic stats
            int width  = this._color[0].Buffer.Width;
            int height = this._color[0].Buffer.Height;
            All format = this._color[0].Buffer.GLFormat;

            Media.PixelFormat axiomFormat = this._color[0].Buffer.Format;

            // Bind simple buffer to add colour attachments
            OpenGLOES.BindFramebuffer(All.FramebufferOes, this._fb);
            GLESConfig.GlCheckError(this);

            /// Bind all attachment points to frame buffer
            for (int x = 0; x < Configuration.Config.MaxMultipleRenderTargets; x++)
            {
                if (this._color[x].Buffer != null)
                {
                    if (this._color[x].Buffer.Width != width || this._color[x].Buffer.Height != height)
                    {
                        string ss = string.Empty;
                        ss += "Attachment " + x + " has incompatible size ";
                        ss += this._color[x].Buffer.Width + "x" + this._color[0].Buffer.Height;
                        ss += ". It must be of the same as the size of surface 0, ";
                        ss += width + "x" + height;
                        ss += ".";
                        throw new AxiomException(ss);
                    }
                    if (this._color[x].Buffer.GLFormat != format)
                    {
                        string ss = string.Empty;
                        ss += "Attachment " + x + " has incompatible format.";
                        throw new AxiomException(ss);
                    }
                    this._color[x].Buffer.BindToFramebuffer(All.ColorAttachment0Oes + x, this._color[x].ZOffset);
                }
                else
                {
                    // Detach
                    OpenGLOES.FramebufferRenderbuffer(All.FramebufferOes, All.ColorAttachment0Oes + x, All.RenderbufferOes, 0);
                    GLESConfig.GlCheckError(this);
                }
            }             //end for x

            // Now deal with depth / stencil
            if (this._multiSampleFB != 0)
            {
                // Bind multisample buffer
                OpenGLOES.BindFramebuffer(All.FramebufferOes, this._multiSampleFB);
                GLESConfig.GlCheckError(this);

                // Create AA render buffer (color)
                // note, this can be shared too because we blit it to the final FBO
                // right after the render is finished
                this._multisampleColorBuffer = Manager.RequestRenderbuffer(format, width, height, this._numSamples);

                // Attach it, because we won't be attaching below and non-multisample has
                // actually been attached to other FBO
                this._multisampleColorBuffer.Buffer.BindToFramebuffer(All.ColorAttachment0Oes, this._multisampleColorBuffer.ZOffset);

                // depth & stencil will be dealt with below
            }

            /// Depth buffer is not handled here anymore.
            /// See GLESFrameBufferObject::attachDepthBuffer() & RenderSystem::setDepthBufferFor()

            /// Do glDrawBuffer calls
            var bufs = new All[Configuration.Config.MaxMultipleRenderTargets];
            int n    = 0;

            for (int x = 0; x < Configuration.Config.MaxMultipleRenderTargets; x++)
            {
                // Fill attached colour buffers
                if (this._color[x].Buffer != null)
                {
                    bufs[x] = All.ColorAttachment0Oes + x;
                    // Keep highest used buffer + 1
                    n = x + 1;
                }
                else
                {
                    bufs[x] = All.Never;
                }
            }             //end for x

            /// Check status
            All status = OpenGLOES.CheckFramebufferStatus(All.FramebufferOes);

            GLESConfig.GlCheckError(this);
            /// Bind main buffer
#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);

            switch (status)
            {
            case All.FramebufferCompleteOes:
                // everything is fine
                break;

            case All.FramebufferUnsupportedOes:
                throw new AxiomException("All framebuffer formats with this texture internal format unsupported");

            default:
                throw new AxiomException("Framebuffer incomplete or other FBO status error");
            }
        }