public void AttachColorAttachment(int width, int height) { // For now TextureID = Gl.GenTexture(); Gl.BindTexture(TextureTarget.Texture2d, TextureID); Gl.TexImage2D(TextureTarget.Texture2d, 0, InternalFormat.Rgb, width, height, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero); Gl.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureMinFilter, Gl.LINEAR); Gl.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureMagFilter, Gl.LINEAR); Bind(); FramebufferAttachment attachment = (FramebufferAttachment)(colorAttachmentsCounter + (int)FramebufferAttachment.ColorAttachment0); Gl.FramebufferTexture2D(FramebufferTarget.Framebuffer, attachment, TextureTarget.Texture2d, TextureID, 0); Gl.DrawBuffers(new int[] { (int)attachment }); uint rbo = Gl.GenRenderbuffer(); Gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, rbo); Gl.RenderbufferStorage(RenderbufferTarget.Renderbuffer, InternalFormat.Depth24Stencil8, width, height); Gl.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthStencilAttachment, RenderbufferTarget.Renderbuffer, rbo); if (Gl.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferStatus.FramebufferComplete) { System.Diagnostics.Debug.WriteLine("ERROR::FRAMEBUFFER: Framebuffer is not complete!"); } Unbind(); }
/// <inheritdoc /> public override RenderTarget CreateRenderTarget(Vector2 size, bool smooth = false, TextureInternalFormat internalFormat = TextureInternalFormat.Rgba, TexturePixelFormat pixelFormat = TexturePixelFormat.Rgba, bool attachStencil = false) { RenderTarget resultTarget = null; InternalFormat intFormat = (InternalFormat)Enum.Parse(typeof(InternalFormat), internalFormat.ToString()); PixelFormat glFormat = (PixelFormat)Enum.Parse(typeof(PixelFormat), pixelFormat.ToString()); GLThread.ExecuteGLThread(() => { // Create the FBO which rendering will be done to. uint newFbo = Gl.GenFramebuffer(); Gl.BindFramebuffer(FramebufferTarget.Framebuffer, newFbo); // Create the texture. uint renderTexture = Gl.GenTexture(); Gl.BindTexture(TextureTarget.Texture2d, renderTexture); Gl.TexImage2D(TextureTarget.Texture2d, 0, intFormat, (int)size.X, (int)size.Y, 0, glFormat, PixelType.UnsignedByte, IntPtr.Zero); Gl.TexParameter(TextureTarget.Texture2d, TextureParameterName.TextureMinFilter, smooth ? Gl.LINEAR : Gl.NEAREST); Gl.TexParameter(TextureTarget.Texture2d, TextureParameterName.TextureMagFilter, smooth ? Gl.LINEAR : Gl.NEAREST); // Attach the texture to the frame buffer. Gl.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2d, renderTexture, 0); // Attach color components. int[] modes = { Gl.COLOR_ATTACHMENT0 }; Gl.DrawBuffers(modes); // Create render buffer. uint depthBuffer = Gl.GenRenderbuffer(); Gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, depthBuffer); Gl.RenderbufferStorage(RenderbufferTarget.Renderbuffer, InternalFormat.Depth24Stencil8, (int)size.X, (int)size.Y); Gl.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, attachStencil ? FramebufferAttachment.DepthStencilAttachment : FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, depthBuffer); // Check status. FramebufferStatus status = Gl.CheckFramebufferStatus(FramebufferTarget.Framebuffer); if (status != FramebufferStatus.FramebufferComplete) { Engine.Log.Warning($"Framebuffer creation failed. Error code {status}.", MessageSource.GL); } // Create the texture object. Texture targetTexture = new GLTexture(renderTexture, new Vector2(size.X, size.Y), null, $"FBO {newFbo} Texture"); // Create the render target object. resultTarget = new GlRenderTarget(newFbo, size, targetTexture); // Clear the target. ClearScreen(); CheckError("creating scale fbo"); // Restore bindings and so on. Engine.Renderer?.EnsureRenderTarget(); }); return(resultTarget); }
/// <summary> /// Allocate this RenderBuffer. /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> used for allocation. /// </param> /// <param name="w"> /// A <see cref="Int32"/> that specify the width of the renderbuffer. /// </param> /// <param name="h"> /// A <see cref="Int32"/> that specify the height of the renderbuffer. /// </param> public void Allocate(GraphicsContext ctx, uint w, uint h) { // Allocate buffer Gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, ObjectName); // Define buffer storage Gl.RenderbufferStorage(RenderbufferTarget.Renderbuffer, _InternalFormat.GetGlInternalFormat(), (int)w, (int)h); }
private static void RenderOsdFramebuffer(DeviceContext deviceContext) { IntPtr glContext = IntPtr.Zero; uint framebuffer = 0; uint renderbuffer = 0; try { // Create context and make current on this thread if ((glContext = deviceContext.CreateContext(IntPtr.Zero)) == IntPtr.Zero) { throw new System.ComponentModel.Win32Exception(System.Runtime.InteropServices.Marshal.GetLastWin32Error()); // XXX } deviceContext.MakeCurrent(glContext); // Create framebuffer resources int w = Math.Min(800, Gl.CurrentLimits.MaxRenderbufferSize); int h = Math.Min(600, Gl.CurrentLimits.MaxRenderbufferSize); renderbuffer = Gl.GenRenderbuffer(); Gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, renderbuffer); Gl.RenderbufferStorage(RenderbufferTarget.Renderbuffer, InternalFormat.Rgb8, w, h); framebuffer = Gl.GenFramebuffer(); Gl.BindFramebuffer(FramebufferTarget.ReadFramebuffer, framebuffer); Gl.BindFramebuffer(FramebufferTarget.Framebuffer, framebuffer); Gl.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, RenderbufferTarget.Renderbuffer, renderbuffer); FramebufferStatus framebufferStatus = Gl.CheckFramebufferStatus(FramebufferTarget.Framebuffer); if (framebufferStatus != FramebufferStatus.FramebufferComplete) { throw new InvalidOperationException("framebuffer not complete"); } Gl.DrawBuffers(Gl.COLOR_ATTACHMENT0); RenderOsd(w, h); Gl.ReadBuffer(ReadBufferMode.ColorAttachment0); SnapshotOsd(w, h); } finally { if (renderbuffer != 0) { Gl.DeleteRenderbuffers(renderbuffer); } if (framebuffer != 0) { Gl.DeleteFramebuffers(framebuffer); } if (glContext != IntPtr.Zero) { deviceContext.DeleteContext(glContext); } } }
/// <inheritdoc /> public override RenderTarget CreateMSAARenderTarget(int samples, Vector2 size, TextureInternalFormat internalFormat = TextureInternalFormat.Rgba, bool attachStencil = false) { RenderTarget resultTarget = null; InternalFormat intFormat = (InternalFormat)Enum.Parse(typeof(InternalFormat), internalFormat.ToString()); GLThread.ExecuteGLThread(() => { // Create the FBO. uint newFbo = Gl.GenFramebuffer(); Gl.BindFramebuffer(FramebufferTarget.Framebuffer, newFbo); // Create the texture. uint renderTexture = Gl.GenTexture(); Gl.BindTexture(TextureTarget.Texture2dMultisample, renderTexture); Gl.TexImage2DMultisample(TextureTarget.Texture2dMultisample, samples, intFormat, (int)size.X, (int)size.Y, true); // Attach the texture to the frame buffer. Gl.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2dMultisample, renderTexture, 0); // Attach color components. int[] modes = { Gl.COLOR_ATTACHMENT0 }; Gl.DrawBuffers(modes); // Create render buffer. uint depthBuffer = Gl.GenRenderbuffer(); Gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, depthBuffer); Gl.RenderbufferStorageMultisample(RenderbufferTarget.Renderbuffer, samples, InternalFormat.Depth24Stencil8, (int)size.X, (int)size.Y); Gl.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, attachStencil ? FramebufferAttachment.DepthStencilAttachment : FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, depthBuffer); // Check status. FramebufferStatus status = Gl.CheckFramebufferStatus(FramebufferTarget.Framebuffer); if (status != FramebufferStatus.FramebufferComplete) { Engine.Log.Warning($"MSAA Framebuffer creation failed. Error code {status}.", MessageSource.GL); } // Construct a texture object for it. Texture targetTexture = new GLTexture(renderTexture, new Vector2(size.X, size.Y), null, $"MSAA{samples} FBO Texture"); // Create the render target object. resultTarget = new GlRenderTarget(newFbo, size, targetTexture); // Clear the target. ClearScreen(); CheckError("creating msaa fbo"); // Restore bindings and so on. Engine.Renderer?.EnsureRenderTarget(); }); return(resultTarget); }
/// <summary> /// Actually create this GraphicsResource resources. /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> used for allocating resources. /// </param> protected override void CreateObject(GraphicsContext ctx) { int currentBinding; Gl.Get(Gl.RENDERBUFFER_BINDING, out currentBinding); Gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, ObjectName); // Define buffer storage Gl.RenderbufferStorage(RenderbufferTarget.Renderbuffer, _InternalFormat.GetGlInternalFormat(), (int)_Width, (int)_Height); // Restore previous RenderBuffer binding Gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, (uint)currentBinding); }
private uint CreateDepthBufferAttachment(int width, int height) { uint depthBuffer = Gl.GenRenderbuffer(); Gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, depthBuffer); Gl.RenderbufferStorage(RenderbufferTarget.Renderbuffer, InternalFormat.DepthComponent, width, height); Gl.FramebufferRenderbuffer(FramebufferTarget.Framebuffer , FramebufferAttachment.DepthAttachment , RenderbufferTarget.Renderbuffer , depthBuffer); return(depthBuffer); }
public override void Upload(Vector2 size, byte[] data, PixelFormat?pixelFormat = null, InternalFormat?internalFormat = null, PixelType?pixelType = null) { if (RenderBufferPtr != 0) { Gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, RenderBufferPtr); Gl.RenderbufferStorage(RenderbufferTarget.Renderbuffer, InternalFormat, (int)size.X, (int)size.Y); } if (Pointer == 0) { return; } base.Upload(size, data, pixelFormat, internalFormat, pixelType); }
private static void RenderOsdFramebuffer(DeviceContext deviceContext) { IntPtr glContext = IntPtr.Zero; uint framebuffer = 0; uint renderbuffer = 0; try { // Create context and make current on this thread if ((glContext = deviceContext.CreateContext(IntPtr.Zero)) == IntPtr.Zero) throw new System.ComponentModel.Win32Exception(System.Runtime.InteropServices.Marshal.GetLastWin32Error()); // XXX deviceContext.MakeCurrent(glContext); // Create framebuffer resources int w = Math.Min(800, Gl.CurrentLimits.MaxRenderBufferSize); int h = Math.Min(600, Gl.CurrentLimits.MaxRenderBufferSize); renderbuffer = Gl.GenRenderbuffer(); Gl.BindRenderbuffer(Gl.RENDERBUFFER, renderbuffer); Gl.RenderbufferStorage(Gl.RENDERBUFFER, Gl.RGB8, w, h); framebuffer = Gl.GenFramebuffer(); Gl.BindFramebuffer(Gl.READ_FRAMEBUFFER, framebuffer); Gl.BindFramebuffer(Gl.FRAMEBUFFER, framebuffer); Gl.FramebufferRenderbuffer(Gl.FRAMEBUFFER, Gl.COLOR_ATTACHMENT0, Gl.RENDERBUFFER, renderbuffer); int framebufferStatus = Gl.CheckFramebufferStatus(Gl.FRAMEBUFFER); if (framebufferStatus != Gl.FRAMEBUFFER_COMPLETE) throw new InvalidOperationException("framebuffer not complete"); Gl.DrawBuffers(Gl.COLOR_ATTACHMENT0); RenderOsd(w, h); Gl.ReadBuffer(ReadBufferMode.ColorAttachment0); SnapshotOsd(w, h); } finally { if (renderbuffer != 0) Gl.DeleteRenderbuffers(renderbuffer); if (framebuffer != 0) Gl.DeleteFramebuffers(framebuffer); if (glContext != IntPtr.Zero) deviceContext.DeleteContext(glContext); } }
public Framebuffer(Vector2I size) : base(Gl.GenFramebuffer(), buffer => Gl.BindFramebuffer(FramebufferTarget.Framebuffer, buffer), Gl.DeleteFramebuffers) { Gl.BindFramebuffer(FramebufferTarget.Framebuffer, Handle); //Color texture uint colorTexture = Gl.GenTexture(); Gl.BindTexture(TextureTarget.Texture2d, colorTexture); Gl.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureMinFilter, Gl.LINEAR); Gl.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureMagFilter, Gl.LINEAR); Gl.TexImage2D(TextureTarget.Texture2d, 0, InternalFormat.Rgba, size.X, size.Y, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero); Gl.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2d, colorTexture, 0); Texture = new Texture(colorTexture, size); //Depth render buffer uint depth = Gl.GenRenderbuffer(); Gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, depth); Gl.RenderbufferStorage(RenderbufferTarget.Renderbuffer, InternalFormat.DepthComponent, size.X, size.Y); Gl.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, depth); //Set OpenGL state Gl.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); Gl.Enable(EnableCap.Blend); Gl.Enable(EnableCap.Multisample); Gl.Enable(EnableCap.DepthTest); if (Gl.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferStatus.FramebufferComplete) { throw new Exception("Framebuffer failed to initialize."); } Gl.BindFramebuffer(FramebufferTarget.Framebuffer, 0); }
private static uint CreatePrefilteredEnvironmentMap(Shader shader, Action preRender) { var cube = new Cube(); var captureFbo = Gl.GenFramebuffer(); Gl.BindFramebuffer(FramebufferTarget.Framebuffer, captureFbo); var captureRbo = Gl.GenRenderbuffer(); Gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, captureRbo); Gl.RenderbufferStorage(RenderbufferTarget.Renderbuffer, InternalFormat.DepthComponent24, 128, 128); Gl.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, captureRbo); var prefilterMap = Gl.GenTexture(); Gl.BindTexture(TextureTarget.TextureCubeMap, prefilterMap); for (int i = 0; i < 6; ++i) { Gl.TexImage2D(TextureTarget.TextureCubeMapPositiveX + i, 0, InternalFormat.Rgb16f, 128, 128, 0, PixelFormat.Rgb, PixelType.Float, IntPtr.Zero); } Gl.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear); Gl.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); Gl.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); Gl.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); Gl.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapR, (int)TextureWrapMode.ClampToEdge); Gl.GenerateMipmap(TextureTarget.TextureCubeMap); var projMatrix = Matrix4x4f.Perspective(90f, 1.0f, 0.1f, 10.0f); var viewMatrices = new Matrix4x4f[] { Matrix4x4f.LookAt(new Vertex3f(0f, 0f, 0f), new Vertex3f(1f, 0f, 0f), new Vertex3f(0f, -1f, 0f)), Matrix4x4f.LookAt(new Vertex3f(0f, 0f, 0f), new Vertex3f(-1f, 0f, 0f), new Vertex3f(0f, -1f, 0f)), Matrix4x4f.LookAt(new Vertex3f(0f, 0f, 0f), new Vertex3f(0f, 1f, 0f), new Vertex3f(0f, 0f, 1f)), Matrix4x4f.LookAt(new Vertex3f(0f, 0f, 0f), new Vertex3f(0f, -1f, 0f), new Vertex3f(0f, 0f, -1f)), Matrix4x4f.LookAt(new Vertex3f(0f, 0f, 0f), new Vertex3f(0f, 0f, 1f), new Vertex3f(0f, -1f, 0f)), Matrix4x4f.LookAt(new Vertex3f(0f, 0f, 0f), new Vertex3f(0f, 0f, -1f), new Vertex3f(0f, -1f, 0f)), }; shader.Use(); preRender.Invoke(); shader.SetMatrix("projectionMatrix", projMatrix); Gl.BindFramebuffer(FramebufferTarget.Framebuffer, captureFbo); int mipLevels = 5; for (int mips = 0; mips < mipLevels; ++mips) { int mipSize = (int)(128 * (float)Math.Pow(0.5, mips)); Gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, captureRbo); Gl.RenderbufferStorage(RenderbufferTarget.Renderbuffer, InternalFormat.DepthComponent24, mipSize, mipSize); Gl.Viewport(0, 0, mipSize, mipSize); float roughness = mips / (float)(mipLevels - 1); shader.SetFloat("roughness", roughness); for (int i = 0; i < 6; ++i) { shader.SetMatrix("viewMatrix", viewMatrices[i]); Gl.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.TextureCubeMapPositiveX + i, prefilterMap, mips); Gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); cube.Draw(); } } Gl.BindFramebuffer(FramebufferTarget.Framebuffer, 0); return(prefilterMap); }
public ScreenController(IntPtr window) { this.window = window; var glcontext = SDL.SDL_GL_CreateContext(window); SDL.SDL_GL_SetSwapInterval(1); shader = new ShaderProgram( File.ReadAllText(Assets.LoadPath("outputvert.glsl")), File.ReadAllText(Assets.LoadPath("outputfrag.glsl")) ); framebuffer = Gl.GenFramebuffer(); Gl.BindFramebuffer(FramebufferTarget.Framebuffer, framebuffer); texture = Gl.GenTexture(); Gl.UseProgram(shader); Gl.BindTexture(TextureTarget.Texture2D, texture); Gl.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, screenWidth, screenHeight, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero); Gl.TexParameteri(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, TextureParameter.Nearest); Gl.TexParameteri(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, TextureParameter.Nearest); var renderBuffer = Gl.GenRenderbuffer(); Gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, renderBuffer); Gl.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.DepthComponent16, screenWidth, screenHeight); Gl.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, renderBuffer); Gl.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, texture, 0); Gl.DrawBuffer(DrawBufferMode.ColorAttachment0); var error = Gl.CheckFramebufferStatus(FramebufferTarget.Framebuffer); switch (error) { case FramebufferErrorCode.FramebufferComplete: break; default: Console.WriteLine($"fbo error: {error}"); break; } vertices = new VBO <Vector3>( new Vector3[] { new Vector3(-1, -1, 0), new Vector3(1, -1, 0), new Vector3(1, 1, 0), new Vector3(-1, 1, 0), } ); uvs = new VBO <Vector2>( new Vector2[] { new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1), } ); triangles = new VBO <uint>( new uint[] { 0, 1, 2, 0, 2, 3 }, BufferTarget.ElementArrayBuffer ); drawScreen = new DrawRenderer( new ShaderProgram( File.ReadAllText(Assets.LoadPath("screenvert.glsl")), File.ReadAllText(Assets.LoadPath("screenfrag.glsl")) ) ); }
public void Unbind() { Gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, 0); }
public void Bind() { Gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, Handle); }