2016-12-28 3 views
1

Я создаю простой дисплей текстуры, который по существу визуализирует видеокадры в формате BGRA через металлический дисплей. Я выполняю те же шаги, что и на сессии Metal WWDC. Но у меня возникают проблемы с созданием кодировщика рендеринга. Мой кодМеталлическая рама на macOS

id <MTLDevice> device = MTLCreateSystemDefaultDevice(); 
id<MTLCommandQueue> commandQueue = [device newCommandQueue]; 

id<MTLLibrary> library = [device newDefaultLibrary]; 

// Create Render Command Descriptor. 
MTLRenderPipelineDescriptor* renderPipelineDesc = [MTLRenderPipelineDescriptor new]; 
renderPipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm; 
renderPipelineDesc.vertexFunction = [library newFunctionWithName:@"basic_vertex"]; 
renderPipelineDesc.fragmentFunction = [library newFunctionWithName:@"basic_fragment"]; 

NSError* error = nil; 
id<MTLRenderPipelineState> renderPipelineState = [device newRenderPipelineStateWithDescriptor:renderPipelineDesc 
                   error:&error]; 

id<MTLCommandBuffer> commandBuffer = [commandQueue commandBuffer]; 

MTLRenderPassDescriptor* renderPassDesc = [MTLRenderPassDescriptor renderPassDescriptor]; 

id<CAMetalDrawable> drawable = [_metalLayer nextDrawable]; 

MTLRenderPassColorAttachmentDescriptor* colorAttachmentDesc = [MTLRenderPassColorAttachmentDescriptor new]; 
colorAttachmentDesc.texture = drawable.texture; 
colorAttachmentDesc.loadAction = MTLLoadActionLoad; 
colorAttachmentDesc.storeAction = MTLStoreActionStore; 
colorAttachmentDesc.clearColor = MTLClearColorMake(0, 0, 0, 1); 

[renderPassDesc.colorAttachments setObject:colorAttachmentDesc atIndexedSubscript:0]; 

[inTexture replaceRegion:region 
     mipmapLevel:0 
      withBytes:imageBytes 
     bytesPerRow:CVPixelBufferGetBytesPerRow(_image)]; 

id<MTLRenderCommandEncoder> renderCmdEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDesc]; 

[renderCmdEncoder setRenderPipelineState:_renderPipelineState]; 
[renderCmdEncoder endEncoding]; 

Этого код авария на линии говорит "Нет Render Targets Найден" идентификатор renderCmdEncoder = [commandBuffer renderCommandEncoderWithDescriptor: renderPassDesc]; Я не могу определить, где и как установить цель рендеринга.

ответ

0

Это будет работать отлично; если вам нужна помощь в его осуществлении, дайте мне знать:

@import UIKit; 
@import AVFoundation; 
@import CoreMedia; 
#import <MetalKit/MetalKit.h> 
#import <Metal/Metal.h> 
#import <MetalPerformanceShaders/MetalPerformanceShaders.h> 

@interface ViewController : UIViewController <MTKViewDelegate, AVCaptureVideoDataOutputSampleBufferDelegate> { 
    NSString *_displayName; 
    NSString *serviceType; 
} 

@property (retain, nonatomic) SessionContainer *session; 
@property (retain, nonatomic) AVCaptureSession *avSession; 

@end; 

#import "ViewController.h" 

@interface ViewController() { 
    MTKView *_metalView; 

    id<MTLDevice> _device; 
    id<MTLCommandQueue> _commandQueue; 
    id<MTLTexture> _texture; 

    CVMetalTextureCacheRef _textureCache; 
} 

@property (strong, nonatomic) AVCaptureDevice *videoDevice; 
@property (nonatomic) dispatch_queue_t sessionQueue; 

@end 

@implementation ViewController 

- (void)viewDidLoad { 
    NSLog(@"%s", __PRETTY_FUNCTION__); 
    [super viewDidLoad]; 

    _device = MTLCreateSystemDefaultDevice(); 
    _metalView = [[MTKView alloc] initWithFrame:self.view.bounds]; 
    [_metalView setContentMode:UIViewContentModeScaleAspectFit]; 
    _metalView.device = _device; 
    _metalView.delegate = self; 
    _metalView.clearColor = MTLClearColorMake(1, 1, 1, 1); 
    _metalView.colorPixelFormat = MTLPixelFormatBGRA8Unorm; 
    _metalView.framebufferOnly = NO; 
    _metalView.autoResizeDrawable = NO; 

    CVMetalTextureCacheCreate(NULL, NULL, _device, NULL, &_textureCache); 

    [self.view addSubview:_metalView]; 

    self.sessionQueue = dispatch_queue_create("session queue", DISPATCH_QUEUE_SERIAL); 

    if ([self setupCamera]) { 
     [_avSession startRunning]; 
    } 
} 

