diff --git a/Cocoa/GBViewMetal.m b/Cocoa/GBViewMetal.m index 157ddf3..8953492 100644 --- a/Cocoa/GBViewMetal.m +++ b/Cocoa/GBViewMetal.m @@ -24,6 +24,7 @@ static const vector_float2 rect[] = id vertices; id pipeline_state; id command_queue; + id mix_previous_buffer; } - (void)createInternalView @@ -46,6 +47,12 @@ static const vector_float2 rect[] = length:sizeof(rect) options:MTLResourceStorageModeShared]; + + static const bool default_mix_value = false; + mix_previous_buffer = [device newBufferWithBytes:&default_mix_value + length:sizeof(default_mix_value) + options:MTLResourceStorageModeShared]; + [self loadShader]; } @@ -93,12 +100,19 @@ static const vector_float2 rect[] = mipmapLevel:0 withBytes:[self currentBuffer] bytesPerRow:PITCH]; + if ([self shouldBlendFrameWithPrevious]) { + [previous_texture replaceRegion:region + mipmapLevel:0 + withBytes:[self previousBuffer] + bytesPerRow:PITCH]; + } MTLRenderPassDescriptor *render_pass_descriptor = view.currentRenderPassDescriptor; id command_buffer = [command_queue commandBuffer]; if(render_pass_descriptor != nil) { + *(bool *)[mix_previous_buffer contents] = [self shouldBlendFrameWithPrevious]; id render_encoder = [command_buffer renderCommandEncoderWithDescriptor:render_pass_descriptor]; @@ -113,9 +127,16 @@ static const vector_float2 rect[] = offset:0 atIndex:0]; + [render_encoder setFragmentBuffer:mix_previous_buffer + offset:0 + atIndex:0]; + [render_encoder setFragmentTexture:texture atIndex:0]; + [render_encoder setFragmentTexture:previous_texture + atIndex:1]; + [render_encoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; diff --git a/Shaders/MasterShader.metal b/Shaders/MasterShader.metal index a515764..928c4c7 100644 --- a/Shaders/MasterShader.metal +++ b/Shaders/MasterShader.metal @@ -37,9 +37,14 @@ static inline float4 texture(texture2d texture, float2 pos) } fragment float4 fragment_shader(rasterizer_data in [[stage_in]], - texture2d image [[ texture(0) ]]) + texture2d image [[ texture(0) ]], + texture2d previous_image [[ texture(1) ]], + constant bool *mix_previous [[ buffer(0) ]]) { in.texcoords.y = 1 - in.texcoords.y; + if (*mix_previous) { + return mix(texture(image, in.texcoords), texture(previous_image, in.texcoords), 0.5); + } return texture(image, in.texcoords); }