gpt4 book ai didi

macos - 调整 MTKView 的大小会在重绘之前缩放旧内容

转载 作者:行者123 更新时间:2023-12-01 11:04:47 27 4
gpt4 key购买 nike

我正在使用 MTKView 来绘制 Metal 内容。它的配置如下:

    mtkView = MTKView(frame: self.view.frame, device: device)
mtkView.colorPixelFormat = .bgra8Unorm
mtkView.delegate=self
mtkView.sampleCount=4
mtkView.isPaused=true
mtkView.enableSetNeedsDisplay=true
setFrameSize被覆盖以触发重新显示。

每当 View 调整大小时,它都会在重绘所有内容之前缩放其旧内容。这给人一种抖动的感觉。

我尝试设置 contentGravity MTKView 图层的属性设置为非调整大小的值,但这完全搞乱了内容的比例和位置。似乎 MTKView 不想让我摆弄那个参数。

如何确保在调整大小期间始终正确重绘内容?

最佳答案

在我对 Metal 和 MTKView 的使用中,我尝试了presentsWithTransaction的各种组合和 waitUntilScheduled没有成功。在实时调整大小期间,我仍然偶尔会在正确渲染的内容帧之间遇到拉伸(stretch)内容的帧。
最后,我放弃了MTKView并创建了我自己的使用 CAMetalLayer 的 NSView 子类并且调整大小现在看起来不错(不使用 presentsWithTransactionwaitUntilScheduled )。一个关键点是我需要设置图层的 autoresizingMask获取 displayLayer在窗口调整大小期间每帧调用的方法。
这是头文件:

#import <Cocoa/Cocoa.h>

@interface MyMTLView : NSView<CALayerDelegate>
@end
这是实现:
#import <QuartzCore/CAMetalLayer.h>
#import <Metal/Metal.h>

@implementation MyMTLView

- (id)initWithFrame:(NSRect)frame
{
if (!(self = [super initWithFrame:frame])) {
return self;
}

// We want to be backed by a CAMetalLayer.
self.wantsLayer = YES;

// We want to redraw the layer during live window resize.
self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawDuringViewResize;

// Not strictly necessary, but in case something goes wrong with live window
// resize, this layer placement makes it more obvious what's going wrong.
self.layerContentsPlacement = NSViewLayerContentsPlacementTopLeft;

return self;
}

- (CALayer*)makeBackingLayer
{
CAMetalLayer* metalLayer = [CAMetalLayer layer];
metalLayer.device = MTLCreateSystemDefaultDevice();
metalLayer.delegate = self;

// *Both* of these properties are crucial to getting displayLayer to be
// called during live window resize.
metalLayer.autoresizingMask = kCALayerHeightSizable | kCALayerWidthSizable;
metalLayer.needsDisplayOnBoundsChange = YES;

return metalLayer;
}

- (CAMetalLayer*)metalLayer
{
return (CAMetalLayer*)self.layer;
}

- (void)setFrameSize:(NSSize)newSize
{
[super setFrameSize:newSize];

self.metalLayer.drawableSize = newSize;
}

- (void)displayLayer:(CALayer*)layer
{
// Do drawing with Metal.
}

@end
作为引用,我在 MTKView 的 drawRect 中绘制了所有 Metal 图。方法。

关于macos - 调整 MTKView 的大小会在重绘之前缩放旧内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45375548/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com