SignatureRenderer.m 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. //
  2. // SignatureRenderer.m
  3. // HelloTriangle
  4. //
  5. // Created by Rui Zhang on 4/27/23.
  6. // Copyright © 2023 Apple. All rights reserved.
  7. //
  8. #import "SignatureRenderer.h"
  9. @implementation SignatureRenderer
  10. {
  11. id<MTLDevice> _device;
  12. // The render pipeline generated from the vertex and fragment shaders in the .metal shader file.
  13. id<MTLRenderPipelineState> _pipelineState;
  14. // The command queue used to pass commands to the device.
  15. id<MTLCommandQueue> _commandQueue;
  16. // The current size of the view, used as an input to the vertex shader.
  17. vector_uint2 _viewportSize;
  18. }
  19. - (nonnull instancetype)initWithMetalKitView:(nonnull MTKView *)mtkView
  20. {
  21. self = [super init];
  22. if(self)
  23. {
  24. NSError *error;
  25. _device = mtkView.device;
  26. self.vertexTotal = 10000;
  27. // Load all the shader files with a .metal file extension in the project.
  28. id<MTLLibrary> defaultLibrary = [_device newDefaultLibrary];
  29. id<MTLFunction> vertexFunction = [defaultLibrary newFunctionWithName:@"vertexShader"];
  30. id<MTLFunction> fragmentFunction = [defaultLibrary newFunctionWithName:@"fragmentShader"];
  31. // Configure a pipeline descriptor that is used to create a pipeline state.
  32. MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
  33. pipelineStateDescriptor.label = @"Simple Pipeline";
  34. pipelineStateDescriptor.vertexFunction = vertexFunction;
  35. pipelineStateDescriptor.fragmentFunction = fragmentFunction;
  36. pipelineStateDescriptor.colorAttachments[0].pixelFormat = mtkView.colorPixelFormat;
  37. // pipelineStateDescriptor.colorAttachments[0].cle = MTLClearColorMake(1.0, 1.0, 1.0, 1.0);
  38. _pipelineState = [_device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor
  39. error:&error];
  40. // Pipeline State creation could fail if the pipeline descriptor isn't set up properly.
  41. // If the Metal API validation is enabled, you can find out more information about what
  42. // went wrong. (Metal API validation is enabled by default when a debug build is run
  43. // from Xcode.)
  44. NSAssert(_pipelineState, @"Failed to create pipeline state: %@", error);
  45. // Create the command queue
  46. _commandQueue = [_device newCommandQueue];
  47. }
  48. return self;
  49. }
  50. /// Called whenever view changes orientation or is resized
  51. - (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size
  52. {
  53. // Save the size of the drawable to pass to the vertex shader.
  54. _viewportSize.x = size.width;
  55. _viewportSize.y = size.height;
  56. }
  57. /// Called whenever the view needs to render a frame.
  58. - (void)drawInMTKView:(nonnull MTKView *)view
  59. {
  60. // static const PPSSignaturePoint triangleVertices[] =
  61. // {
  62. // // 2D positions, RGBA colors
  63. // { { 0, 0 }, { 1, 1, 1, 1 } },
  64. // { { 0, 580 }, { 1, 1, 1, 1 } },
  65. // { { 580, 580 }, { 1, 1, 1, 1 } },
  66. // { { 580, 0 }, { 1, 1, 1, 1 } },
  67. // { { 0, 0 }, { 1, 1, 1, 1 } },
  68. // { { 290, -290 }, { 1, 1, 1, 1 } },
  69. //
  70. // };
  71. // Create a new command buffer for each render pass to the current drawable.
  72. id<MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];
  73. commandBuffer.label = @"MyCommand";
  74. // Obtain a renderPassDescriptor generated from the view's drawable textures.
  75. MTLRenderPassDescriptor *renderPassDescriptor = view.currentRenderPassDescriptor;
  76. if(renderPassDescriptor != nil)
  77. {
  78. renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(1.0, 1.0, 1.0, 0.0);
  79. // Create a render command encoder.
  80. id<MTLRenderCommandEncoder> renderEncoder =
  81. [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
  82. renderEncoder.label = @"MyRenderEncoder";
  83. // Set the region of the drawable to draw into.
  84. [renderEncoder setViewport:(MTLViewport){0.0, 0.0, _viewportSize.x, _viewportSize.y, 0.0, 1.0 }];
  85. [renderEncoder setRenderPipelineState:_pipelineState];
  86. // Pass in the parameter data.
  87. // renderEncoder setvertex
  88. ;
  89. // for(int i=0;i<self.parts.count;i++)
  90. // {
  91. // if([self.parts[i] intValue]>0)
  92. // {
  93. // int begin = 0;
  94. // if(i>0)
  95. // begin =[self.parts[i-1] intValue];
  96. // int count = [self.parts[i] intValue];
  97. // int length = count*sizeof(PPSSignaturePoint);
  98. // [renderEncoder setVertexBytes:&self.SignatureVertexData[begin]
  99. // length:length
  100. // atIndex:AAPLVertexInputIndexVertices];
  101. // }
  102. // }
  103. id<MTLBuffer> buffer = [view.device newBufferWithBytes:self.SignatureVertexData length:sizeof(PPSSignaturePoint)*self.vertexTotal options:MTLResourceOptionCPUCacheModeDefault];
  104. [renderEncoder setVertexBuffer:buffer offset:0 atIndex:0];
  105. // id<MTLBuffer> buffer = [view.device newBufferWithBytes:triangleVertices length:sizeof(PPSSignaturePoint)*self.vertexTotal options:nil];
  106. // [renderEncoder setVertexBuffer:buffer offset:0 atIndex:0];
  107. // [renderEncoder setVertexBytes:triangleVertices
  108. // length:sizeof(PPSSignaturePoint)*100
  109. // atIndex:AAPLVertexInputIndexVertices];
  110. [renderEncoder setVertexBytes:&_viewportSize
  111. length:sizeof(_viewportSize)
  112. atIndex:AAPLVertexInputIndexViewportSize];
  113. // Draw the triangle.
  114. // [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangleStrip
  115. // vertexStart:0
  116. // vertexCount:6];
  117. for(int i=0;i<self.parts.count;i++)
  118. {
  119. if([self.parts[i] intValue]>0)
  120. {
  121. int begin = 0;
  122. if(i>0)
  123. begin =[self.parts[i-1] intValue];
  124. int count = [self.parts[i] intValue];
  125. [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangleStrip
  126. vertexStart:begin
  127. vertexCount:count];
  128. // int length = count*sizeof(PPSSignaturePoint);
  129. // [renderEncoder setVertexBytes:&self.SignatureVertexData[begin]
  130. // length:length
  131. // atIndex:AAPLVertexInputIndexVertices];
  132. }
  133. }
  134. // [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle
  135. // vertexStart:1
  136. // vertexCount:3];
  137. [renderEncoder endEncoding];
  138. // Schedule a present once the framebuffer is complete using the current drawable.
  139. [commandBuffer presentDrawable:view.currentDrawable];
  140. }
  141. // Finalize rendering here & push the command buffer to the GPU.
  142. [commandBuffer commit];
  143. }
  144. @end