admin管理员组文章数量:1357232
on macOS, I want to display a metal rendered texture in a view, and I want the transparent areas of this texture let mouse events propagate through other underlying UI/Apps, like it is the native behavior in macOS (e.g transparent areas of a view go through underlying UI objects)
I'm trying to render metal contents into a CAMEtalLayer (using c# with eto library, but it doesn't matter as I use mostly macOS native objects). I'm able to render the CAMetalLayer in a custom view without problem. The transparent area (for now just a transparent frame with a red circle in center) is correctly display (e.g. I can see underlying macOS UI element through the NSView transparent area) and I see the red circle in center.
The weird thing is that with CAMetalLayer, it seems that the transparent area (e.g. the whole metal texture) block mouse events to propagate through.
If I create the same view with a "classic" CAMetal layer, the transparent area lets mouse events pass through (as this is the normal behavior in MacOS).
Is there a way for my CAMetalLayer transparent area to let mouse events pass through it, so the underlying UI elements (or applications etc.) can handle those mouse events ?
Example in below image. The CAMetalLayer frame is represented by the black rectangle. It is display above an application (Rhino 3D). When I mouse over inside the transparent area of the frame, the underlying app (Rhino 3D) doesn't get mouse move events. If I do the same thing with a CALayer, it works (e.g. The mouse events are propagated to the underlying app)
Here is some trunks of my code: 1 - Create the Metal layer
MetalLayer = new CAMetalLayer
{
Device = MetalDevice,
PixelFormat = MTLPixelFormat.RGBA8Unorm,
FramebufferOnly = true,
Opaque = false,
BackgroundColor = NSColor.Clear.CGColor,
BorderColor = NSColor.Black.CGColor,
BorderWidth = 2,
// BackgroundColor = NSColor.Blue.CGColor,
// ContentsScale = 2,
// ShouldRasterize = true,
ShadowColor = NSColor.Clear.CGColor,
//FIXME: This does not work has Rhino Microsoft.macOS is V12.3.7 (and on macos 15.3 this is v13.3.0)
// WantsExtendedDynamicRangeContent = true
};
2 - Render metal pass (remark : I also tried drawable.present();
but same result)
var drawable = MetalLayer.NextDrawable();
if (drawable != null)
{
var currentTexture = drawable.Texture; // Get Metal texture for drawing
// REMARK: We must create a new surface at each render loop. If we keep the same surface instance, the radial menu display is blinking (don't know why)
SkiaSurface?.Dispose();
// Create Skia surface from Metal texture
var backendRenderTarget = new GRBackendRenderTarget(
(int)currentTexture.Width,
(int)currentTexture.Height,
1,
new GRMtlTextureInfo(currentTexture));
SkiaSurface = SKSurface.Create(GrContext, backendRenderTarget, GRSurfaceOrigin.TopLeft, SKColorType.Rgba8888);
var stopwatchDrawing = Stopwatch.StartNew();
PointF center = new PointF((currentTexture.Width / 2.0f), (currentTexture.Height / 2.0f));
// Draw something in canvas here...
var canvas = SkiaSurface.Canvas;
canvas.Clear(SKColors.Transparent);
using (var paint = new SKPaint()
{
Style = SKPaintStyle.Fill,
IsAntialias = true,
Color = SKColors.Red
})
{
canvas.DrawCircle((float)currentTexture.Width / 2, (float)currentTexture.Height / 2, (float)150, paint);
}
// Present the drawable
GrContext.Flush();// Ensure everything is drawn
// Create a command buffer and render pass for blending
var commandBuffer = CommandQueue.CommandBuffer();
var renderPassDescriptor = new MTLRenderPassDescriptor
{
ColorAttachments = { [0] = new MTLRenderPassColorAttachmentDescriptor() }
};
var colorAttachment = renderPassDescriptor.ColorAttachments[0];
colorAttachment.Texture = currentTexture;
colorAttachment.LoadAction = MTLLoadAction.Load; // Load the Skia-rendered texture
colorAttachment.StoreAction = MTLStoreAction.Store;
colorAttachment.ClearColor = new MTLClearColor(0, 0, 0, 0);
var renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor);
renderEncoder.SetRenderPipelineState(RenderPipelineState);
// Set vertex and texture coordinate buffers
renderEncoder.SetVertexBuffer(VertexBuffer, 0, 0);
renderEncoder.SetVertexBuffer(TexCoordBuffer, 0, 1);
renderEncoder.SetFragmentTexture(currentTexture, 0);
// Draw the quad
renderEncoder.DrawPrimitives(MTLPrimitiveType.TriangleStrip, 0, 4);
renderEncoder.EndEncoding();
// Present the drawable
commandBuffer.PresentDrawable(drawable);
commandBuffer.Commit();
3 - For information, here is the render pipeline and colorAttachement I'm using
// RGB blending: Standard alpha blending
colorAttachment.SourceRgbBlendFactor = MTLBlendFactor.SourceAlpha; // Source RGB * Source.a
colorAttachment.DestinationRgbBlendFactor = MTLBlendFactor.OneMinusSourceAlpha; // Dest RGB * (1 - Source.a)
colorAttachment.RgbBlendOperation = MTLBlendOperation.Add;
// Alpha blending: Source alpha overrides destination alpha
colorAttachment.SourceAlphaBlendFactor = MTLBlendFactor.One; // Preserve source alpha; // Source.a * 1.0
colorAttachment.DestinationAlphaBlendFactor = MTLBlendFactor.OneMinusSourceAlpha; ; // Dest.a * 0
colorAttachment.AlphaBlendOperation = MTLBlendOperation.Add;
Any help would be appreciated :-)
本文标签: macosCAMetalLayer transparent area not behaves like in CALayerStack Overflow
版权声明:本文标题:macos - CAMetalLayer transparent area not behaves like in CALayer - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744075625a2586692.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论