Subversion Repositories AndroidProjects

Rev

Blame | Last modification | View Log | RSS feed

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Tao.OpenGl;
using OpenTK.Graphics.OpenGL;

namespace BauzoidNET.graphics.texture
{
    public class Framebuffer : GraphicsObject
    {
        const int DEFAULT_FRAMEBUFFER = 0;

        protected Texture mColorTexture = null;

        private static int[] FRAMEBUFFERID = new int[1];
        private int mBufferID = 0;
        private int mDepthBufferID = 0;

        protected int mBufferWidth = 0;
        protected int mBufferHeight = 0;
        protected bool mHasDepth = false;

        public Framebuffer(Graphics graphics, int width, int height, bool hasDepth) : base(graphics)
        {
            mBufferWidth = width;
            mBufferHeight = height;
            mHasDepth = hasDepth;

            create();
        }

        public void createTexture()
        {
            mColorTexture = new Texture(getGraphics(), mBufferWidth, mBufferHeight);
            mColorTexture.setFilter(Texture.Filter.LINEAR, Texture.Filter.LINEAR);
            mColorTexture.setWrap(Texture.Wrap.CLAMP_TO_EDGE, Texture.Wrap.CLAMP_TO_EDGE);
        }

        public void create()
        {
            createTexture();

            //Gl.glGenFramebuffers(1, FRAMEBUFFERID);
            GL.GenFramebuffers(1, FRAMEBUFFERID);
            mBufferID = FRAMEBUFFERID[0];

            if (hasDepth())
            {
                GL.GenRenderbuffers(1, FRAMEBUFFERID);
                mDepthBufferID = FRAMEBUFFERID[0];
            }

            //mColorTexture.bind();
            GL.BindTexture(TextureTarget.Texture2D, mColorTexture.getTextureHandle());

            if (hasDepth())
            {
                GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, mDepthBufferID);
                GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.DepthComponent16, mColorTexture.getWidth(), mColorTexture.getHeight());
            }

            GL.BindFramebuffer(FramebufferTarget.Framebuffer, mBufferID);
            GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, mColorTexture.getTextureHandle(), 0);

            if (hasDepth())
            {
                GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, mDepthBufferID);
            }

            FramebufferErrorCode result = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);

            GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, 0);
            GL.BindTexture(TextureTarget.Texture2D, 0);
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, DEFAULT_FRAMEBUFFER);

            if (result != FramebufferErrorCode.FramebufferComplete)
            {
                mColorTexture.dispose();
                if (hasDepth())
                {
                    FRAMEBUFFERID[0] = mDepthBufferID;
                    GL.DeleteBuffers(1, FRAMEBUFFERID);
                }

                FRAMEBUFFERID[0] = mBufferID;
                GL.DeleteFramebuffers(1, FRAMEBUFFERID);

                if (result == FramebufferErrorCode.FramebufferIncompleteAttachment)
                {
                    System.Diagnostics.Debug.WriteLine("frame buffer couldn't be constructed: incomplete attachment");
                }
                if (result == FramebufferErrorCode.FramebufferIncompleteDimensionsExt)
                {
                    System.Diagnostics.Debug.WriteLine("frame buffer couldn't be constructed: incomplete dimensions");
                }
                if (result == FramebufferErrorCode.FramebufferIncompleteMissingAttachment)
                {
                    System.Diagnostics.Debug.WriteLine("frame buffer couldn't be constructed: missing attachment");
                }
            }
        }

        public void dispose()
        {
            if (mColorTexture != null)
            {
                mColorTexture.dispose();
                mColorTexture = null;
            }

            if (hasDepth())
            {
                FRAMEBUFFERID[0] = mDepthBufferID;
                GL.DeleteRenderbuffers(1, FRAMEBUFFERID);
            }

            FRAMEBUFFERID[0] = mBufferID;
            GL.DeleteFramebuffers(1, FRAMEBUFFERID);
        }

        public void activate()
        {
            GL.Viewport(0, 0, mColorTexture.getWidth(), mColorTexture.getHeight());
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, mBufferID);
        }

        public void deactivate()
        {
            GL.Viewport(0, 0, getGraphics().getWidth(), getGraphics().getHeight());
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, DEFAULT_FRAMEBUFFER);
        }

        public bool hasDepth()
        {
            return mHasDepth;
        }

        public int getBufferID()
        {
            return mBufferID;
        }

        public Texture getColorTexture()
        {
            return mColorTexture;
        }

    }
}