Пример #1
0
        public ITexture Bind(bool CreateNewTexture, Size size)
        {
            VerifyThreadAffinity();

            // Cache viewport rect to restore when unbinding
            cv = ViewportRectangle();

            OpenGL.glFlush();
            OpenGL.CheckGLError();
            OpenGL.glBindFramebuffer(OpenGL.FRAMEBUFFER_EXT, framebuffer);
            OpenGL.CheckGLError();
            ITextureInternal tex = null;

            if (CreateNewTexture)
            {
                tex = new Texture();
            }

            this.texture.Add(tex);
            tex.SetEmpty(size.Width, size.Height);

            OpenGL.glFramebufferTexture2D(OpenGL.FRAMEBUFFER_EXT, OpenGL.COLOR_ATTACHMENT0_EXT, OpenGL.GL_TEXTURE_2D, tex.ID, 0);
            OpenGL.CheckGLError();

            OpenGL.glViewport(0, 0, size.Width, size.Height);
            OpenGL.CheckGLError();
            OpenGL.glClearColor(0, 0, 0, 0);
            OpenGL.CheckGLError();
            OpenGL.glClear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
            OpenGL.CheckGLError();
            return(tex);
        }
Пример #2
0
        public byte[] GetData()
        {
            VerifyThreadAffinity();
            var data = new byte[4 * Size.Width * Size.Height];

            // GLES doesn't support glGetTexImage so data must be read back via a frame buffer
            if (OpenGL.Features.HasFlag(OpenGL.GLFeatures.GLES))
            {
                // Query the active framebuffer so we can restore it afterwards
                int lastFramebuffer;
                OpenGL.glGetIntegerv(OpenGL.GL_FRAMEBUFFER_BINDING, out lastFramebuffer);

                uint framebuffer;
                OpenGL.glGenFramebuffers(1, out framebuffer);
                OpenGL.glBindFramebuffer(OpenGL.GL_FRAMEBUFFER, framebuffer);
                OpenGL.CheckGLError();

                OpenGL.glFramebufferTexture2D(OpenGL.GL_FRAMEBUFFER, OpenGL.GL_COLOR_ATTACHMENT0, OpenGL.GL_TEXTURE_2D, texture, 0);
                OpenGL.CheckGLError();

                unsafe
                {
                    fixed(byte *ptr = &data[0])
                    {
                        var intPtr = new IntPtr((void *)ptr);

                        OpenGL.glReadPixels(0, 0, Size.Width, Size.Height, OpenGL.GL_BGRA, OpenGL.GL_UNSIGNED_BYTE, intPtr);
                        OpenGL.CheckGLError();
                    }
                }

                OpenGL.glBindFramebuffer(OpenGL.GL_FRAMEBUFFER, (uint)lastFramebuffer);
                OpenGL.glDeleteFramebuffers(1, ref framebuffer);
                OpenGL.CheckGLError();
            }
            else
            {
                OpenGL.glBindTexture(OpenGL.GL_TEXTURE_2D, texture);
                unsafe
                {
                    fixed(byte *ptr = &data[0])
                    {
                        var intPtr = new IntPtr((void *)ptr);

                        OpenGL.glGetTexImage(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_BGRA,
                                             OpenGL.GL_UNSIGNED_BYTE, intPtr);
                    }
                }

                OpenGL.CheckGLError();
            }

            return(data);
        }
