private void BlitEye(GPUTexture gt, float x, float y, float w, float h, bool horizontalRight = false, bool horizontalLeft = false) { float rtAspectRatio = gt.Width / (float)gt.Height; float aspectRatio = w / h; float sampleWidth; float sampleHeight; if (aspectRatio > 1) { sampleHeight = h; sampleWidth = h * rtAspectRatio; } else { sampleWidth = w; sampleHeight = w / rtAspectRatio; } float posX = x + w * 0.5f - sampleWidth * 0.5f; float posY = y + h * 0.5f - sampleHeight * 0.5f; if (horizontalLeft) { posX = x; } if (horizontalRight) { posX = x + w - sampleWidth; } Render2D.DrawTexture(gt, new Rectangle(posX, posY, sampleWidth, sampleHeight), Color.White); }
/// <summary> /// Synchronizes size of the back buffer with the size of the control. /// </summary> public void SyncBackbufferSize() { float scale = ResolutionScale * Platform.DpiScale; int width = Mathf.CeilToInt(Width * scale); int height = Mathf.CeilToInt(Height * scale); if (_backBuffer == null || _backBuffer.Width == width && _backBuffer.Height == height) { return; } if (width < 1 || height < 1) { _backBuffer.ReleaseGPU(); Object.Destroy(ref _backBufferOld); return; } // Cache old backbuffer to remove flickering effect if (_backBufferOld == null && _backBuffer.IsAllocated) { _backBufferOld = _backBuffer; _backBuffer = GPUDevice.Instance.CreateTexture(); } // Set timeout to remove old buffer _oldBackbufferLiveTimeLeft = 3; // Resize backbuffer var desc = GPUTextureDescription.New2D(width, height, BackBufferFormat); _backBuffer.Init(ref desc); _task.Output = _backBuffer; }
private void OnUpdate() { if (_queue.Count == 0 || (_task != null && _task.Enabled)) { return; } // TODO: add delay when processing the requests to reduce perf impact (eg. 0.2s before actual rendering) // Setup pipeline if (_atlases == null) { _atlases = new List <Atlas>(4); } if (_output == null) { _output = GPUDevice.Instance.CreateTexture("CameraCutMedia.Output"); var desc = GPUTextureDescription.New2D(Width, Height, PixelFormat.R8G8B8A8_UNorm); _output.Init(ref desc); } if (_task == null) { _task = Object.New <SceneRenderTask>(); _task.Output = _output; _task.Begin += OnBegin; _task.End += OnEnd; } // Kick off the rendering _task.Enabled = true; }
public void Dispose() { if (GPUTexture != null) { GPUTexture.Dispose(); } GPUTexture = null; }
public static void DrawIcons(GPUContext context, RenderTask task, GPUTexture target, GPUTexture targetDepth, Scene scene) { #if UNIT_TEST_COMPILANT throw new NotImplementedException("Unit tests, don't support methods calls. Only properties can be get or set."); #else Internal_DrawIcons(FlaxEngine.Object.GetUnmanagedPtr(context), FlaxEngine.Object.GetUnmanagedPtr(task), FlaxEngine.Object.GetUnmanagedPtr(target), FlaxEngine.Object.GetUnmanagedPtr(targetDepth), FlaxEngine.Object.GetUnmanagedPtr(scene)); #endif }
/// <summary> /// Adds GPU texture image to the layout. /// </summary> /// <param name="texture">The GPU texture.</param> /// <returns>The created element.</returns> public ImageElement Image(GPUTexture texture) { var element = new ImageElement(); element.Image.Brush = new GPUTextureBrush(texture); OnAddElement(element); return(element); }
/// <summary> /// The bitmap and the texture should be same size. /// The Texture format should be B8G8R8A8_UNorm /// Bitmap pixelformat is read as PixelFormat.Format32bppArgb, so if this is the native format maybe speed is higher? /// </summary> /// <param name="bmp"></param> /// <param name="tex"></param> public void WriteBitmapToTexture(Bitmap bmp, GPUTexture tex) { System.Diagnostics.Debug.Assert(tex.Resource.Description.Format == Format.B8G8R8A8_UNorm); var bytes = getBitmapRawBytes(bmp); tex.SetTextureRawData(bytes); }
public static void Capture(GPUTexture target, string path = null) { if (target == null) { throw new ArgumentNullException(); } Internal_Capture1(target.unmanagedPtr, path); }
/// <inheritdoc /> public override void Render(GPUContext context, SceneRenderTask task, GPUTexture input, GPUTexture output) { if (Viewport == null) { throw new NullReferenceException(); } Profiler.BeginEventGPU("Editor Primitives"); // Check if use MSAA var format = output.Format; GPUDevice.GetFeatures(format, out var formatSupport); bool enableMsaa = formatSupport.MSAALevelMax >= MSAALevel.X4 && Editor.Instance.Options.Options.Visual.EnableMSAAForDebugDraw; // Prepare var msaaLevel = enableMsaa ? MSAALevel.X4 : MSAALevel.None; var width = output.Width; var height = output.Height; var desc = GPUTextureDescription.New2D(width, height, format, GPUTextureFlags.RenderTarget | GPUTextureFlags.ShaderResource, 1, 1, msaaLevel); var target = RenderTargetPool.Get(ref desc); desc = GPUTextureDescription.New2D(width, height, PixelFormat.D24_UNorm_S8_UInt, GPUTextureFlags.DepthStencil, 1, 1, msaaLevel); var targetDepth = RenderTargetPool.Get(ref desc); // Copy frame and clear depth context.Draw(target, input); context.ClearDepth(targetDepth); // Draw gizmos and other editor primitives (collect draw calls only) _drawCallsCollector.Clear(); for (int i = 0; i < Viewport.Gizmos.Count; i++) { Viewport.Gizmos[i].Draw(_drawCallsCollector); } Viewport.DrawEditorPrimitives(context, task, target, targetDepth, _drawCallsCollector); // Draw gizmos (actual drawing) _drawCallsCollector.ExecuteDrawCalls(context, task, target, DrawPass.GBuffer); _drawCallsCollector.ExecuteDrawCalls(context, task, target, DrawPass.Forward); // Resolve MSAA texture if (enableMsaa) { context.ResolveMultisample(target, output); } else { context.Draw(output, target); } // Cleanup RenderTargetPool.Release(targetDepth); RenderTargetPool.Release(target); Profiler.EndEventGPU(); }
public PostFxRenderer SetInput(string name, GPUTexture texture) { var param = Material.GetParam(name); if (param != null) { param.Value = texture; } return(this); }
public override void Initialize() { _output = GPUDevice.CreateTexture(); _cachedSize = SizeGetter(); var description = GPUTextureDescription.New2D(_cachedSize.X, _cachedSize.Y, PixelFormat.R8G8B8A8_UNorm); _output.Init(ref description); _outputPromise.SetResult(_output); Task.Render = OnRender; Task.Enabled = true; }
/// <inheritdoc /> public override void Render(GPUContext context, SceneRenderTask task, GPUTexture input, GPUTexture output) { Profiler.BeginEventGPU("Editor Primitives"); for (int i = 0; i < SceneManager.ScenesCount; i++) { var scene = SceneManager.GetScene(i); ViewportIconsRenderer.DrawIcons(context, task, input, task.Buffers.DepthBuffer, scene); } Profiler.EndEventGPU(); }
public override void OnEnable() { base.OnEnable(); Output = CreateOutputTexture(Size); RenderTask = FlaxEngine.Object.New <SceneRenderTask>(); RenderTask.Order = Order; RenderTask.Camera = Camera; RenderTask.ActorsSource = ActorsSources.Scenes; RenderTask.Output = Output; RenderTask.Begin += OnRenderTaskBegin; RenderTask.End += OnRenderTaskEnd; }
/// <inheritdoc /> public override void OnInit() { // Create cache folder if (!Directory.Exists(_cacheFolder)) { Directory.CreateDirectory(_cacheFolder); } // Find atlases in a Editor cache directory var files = Directory.GetFiles(_cacheFolder, "cache_*.flax", SearchOption.TopDirectoryOnly); int atlases = 0; for (int i = 0; i < files.Length; i++) { // Load asset var asset = FlaxEngine.Content.LoadAsync(files[i]); if (asset == null) { continue; } // Validate type if (asset is PreviewsCache atlas) { // Cache atlas atlases++; _cache.Add(atlas); } else { // Skip asset Editor.LogWarning(string.Format("Asset \'{0}\' is inside Editor\'s private directory for Assets Thumbnails Cache. Please move it.", asset.Path)); } } Editor.Log(string.Format("Previews cache count: {0} (capacity for {1} icons)", atlases, atlases * PreviewsCache.AssetIconsPerAtlas)); // Prepare at least one atlas if (_cache.Count == 0) { GetValidAtlas(); } // Create render task but disabled for now _output = GPUDevice.Instance.CreateTexture("ThumbnailsOutput"); var desc = GPUTextureDescription.New2D(PreviewsCache.AssetIconSize, PreviewsCache.AssetIconSize, PreviewsCache.AssetIconsAtlasFormat); _output.Init(ref desc); _task = Object.New <RenderTask>(); _task.Order = 50; // Render this task later _task.Enabled = false; _task.Render += OnRender; }
public void SaveToImageSlices(DX11Game game, DirectoryInfo dir) { for (int i = 0; i < Resource.Description.Depth; i++) { var tex2d = GPUTexture.CreateCPUWritable(game, Resource.Description.Width, Resource.Description.Height, Format.R8G8B8A8_UNorm); Resource.Device.ImmediateContext.CopySubresourceRegion(Resource, 0, new ResourceRegion(0, 0, i, Resource.Description.Width, Resource.Description.Height, i + 1), tex2d.Resource, 0, 0, 0, 0); Texture2D.SaveTextureToFile(game.Device.ImmediateContext, tex2d.Resource, ImageFileFormat.Bmp, dir.FullName + "/" + i + ".bmp"); } }
/// <summary> /// Initializes a new instance of the <see cref="RenderOutputControl"/> class. /// </summary> /// <param name="task">The task. Cannot be null.</param> /// <exception cref="System.ArgumentNullException">Invalid task.</exception> public RenderOutputControl(SceneRenderTask task) { if (task == null) { throw new ArgumentNullException(); } _backBuffer = GPUDevice.CreateTexture(); _resizeTime = ResizeCheckTime; _task = task; _task.Output = _backBuffer; _task.CanSkipRendering += CanSkipRendering; _task.End += OnEnd; }
private void SubmitTexture(CVRCompositor compositor, GPUTexture colorTex, EVREye eye) { Texture_t texT; var renderer = GPUDevice.RendererType; if (renderer == RendererType.DirectX10 || renderer == RendererType.DirectX10_1 || renderer == RendererType.DirectX11) { texT.handle = colorTex.NativePtr; texT.eColorSpace = EColorSpace.Gamma; texT.eType = ETextureType.DirectX; } else { throw new Exception($"Renderer '{renderer}' is not yet supported"); } /*if (rt == RendererType.DirectX12) * { * texT.handle = colorTex.NativePtr; * texT.eColorSpace = EColorSpace.Gamma; * texT.eType = ETextureType.DirectX12; * } * * if(rt == RendererType.Vulkan) * { * texT.handle = colorTex.NativePtr; * texT.eColorSpace = EColorSpace.Gamma; * texT.eType = ETextureType.Vulkan; * }*/ VRTextureBounds_t boundsT; boundsT.uMin = 0; boundsT.uMax = 1; boundsT.vMin = 0; boundsT.vMax = 1; EVRCompositorError compositorError = EVRCompositorError.None; compositorError = compositor.Submit(eye, ref texT, ref boundsT, EVRSubmitFlags.Submit_Default); if (compositorError != EVRCompositorError.None) { throw new Exception($"Failed to submit to the OpenVR Compositor: {compositorError}"); } }
/// <summary> /// Initializes a new instance of the <see cref="RenderOutputControl"/> class. /// </summary> /// <param name="task">The task. Cannot be null.</param> /// <exception cref="System.ArgumentNullException">Invalid task.</exception> public RenderOutputControl(SceneRenderTask task) { if (task == null) { throw new ArgumentNullException(); } _backBuffer = GPUDevice.Instance.CreateTexture(); _resizeTime = ResizeCheckTime; _task = task; _task.Output = _backBuffer; _task.End += OnEnd; Scripting.Update += OnUpdate; }
public override void OnEnable() { base.OnEnable(); if (!Material || !Material.IsSurface) { return; } Material.WaitForLoaded(); _materialInstance = Material.CreateVirtualInstance(); _inputParameters = GetPublicParameters(_materialInstance); var size = Size; _orthographicCamera = CreateOrthographicCamera(); _model = Content.CreateVirtualAsset <Model>(); _model.SetupLODs(1); _model.SetupMaterialSlots(1); _model.MinScreenSize = 0; // TODO: Optimize, use instanced rendering and whatnot GenerateGridMesh(_model.LODs[0].Meshes[0], size); _cachedSize = size; _modelActor = FlaxEngine.Object.New <StaticModel>(); _modelActor.Model = _model; _modelActor.DrawModes = DrawPass.Depth | DrawPass.GBuffer; // TODO: Optionally enable transparency? _modelActor.Entries[0].ReceiveDecals = false; _modelActor.Entries[0].ShadowsMode = ShadowsCastingMode.None; _modelActor.Entries[0].Material = _materialInstance; _modelActor.LocalPosition = new Vector3(size * -0.5f, DistanceFromOrigin); Output = CreateOutputTexture(Size); RenderTask = FlaxEngine.Object.New <SceneRenderTask>(); RenderTask.AllowGlobalCustomPostFx = false; RenderTask.Order = Order; RenderTask.Camera = _orthographicCamera; RenderTask.ActorsSource = ActorsSources.CustomActors; RenderTask.Output = Output; RenderTask.Begin += OnRenderTaskBegin; RenderTask.End += OnRenderTaskEnd; RenderTask.CustomActors.Add(_modelActor); RenderTask.View.MaxShadowsQuality = Quality.Low; RenderTask.View.Mode = ViewMode.Emissive; RenderTask.View.Flags = ViewFlags.None; }
public TextTexture(DX11Game game, int width, int height) { bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb); GPUTexture = GPUTexture.CreateCPUWritable(game, bmp.Width, bmp.Height, Format.B8G8R8A8_UNorm); SetFont("Verdana", 10); //Then you create a StringFormat object to specify text alignments etc. sf = StringFormat.GenericDefault; //Then create a graphics object to be able to write in the bmp image g = System.Drawing.Graphics.FromImage(bmp); g.PageUnit = GraphicsUnit.Pixel; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; Clear(); }
public void TestGaussionBlur() { var blur = new GaussianBlurFilter(game); var input = GPUTexture.FromFile(game, TWDir.GameData.FullName + "\\Core\\Checker.png"); var buffer = GPUTexture.CreateUAV(game, input.Resource.Description.Width, input.Resource.Description.Height, Format.R8G8B8A8_UNorm); var output = GPUTexture.CreateUAV(game, input.Resource.Description.Width, input.Resource.Description.Height, Format.R8G8B8A8_UNorm); game.GameLoopEvent += delegate { blur.Blur(input.View, buffer, output.UnorderedAccessView); game.Device.ImmediateContext.ClearState(); game.SetBackbuffer(); var size = 256; game.TextureRenderer.Draw(input.View, new Vector2(0, 0), new Vector2(size, size)); game.TextureRenderer.Draw(output.View, new Vector2(size, 0), new Vector2(size, size)); }; game.Run(); }
public void Blur(ShaderResourceView input, GPUTexture buffer, UnorderedAccessView output) { var width = buffer.Resource.Description.Width; int groupsX = (int)Math.Ceiling(width / (double)ThreadGroupSize); var height = buffer.Resource.Description.Height; int groupsY = (int)Math.Ceiling(height / (double)ThreadGroupSize); context.ClearState(); context.ComputeShader.Set(csX); context.ComputeShader.SetShaderResource(input, 0); context.ComputeShader.SetUnorderedAccessView(buffer.UnorderedAccessView, 0); context.Dispatch(groupsX, height, 1); context.ClearState(); context.ComputeShader.Set(csY); context.ComputeShader.SetShaderResource(buffer.View, 0); context.ComputeShader.SetUnorderedAccessView(output, 0); context.Dispatch(width, groupsY, 1); }
public void TestDrawingToD3D11Conversion() { var bmp = createBitmap(); var game = new DX11Game(); game.InitDirectX(); var tex = GPUTexture.CreateCPUWritable(game, bmp.Width, bmp.Height, Format.B8G8R8A8_UNorm); var convert = new DrawingToD3D11Conversion(); convert.WriteBitmapToTexture(bmp, tex); game.GameLoopEvent += delegate { game.TextureRenderer.Draw(tex.View, Vector2.Zero, new Vector2(100, 100)); }; game.Run(); }
/// <summary> /// Gets the brush material for the terrain chunk rendering. It must have domain set to Terrain. Setup material parameters within this call. /// </summary> /// <param name="position">The world-space brush position.</param> /// <param name="color">The brush position.</param> /// <param name="sceneDepth">The scene depth buffer (used for manual brush pixels clipping with rendered scene).</param> /// <returns>The ready to render material for terrain chunks overlay on top of the terrain.</returns> public MaterialInstance GetBrushMaterial(ref Vector3 position, ref Color color, GPUTexture sceneDepth) { if (!_material) { var material = FlaxEngine.Content.LoadAsyncInternal <Material>(EditorAssets.FoliageBrushMaterial); material.WaitForLoaded(); _material = material.CreateVirtualInstance(); } if (_material) { // TODO: cache parameters _material.GetParam("Color").Value = color; _material.GetParam("DepthBuffer").Value = sceneDepth; } return(_material); }
/// <inheritdoc /> public void DrawEditorPrimitives(GPUContext context, ref RenderContext renderContext, GPUTexture target, GPUTexture targetDepth) { }
public override void RenderFrame(GPUContext context, ref StagingTexture frame, RenderOptions options, GPUTexture output) { // Copy texture back to the staging texture context.CopyTexture(frame.Texture, 0, 0, 0, 0, output, 0); }
public abstract void RenderFrame(GPUContext context, ref StagingTexture frame, RenderOptions options, GPUTexture output);
/// <summary> /// Performs custom postFx rendering. /// </summary> /// <param name="context">The GPU commands context.</param> /// <param name="renderContext">The rendering context.</param> /// <param name="input">The input texture.</param> /// <param name="output">The output texture.</param> public abstract void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output);
/// <inheritdoc /> public override void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output) { if (Viewport == null) { throw new NullReferenceException(); } Profiler.BeginEventGPU("Editor Primitives"); // Check if use MSAA var format = output.Format; var formatFeatures = GPUDevice.Instance.GetFormatFeatures(format); bool enableMsaa = formatFeatures.MSAALevelMax >= MSAALevel.X4 && Editor.Instance.Options.Options.Visual.EnableMSAAForDebugDraw; // Prepare var msaaLevel = enableMsaa ? MSAALevel.X4 : MSAALevel.None; var width = output.Width; var height = output.Height; var desc = GPUTextureDescription.New2D(width, height, format, GPUTextureFlags.RenderTarget | GPUTextureFlags.ShaderResource, 1, 1, msaaLevel); var target = RenderTargetPool.Get(ref desc); desc = GPUTextureDescription.New2D(width, height, PixelFormat.D24_UNorm_S8_UInt, GPUTextureFlags.DepthStencil, 1, 1, msaaLevel); var targetDepth = RenderTargetPool.Get(ref desc); // Copy frame and clear depth context.Draw(target, input); context.ClearDepth(targetDepth.View()); context.SetViewport(width, height); context.SetRenderTarget(targetDepth.View(), target.View()); // Draw gizmos and other editor primitives var renderList = RenderList.GetFromPool(); var prevList = renderContext.List; renderContext.List = renderList; for (int i = 0; i < Viewport.Gizmos.Count; i++) { Viewport.Gizmos[i].Draw(ref renderContext); } Viewport.DrawEditorPrimitives(context, ref renderContext, target, targetDepth); // Sort draw calls renderList.SortDrawCalls(ref renderContext, false, DrawCallsListType.GBuffer); renderList.SortDrawCalls(ref renderContext, false, DrawCallsListType.GBufferNoDecals); renderList.SortDrawCalls(ref renderContext, true, DrawCallsListType.Forward); // Perform the rendering renderContext.View.Pass = DrawPass.GBuffer; renderList.ExecuteDrawCalls(ref renderContext, DrawCallsListType.GBuffer); renderList.ExecuteDrawCalls(ref renderContext, DrawCallsListType.GBufferNoDecals); renderContext.View.Pass = DrawPass.Forward; renderList.ExecuteDrawCalls(ref renderContext, DrawCallsListType.Forward); // Resolve MSAA texture if (enableMsaa) { context.ResolveMultisample(target, output); } else { context.Draw(output, target); } // Cleanup RenderTargetPool.Release(targetDepth); RenderTargetPool.Release(target); RenderList.ReturnToPool(renderList); renderContext.List = prevList; Profiler.EndEventGPU(); }
/// <inheritdoc /> public override void DrawEditorPrimitives(GPUContext context, ref RenderContext renderContext, GPUTexture target, GPUTexture targetDepth) { // Draw gizmos for (int i = 0; i < Gizmos.Count; i++) { Gizmos[i].Draw(ref renderContext); } base.DrawEditorPrimitives(context, ref renderContext, target, targetDepth); }