public GLES2SurfaceDesc RequestRenderBuffer(GLenum format, int width, int height, int fsaa) { var retVal = new GLES2SurfaceDesc(); retVal.buffer = null; if (format != GLenum.None) { var key = new RBFormat(format, width, height, fsaa); if (this.renderBufferMap.ContainsKey(key)) { retVal.buffer = this.renderBufferMap[key].buffer; retVal.zoffset = 0; retVal.numSamples = fsaa; } else { //New one var rb = new GLES2RenderBuffer(format, width, height, fsaa); this.renderBufferMap.Add(key, new RBRef(rb)); retVal.buffer = rb; retVal.zoffset = 0; retVal.numSamples = fsaa; } } return(retVal); }
public GLES2RenderTexture( string name, GLES2SurfaceDesc target, bool writeGamma, int fsaa ) : base( target.buffer, target.zoffset ) { base.name = name; hwGamma = writeGamma; base.fsaa = fsaa; }
public GLES2RenderTexture(string name, GLES2SurfaceDesc target, bool writeGamma, int fsaa) : base(target.buffer, target.zoffset) { base.name = name; hwGamma = writeGamma; base.fsaa = fsaa; }
public GLES2FBORenderTexture( GLES2FBOManager manager, string name, GLES2SurfaceDesc target, bool writeGamma, int fsaa ) : base( name, target, writeGamma, fsaa ) { this.fb.BindSurface( 0, target ); width = this.fb.Width; height = this.fb.Height; }
public GLES2FBORenderTexture(GLES2FBOManager manager, string name, GLES2SurfaceDesc target, bool writeGamma, int fsaa) : base(name, target, writeGamma, fsaa) { this.fb.BindSurface(0, target); width = this.fb.Width; height = this.fb.Height; }
/// <summary> /// Binds a surface to a certain attachment point. attachemnt: 0..Axiom.Config.MaxMultipleRenderTarget-1 /// </summary> /// <param name="attachment"> </param> /// <param name="target"> </param> public void BindSurface(int attachment, GLES2SurfaceDesc target) { this._color[attachment] = target; //Re-initialize if (this._color[0].buffer != null) { this.Initialize(); } }
public void RequestRenderBuffer(ref GLES2SurfaceDesc surface) { if (surface.buffer == null) { return; } var key = new RBFormat(surface.buffer.GLFormat, surface.buffer.Width, surface.buffer.Height, surface.numSamples); if (this.renderBufferMap.ContainsKey(key)) { } }
public void ReleaseRenderBuffer(GLES2SurfaceDesc surface) { if (surface.buffer == null) { return; } var key = new RBFormat(surface.buffer.GLFormat, surface.buffer.Width, surface.buffer.Height, surface.numSamples); if (this.renderBufferMap.ContainsKey(key)) { this.renderBufferMap[key].buffer.Dispose(); this.renderBufferMap.Remove(key); } }
/// <summary> /// Initializes object (find suitable depth and stencil format). Must be called every time the bindings change. It will throw an exception if: -Attachment point 0 has no binding -Not all bound surfaces have the same size -Not all bound surfaces have the same internal format /// </summary> private void Initialize() { this._manager.ReleaseRenderBuffer(this._depth); this._manager.ReleaseRenderBuffer(this._stencil); this._manager.ReleaseRenderBuffer(this._multiSampleColorBuffer); //First buffer must be bound if (this._color[0].buffer == null) { throw new Core.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 var maxSupportedMRTs = Core.Root.Instance.RenderSystem.Capabilities.MultiRenderTargetCount; //Store basic stats int width = this._color[0].buffer.Width; int height = this._color[0].buffer.Height; GLenum format = this._color[0].buffer.GLFormat; //Bind simple buffer to add color attachments GL.BindFramebuffer(OpenTK.Graphics.ES20.All.Framebuffer, this._fb); GLES2Config.GlCheckError(this); //bind all attachment points to frame buffer for (int x = 0; x < maxSupportedMRTs; x++) { if (this._color[x].buffer != null) { if (this._color[x].buffer.Width != width || this._color[x].buffer.Height != height) { var ss = new StringBuilder(); ss.Append("Attachment " + x + " has incompatible size "); ss.Append(this._color[x].buffer.Width + "x" + this._color[x].buffer.Height); ss.Append(". It must be of the same as the size of surface 0, "); ss.Append(width + "x" + height.ToString()); ss.Append("."); throw new Core.AxiomException(ss.ToString()); } if (this._color[x].buffer.GLFormat != format) { throw new Core.AxiomException("Attachment " + x.ToString() + " has incompatible format."); } this._color[x].buffer.BindToFramebuffer((GLenum)((int)GLenum.ColorAttachment0) + x, this._color[x].zoffset); } else { //Detach GL.FramebufferRenderbuffer(GLenum.Framebuffer, (GLenum)((int)GLenum.ColorAttachment0) + x, GLenum.Renderbuffer, 0); GLES2Config.GlCheckError(this); } } //Now deal with depth/stencil if (this._multiSampleFB > 0) { //Bind multisample buffer GL.BindFramebuffer(GLenum.Framebuffer, this._multiSampleFB); GLES2Config.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 = this._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(GLenum.ColorAttachment0, this._multiSampleColorBuffer.zoffset); //depth & stencil will be dealt with below } /// Depth buffer is not handled here anymore. /// See GLES2FrameBufferObject::attachDepthBuffer() & RenderSystem::setDepthBufferFor() var bufs = new GLenum[Configuration.Config.MaxMultipleRenderTargets]; for (int x = 0; x < Configuration.Config.MaxMultipleRenderTargets; x++) { //Fill attached color buffers if (this._color[x].buffer != null) { bufs[x] = (GLenum)((int)GLenum.ColorAttachment0) + x; } else { bufs[x] = GLenum.None; } } //Check status var status = GL.CheckFramebufferStatus(GLenum.Framebuffer); GLES2Config.GlCheckError(this); //Possible todo: /*Port notes * Ogre leaves a comment indicating that the screen buffer for iOS * is 1 as opposed to 0 in the case of most other devices * I'd like to think that OpenTK takes care of this for us and have defaulted it * to 0 */ GL.BindFramebuffer(GLenum.Framebuffer, 0); GLES2Config.GlCheckError(this); switch (status) { case GLenum.FramebufferComplete: //All is good break; case GLenum.FramebufferUnsupported: throw new Core.AxiomException("All framebuffer formats with this texture internal format unsupported"); default: throw new Core.AxiomException("Framebuffer incomplete or other FBO status error"); } }
public virtual RenderTexture CreateRenderTexture(string name, GLES2SurfaceDesc target, bool writeGamme, int fsaa) { return(null); }
public GLES2SurfaceDesc RequestRenderBuffer( GLenum format, int width, int height, int fsaa ) { var retVal = new GLES2SurfaceDesc(); retVal.buffer = null; if ( format != GLenum.None ) { var key = new RBFormat( format, width, height, fsaa ); if ( this.renderBufferMap.ContainsKey( key ) ) { retVal.buffer = this.renderBufferMap[ key ].buffer; retVal.zoffset = 0; retVal.numSamples = fsaa; } else { //New one var rb = new GLES2RenderBuffer( format, width, height, fsaa ); this.renderBufferMap.Add( key, new RBRef( rb ) ); retVal.buffer = rb; retVal.zoffset = 0; retVal.numSamples = fsaa; } } return retVal; }
/// <summary> /// Initializes object (find suitable depth and stencil format). Must be called every time the bindings change. It will throw an exception if: -Attachment point 0 has no binding -Not all bound surfaces have the same size -Not all bound surfaces have the same internal format /// </summary> private void Initialize() { this._manager.ReleaseRenderBuffer( this._depth ); this._manager.ReleaseRenderBuffer( this._stencil ); this._manager.ReleaseRenderBuffer( this._multiSampleColorBuffer ); //First buffer must be bound if ( this._color[ 0 ].buffer == null ) { throw new Core.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 var maxSupportedMRTs = Core.Root.Instance.RenderSystem.Capabilities.MultiRenderTargetCount; //Store basic stats int width = this._color[ 0 ].buffer.Width; int height = this._color[ 0 ].buffer.Height; GLenum format = this._color[ 0 ].buffer.GLFormat; //Bind simple buffer to add color attachments GL.BindFramebuffer( OpenTK.Graphics.ES20.All.Framebuffer, this._fb ); GLES2Config.GlCheckError( this ); //bind all attachment points to frame buffer for ( int x = 0; x < maxSupportedMRTs; x++ ) { if ( this._color[ x ].buffer != null ) { if ( this._color[ x ].buffer.Width != width || this._color[ x ].buffer.Height != height ) { var ss = new StringBuilder(); ss.Append( "Attachment " + x + " has incompatible size " ); ss.Append( this._color[ x ].buffer.Width + "x" + this._color[ x ].buffer.Height ); ss.Append( ". It must be of the same as the size of surface 0, " ); ss.Append( width + "x" + height.ToString() ); ss.Append( "." ); throw new Core.AxiomException( ss.ToString() ); } if ( this._color[ x ].buffer.GLFormat != format ) { throw new Core.AxiomException( "Attachment " + x.ToString() + " has incompatible format." ); } this._color[ x ].buffer.BindToFramebuffer( (GLenum) ( (int) GLenum.ColorAttachment0 ) + x, this._color[ x ].zoffset ); } else { //Detach GL.FramebufferRenderbuffer( GLenum.Framebuffer, (GLenum) ( (int) GLenum.ColorAttachment0 ) + x, GLenum.Renderbuffer, 0 ); GLES2Config.GlCheckError( this ); } } //Now deal with depth/stencil if ( this._multiSampleFB > 0 ) { //Bind multisample buffer GL.BindFramebuffer( GLenum.Framebuffer, this._multiSampleFB ); GLES2Config.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 = this._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( GLenum.ColorAttachment0, this._multiSampleColorBuffer.zoffset ); //depth & stencil will be dealt with below } /// Depth buffer is not handled here anymore. /// See GLES2FrameBufferObject::attachDepthBuffer() & RenderSystem::setDepthBufferFor() var bufs = new GLenum[ Configuration.Config.MaxMultipleRenderTargets ]; for ( int x = 0; x < Configuration.Config.MaxMultipleRenderTargets; x++ ) { //Fill attached color buffers if ( this._color[ x ].buffer != null ) { bufs[ x ] = (GLenum) ( (int) GLenum.ColorAttachment0 ) + x; } else { bufs[ x ] = GLenum.None; } } //Check status var status = GL.CheckFramebufferStatus( GLenum.Framebuffer ); GLES2Config.GlCheckError( this ); //Possible todo: /*Port notes * Ogre leaves a comment indicating that the screen buffer for iOS * is 1 as opposed to 0 in the case of most other devices * I'd like to think that OpenTK takes care of this for us and have defaulted it * to 0 */ GL.BindFramebuffer( GLenum.Framebuffer, 0 ); GLES2Config.GlCheckError( this ); switch ( status ) { case GLenum.FramebufferComplete: //All is good break; case GLenum.FramebufferUnsupported: throw new Core.AxiomException( "All framebuffer formats with this texture internal format unsupported" ); default: throw new Core.AxiomException( "Framebuffer incomplete or other FBO status error" ); } }
public override Graphics.RenderTexture CreateRenderTexture(string name, GLES2SurfaceDesc target, bool writeGamme, int fsaa) { var retVal = new GLES2FBORenderTexture(this, name, target, writeGamme, fsaa); return(retVal); }
public void ReleaseRenderBuffer( GLES2SurfaceDesc surface ) { if ( surface.buffer == null ) { return; } var key = new RBFormat( surface.buffer.GLFormat, surface.buffer.Width, surface.buffer.Height, surface.numSamples ); if ( this.renderBufferMap.ContainsKey( key ) ) { this.renderBufferMap[ key ].buffer.Dispose(); this.renderBufferMap.Remove( key ); } }
public void RequestRenderBuffer( ref GLES2SurfaceDesc surface ) { if ( surface.buffer == null ) { return; } var key = new RBFormat( surface.buffer.GLFormat, surface.buffer.Width, surface.buffer.Height, surface.numSamples ); if ( this.renderBufferMap.ContainsKey( key ) ) {} }
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 ] ); } } }
public virtual RenderTexture CreateRenderTexture( string name, GLES2SurfaceDesc target, bool writeGamme, int fsaa ) { return null; }
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]); } } }
/// <summary> /// Binds a surface to a certain attachment point. attachemnt: 0..Axiom.Config.MaxMultipleRenderTarget-1 /// </summary> /// <param name="attachment"> </param> /// <param name="target"> </param> public void BindSurface( int attachment, GLES2SurfaceDesc target ) { this._color[ attachment ] = target; //Re-initialize if ( this._color[ 0 ].buffer != null ) { this.Initialize(); } }
public override Graphics.RenderTexture CreateRenderTexture( string name, GLES2SurfaceDesc target, bool writeGamme, int fsaa ) { var retVal = new GLES2FBORenderTexture( this, name, target, writeGamme, fsaa ); return retVal; }