Пример #3
0
        public FrameBuffer(Size size, ITextureInternal texture, Color clearColor)
        {
            this.size       = size;
            this.clearColor = clearColor;
            if (!Exts.IsPowerOf2(size.Width) || !Exts.IsPowerOf2(size.Height))
            {
                throw new InvalidDataException("Frame buffer size ({0}x{1}) must be a power of two".F(size.Width, size.Height));
            }

            OpenGL.glGenFramebuffers(1, out framebuffer);
            OpenGL.CheckGLError();
            OpenGL.glBindFramebuffer(OpenGL.GL_FRAMEBUFFER, framebuffer);
            OpenGL.CheckGLError();

            // Color
            this.texture = texture;
            texture.SetEmpty(size.Width, size.Height);
            OpenGL.glFramebufferTexture2D(OpenGL.GL_FRAMEBUFFER, OpenGL.GL_COLOR_ATTACHMENT0, OpenGL.GL_TEXTURE_2D, texture.ID, 0);
            OpenGL.CheckGLError();

            // Depth
            OpenGL.glGenRenderbuffers(1, out depth);
            OpenGL.CheckGLError();

            OpenGL.glBindRenderbuffer(OpenGL.GL_RENDERBUFFER, depth);
            OpenGL.CheckGLError();

            var glDepth = OpenGL.Profile == GLProfile.Embedded ? OpenGL.GL_DEPTH_COMPONENT16 : OpenGL.GL_DEPTH_COMPONENT;

            OpenGL.glRenderbufferStorage(OpenGL.GL_RENDERBUFFER, glDepth, size.Width, size.Height);
            OpenGL.CheckGLError();

            OpenGL.glFramebufferRenderbuffer(OpenGL.GL_FRAMEBUFFER, OpenGL.GL_DEPTH_ATTACHMENT, OpenGL.GL_RENDERBUFFER, depth);
            OpenGL.CheckGLError();

            // Test for completeness
            var status = OpenGL.glCheckFramebufferStatus(OpenGL.GL_FRAMEBUFFER);

            if (status != OpenGL.GL_FRAMEBUFFER_COMPLETE)
            {
                var error = "Error creating framebuffer: {0}\n{1}".F(status, new StackTrace());
                OpenGL.WriteGraphicsLog(error);
                throw new InvalidOperationException("OpenGL Error: See graphics.log for details.");
            }

            // Restore default buffer
            OpenGL.glBindFramebuffer(OpenGL.GL_FRAMEBUFFER, 0);
            OpenGL.CheckGLError();
        }
Пример #4
0
        public FrameBuffer(Size size)
        {
            this.size = size;
            if (!Exts.IsPowerOf2(size.Width) || !Exts.IsPowerOf2(size.Height))
            {
                throw new InvalidDataException("Frame buffer size ({0}x{1}) must be a power of two".F(size.Width, size.Height));
            }

            OpenGL.glGenFramebuffers(1, out framebuffer);
            OpenGL.CheckGLError();
            OpenGL.glBindFramebuffer(OpenGL.FRAMEBUFFER_EXT, framebuffer);
            OpenGL.CheckGLError();

            // Color
            texture = new Texture();
            texture.SetEmpty(size.Width, size.Height);
            OpenGL.glFramebufferTexture2D(OpenGL.FRAMEBUFFER_EXT, OpenGL.COLOR_ATTACHMENT0_EXT, OpenGL.GL_TEXTURE_2D, texture.ID, 0);
            OpenGL.CheckGLError();

            // Depth
            OpenGL.glGenRenderbuffers(1, out depth);
            OpenGL.CheckGLError();

            OpenGL.glBindRenderbuffer(OpenGL.RENDERBUFFER_EXT, depth);
            OpenGL.CheckGLError();

            OpenGL.glRenderbufferStorage(OpenGL.RENDERBUFFER_EXT, OpenGL.GL_DEPTH_COMPONENT, size.Width, size.Height);
            OpenGL.CheckGLError();

            OpenGL.glFramebufferRenderbuffer(OpenGL.FRAMEBUFFER_EXT, OpenGL.DEPTH_ATTACHMENT_EXT, OpenGL.RENDERBUFFER_EXT, depth);
            OpenGL.CheckGLError();

            // Test for completeness
            var status = OpenGL.glCheckFramebufferStatus(OpenGL.FRAMEBUFFER_EXT);

            if (status != OpenGL.FRAMEBUFFER_COMPLETE_EXT)
            {
                var error = "Error creating framebuffer: {0}\n{1}".F(status, new StackTrace());
                OpenGL.WriteGraphicsLog(error);
                throw new InvalidOperationException("OpenGL Error: See graphics.log for details.");
            }

            // Restore default buffer
            OpenGL.glBindFramebuffer(OpenGL.FRAMEBUFFER_EXT, 0);
            OpenGL.CheckGLError();
        }
