/// <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); }
/// <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); }
/// <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); }
/// <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"); } }