public void SetTexture(int index, ShaderStage stage, ITexture texture) { int unit = _program.GetTextureUnit(stage, index); if (unit != -1 && texture != null) { if (unit == 0) { _unit0Texture = ((TextureView)texture); } else { ((TextureView)texture).Bind(unit); } } }
public void AttachColor(int index, TextureView color) { FramebufferAttachment attachment = FramebufferAttachment.ColorAttachment0 + index; if (HwCapabilities.Vendor == HwCapabilities.GpuVendor.Amd || HwCapabilities.Vendor == HwCapabilities.GpuVendor.Intel) { GL.FramebufferTexture(FramebufferTarget.Framebuffer, attachment, color?.GetIncompatibleFormatViewHandle() ?? 0, 0); _colors[index] = color; } else { GL.FramebufferTexture(FramebufferTarget.Framebuffer, attachment, color?.Handle ?? 0, 0); } }
public void Copy( TextureView src, TextureView dst, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter) { int oldReadFramebufferHandle = GL.GetInteger(GetPName.ReadFramebufferBinding); int oldDrawFramebufferHandle = GL.GetInteger(GetPName.DrawFramebufferBinding); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, GetSrcFramebufferLazy()); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, GetDstFramebufferLazy()); Attach(FramebufferTarget.ReadFramebuffer, src.Format, src.Handle); Attach(FramebufferTarget.DrawFramebuffer, dst.Format, dst.Handle); ClearBufferMask mask = GetMask(src.Format); BlitFramebufferFilter filter = linearFilter ? BlitFramebufferFilter.Linear : BlitFramebufferFilter.Nearest; GL.ReadBuffer(ReadBufferMode.ColorAttachment0); GL.DrawBuffer(DrawBufferMode.ColorAttachment0); GL.Disable(EnableCap.RasterizerDiscard); GL.Disable(IndexedEnableCap.ScissorTest, 0); GL.BlitFramebuffer( srcRegion.X1, srcRegion.Y1, srcRegion.X2, srcRegion.Y2, dstRegion.X1, dstRegion.Y1, dstRegion.X2, dstRegion.Y2, mask, filter); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle); ((Pipeline)_renderer.Pipeline).RestoreScissor0Enable(); ((Pipeline)_renderer.Pipeline).RestoreRasterizerDiscard(); }
public void Dispose() { if (_incompatibleFormatView != null) { _incompatibleFormatView.Dispose(); _incompatibleFormatView = null; } if (Handle != 0) { GL.DeleteTexture(Handle); _parent.DecrementViewsCount(); Handle = 0; } }
public void Copy( TextureView src, TextureView dst, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter) { GL.Disable(EnableCap.FramebufferSrgb); int oldReadFramebufferHandle = GL.GetInteger(GetPName.ReadFramebufferBinding); int oldDrawFramebufferHandle = GL.GetInteger(GetPName.DrawFramebufferBinding); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, GetSrcFramebufferLazy()); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, GetDstFramebufferLazy()); Attach(FramebufferTarget.ReadFramebuffer, src.Format, src.Handle); Attach(FramebufferTarget.DrawFramebuffer, dst.Format, dst.Handle); ClearBufferMask mask = GetMask(src.Format); BlitFramebufferFilter filter = linearFilter ? BlitFramebufferFilter.Linear : BlitFramebufferFilter.Nearest; GL.ReadBuffer(ReadBufferMode.ColorAttachment0); GL.DrawBuffer(DrawBufferMode.ColorAttachment0); GL.BlitFramebuffer( srcRegion.X1, srcRegion.Y1, srcRegion.X2, srcRegion.Y2, dstRegion.X1, dstRegion.Y1, dstRegion.X2, dstRegion.Y2, mask, filter); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle); GL.Enable(EnableCap.FramebufferSrgb); }
public void CopyTo(ITexture destination, int firstLayer, int firstLevel) { TextureView destinationView = (TextureView)destination; TextureCopyUnscaled.Copy(_info, destinationView._info, Handle, destinationView.Handle, 0, firstLayer, 0, firstLevel); if (destinationView._emulatedViewParent != null) { TextureCopyUnscaled.Copy( _info, destinationView._emulatedViewParent._info, Handle, destinationView._emulatedViewParent.Handle, 0, destinationView.FirstLayer, 0, destinationView.FirstLevel); } }
public void Draw( TextureView texture, Sampler sampler, float x0, float y0, float x1, float y1, float s0, float t0, float s1, float t1) { EnsureInitialized(); GL.UseProgram(_programHandle); texture.Bind(0); sampler.Bind(0); if (x0 > x1) { float temp = s0; s0 = s1; s1 = temp; } if (y0 > y1) { float temp = t0; t0 = t1; t1 = temp; } GL.Uniform1(_uniformSrcX0Location, s0); GL.Uniform1(_uniformSrcY0Location, t0); GL.Uniform1(_uniformSrcX1Location, s1); GL.Uniform1(_uniformSrcY1Location, t1); GL.ViewportIndexed(0, MathF.Min(x0, x1), MathF.Min(y0, y1), MathF.Abs(x1 - x0), MathF.Abs(y1 - y0)); GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4); }
public int GetIncompatibleFormatViewHandle() { // AMD and Intel has a bug where the view format is always ignored, // it uses the parent format instead. // As workaround we create a new texture with the correct // format, and then do a copy after the draw. if (_parent.Info.Format != Format) { if (_incompatibleFormatView == null) { _incompatibleFormatView = (TextureView)_renderer.CreateTexture(_info); } TextureCopyUnscaled.Copy(_parent.Info, _incompatibleFormatView._info, _parent.Handle, _incompatibleFormatView.Handle, FirstLayer, 0, FirstLevel, 0); return(_incompatibleFormatView.Handle); } return(Handle); }
/// <summary> /// Add a texture that is not being used anymore to the resource pool to be used later. /// Both the texture's view and storage should be completely unused. /// </summary> /// <param name="view">The texture's view</param> public void AddTexture(TextureView view) { lock (_lock) { List <DisposedTexture> list; if (!_textures.TryGetValue(view.Info, out list)) { list = new List <DisposedTexture>(); _textures.Add(view.Info, list); } list.Add(new DisposedTexture() { Info = view.Info, View = view, ScaleFactor = view.ScaleFactor, RemainingFrames = DisposedLiveFrames }); } }
public void SetRenderTargets(ITexture[] colors, ITexture depthStencil) { EnsureFramebuffer(); for (int index = 0; index < colors.Length; index++) { TextureView color = (TextureView)colors[index]; _framebuffer.AttachColor(index, color); } TextureView depthStencilView = (TextureView)depthStencil; _framebuffer.AttachDepthStencil(depthStencilView); _framebuffer.SetDrawBuffers(colors.Length); _hasDepthBuffer = depthStencil != null && depthStencilView.Format != Format.S8Uint; UpdateDepthTest(); }
public void AttachDepthStencil(TextureView depthStencil) { // Detach the last depth/stencil buffer if there is any. if (_lastDsAttachment != 0) { GL.FramebufferTexture(FramebufferTarget.Framebuffer, _lastDsAttachment, 0, 0); } if (depthStencil != null) { FramebufferAttachment attachment; if (IsPackedDepthStencilFormat(depthStencil.Format)) { attachment = FramebufferAttachment.DepthStencilAttachment; } else if (IsDepthOnlyFormat(depthStencil.Format)) { attachment = FramebufferAttachment.DepthAttachment; } else { attachment = FramebufferAttachment.StencilAttachment; } GL.FramebufferTexture( FramebufferTarget.Framebuffer, attachment, depthStencil.Handle, 0); _lastDsAttachment = attachment; } else { _lastDsAttachment = 0; } }
private void CopyTextureToFrameBufferRGB(int drawFramebuffer, int readFramebuffer, TextureView view, ImageCrop crop) { (int oldDrawFramebufferHandle, int oldReadFramebufferHandle) = ((Pipeline)_renderer.Pipeline).GetBoundFramebuffers(); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, drawFramebuffer); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, readFramebuffer); TextureView viewConverted = view.Format.IsBgr() ? _renderer.TextureCopy.BgraSwap(view) : view; GL.FramebufferTexture( FramebufferTarget.ReadFramebuffer, FramebufferAttachment.ColorAttachment0, viewConverted.Handle, 0); GL.ReadBuffer(ReadBufferMode.ColorAttachment0); GL.Disable(EnableCap.RasterizerDiscard); GL.Disable(IndexedEnableCap.ScissorTest, 0); GL.Clear(ClearBufferMask.ColorBufferBit); int srcX0, srcX1, srcY0, srcY1; float scale = view.ScaleFactor; if (crop.Left == 0 && crop.Right == 0) { srcX0 = 0; srcX1 = (int)(view.Width / scale); } else { srcX0 = crop.Left; srcX1 = crop.Right; } if (crop.Top == 0 && crop.Bottom == 0) { srcY0 = 0; srcY1 = (int)(view.Height / scale); } else { srcY0 = crop.Top; srcY1 = crop.Bottom; } if (scale != 1f) { srcX0 = (int)(srcX0 * scale); srcY0 = (int)(srcY0 * scale); srcX1 = (int)Math.Ceiling(srcX1 * scale); srcY1 = (int)Math.Ceiling(srcY1 * scale); } float ratioX = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _height * crop.AspectRatioX / (_width * crop.AspectRatioY)); float ratioY = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _width * crop.AspectRatioY / (_height * crop.AspectRatioX)); int dstWidth = (int)(_width * ratioX); int dstHeight = (int)(_height * ratioY); int dstPaddingX = (_width - dstWidth) / 2; int dstPaddingY = (_height - dstHeight) / 2; int dstX0 = crop.FlipX ? _width - dstPaddingX : dstPaddingX; int dstX1 = crop.FlipX ? dstPaddingX : _width - dstPaddingX; int dstY0 = crop.FlipY ? dstPaddingY : _height - dstPaddingY; int dstY1 = crop.FlipY ? _height - dstPaddingY : dstPaddingY; if (ScreenCaptureRequested) { CaptureFrame(srcX0, srcY0, srcX1, srcY1, view.Format.IsBgr(), crop.FlipX, crop.FlipY); ScreenCaptureRequested = false; } GL.BlitFramebuffer( srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Linear); // Remove Alpha channel GL.ColorMask(false, false, false, true); GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f); GL.Clear(ClearBufferMask.ColorBufferBit); for (int i = 0; i < Constants.MaxRenderTargets; i++) { ((Pipeline)_renderer.Pipeline).RestoreComponentMask(i); } GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle); ((Pipeline)_renderer.Pipeline).RestoreScissor0Enable(); ((Pipeline)_renderer.Pipeline).RestoreRasterizerDiscard(); if (viewConverted != view) { viewConverted.Dispose(); } }
private void CopyTextureToFrameBufferRGB(int drawFramebuffer, int readFramebuffer, TextureView view, ImageCrop crop) { bool[] oldFramebufferColorWritemask = new bool[4]; (int oldDrawFramebufferHandle, int oldReadFramebufferHandle) = ((Pipeline)_renderer.Pipeline).GetBoundFramebuffers(); GL.GetBoolean(GetIndexedPName.ColorWritemask, drawFramebuffer, oldFramebufferColorWritemask); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, drawFramebuffer); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, readFramebuffer); GL.FramebufferTexture( FramebufferTarget.ReadFramebuffer, FramebufferAttachment.ColorAttachment0, view.Handle, 0); GL.ReadBuffer(ReadBufferMode.ColorAttachment0); GL.Disable(EnableCap.RasterizerDiscard); GL.Disable(IndexedEnableCap.ScissorTest, 0); GL.Clear(ClearBufferMask.ColorBufferBit); int srcX0, srcX1, srcY0, srcY1; if (crop.Left == 0 && crop.Right == 0) { srcX0 = 0; srcX1 = view.Width; } else { srcX0 = crop.Left; srcX1 = crop.Right; } if (crop.Top == 0 && crop.Bottom == 0) { srcY0 = 0; srcY1 = view.Height; } else { srcY0 = crop.Top; srcY1 = crop.Bottom; } float ratioX = MathF.Min(1f, (_height * (float)NativeWidth) / ((float)NativeHeight * _width)); float ratioY = MathF.Min(1f, (_width * (float)NativeHeight) / ((float)NativeWidth * _height)); int dstWidth = (int)(_width * ratioX); int dstHeight = (int)(_height * ratioY); int dstPaddingX = (_width - dstWidth) / 2; int dstPaddingY = (_height - dstHeight) / 2; int dstX0 = crop.FlipX ? _width - dstPaddingX : dstPaddingX; int dstX1 = crop.FlipX ? dstPaddingX : _width - dstPaddingX; int dstY0 = crop.FlipY ? dstPaddingY : _height - dstPaddingY; int dstY1 = crop.FlipY ? _height - dstPaddingY : dstPaddingY; GL.BlitFramebuffer( srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Linear); // Remove Alpha channel GL.ColorMask(drawFramebuffer, false, false, false, true); GL.ClearBuffer(ClearBuffer.Color, 0, new float[] { 0.0f, 0.0f, 0.0f, 1.0f }); GL.ColorMask(drawFramebuffer, oldFramebufferColorWritemask[0], oldFramebufferColorWritemask[1], oldFramebufferColorWritemask[2], oldFramebufferColorWritemask[3]); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle); ((Pipeline)_renderer.Pipeline).RestoreScissor0Enable(); ((Pipeline)_renderer.Pipeline).RestoreRasterizerDiscard(); }
public static void Copy(TextureView src, TextureView dst, int dstLayer, int dstLevel) { int srcWidth = src.Width; int srcHeight = src.Height; int srcDepth = src.DepthOrLayers; int srcLevels = src.Levels; srcWidth = Math.Max(1, srcWidth >> dstLevel); srcHeight = Math.Max(1, srcHeight >> dstLevel); if (src.Target == Target.Texture3D) { srcDepth = Math.Max(1, srcDepth >> dstLevel); } int dstWidth = dst.Width; int dstHeight = dst.Height; int dstDepth = dst.DepthOrLayers; int dstLevels = dst.Levels; // When copying from a compressed to a non-compressed format, // the non-compressed texture will have the size of the texture // in blocks (not in texels), so we must adjust that size to // match the size in texels of the compressed texture. if (!src.IsCompressed && dst.IsCompressed) { dstWidth = BitUtils.DivRoundUp(dstWidth, dst.BlockWidth); dstHeight = BitUtils.DivRoundUp(dstHeight, dst.BlockHeight); } else if (src.IsCompressed && !dst.IsCompressed) { dstWidth *= dst.BlockWidth; dstHeight *= dst.BlockHeight; } int width = Math.Min(srcWidth, dstWidth); int height = Math.Min(srcHeight, dstHeight); int depth = Math.Min(srcDepth, dstDepth); int levels = Math.Min(srcLevels, dstLevels); for (int level = 0; level < levels; level++) { // Stop copy if we are already out of the levels range. if (level >= src.Levels || dstLevel + level >= dst.Levels) { break; } GL.CopyImageSubData( src.Handle, src.Target.ConvertToImageTarget(), level, 0, 0, 0, dst.Handle, dst.Target.ConvertToImageTarget(), dstLevel + level, 0, 0, dstLayer, width, height, depth); width = Math.Max(1, width >> 1); height = Math.Max(1, height >> 1); if (src.Target == Target.Texture3D) { depth = Math.Max(1, depth >> 1); } } }
private void CopyTextureToFrameBufferRGB(int drawFramebuffer, int readFramebuffer, TextureView view, ImageCrop crop, Action <object> swapBuffersCallback) { GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, drawFramebuffer); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, readFramebuffer); GL.FramebufferTexture2D(FramebufferTarget.DrawFramebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, _stagingTextures[_currentTexture], 0); TextureView viewConverted = view.Format.IsBgr() ? _renderer.TextureCopy.BgraSwap(view) : view; GL.FramebufferTexture( FramebufferTarget.ReadFramebuffer, FramebufferAttachment.ColorAttachment0, viewConverted.Handle, 0); GL.ReadBuffer(ReadBufferMode.ColorAttachment0); GL.Disable(EnableCap.RasterizerDiscard); GL.Disable(IndexedEnableCap.ScissorTest, 0); GL.Clear(ClearBufferMask.ColorBufferBit); int srcX0, srcX1, srcY0, srcY1; float scale = view.ScaleFactor; if (crop.Left == 0 && crop.Right == 0) { srcX0 = 0; srcX1 = (int)(view.Width / scale); } else { srcX0 = crop.Left; srcX1 = crop.Right; } if (crop.Top == 0 && crop.Bottom == 0) { srcY0 = 0; srcY1 = (int)(view.Height / scale); } else { srcY0 = crop.Top; srcY1 = crop.Bottom; } if (scale != 1f) { srcX0 = (int)(srcX0 * scale); srcY0 = (int)(srcY0 * scale); srcX1 = (int)Math.Ceiling(srcX1 * scale); srcY1 = (int)Math.Ceiling(srcY1 * scale); } float ratioX = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _height * crop.AspectRatioX / (_width * crop.AspectRatioY)); float ratioY = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _width * crop.AspectRatioY / (_height * crop.AspectRatioX)); int dstWidth = (int)(_width * ratioX); int dstHeight = (int)(_height * ratioY); int dstPaddingX = (_width - dstWidth) / 2; int dstPaddingY = (_height - dstHeight) / 2; int dstX0 = crop.FlipX ? _width - dstPaddingX : dstPaddingX; int dstX1 = crop.FlipX ? dstPaddingX : _width - dstPaddingX; int dstY0 = crop.FlipY ? dstPaddingY : _height - dstPaddingY; int dstY1 = crop.FlipY ? _height - dstPaddingY : dstPaddingY; if (ScreenCaptureRequested) { CaptureFrame(srcX0, srcY0, srcX1, srcY1, view.Format.IsBgr(), crop.FlipX, crop.FlipY); ScreenCaptureRequested = false; } GL.BlitFramebuffer( srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Linear); // Remove Alpha channel GL.ColorMask(false, false, false, true); GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f); GL.Clear(ClearBufferMask.ColorBufferBit); for (int i = 0; i < Constants.MaxRenderTargets; i++) { ((Pipeline)_renderer.Pipeline).RestoreComponentMask(i); } // Set clip control, viewport and the framebuffer to the output to placate overlays and OBS capture. GL.ClipControl(ClipOrigin.LowerLeft, ClipDepthMode.NegativeOneToOne); GL.Viewport(0, 0, _width, _height); GL.BindFramebuffer(FramebufferTarget.Framebuffer, drawFramebuffer); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, _stagingFrameBuffer); swapBuffersCallback((object)_stagingTextures[_currentTexture]); _currentTexture = ++_currentTexture % _stagingTextures.Length; ((Pipeline)_renderer.Pipeline).RestoreClipControl(); ((Pipeline)_renderer.Pipeline).RestoreScissor0Enable(); ((Pipeline)_renderer.Pipeline).RestoreRasterizerDiscard(); ((Pipeline)_renderer.Pipeline).RestoreViewport0(); if (viewConverted != view) { viewConverted.Dispose(); } }
public void Present(ITexture texture, ImageCrop crop) { TextureView view = (TextureView)texture; GL.Disable(EnableCap.FramebufferSrgb); int oldReadFramebufferHandle = GL.GetInteger(GetPName.ReadFramebufferBinding); int oldDrawFramebufferHandle = GL.GetInteger(GetPName.DrawFramebufferBinding); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, 0); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, GetCopyFramebufferHandleLazy()); GL.FramebufferTexture( FramebufferTarget.ReadFramebuffer, FramebufferAttachment.ColorAttachment0, view.Handle, 0); GL.ReadBuffer(ReadBufferMode.ColorAttachment0); GL.Clear(ClearBufferMask.ColorBufferBit); int srcX0, srcX1, srcY0, srcY1; if (crop.Left == 0 && crop.Right == 0) { srcX0 = 0; srcX1 = view.Width; } else { srcX0 = crop.Left; srcX1 = crop.Right; } if (crop.Top == 0 && crop.Bottom == 0) { srcY0 = 0; srcY1 = view.Height; } else { srcY0 = crop.Top; srcY1 = crop.Bottom; } float ratioX = MathF.Min(1f, (_height * (float)NativeWidth) / ((float)NativeHeight * _width)); float ratioY = MathF.Min(1f, (_width * (float)NativeHeight) / ((float)NativeWidth * _height)); int dstWidth = (int)(_width * ratioX); int dstHeight = (int)(_height * ratioY); int dstPaddingX = (_width - dstWidth) / 2; int dstPaddingY = (_height - dstHeight) / 2; int dstX0 = crop.FlipX ? _width - dstPaddingX : dstPaddingX; int dstX1 = crop.FlipX ? dstPaddingX : _width - dstPaddingX; int dstY0 = crop.FlipY ? dstPaddingY : _height - dstPaddingY; int dstY1 = crop.FlipY ? _height - dstPaddingY : dstPaddingY; GL.BlitFramebuffer( srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Linear); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle); GL.Enable(EnableCap.FramebufferSrgb); }