代码之家  ›  专栏  ›  技术社区  ›  zzyzy

skrenderer-神秘类

  •  5
  • zzyzy  · 技术社区  · 6 年前

    在这里,我在观看完WWDC2017第609次会议的视频后,被大肆宣传要从SpriteKit中提取屏幕上的金属纹理。

    这是一年多以前的事了!

    但绝对没有关于 SKRenderer 也没有样本代码。 https://developer.apple.com/documentation/spritekit/skrenderer

    我觉得这确实很奇怪。 这里有人对这个类、它的文档或示例代码有什么见解吗?

    顺便说一句,同样的道理 SKTransformNode .

    2 回复  |  直到 6 年前
        1
  •  11
  •   warrenm    6 年前

    基本用途 SKRenderer 很简单,但也有一些奇怪的地方在实践中让人觉得有些古怪。

    第一,基本面。要实例化渲染器,请使用 rendererWithDevice: 方法。这种方法需要 id<MTLDevice> ,例如系统默认设备。请原谅objective-c;这很容易翻译成swift:

    SKRenderer *renderer = [SKRenderer rendererWithDevice:mtlDevice];
    

    为了告诉渲染器要绘制什么,我们将其与先前创建的场景相关联:

    renderer.scene = (SKScene *)scene;
    

    如果要运行操作,则需要手动取消暂停场景,这通常是由 SKView 呈现场景时:

    scene.paused = NO;
    

    要实际绘制场景,我们需要提供一个命令缓冲区和渲染过程描述符。假设你用的是 MTKView 运行显示链接计时器并管理 CAMetalLayer 您可以编写这样的委托方法,它通过渲染器更新场景的时间(和动作),然后绘制到 MTKVIEW 可画:

    - (void)drawInMTKView:(nonnull MTKView *)view {
        MTLRenderPassDescriptor *renderPassDescriptor = view.currentRenderPassDescriptor;
        if (renderPassDescriptor == nil) {
            return;
        }
    
        [self.renderer updateAtTime:CACurrentMediaTime()];
    
        id<MTLCommandBuffer> commandBuffer = [self.commandQueue commandBuffer];
        CGRect viewport = CGRectMake(0, 0, view.drawableSize.width, view.drawableSize.height);
        [self.renderer renderWithViewport:viewport
                            commandBuffer:commandBuffer
                     renderPassDescriptor:renderPassDescriptor];
    
        // TODO: Add any additional Metal rendering here
    
        [commandBuffer presentDrawable:view.currentDrawable];
        [commandBuffer commit];
    }
    

    记住设置 MTKVIEW framebufferOnly 属性到 NO 如果你用这种方法。

    如果你想把屏幕渲染成你所创建的纹理,你需要做更多的手工工作,但是所涉及的概念是相同的。您可以通过创建附加的渲染传递描述符/编码器来编码呈现给同一纹理的单独传递,只要记住设置 loadAction 原色附着到 MTLLoadActionLoad 保存纹理的内容。

    您也可以使用 renderWithViewport:renderCommandEncoder:renderPassDescriptor:commandQueue: 将所有绘图合并为一个通道。

    一些注意事项:

    • 据我所知 viewport 参数被忽略。
    • 如果你想 SKScene 接收 NSResponder 操作时,需要手动转发它们或将场景插入响应程序链。这尤其适用于关键事件,其中场景(或负责转发到它的对象)需要 第一 应答者。
    • 当场景不是由 斯威克 ;你需要做些手工翻译。
        2
  •  0
  •   masaldana2    5 年前

    敏捷的

       func render(renderCommandEncoder: MTLRenderCommandEncoder){
        skScene.size = Engine.previewViewSize
    
    
    
            currentTime = 0//allows looping skaction
    
    
        //sprite kit render
        skrender.update(atTime: currentTime )
    
        let viewport = CGRect(x: 0, y: 0, width: (Engine.previewViewSize.width), height: (Engine.previewViewSize.height))
    
        skScene.isPaused = false
    
        skrender.scene = skScene
    
        skrender.render(withViewport: viewport, renderCommandEncoder: renderCommandEncoder, renderPassDescriptor: Engine.currentRenderPassDescriptor, commandQueue: Engine.CommandQueue)
    
    
    }