/// <summary> /// </summary> /// <param name="surface"> </param> public void ReleaseRenderbuffer(GLESSurfaceDescription surface) { if (surface.Buffer == null) { return; } var key = new RBFormat(surface.Buffer.GLFormat, surface.Buffer.Width, surface.Buffer.Height, surface.NumSamples); RBRef refval; if (this._renderBuffer.TryGetValue(key, out refval)) { // Decrease refcount refval.RefCount--; if (refval.RefCount == 0) { // If refcount reaches zero, delete buffer and remove from map refval.Buffer.Dispose(); this._renderBuffer.Remove(key); } else { this._renderBuffer[key] = refval; } } }
/// <summary> /// Request a render buffer. If format is GL_NONE, return a zero buffer. /// </summary> /// <param name="format"> </param> /// <param name="width"> </param> /// <param name="height"> </param> /// <param name="fsaa"> </param> /// <returns> </returns> public GLESSurfaceDescription RequestRenderbuffer(All format, int width, int height, int fsaa) { var retval = new GLESSurfaceDescription(); if (format != All.Zero) { var key = new RBFormat(format, width, height, fsaa); RBRef iter; if (this._renderBuffer.TryGetValue(key, out iter)) { retval.Buffer = iter.Buffer; retval.ZOffset = 0; retval.NumSamples = fsaa; iter.RefCount++; } else { // New one var rb = new GLESRenderBuffer(format, width, height, fsaa); this._renderBuffer.Add(key, new RBRef(rb)); retval.Buffer = rb; retval.ZOffset = 0; retval.NumSamples = fsaa; } } return(retval); }
/// <summary> /// /// </summary> /// <param name="name"></param> /// <param name="target"></param> /// <param name="writeGamma"></param> /// <param name="fsaa"></param> public GLESPBRenderTexture( GLESPBRTTManager manager, string name, GLESSurfaceDescription target, bool writeGamma, int fsaa ) : base( name, target, writeGamma, fsaa ) { this._manager = manager; this._pbFormat = PixelUtil.GetComponentType( target.Buffer.Format ); this._manager.RequestPBuffer( _pbFormat, Width, Height ); }
/// <summary> /// /// </summary> /// <param name="name"></param> /// <param name="target"></param> /// <param name="writeGamma"></param> /// <param name="fsaa"></param> public GLESRenderTexture( string name, GLESSurfaceDescription target, bool writeGamma, int fsaa ) : base( target.Buffer, target.ZOffset ) { Name = name; HardwareGammaEnabled = writeGamma; FSAA = fsaa; }
/// <summary> /// </summary> /// <param name="name"> </param> /// <param name="target"> </param> /// <param name="writeGamma"> </param> /// <param name="fsaa"> </param> public GLESRenderTexture(string name, GLESSurfaceDescription target, bool writeGamma, int fsaa) : base(target.Buffer, target.ZOffset) { Name = name; HardwareGammaEnabled = writeGamma; FSAA = fsaa; }
/// <summary> /// </summary> /// <param name="name"> </param> /// <param name="target"> </param> /// <param name="writeGamma"> </param> /// <param name="fsaa"> </param> public GLESPBRenderTexture(GLESPBRTTManager manager, string name, GLESSurfaceDescription target, bool writeGamma, int fsaa) : base(name, target, writeGamma, fsaa) { this._manager = manager; this._pbFormat = PixelUtil.GetComponentType(target.Buffer.Format); this._manager.RequestPBuffer(this._pbFormat, Width, Height); }
public GLESFBORenderTexture( GLESFBORTTManager manager, string name, GLESSurfaceDescription target, bool writeGamma, int fsaa ) : base( name, target, writeGamma, fsaa ) { this._fbo = new GLESFrameBufferObject( manager, fsaa ); GLESConfig.GlCheckError( this ); Width = _fbo.Width; Height = _fbo.Height; }
/// <summary> /// Bind a surface to a certain attachment point. /// </summary> /// <param name="attachment"> 0..MaxMultipleRenderTargets-1 </param> /// <param name="target"> </param> public void BindSurface(int attachment, GLESSurfaceDescription target) { Contract.Requires(attachment < Configuration.Config.MaxMultipleRenderTargets); this._color[attachment] = target; // Re-initialise if (this._color[0].Buffer != null) { Intialize(); } }
/// <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]); } } }
/// <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(); } }
public override object this[string attribute] { get { switch (attribute.ToLower()) { case "target": var target = new GLESSurfaceDescription(); target.Buffer = (GLESHardwarePixelBuffer)pixelBuffer; target.ZOffset = zOffset; return(target); } return(base[attribute]); } }
public override object this[ string attribute ] { get { switch ( attribute.ToLower() ) { case "target": GLESSurfaceDescription target = new GLESSurfaceDescription(); target.Buffer = (GLESHardwarePixelBuffer)pixelBuffer; target.ZOffset = zOffset; return target; } return base[ attribute ]; } }
/// <summary> /// Request the specify render buffer in case shared somewhere. Ignore silently if surface.buffer is null. /// </summary> /// <param name="surface"> </param> public void RequestRenderbuffer(GLESSurfaceDescription surface) { if (surface.Buffer == null) { return; } var key = new RBFormat(surface.Buffer.GLFormat, surface.Buffer.Width, surface.Buffer.Height, surface.NumSamples); Utilities.Contract.Requires(this._renderBuffer.ContainsKey(key)); Utilities.Contract.Requires(this._renderBuffer[key].Buffer == surface.Buffer); RBRef refval = this._renderBuffer[key]; refval.RefCount++; this._renderBuffer[key] = refval; }
/// <summary> /// Request a render buffer. If format is GL_NONE, return a zero buffer. /// </summary> /// <param name="format"> </param> /// <param name="width"> </param> /// <param name="height"> </param> /// <param name="fsaa"> </param> /// <returns> </returns> public GLESSurfaceDescription RequestRenderbuffer( All format, int width, int height, int fsaa ) { var retval = new GLESSurfaceDescription(); if ( format != All.Zero ) { var key = new RBFormat( format, width, height, fsaa ); RBRef iter; if ( this._renderBuffer.TryGetValue( key, out iter ) ) { retval.Buffer = iter.Buffer; retval.ZOffset = 0; retval.NumSamples = fsaa; iter.RefCount++; } else { // New one var rb = new GLESRenderBuffer( format, width, height, fsaa ); this._renderBuffer.Add( key, new RBRef( rb ) ); retval.Buffer = rb; retval.ZOffset = 0; retval.NumSamples = fsaa; } } return retval; }
/// <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"); } }
/// <summary> /// Create a texture rendertarget object /// </summary> /// <param name="name"> </param> /// <param name="target"> </param> /// <param name="writeGame"> </param> /// <param name="fsaa"> </param> /// <returns> </returns> public abstract RenderTexture CreateRenderTexture( string name, GLESSurfaceDescription target, bool writeGama, int fsaa );
public GLESCopyingRenderTexture( GLESCopyingRTTManager manager, string name, GLESSurfaceDescription target, bool writeGamma, int fsaa ) : base( name, target, writeGamma, fsaa ) { }
/// <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" ); } }
/// <summary> /// Bind a surface to a certain attachment point. /// </summary> /// <param name="attachment"> 0..MaxMultipleRenderTargets-1 </param> /// <param name="target"> </param> public void BindSurface( int attachment, GLESSurfaceDescription target ) { Contract.Requires( attachment < Configuration.Config.MaxMultipleRenderTargets ); this._color[ attachment ] = target; // Re-initialise if ( this._color[ 0 ].Buffer != null ) { Intialize(); } }
/// <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(); } }
/// <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 ) { _target = targetfmt; _textureId = id; _face = face; _level = level; _softwareMipmap = crappyCard; GLESConfig.GlCheckError( this ); OpenGL.BindTexture( All.Texture2D, _textureId ); GLESConfig.GlCheckError( this ); // Get face identifier _faceTarget = _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/" + this.GetHashCode() + "/" + basename; GLESSurfaceDescription target = new GLESSurfaceDescription(); target.Buffer = this; target.ZOffset = zoffset; RenderTexture trt = GLESRTTManager.Instance.CreateRenderTexture( name, target, writeGamma, fsaa ); _sliceTRT.Add( trt ); Root.Instance.RenderSystem.AttachRenderTarget( _sliceTRT[ zoffset ] ); } } }
/// <summary> /// </summary> /// <param name="surface"> </param> public void ReleaseRenderbuffer( GLESSurfaceDescription surface ) { if ( surface.Buffer == null ) { return; } var key = new RBFormat( surface.Buffer.GLFormat, surface.Buffer.Width, surface.Buffer.Height, surface.NumSamples ); RBRef refval; if ( this._renderBuffer.TryGetValue( key, out refval ) ) { // Decrease refcount refval.RefCount--; if ( refval.RefCount == 0 ) { // If refcount reaches zero, delete buffer and remove from map refval.Buffer.Dispose(); this._renderBuffer.Remove( key ); } else { this._renderBuffer[ key ] = refval; } } }
public override Graphics.RenderTexture CreateRenderTexture( string name, GLESSurfaceDescription target, bool writeGama, int fsaa ) { return new GLESPBRenderTexture( this, name, target, writeGama, fsaa ); }
/// <summary> /// Create a texture rendertarget object /// </summary> /// <param name="name"> </param> /// <param name="target"> </param> /// <param name="writeGame"> </param> /// <param name="fsaa"> </param> /// <returns> </returns> public abstract RenderTexture CreateRenderTexture(string name, GLESSurfaceDescription target, bool writeGama, int fsaa);
public override Graphics.RenderTexture CreateRenderTexture(string name, GLESSurfaceDescription target, bool writeGama, int fsaa) { return(new GLESPBRenderTexture(this, name, target, writeGama, fsaa)); }
/// <summary> /// Request the specify render buffer in case shared somewhere. Ignore silently if surface.buffer is null. /// </summary> /// <param name="surface"> </param> public void RequestRenderbuffer( GLESSurfaceDescription surface ) { if ( surface.Buffer == null ) { return; } var key = new RBFormat( surface.Buffer.GLFormat, surface.Buffer.Width, surface.Buffer.Height, surface.NumSamples ); Utilities.Contract.Requires( this._renderBuffer.ContainsKey( key ) ); Utilities.Contract.Requires( this._renderBuffer[ key ].Buffer == surface.Buffer ); RBRef refval = this._renderBuffer[ key ]; refval.RefCount++; this._renderBuffer[ key ] = refval; }