From 13970744b485aacc9ee1ba118f7d347cf64fc0b0 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Fri, 10 Jan 2020 18:57:08 +0200 Subject: [PATCH] Fixed blending bug in the Metal renderer where the destination alpha was not updated which caused problems while rendering the program in full screen mode. --- metal/4ed_metal_render.mm | 50 ++++++++++++++++++++++++----------- platform_mac/mac_4ed.mm | 31 ++++++++++++++-------- platform_mac/mac_4ed_metal.mm | 2 +- 3 files changed, 55 insertions(+), 28 deletions(-) diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index 3209e53e..c7452e02 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -25,9 +25,12 @@ struct Metal_Buffer{ @interface Metal_Renderer : NSObject @property (nonatomic) Render_Target *target; -- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)mtkView; +- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)mtkView target:(Render_Target*)target; + - (u32)get_texture_of_dim:(Vec3_i32)dim kind:(Texture_Kind)kind; - (b32)fill_texture:(u32)texture kind:(Texture_Kind)kind pos:(Vec3_i32)p dim:(Vec3_i32)dim data:(void*)data; +- (void)bind_texture:(u32)handle encoder:(id)render_encoder; + - (Metal_Buffer*)get_reusable_buffer_with_size:(NSUInteger)size; - (void)add_reusable_buffer:(Metal_Buffer*)buffer; @end @@ -127,8 +130,8 @@ sd = (abs(sd + in.half_thickness) - in.half_thickness); float shape_value = (1.0 - smoothstep(-1.0, 0.0, sd)); shape_value *= has_thickness; -// TOOD(yuval): Add sample_value to alpha float4 out_color = float4(in.color.xyz, in.color.a * (sample_value + shape_value)); +//float4 out_color = float4(1, 1, 1, shape_value); return(out_color); } )"; @@ -165,7 +168,7 @@ metal__make_buffer(u32 size, id device){ u32 next_texture_handle_index; } -- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)mtk_view{ +- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)mtk_view target:(Render_Target*)target{ self = [super init]; if (self == nil){ return(nil); @@ -226,8 +229,8 @@ metal__make_buffer(u32 size, id device){ pipeline_state_descriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; pipeline_state_descriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha; pipeline_state_descriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha; - /*pipeline_state_descriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne; - pipeline_state_descriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;*/ + pipeline_state_descriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne; + pipeline_state_descriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha; pipeline_state = [device newRenderPipelineStateWithDescriptor:pipeline_state_descriptor error:&error]; @@ -246,6 +249,16 @@ metal__make_buffer(u32 size, id device){ textures = (Metal_Texture*)system_memory_allocate(metal__max_textures * sizeof(Metal_Texture), file_name_line_number_lit_u8); next_texture_handle_index = 0; + // NOTE(yuval): Create the fallback texture + target->fallback_texture_id = [self get_texture_of_dim:V3i32(2, 2, 1) + kind:TextureKind_Mono]; + u8 white_block[] = {0xFF, 0xFF, 0xFF, 0xFF}; + [self fill_texture:target->fallback_texture_id + kind:TextureKind_Mono + pos:V3i32(0, 0, 0) + dim:V3i32(2, 2, 1) + data:white_block]; + // NOTE(yuval): Create a capture scope for gpu frame capture capture_scope = [[MTLCaptureManager sharedCaptureManager] newCaptureScopeWithDevice:device]; @@ -324,10 +337,9 @@ metal__make_buffer(u32 size, id device){ atIndex:1]; u32 buffer_offset = 0; - i32 count = 0; for (Render_Group *group = _target->group_first; group; - group = group->next, ++count){ + group = group->next){ // NOTE(yuval): Set scissor rect { Rect_i32 box = Ri32(group->clip_box); @@ -349,19 +361,17 @@ metal__make_buffer(u32 size, id device){ i32 vertex_count = group->vertex_list.vertex_count; if (vertex_count > 0){ - // TODO(yuval): Bind a texture + // NOTE(yuval): Bind a texture { Face* face = font_set_face_from_id(font_set, group->face_id); if (face != 0){ - // TODO(yuval): Bind face texture - u32 texture_handle = face->texture; - Metal_Texture texture = textures[texture_handle]; - if (texture != 0){ - [render_encoder setFragmentTexture:texture - atIndex:0]; - } + // NOTE(yuval): Bind face texture + [self bind_texture:face->texture + encoder:render_encoder]; } else{ - // TODO(yuval): Bind default texture + // NOTE(yuval): Bind fallback texture + [self bind_texture:_target->fallback_texture_id + encoder:render_encoder]; } } @@ -458,6 +468,14 @@ metal__make_buffer(u32 size, id device){ return result; } +- (void)bind_texture:(u32)handle encoder:(id)render_encoder{ + Metal_Texture texture = textures[handle]; + if (texture != 0){ + [render_encoder setFragmentTexture:texture + atIndex:0]; + } +} + - (Metal_Buffer*)get_reusable_buffer_with_size:(NSUInteger)size{ // NOTE(yuval): This routine is a modified version of Dear ImGui's MetalContext::dequeueReusableBufferOfLength in imgui_impl_metal.mm diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 31ff96ef..f8ad5a20 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -360,21 +360,35 @@ mac_resize(NSWindow *window){ @end @implementation FCoderWindowDelegate -- (BOOL)windowShouldClose:(id)sender { +- (BOOL)windowShouldClose:(id)sender{ mac_vars.input_chunk.trans.trying_to_kill = true; system_signal_step(0); return(NO); } -- (void)windowDidResize:(NSNotification*)notification { +- (void)windowDidResize:(NSNotification*)notification{ mac_resize(mac_vars.window); } -- (void)windowDidMiniaturize:(NSNotification*)notification { +- (void)windowDidMiniaturize:(NSNotification*)notification{ } -- (void)windowDidDeminiaturize:(NSNotification*)notification { +- (void)windowDidDeminiaturize:(NSNotification*)notification{ +} + +- (void)windowDidBecomeKey:(NSNotification *)notification{ + printf("Focus\n"); + system_signal_step(0); +} + +- (void)windowDidResignKey:(NSNotification *)notification{ + printf("Lost Focus\n"); + system_signal_step(0); +} + +- (void)windowDidEnterFullScreen:(NSNotification *)notification{ + system_signal_step(0); } @end @@ -430,8 +444,6 @@ this only gets called for window creation and other extraordinary events. block_zero_struct(&mac_vars.input_chunk.trans); - printf("Step scroll wheel: %d\n", input.mouse.wheel); - // NOTE(yuval): See comment in win32_4ed.cpp's main loop if (mac_vars.send_exit_signal){ input.trying_to_kill = true; @@ -512,9 +524,6 @@ this only gets called for window creation and other extraordinary events. float dx = event.scrollingDeltaX; float dy = event.scrollingDeltaY; - printf("Mouse scroll - dx:%f dy:%f\n", dx, dy); - - //mac_vars.input_chunk.trans.mouse_wheel = -((int32_t)dy); i8 scroll_speed = 100; if (dy > 0){ scroll_speed *= -1; @@ -567,7 +576,7 @@ this only gets called for window creation and other extraordinary events. mac_vars.input_chunk.pers.mouse = new_m; } - system_signal_step(0); + //system_signal_step(0); } @end @@ -776,7 +785,7 @@ main(int arg_count, char **args){ [mac_vars.window makeKeyAndOrderFront:nil]; // NOTE(yuval): Initialize the renderer - renderer = mac_init_renderer(MacRenderer_OpenGL, mac_vars.window, &target); + renderer = mac_init_renderer(MacRenderer_Metal, mac_vars.window, &target); mac_resize(w, h); diff --git a/platform_mac/mac_4ed_metal.mm b/platform_mac/mac_4ed_metal.mm index 117eec2d..60b754d9 100644 --- a/platform_mac/mac_4ed_metal.mm +++ b/platform_mac/mac_4ed_metal.mm @@ -67,7 +67,7 @@ mac_metal__init(NSWindow *window, Render_Target *target){ [content_view addSubview:metal->view]; // NOTE(yuval): Create the Metal renderer and set it as the Metal view's delegate - metal->renderer = [[Metal_Renderer alloc] initWithMetalKitView:metal->view]; + metal->renderer = [[Metal_Renderer alloc] initWithMetalKitView:metal->view target:target]; metal->view.delegate = metal->renderer; return(metal);