Пример #5
0
        public void ReBind(ITextureInternal t)
        {
            VerifyThreadAffinity();

            // Cache viewport rect to restore when unbinding
            cv = ViewportRectangle();

            OpenGL.glFlush();
            OpenGL.CheckGLError();
            OpenGL.glBindFramebuffer(OpenGL.FRAMEBUFFER_EXT, framebuffer);
            OpenGL.CheckGLError();


            OpenGL.glFramebufferTexture2D(OpenGL.FRAMEBUFFER_EXT, OpenGL.COLOR_ATTACHMENT0_EXT, OpenGL.GL_TEXTURE_2D, t.ID, 0);
            OpenGL.CheckGLError();

            OpenGL.glViewport(0, 0, size.Width, size.Height);
            OpenGL.CheckGLError();
            OpenGL.glClearColor(0, 0, 0, 0);
            OpenGL.CheckGLError();
            OpenGL.glClear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
            OpenGL.CheckGLError();
        }
Пример #6
0
        public byte[] GetData()
        {
            VerifyThreadAffinity();
            var data = new byte[4 * Size.Width * Size.Height];

            // GLES doesn't support glGetTexImage so data must be read back via a frame buffer
            if (OpenGL.Profile == GLProfile.Embedded)
            {
                // Query the active framebuffer so we can restore it afterwards
                int lastFramebuffer;
                OpenGL.glGetIntegerv(OpenGL.GL_FRAMEBUFFER_BINDING, out lastFramebuffer);

                uint framebuffer;
                OpenGL.glGenFramebuffers(1, out framebuffer);
                OpenGL.glBindFramebuffer(OpenGL.GL_FRAMEBUFFER, framebuffer);
                OpenGL.CheckGLError();

                OpenGL.glFramebufferTexture2D(OpenGL.GL_FRAMEBUFFER, OpenGL.GL_COLOR_ATTACHMENT0, OpenGL.GL_TEXTURE_2D, texture, 0);
                OpenGL.CheckGLError();

                var canReadBGRA = OpenGL.Features.HasFlag(OpenGL.GLFeatures.ESReadFormatBGRA);

                unsafe
                {
                    fixed(byte *ptr = &data[0])
                    {
                        var intPtr = new IntPtr(ptr);

                        var format = canReadBGRA ? OpenGL.GL_BGRA : OpenGL.GL_RGBA;

                        OpenGL.glReadPixels(0, 0, Size.Width, Size.Height, format, OpenGL.GL_UNSIGNED_BYTE, intPtr);
                        OpenGL.CheckGLError();
                    }
                }

                // Convert RGBA to BGRA
                if (!canReadBGRA)
                {
                    for (var i = 0; i < 4 * Size.Width * Size.Height; i += 4)
                    {
                        var temp = data[i];
                        data[i]     = data[i + 2];
                        data[i + 2] = temp;
                    }
                }

                OpenGL.glBindFramebuffer(OpenGL.GL_FRAMEBUFFER, (uint)lastFramebuffer);
                OpenGL.glDeleteFramebuffers(1, ref framebuffer);
                OpenGL.CheckGLError();
            }
            else
            {
                OpenGL.glBindTexture(OpenGL.GL_TEXTURE_2D, texture);
                unsafe
                {
                    fixed(byte *ptr = &data[0])
                    {
                        var intPtr = new IntPtr((void *)ptr);

                        OpenGL.glGetTexImage(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_BGRA,
                                             OpenGL.GL_UNSIGNED_BYTE, intPtr);
                    }
                }

                OpenGL.CheckGLError();
            }

            return(data);
        }