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); }
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); }
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(); }
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(); }
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(); }
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); }