Example #1
0
        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;
		}
Example #3
0
 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;
		}
Example #5
0
        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;
        }
Example #6
0
 /// <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();
     }
 }
Example #7
0
        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))
            {
            }
        }
Example #8
0
        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);
            }
        }
Example #9
0
        /// <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");
            }
        }
Example #10
0
 public virtual RenderTexture CreateRenderTexture(string name, GLES2SurfaceDesc target, bool writeGamme, int fsaa)
 {
     return(null);
 }
Example #11
0
		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" );
			}
		}
Example #13
0
        public override Graphics.RenderTexture CreateRenderTexture(string name, GLES2SurfaceDesc target, bool writeGamme, int fsaa)
        {
            var retVal = new GLES2FBORenderTexture(this, name, target, writeGamme, fsaa);

            return(retVal);
        }
Example #14
0
		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 );
			}
		}
Example #15
0
		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 ) ) {}
		}
Example #16
0
		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 ] );
				}
			}
		}
Example #17
0
		public virtual RenderTexture CreateRenderTexture( string name, GLES2SurfaceDesc target, bool writeGamme, int fsaa )
		{
			return null;
		}
Example #18
0
        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();
			}
		}
Example #20
0
		public override Graphics.RenderTexture CreateRenderTexture( string name, GLES2SurfaceDesc target, bool writeGamme, int fsaa )
		{
			var retVal = new GLES2FBORenderTexture( this, name, target, writeGamme, fsaa );
			return retVal;
		}