自定义 Metal 渲染视图

本文详述如何通过自定义NSView或UIView与CAMetalLayer合作,实现Metal在iOS和macOS上的高性能渲染,包括指定图层类型、配置MTLRenderPassDescriptor、渲染循环的实现和关键代码片段。

 

概述

我们可以通过 MetalKit 提供的 MTKView 来快速编写基于 Metal 渲染的视图,MTKView 视图把 Metal 的操作都封装了起来,一定程度上方面了开发。

但有时我们希望能够更加灵活的来控制 Metal 内容的呈现方式,这时就需要自己从头开始操作 Metal 来实现渲染流程。

​​​​​​​

本例将自定义 NSView 或 UIView 来实现 Metal 渲染,使用 CAMetalLayer 对象来保存视图的内容。

使用 Metal Layer 来配置视图

为了支持 Metal 渲染到视图,必须指定视图的图层为 CAMetalLayer 。

UIKit 中的所有视图都是有 layer 来渲染的。视图实现了 layerClass 类方法,来指定 layer 的类型。

``` oc

  • (Class) layerClass

{

    return [CAMetalLayer class];

}

```

在 AppKit 中,需要设置视图的 WantsLayer 属性来支持视图层。

``` oc

self.wantsLayer = YES;

```

这会触发对视图的 makeBackingLayer 方法的调用,该方法返回一个 CAMetalLayer 对象。

``` oc

  • (CALayer *)makeBackingLayer

{

    return [CAMetalLayer layer];

}

```

渲染到视图

要渲染到视图,需要创建一个 MTLRenderPassDescriptor 对象。该对象以图层提供的纹理为目标,可以设置清空的背景色,并在渲染通道完成时将渲染的内容存储到纹理中。

``` oc

_drawableRenderDescriptor = [MTLRenderPassDescriptor new];

_drawableRenderDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;

_drawableRenderDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;

_drawableRenderDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 1, 1, 1);

```

需要创建一个纹理来存储渲染通道渲染的结果。每次应用程序渲染一帧时,渲染器都会从 Metal 层获取一个 CAMetalDrawable 对象, 该对象为 Core Animation 提供了在屏幕上呈现的纹理。

``` oc

id currentDrawable = [metalLayer nextDrawable];

// If the current drawable is nil, skip rendering this frame

if(!currentDrawable)

{

    return;

}

_drawableRenderDescriptor.colorAttachments[0].texture = currentDrawable.texture;

```

实现一个渲染的循环

需要设置一个定时器以指定的时间间隔重绘制视图。iOS 中使用 CADisplayLink 来创建一个定时器。

需要在创建定时器之前知道窗口在哪个屏幕上,所以当 UIKit 调用视图的 didMoveToWindow() 方法时,会调用这个方法。 UIKit 在第一次将视图添加到窗口以及将视图移动到另一个屏幕时调用此方法。下面的代码停止渲染循环并初始化一个新的循环。

``` oc

  • (void)setupCADisplayLinkForScreen:(UIScreen*)screen

{

    [self stopRenderLoop];

    _displayLink = [screen displayLinkWithTarget:self selector:@selector(render)];

    _displayLink.paused = self.paused;

    _displayLink.preferredFramesPerSecond = 60;

}

```

在 macOS 中 CADisplayLink 不可用,需要使用 CVDisplayLink 来创建定时器, 它们看起来不同,但原则上具有相同的目标,即允许回调与显示同步。创建定时器时机也与 iOS 一样,在第一次将视图添加到窗口以及将视图移动到另一个屏幕时调用此方法。

``` oc

  • (BOOL)setupCVDisplayLinkForScreen:(NSScreen*)screen

{

if RENDERONMAIN_THREAD

    // The CVDisplayLink callback, DispatchRenderLoop, never executes     // on the main thread. To execute rendering on the main thread, create     // a dispatch source using the main queue (the main thread).     // DispatchRenderLoop merges this dispatch source in each call     // to execute rendering on the main thread.     displaySource = dispatchsourcecreate(DISPATCHSOURCETYPEDATAADD, 0, 0, dispatchgetmainqueue());

    __weak AAPLView* weakSelf = self;

    dispatchsourceseteventhandler(displaySource, ^(){         @autoreleasepool         {             [weakSelf render];         }     });     dispatchresume(_displaySource);

endif // END RENDERONMAIN_THREAD

    CVReturn cvReturn;     // Create a display link capable of being used with all active displays

    cvReturn = CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);     if(cvReturn != kCVReturnSuccess)

    {         return NO;     }

if RENDERONMAIN_THREAD

    // Set DispatchRenderLoop as the callback function and     // supply displaySource as the argument to the callback.     cvReturn = CVDisplayLinkSetOutputCallback(displayLink, &DispatchRenderLoop, (_bridge void*)displaySource);

else // IF !RENDERONMAIN_THREAD

    // Set DispatchRenderLoop as the callback function and

    // supply this view as the argument to the callback.

    cvReturn = CVDisplayLinkSetOutputCallback(displayLink, &DispatchRenderLoop, (_bridge void*)self);

endif // END !RENDERONMAIN_THREAD

    if(cvReturn != kCVReturnSuccess)

    {         return NO;     }

    // Associate the display link with the display on which the

    // view resides

    CGDirectDisplayID viewDisplayID =

        (CGDirectDisplayID) [self.window.screen.deviceDescription[@"NSScreenNumber"] unsignedIntegerValue];

cvReturn = CVDisplayLinkSetCurrentCGDisplay(_displayLink, viewDisplayID);

    if(cvReturn != kCVReturnSuccess)

    {

        return NO;

    }

    CVDisplayLinkStart(_displayLink);

    NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter];

    // Register to be notified when the window closes so that you

    // can stop the display link

    [notificationCenter addObserver:self

                           selector:@selector(windowWillClose:)

                               name:NSWindowWillCloseNotification

                             object:self.window];

    return YES;

}

```

