diff --git a/src/render/d3d11/generated/render_d3d11.meta.h b/src/render/d3d11/generated/render_d3d11.meta.h index 6578fe5b..9855582f 100644 --- a/src/render/d3d11/generated/render_d3d11.meta.h +++ b/src/render/d3d11/generated/render_d3d11.meta.h @@ -306,7 +306,6 @@ str8_lit_comp( "{\n" " // rjf: blend weighted texture samples into color\n" " float3 color = kernel[0].x * stage_t2d.Sample(stage_sampler, v2p.texcoord).rgb;\n" -" \n" " for(uint i = 1; i < blur_count; i += 1)\n" " {\n" " float weight = kernel[i].x;\n" @@ -321,7 +320,7 @@ str8_lit_comp( " \n" " // rjf: weight output color by sdf\n" " // this is doing alpha testing, leave blurring only where mostly opaque pixels are\n" -" if (corner_sdf_t < 0.9f)\n" +" if(corner_sdf_t < 0.9f)\n" " {\n" " discard;\n" " }\n" diff --git a/src/render/d3d11/render_d3d11.mdesk b/src/render/d3d11/render_d3d11.mdesk index 888fa4a9..102dd590 100644 --- a/src/render/d3d11/render_d3d11.mdesk +++ b/src/render/d3d11/render_d3d11.mdesk @@ -304,7 +304,6 @@ ps_main(Vertex2Pixel v2p) : SV_TARGET { // rjf: blend weighted texture samples into color float3 color = kernel[0].x * stage_t2d.Sample(stage_sampler, v2p.texcoord).rgb; - for(uint i = 1; i < blur_count; i += 1) { float weight = kernel[i].x; @@ -319,7 +318,7 @@ ps_main(Vertex2Pixel v2p) : SV_TARGET // rjf: weight output color by sdf // this is doing alpha testing, leave blurring only where mostly opaque pixels are - if (corner_sdf_t < 0.9f) + if(corner_sdf_t < 0.9f) { discard; } diff --git a/src/render/opengl/generated/render_opengl.meta.h b/src/render/opengl/generated/render_opengl.meta.h index ed115dd8..0e94599d 100644 --- a/src/render/opengl/generated/render_opengl.meta.h +++ b/src/render/opengl/generated/render_opengl.meta.h @@ -216,7 +216,7 @@ str8_lit_comp( " vec2 rect_half_size = vec2((rect.z-rect.x)/2, (rect.w-rect.y)/2);\n" " \n" " gl_Position = vec4(vertex_position_scr.x, -vertex_position_scr.y, 0.f, 1.f);\n" -" texcoord = vertex_position_pct;\n" +" texcoord = vec2(vertex_position_pct.x, 1-vertex_position_pct.y);\n" " sdf_sample_pos = (2.f * cornercoords_pct - 1.f) * rect_half_size;\n" " rect_half_size = rect_half_size - 2.f;\n" " corner_radius = corner_radii_px[gl_VertexID];\n" @@ -251,7 +251,6 @@ str8_lit_comp( "{\n" " // rjf: blend weighted texture samples into color\n" " vec3 color = kernel[0].x * texture(tex, texcoord).rgb;\n" -" \n" " for(int i = 1; i < blur_count; i += 1)\n" " {\n" " float weight = kernel[i].x;\n" @@ -262,7 +261,7 @@ str8_lit_comp( " \n" " // rjf: sample for corners\n" " float corner_sdf_s = rect_sdf(sdf_sample_pos, rect_half_size, corner_radius);\n" -" float corner_sdf_t = 1-smoothstep(0, 2, corner_sdf_s);\n" +" float corner_sdf_t = smoothstep(0, 2, corner_sdf_s);\n" " \n" " // rjf: weight output color by sdf\n" " // this is doing alpha testing, leave blurring only where mostly opaque pixels are\n" diff --git a/src/render/opengl/render_opengl.c b/src/render/opengl/render_opengl.c index f9fcb290..dc58659b 100644 --- a/src/render/opengl/render_opengl.c +++ b/src/render/opengl/render_opengl.c @@ -172,15 +172,28 @@ r_init(CmdLine *cmdln) } //- rjf: set up built-in resources - glGenVertexArrays(1, &r_ogl_state->all_purpose_vao); - glGenBuffers(1, &r_ogl_state->scratch_buffer_64kb); - glBindBuffer(GL_ARRAY_BUFFER, r_ogl_state->scratch_buffer_64kb); - glBufferData(GL_ARRAY_BUFFER, KB(64), 0, GL_DYNAMIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glGenTextures(1, &r_ogl_state->white_texture); - glBindTexture(GL_TEXTURE_2D, r_ogl_state->white_texture); - U32 white_pixel = 0xffffffff; - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &white_pixel); + { + // rjf: all-purpose VAO + glGenVertexArrays(1, &r_ogl_state->all_purpose_vao); + + // rjf: scratch buffer + { + glGenBuffers(1, &r_ogl_state->scratch_buffer_64kb); + glBindBuffer(GL_ARRAY_BUFFER, r_ogl_state->scratch_buffer_64kb); + glBufferData(GL_ARRAY_BUFFER, KB(64), 0, GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + + // rjf: white texture + { + glGenTextures(1, &r_ogl_state->white_texture); + glBindTexture(GL_TEXTURE_2D, r_ogl_state->white_texture); + U32 white_pixel = 0xffffffff; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &white_pixel); + } + } + + //- rjf: set up options glEnable(GL_FRAMEBUFFER_SRGB); //- rjf: set up buffer flush state @@ -203,14 +216,27 @@ r_init(CmdLine *cmdln) r_hook R_Handle r_window_equip(WM_Window window) { - R_Handle result = r_ogl_os_window_equip(window); + R_OGL_Window *w = r_ogl_state->free_window; + if(w != 0) + { + SLLStackPop(r_ogl_state->free_window); + } + else + { + w = push_array(r_ogl_state->arena, R_OGL_Window, 1); + } + MemoryZeroStruct(w); + w->os = r_ogl_os_window_equip(window); + R_Handle result = {(U64)w}; return result; } r_hook void r_window_unequip(WM_Window window, R_Handle window_equip) { - r_ogl_os_window_unequip(window, window_equip); + R_OGL_Window *w = (R_OGL_Window *)window_equip.u64[0]; + r_ogl_os_window_unequip(window, w->os); + SLLStackPush(r_ogl_state->free_window, w); } //- rjf: textures @@ -337,21 +363,68 @@ r_begin_frame(void) r_hook void r_end_frame(void) { - // TODO(rjf) + for(R_OGL_FlushBuffer *flush_buffer = r_ogl_state->first_buffer_to_flush; flush_buffer != 0; flush_buffer = flush_buffer->next) + { + glDeleteBuffers(1, &flush_buffer->id); + } + arena_clear(r_ogl_state->buffer_flush_arena); + r_ogl_state->first_buffer_to_flush = r_ogl_state->last_buffer_to_flush = 0; } r_hook void r_window_begin_frame(WM_Window os, R_Handle r) { r_ogl_os_select_window(os, r); + R_OGL_Window *window = (R_OGL_Window *)r.u64[0]; //- rjf: unpack window viewport info Rng2F32 client_rect = wm_client_rect_from_window(os); Vec2F32 client_rect_dim = dim_2f32(client_rect); + //- rjf: set up targets if needed + if(client_rect_dim.x != window->last_client_rect_dim.x || client_rect_dim.y != window->last_client_rect_dim.y) + { + window->last_client_rect_dim = client_rect_dim; + R_OGL_RenderTarget *targets[] = + { + &window->stage_target, + &window->stage_scratch_target, + }; + for EachElement(idx, targets) + { + if(targets[idx]->fbo != 0) + { + glDeleteFramebuffers(1, &targets[idx]->fbo); + glDeleteTextures(1, &targets[idx]->color_texture); + } + glGenFramebuffers(1, &targets[idx]->fbo); + glGenTextures(1, &targets[idx]->color_texture); + glBindFramebufferScope(GL_FRAMEBUFFER, targets[idx]->fbo) + glBindTextureScope(GL_TEXTURE_2D, targets[idx]->color_texture) + { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (S32)client_rect_dim.x, (S32)client_rect_dim.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, targets[idx]->color_texture, 0); + } + } + } + //- rjf: clear and reset state - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + { + GLuint fbos[] = + { + window->stage_target.fbo, + window->stage_scratch_target.fbo, + 0, + }; + for EachElement(idx, fbos) + { + glBindFramebufferScope(GL_FRAMEBUFFER, fbos[idx]) + { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + } + } glViewport(0, 0, (S32)client_rect_dim.x, (S32)client_rect_dim.y); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -360,12 +433,18 @@ r_window_begin_frame(WM_Window os, R_Handle r) r_hook void r_window_end_frame(WM_Window os, R_Handle r) { - for(R_OGL_FlushBuffer *flush_buffer = r_ogl_state->first_buffer_to_flush; flush_buffer != 0; flush_buffer = flush_buffer->next) + R_OGL_Window *window = (R_OGL_Window *)r.u64[0]; + + //- rjf: blit window's main staging frame buffer to window frame buffer + glBindFramebufferScope(GL_READ_FRAMEBUFFER, window->stage_target.fbo) glBindFramebufferScope(GL_DRAW_FRAMEBUFFER, 0) { - glDeleteBuffers(1, &flush_buffer->id); + glBlitFramebuffer(0, 0, (S32)window->last_client_rect_dim.x, (S32)window->last_client_rect_dim.y, + 0, 0, (S32)window->last_client_rect_dim.x, (S32)window->last_client_rect_dim.y, + GL_COLOR_BUFFER_BIT, + GL_NEAREST); } - arena_clear(r_ogl_state->buffer_flush_arena); - r_ogl_state->first_buffer_to_flush = r_ogl_state->last_buffer_to_flush = 0; + + //- rjf: swap buffers r_ogl_os_window_swap(os, r); } @@ -374,6 +453,7 @@ r_window_end_frame(WM_Window os, R_Handle r) r_hook void r_window_submit(WM_Window window, R_Handle window_equip, R_PassList *passes) { + R_OGL_Window *w = (R_OGL_Window *)window_equip.u64[0]; Rng2F32 viewport_rect = wm_client_rect_from_window(window); Vec2F32 viewport_dim = dim_2f32(viewport_rect); for(R_PassNode *pass_n = passes->first; pass_n != 0; pass_n = pass_n->next) @@ -394,7 +474,9 @@ r_window_submit(WM_Window window, R_Handle window_equip, R_PassList *passes) //- rjf: draw each batch group GLuint shader = r_ogl_state->shaders[R_OGL_ShaderKind_Rect]; - glBindVertexArrayScope(r_ogl_state->all_purpose_vao) glUseProgramScope(shader) + glUseProgramScope(shader) + glBindVertexArrayScope(r_ogl_state->all_purpose_vao) + glBindFramebufferScope(GL_FRAMEBUFFER, w->stage_target.fbo) { for(R_BatchGroup2DNode *group_n = rect_batch_groups->first; group_n != 0; group_n = group_n->next) { @@ -500,10 +582,103 @@ r_window_submit(WM_Window window, R_Handle window_equip, R_PassList *passes) case R_PassKind_Blur: { R_PassParams_Blur *params = pass->params_blur; - // GLuint shader = r_ogl_state->shaders[R_OGL_ShaderKind_Blur]; - // glBindVertexArrayScope(r_ogl_state->all_purpose_vao) glUseProgramScope(shader) + GLuint shader = r_ogl_state->shaders[R_OGL_ShaderKind_Blur]; + glUseProgramScope(shader) + glBindVertexArrayScope(r_ogl_state->all_purpose_vao) { - // TODO(rjf) + //- rjf: form blur sampling kernel + Vec4F32 kernel[32] = {0}; + U64 blur_count = 0; + { + // + // TODO(rjf): adopted from martins' d3d11 impl, should dedup in common render helpers + // + F32 weights[ArrayCount(kernel)*2] = {0}; + F32 blur_size = Min(params->blur_size, ArrayCount(weights)); + blur_count = (U64)round_f32(blur_size); + F32 stdev = (blur_size-1.f)/2.f; + F32 one_over_root_2pi_stdev2 = 1/sqrt_f32(2*pi32*stdev*stdev); + F32 euler32 = 2.718281828459045f; + weights[0] = 1.f; + if(stdev > 0.f) + { + for(U64 idx = 0; idx < blur_count; idx += 1) + { + F32 kernel_x = (F32)idx; + weights[idx] = one_over_root_2pi_stdev2*pow_f32(euler32, -kernel_x*kernel_x/(2.f*stdev*stdev)); + } + } + if(weights[0] > 1.f) + { + MemoryZeroArray(weights); + weights[0] = 1.f; + } + else + { + // prepare weights & offsets for bilinear lookup + // blur filter wants to calculate w0*pixel[pos] + w1*pixel[pos+1] + ... + // with bilinear filter we can do this calulation by doing only w*sample(pos+t) = w*((1-t)*pixel[pos] + t*pixel[pos+1]) + // we can see w0=w*(1-t) and w1=w*t + // thus w=w0+w1 and t=w1/w + for(U64 idx = 1; idx < blur_count; idx += 2) + { + F32 w0 = weights[idx + 0]; + F32 w1 = weights[idx + 1]; + F32 w = w0 + w1; + F32 t = w1 / w; + + // each kernel element is float2(weight, offset) + // weights & offsets are adjusted for bilinear sampling + // zw elements are not used, a bit of waste but it allows for simpler shader code + kernel[(idx+1)/2] = v4f32(w, (F32)idx + t, 0, 0); + } + } + kernel[0].x = weights[0]; + } + + //- rjf: set up uniforms + glUniform4fv(glGetUniformLocation(shader, "rect"), 1, (F32 *)(¶ms->rect)); + glUniform4fv(glGetUniformLocation(shader, "corner_radii_px"), 1, params->corner_radii); + glUniform2f(glGetUniformLocation(shader, "viewport_size"), viewport_dim.x, viewport_dim.y); + glUniform1i(glGetUniformLocation(shader, "blur_count"), blur_count); + glUniform4fv(glGetUniformLocation(shader, "kernel"), ArrayCount(kernel), (F32 *)&kernel[0]); + glActiveTexture(GL_TEXTURE0); + + //- rjf: set up scissor + if(params->clip.x0 != 0 || + params->clip.x1 != 0 || + params->clip.y0 != 0 || + params->clip.y1 != 0) + { + Rng2F32 clip = params->clip; + glScissor(clip.x0, viewport_dim.y - clip.y1, (clip.x1-clip.x0) + 1, (clip.y1-clip.y0)+1); + glEnable(GL_SCISSOR_TEST); + } + + //- rjf: pass 1: stage -(horizontal)-> stage_scratch + glBindFramebufferScope(GL_FRAMEBUFFER, w->stage_scratch_target.fbo) + glBindTextureScope(GL_TEXTURE_2D, w->stage_target.color_texture) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glUniform2f(glGetUniformLocation(shader, "direction"), 1.f/viewport_dim.x, 0); + glUniform1i(glGetUniformLocation(shader, "tex"), 0); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + + //- rjf: pass 2: stage_scratch -(vertical)-> stage + glBindFramebufferScope(GL_FRAMEBUFFER, w->stage_target.fbo) + glBindTextureScope(GL_TEXTURE_2D, w->stage_scratch_target.color_texture) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glUniform2f(glGetUniformLocation(shader, "direction"), 0, 1.f/viewport_dim.y); + glUniform1i(glGetUniformLocation(shader, "tex"), 0); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + + //- rjf: unset scissor + glDisable(GL_SCISSOR_TEST); } }break; diff --git a/src/render/opengl/render_opengl.h b/src/render/opengl/render_opengl.h index 927d2007..b26fe155 100644 --- a/src/render/opengl/render_opengl.h +++ b/src/render/opengl/render_opengl.h @@ -11,9 +11,46 @@ typedef char GLchar; typedef ptrdiff_t GLsizeiptr; typedef ptrdiff_t GLintptr; +#define GL_FRAMEBUFFER 0x8D40 #define GL_FRAMEBUFFER_SRGB 0x8DB9 #define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 + +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_COLOR_ATTACHMENT16 0x8CF0 +#define GL_COLOR_ATTACHMENT17 0x8CF1 +#define GL_COLOR_ATTACHMENT18 0x8CF2 +#define GL_COLOR_ATTACHMENT19 0x8CF3 +#define GL_COLOR_ATTACHMENT20 0x8CF4 +#define GL_COLOR_ATTACHMENT21 0x8CF5 +#define GL_COLOR_ATTACHMENT22 0x8CF6 +#define GL_COLOR_ATTACHMENT23 0x8CF7 +#define GL_COLOR_ATTACHMENT24 0x8CF8 +#define GL_COLOR_ATTACHMENT25 0x8CF9 +#define GL_COLOR_ATTACHMENT26 0x8CFA +#define GL_COLOR_ATTACHMENT27 0x8CFB +#define GL_COLOR_ATTACHMENT28 0x8CFC +#define GL_COLOR_ATTACHMENT29 0x8CFD +#define GL_COLOR_ATTACHMENT30 0x8CFE +#define GL_COLOR_ATTACHMENT31 0x8CFF + #define GL_R8 0x8229 #define GL_ARRAY_BUFFER 0x8892 @@ -117,6 +154,8 @@ X(glBindBuffer, void, (GLenum target, GLuint buffer))\ X(glDeleteBuffers, void, (GLsizei n, GLuint *buffers))\ X(glGenVertexArrays, void, (GLsizei n, GLuint *arrays))\ X(glBindVertexArray, void, (GLuint array))\ +X(glGenFramebuffers, void, (GLsizei n, GLuint *fbos))\ +X(glDeleteFramebuffers, void, (GLsizei n, GLuint *fbos))\ X(glCreateProgram, GLuint, (void))\ X(glCreateShader, GLuint, (GLenum type))\ X(glShaderSource, void, (GLuint shader, GLsizei count, char **string, GLint *length))\ @@ -141,6 +180,7 @@ X(glUniform1f, void, (GLint location, GLfloat v0))\ X(glUniform2f, void, (GLint location, GLfloat v0, GLfloat v1))\ X(glUniform3f, void, (GLint location, GLfloat v0, GLfloat v1, GLfloat v2))\ X(glUniform4f, void, (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3))\ +X(glUniform4fv, void, (GLint location, GLsizei count, const GLfloat *value))\ X(glUniformMatrix3fv, void, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value))\ X(glUniformMatrix4fv, void, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value))\ X(glUniform1i, void, (GLint location, GLint v0))\ @@ -149,10 +189,13 @@ X(glTexSubImage3D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffs X(glGenerateMipmap, void, (GLenum target))\ X(glBindAttribLocation, void, (GLuint programObj, GLuint index, char *name))\ X(glBindFragDataLocation, void, (GLuint program, GLuint color, char *name))\ +X(glBindFramebuffer, void, (GLenum target, GLuint fbo))\ X(glActiveTexture, void, (GLenum texture))\ X(glVertexAttribDivisor, void, (GLuint index, GLuint divisor))\ X(glDrawArraysInstanced, void, (GLenum mode, GLint first, GLsizei count, GLsizei instancecount))\ X(glDebugMessageCallback, void, (void (*)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam), void *user_data))\ +X(glFramebufferTexture2D, void, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level))\ +X(glBlitFramebuffer, void, (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter))\ #define X(name, r, p) typedef r name##_FunctionType p; R_OGL_ProcedureXList @@ -189,10 +232,28 @@ struct R_OGL_FlushBuffer GLuint id; }; +typedef struct R_OGL_RenderTarget R_OGL_RenderTarget; +struct R_OGL_RenderTarget +{ + GLuint fbo; + GLuint color_texture; +}; + +typedef struct R_OGL_Window R_OGL_Window; +struct R_OGL_Window +{ + R_OGL_Window *next; + R_Handle os; + Vec2F32 last_client_rect_dim; + R_OGL_RenderTarget stage_target; + R_OGL_RenderTarget stage_scratch_target; +}; + typedef struct R_OGL_State R_OGL_State; struct R_OGL_State { Arena *arena; + R_OGL_Window *free_window; R_OGL_Tex2D *free_tex2d; GLuint shaders[R_OGL_ShaderKind_COUNT]; GLuint all_purpose_vao; @@ -219,6 +280,9 @@ internal void r_ogl_debug_message_callback(GLenum source, GLenum type, GLuint id #define glUseProgramScope(...) DeferLoop(glUseProgram(__VA_ARGS__), glUseProgram(0)) #define glBindVertexArrayScope(...) DeferLoop(glBindVertexArray(__VA_ARGS__), glBindVertexArray(0)) +#define glBindFramebufferScope(target, ...) DeferLoop(glBindFramebuffer((target), __VA_ARGS__), glBindFramebuffer((target), 0)) +#define glBindTextureScope(target, ...) DeferLoop(glBindTexture((target), __VA_ARGS__), glBindTexture((target), 0)) +#define glEnableScope(...) DeferLoop(glEnable(__VA_ARGS__), glDisable(__VA_ARGS__)) //////////////////////////////// //~ rjf: OS-Specific Hooks diff --git a/src/render/opengl/render_opengl.mdesk b/src/render/opengl/render_opengl.mdesk index 777b17d5..d6d31a7a 100644 --- a/src/render/opengl/render_opengl.mdesk +++ b/src/render/opengl/render_opengl.mdesk @@ -240,7 +240,7 @@ void main(void) vec2 rect_half_size = vec2((rect.z-rect.x)/2, (rect.w-rect.y)/2); gl_Position = vec4(vertex_position_scr.x, -vertex_position_scr.y, 0.f, 1.f); - texcoord = vertex_position_pct; + texcoord = vec2(vertex_position_pct.x, 1-vertex_position_pct.y); sdf_sample_pos = (2.f * cornercoords_pct - 1.f) * rect_half_size; rect_half_size = rect_half_size - 2.f; corner_radius = corner_radii_px[gl_VertexID]; @@ -273,7 +273,6 @@ void main(void) { // rjf: blend weighted texture samples into color vec3 color = kernel[0].x * texture(tex, texcoord).rgb; - for(int i = 1; i < blur_count; i += 1) { float weight = kernel[i].x; @@ -284,7 +283,7 @@ void main(void) // rjf: sample for corners float corner_sdf_s = rect_sdf(sdf_sample_pos, rect_half_size, corner_radius); - float corner_sdf_t = 1-smoothstep(0, 2, corner_sdf_s); + float corner_sdf_t = smoothstep(0, 2, corner_sdf_s); // rjf: weight output color by sdf // this is doing alpha testing, leave blurring only where mostly opaque pixels are