- (BOOL)setupCamera { 
    NSLog(@"%s", __PRETTY_FUNCTION__); 
    @try { 
     NSError * error; 

      _avSession = [[AVCaptureSession alloc] init]; 
      [_avSession beginConfiguration]; 
      [_avSession setSessionPreset:AVCaptureSessionPreset640x480]; 

      // get list of devices; connect to front-facing camera 
      self.videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
      if (self.videoDevice == nil) return FALSE; 

      AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:self.videoDevice error:&error]; 
      [_avSession addInput:input]; 

      dispatch_queue_t sampleBufferQueue = dispatch_queue_create("CameraMulticaster", DISPATCH_QUEUE_SERIAL); 

      AVCaptureVideoDataOutput * dataOutput = [[AVCaptureVideoDataOutput alloc] init]; 
      [dataOutput setAlwaysDiscardsLateVideoFrames:YES]; 
      [dataOutput setVideoSettings:@{(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)}]; 
      [dataOutput setSampleBufferDelegate:self queue:sampleBufferQueue]; 

      [_avSession addOutput:dataOutput]; 
      [_avSession commitConfiguration]; 
    } @catch (NSException *exception) { 
     NSLog(@"%s - %@", __PRETTY_FUNCTION__, exception.description); 
     return FALSE; 
    } @finally { 
     return TRUE; 
    } 

} 

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection 
{ 
    CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    { 
     size_t width = CVPixelBufferGetWidth(pixelBuffer); 
     size_t height = CVPixelBufferGetHeight(pixelBuffer); 

     CVMetalTextureRef texture = NULL; 
     CVReturn status = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _textureCache, pixelBuffer, NULL, MTLPixelFormatBGRA8Unorm, width, height, 0, &texture); 
     if(status == kCVReturnSuccess) 
     { 
      _metalView.drawableSize = CGSizeMake(width, height); 
      _texture = CVMetalTextureGetTexture(texture); 
      _commandQueue = [_device newCommandQueue]; 
      CFRelease(texture); 
     } 
    } 
} 

- (void)drawInMTKView:(MTKView *)view { 
    // creating command encoder 
    if (_texture) { 
     id<MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer]; 
     id<MTLTexture> drawingTexture = view.currentDrawable.texture; 

     // set up and encode the filter 
     MPSImageGaussianBlur *filter = [[MPSImageGaussianBlur alloc] initWithDevice:_device sigma:5]; 

     [filter encodeToCommandBuffer:commandBuffer sourceTexture:_texture destinationTexture:drawingTexture]; 

     // committing the drawing 
     [commandBuffer presentDrawable:view.currentDrawable]; 
     [commandBuffer commit]; 
     _texture = nil; 
    } 
} 

- (void)mtkView:(MTKView *)view drawableSizeWillChange:(CGSize)size { 

} 

@end 
0

вы должны попробовать один из следующих пунктов

1.Instead создания нового дескриптора визуализации прохода, использовать текущий проход рендеринга объекта дескриптора из MTKView object.this визуализации дескриптор передачи уже будет configured.you не нужен устанавливать anything.try примера кода данного

цен ниже
if let currentPassDesc = view.currentRenderPassDescriptor, 
let currentDrawable = view.currentDrawable 
{ 
let renderCommandEncoder =   

commandBuffer.makeRenderCommandEncoder(descriptor: currentPassDesc) 


renderCommandEncoder.setRenderPipelineState(renderPipeline) 

//set vertex buffers and call draw apis 
....... 
....... 
commandBuffer.present(currentDrawable) 

} 

2.You создание нового дескриптора визуализацию прохода, а затем установив его прикрепление цвета по текстуре вытяжки объекта поэтому вместо doi В этом случае вы должны создать новый объект текстуры, а затем установить использование этой текстуры в качестве объекта рендеринга. Затем вы получите контент, отображаемый в новой текстуре, но он не будет отображаться на экране, чтобы отобразить содержимое вашего текста, скопируйте содержимое своей текстуры в рисоваемую текстуру, а затем представите ее.

ниже код делает цель визуализации -

renderPassDescriptor.colorAttachments[0].clearColor = 

MTLClearColor(red: 

0.0,green: 0.0,blue: 0.0,alpha: 1.0) 
renderPassDescriptor.colorAttachments[0].loadAction = .clear 
renderPassDescriptor.colorAttachments[0].storeAction = .store 

renderPassDescriptor.depthAttachment.clearDepth = 1.0 
renderPassDescriptor.depthAttachment.loadAction = .clear 
renderPassDescriptor.depthAttachment.storeAction = .dontCare 

let view = self.view as!MTKView 
let textDesc = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: 

.bgra8Unorm, width: Int(view.frame.width), 
height: Int(view.frame.height), mipmapped: false) 
textDesc.depth = 1 
//see below line  
textDesc.usage = 
[MTLTextureUsage.renderTarget,MTLTextureUsage.shaderRead] 
textDesc.storageMode = .private 
mainPassFrameBuffer = device.makeTexture(descriptor: textDesc) 
renderPassDescriptor.colorAttachments[0].texture = mainPassFrameBuffer 
Смежные вопросы