渲染

绘制的代码需要写在这个循环里面,即render,具体绘制方法在本文中暂时讲解。

``` oc

  • (void)render

{     //此处省略 }

```

总结

本文介绍了自定义基于 Metal 渲染视图的步骤,主要包括指定图层类型为CAMetalLayer,创建MTLRenderPassDescriptor对象,实现渲染循环并绘制。


​​​​​​​

 

内容概要:本文针对间歇性光伏出力导致的48V直流母线电压波动问题,研究并构建了一套储能系统双向充放电闭环调控体系,旨在实现离网型直流微网的功率动态平衡与电压稳定控制。通过Simulink搭建包含光伏阵列、Boost DC-DC变换器、负载、双向DC-DC变换器及锂离子电池的完整直流微网系统模型,重点解决光伏发电波动引起的功率供需失衡难题。采用最大功率点跟踪(MPPT)技术提升光伏能量捕获效率,并结合储能系统的双向调节能力,实施削峰填谷策略,实现能量的时空转移与动态补偿。研究涵盖系统建模、控制策略设计、仿真验证全流程,确保在光照变化、负载突变等复杂工况下母线电压的稳定性,提升微网系统的电能质量和运行可靠性。; 适合人群:具备电力电子、自动控制或新能源系统等相关专业知识背景,从事微电网、分布式能源、储能控制等领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于离网光伏直流微网系统的仿真建模与稳定性分析;②掌握MPPT控制与储能双向DC-DC变换器的协同调控技术;③实现直流母线电压的精确稳定控制与系统功率动态平衡的闭环设计;④为实际光伏储能系统的设计、优化与工程应用提供理论依据与仿真技术支持。; 阅读建议:建议结合Simulink仿真环境动手实践,重点关注控制策略的实现逻辑、控制器参数整定方法,并可通过设置光照强度突变、负载跳变等多种动态工况来验证系统的鲁棒性与适应性,深化对系统动态行为的理解。
内容概要:本文针对传统三电平并网逆变器存在的谐波含量高、电网不平衡工况适应性差及动态响应慢等问题,提出一种基于有源中点箝位(ANPC)三电平逆变器的高性能并网控制策略。通过融合双极性倍频脉宽调制(DPWMA)、正负序分离锁相技术与电网电压前馈控制,构建了一体化的复合控制体系。ANPC拓扑凭借其开关损耗均衡、输出谐波低和中点电位可控等优势,为系统提供了优良的硬件基础;DPWMA调制在不增加器件实际开关频率的前提下显著提升等效开关频率,优化输出波形质量;正负序分离技术有效解决电网不平衡导致的锁相失真问题,确保并网电流对称;电网电压前馈控制则提前补偿扰动,增强系统动态响应与抗扰能力。结合三层控制架构(信号采集、核心控制、调制驱动),并通过Simulink仿真验证了系统在稳态、不平衡及动态扰动工况下的优越性能,证明该方案可显著提升电能质量、运行稳定性与工况适应性。; 适合人群:从事电力电子、新能源并网、智能电网及相关领域的科研人员、电气工程专业研究生及高年级本科生,以及具备一定电力系统与控制理论基础的工程技术人员。; 使用场景及目标:①用于大功率新能源发电系统(如光伏、风电)的高性能并网逆变器设计与优化;②解决电网电压不平衡、畸变等复杂工况下的并网稳定性问题;③提升逆变器动态响应能力,适用于对电能质量要求较高的工业与电网应用场景;④为相关课题的仿真研究、论文复现与科研项目提供技术支持与方案参考。; 阅读建议:此资源以理论分析与仿真验证相结合的方式呈现,建议读者结合文中提到的Simulink模型进行实操复现,深入理解各控制模块的设计逻辑与协同机制,重点关注DPWMA调制实现、正负序分离算法及前馈-反馈控制结构的搭建,以实现从理论到仿真的完整闭环学习。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值