MetalShaderShowcase/AAPLParticleSystemRenderer.mm
/* |
Copyright (C) 2016 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
Metal Particle System Renderer for Metal Shader Showpiece. Acts as the update and render delegate for the view controller and performs rendering for the particle system. |
*/ |
#import "AAPLRenderer.h" |
#import "AAPLViewController.h" |
#import "AAPLView.h" |
#import "AAPLTransforms.h" |
#import "AAPLSharedTypes.h" |
#import "AAPLTeapotMesh.h" |
#import "AAPLMesh.h" |
#import "AAPLParticleSystemRenderer.h" |
#import "AAPLParticleSystem.h" |
@implementation AAPLParticleSystemRenderer |
{ |
// particle system data |
NSDate* _startTime; |
AAPLParticleSystem* _particleSystem; |
} |
// Overriding base class method to make particles blend |
- (instancetype)initWithName:(NSString *)name vertexShader:(NSString *)vertexShaderName fragmentShader:(NSString *)fragmentShaderName mesh:(AAPLMesh *)mesh |
{ |
self = [super initWithName:name vertexShader:vertexShaderName fragmentShader:fragmentShaderName mesh:mesh]; |
if (self) |
{ |
_blending = YES; |
_depthWriteEnabled = NO; |
} |
return self; |
} |
#pragma mark RENDER VIEW DELEGATE METHODS |
// Overriding base class method to create the particle system, it's timer, and to set the particle's lifespan |
- (void)configure:(AAPLView *)view |
{ |
[super configure:view]; |
_startTime = [NSDate date]; |
_particleSystem = [[AAPLParticleSystem alloc] initWithDevice:self.device]; |
AAPL::uniforms_t* bufferPointer = (AAPL::uniforms_t *)[_dynamicConstantBuffer contents]; |
bufferPointer->lifespan = _particleSystem.lifespan; |
} |
// Overriding base class method to render the particle system instead of the mesh |
- (void)renderObject:(id <MTLRenderCommandEncoder>)renderEncoder view:(AAPLView *)view bufferOffset:(uint32_t)offset name:(NSString *)name |
{ |
[renderEncoder pushDebugGroup:name]; |
[renderEncoder setRenderPipelineState:_pipelineState]; |
// Go through the reflection items and set the buffers |
for (MTLArgument *arg in _reflection.vertexArguments) |
{ |
if ([arg.name isEqualToString:@"initialDirection"]) |
{ |
[renderEncoder setVertexBuffer:_particleSystem.initial_direction_buffer offset:0 atIndex:arg.index]; |
} |
else if ([arg.name isEqualToString:@"birthOffsets"]) |
{ |
[renderEncoder setVertexBuffer:_particleSystem.birth_offsets_buffer offset:0 atIndex:arg.index]; |
} |
else if ([arg.name isEqualToString:@"uniforms"]) |
{ |
[renderEncoder setVertexBuffer:_dynamicConstantBuffer offset:offset atIndex:arg.index]; |
} |
} |
// tell the render context we want to draw our primitives |
[renderEncoder drawPrimitives:MTLPrimitiveTypePoint vertexStart:0 vertexCount:_particleSystem.num_particles]; |
[renderEncoder popDebugGroup]; |
} |
#pragma mark VIEW CONTROLLER DELEGATE METHODS |
// Overriding base class method to update the time of the particle system and make it not rotate |
- (void)update:(AAPLViewController *)controller |
{ |
AAPL::uniforms_t* bufferPointer = (AAPL::uniforms_t *)[_dynamicConstantBuffer contents]; |
simd::float4x4 model_matrix = AAPL::translate(0.0f, -0.2f, 1.0f); |
bufferPointer->model_matrix = model_matrix; |
// Update the time for our paticle system |
NSDate* currentTime = [NSDate date]; |
bufferPointer->t = [currentTime timeIntervalSinceDate:_startTime]; |
} |
@end |
Copyright © 2016 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2016-06-13