diff options
7 files changed, 121 insertions, 168 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index b9881162e9a..05cc9d1cfaf 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -276,7 +276,7 @@ data_to_c_simple(modes/shaders/edit_mesh_overlay_ghost_clear_vert.glsl SRC) data_to_c_simple(modes/shaders/edit_mesh_overlay_mix_frag.glsl SRC) data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_vert.glsl SRC) data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_frag.glsl SRC) -data_to_c_simple(modes/shaders/edit_curve_overlay_frag.glsl SRC) +data_to_c_simple(modes/shaders/edit_curve_overlay_handle_vert.glsl SRC) data_to_c_simple(modes/shaders/edit_curve_overlay_handle_geom.glsl SRC) data_to_c_simple(modes/shaders/edit_curve_overlay_loosevert_vert.glsl SRC) data_to_c_simple(modes/shaders/edit_lattice_overlay_frag.glsl SRC) diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.c index f2b303207fd..0f06f360b4a 100644 --- a/source/blender/draw/intern/draw_cache_impl_curve.c +++ b/source/blender/draw/intern/draw_cache_impl_curve.c @@ -45,14 +45,11 @@ #include "draw_cache_impl.h" /* own include */ #define SELECT 1 -#define ACTIVE_NURB 1 << 7 /* last char bite */ -#define HANDLE_SEL_OFFSET (TH_HANDLE_SEL_FREE - TH_HANDLE_FREE) +#define ACTIVE_NURB 1 << 2 /* Used as values of `color_id` in `edit_curve_overlay_handle_geom.glsl` */ enum { - COLOR_NURB_ULINE_ID = TH_HANDLE_SEL_AUTOCLAMP - TH_HANDLE_FREE + 1, - COLOR_NURB_SEL_ULINE_ID, - COLOR_ACTIVE_SPLINE, + COLOR_NURB_ULINE_ID = TH_HANDLE_AUTOCLAMP - TH_HANDLE_FREE + 2, TOT_HANDLE_COL, }; @@ -678,10 +675,12 @@ static void curve_batch_cache_create_overlay_batches(Curve *cu) const bool is_active = (i == rdata->actvert); GPU_indexbuf_add_point_vert(&elb, vbo_len_used + 1); for (int j = 0; j < 3; j++) { - char vflag = ((&bezt->f1)[j] & SELECT) - ? (is_active ? VFLAG_VERTEX_ACTIVE : VFLAG_VERTEX_SELECTED) - : 0; + char vflag = ((&bezt->f1)[j] & SELECT) ? VFLAG_VERTEX_SELECTED : 0; + vflag |= (is_active) ? VFLAG_VERTEX_ACTIVE : 0; vflag |= (is_active_nurb) ? ACTIVE_NURB : 0; + /* handle color id */ + char col_id = (&bezt->h1)[j / 2]; + vflag |= col_id << 3; /* << 3 because of ACTIVE_NURB */ GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bezt->vec[j]); GPU_vertbuf_attr_set(vbo, attr_id.data, vbo_len_used, &vflag); vbo_len_used += 1; @@ -695,10 +694,10 @@ static void curve_batch_cache_create_overlay_batches(Curve *cu) for (const BPoint *bp = nu->bp; a < nu->pntsu; a++, bp++) { if (bp->hide == false) { const bool is_active = (i == rdata->actvert); - char vflag = (bp->f1 & SELECT) - ? (is_active ? VFLAG_VERTEX_ACTIVE : VFLAG_VERTEX_SELECTED) - : 0; + char vflag = (bp->f1 & SELECT) ? VFLAG_VERTEX_SELECTED : 0; + vflag |= (is_active) ? VFLAG_VERTEX_ACTIVE : 0; vflag |= (is_active_nurb) ? ACTIVE_NURB : 0; + vflag |= COLOR_NURB_ULINE_ID << 3; /* << 3 because of ACTIVE_NURB */ GPU_indexbuf_add_point_vert(&elb, vbo_len_used); GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bp->vec); GPU_vertbuf_attr_set(vbo, attr_id.data, vbo_len_used, &vflag); @@ -720,78 +719,44 @@ static void curve_batch_cache_create_overlay_batches(Curve *cu) } - if ((cache->overlay.edges == NULL) && (rdata->hide_handles == false)) { - /* Note: we could reference indices to vertices (above) */ - - static GPUVertFormat format = { 0 }; - static struct { uint pos, data; } attr_id; - if (format.attr_len == 0) { - /* initialize vertex format */ - attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - attr_id.data = GPU_vertformat_attr_add(&format, "data", GPU_COMP_U8, 1, GPU_FETCH_INT); - } + if (cache->overlay.edges == NULL) { + GPUVertBuf *vbo = cache->overlay.verts->verts[0]; - GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); const int edge_len = curve_render_data_overlay_edges_len_get(rdata); const int vbo_len_capacity = edge_len * 2; - int vbo_len_used = 0; - GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); + + GPUIndexBufBuilder elb; + GPU_indexbuf_init(&elb, GPU_PRIM_LINES, vbo_len_capacity, vbo->vertex_len); + + int curr_index = 0; int i = 0; for (Nurb *nu = rdata->nurbs->first; nu; nu = nu->next, i++) { - const bool is_active_nurb = (i == cu->actnu); - if (nu->bezt) { int a = 0; for (const BezTriple *bezt = nu->bezt; a < nu->pntsu; a++, bezt++) { if (bezt->hide == false) { - char col_id; - - for (int j = 0; j < 2; j += 1) { - /* same vertex twice, only check different selection */ - GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bezt->vec[1]); - vbo_len_used += 1; - - col_id = (&bezt->h1)[j]; - if ((&bezt->f1)[j * 2] & SELECT) { - col_id += HANDLE_SEL_OFFSET; - } - if (is_active_nurb) { - col_id |= ACTIVE_NURB; - } - - GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bezt->vec[j * 2]); - GPU_vertbuf_attr_set(vbo, attr_id.data, vbo_len_used, &col_id); - vbo_len_used += 1; - } + GPU_indexbuf_add_line_verts(&elb, curr_index + 1, curr_index + 0); + GPU_indexbuf_add_line_verts(&elb, curr_index + 1, curr_index + 2); + curr_index += 3; } } } else if (nu->bp) { + curr_index += 1; int a = 1; for (const BPoint *bp_prev = nu->bp, *bp_curr = &nu->bp[1]; a < nu->pntsu; a++, bp_prev = bp_curr++) { - if ((bp_prev->hide == false) && (bp_curr->hide == false)) { - char col_id = ((bp_prev->f1 & SELECT) && (bp_curr->f1 & SELECT)) ? COLOR_NURB_SEL_ULINE_ID : COLOR_NURB_ULINE_ID; - - if (is_active_nurb) { - col_id |= ACTIVE_NURB; + if (bp_prev->hide == false) { + if (bp_curr->hide == false) { + GPU_indexbuf_add_line_verts(&elb, curr_index - 1, curr_index + 0); } - - GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bp_prev->vec); - vbo_len_used += 1; - - GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bp_curr->vec); - GPU_vertbuf_attr_set(vbo, attr_id.data, vbo_len_used, &col_id); - vbo_len_used += 1; - + curr_index += 1; } } } } - if (vbo_len_capacity != vbo_len_used) { - GPU_vertbuf_data_resize(vbo, vbo_len_used); - } - cache->overlay.edges = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); + GPUIndexBuf *ibo = GPU_indexbuf_build(&elb); + cache->overlay.edges = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, ibo, GPU_BATCH_OWNS_INDEX); } curve_render_data_free(rdata); diff --git a/source/blender/draw/modes/edit_curve_mode.c b/source/blender/draw/modes/edit_curve_mode.c index fd5f5907d24..54541680b9f 100644 --- a/source/blender/draw/modes/edit_curve_mode.c +++ b/source/blender/draw/modes/edit_curve_mode.c @@ -47,13 +47,12 @@ extern struct GlobalsUboStorage ts; /* draw_common.c */ extern char datatoc_common_globals_lib_glsl[]; extern char datatoc_edit_curve_overlay_loosevert_vert_glsl[]; -extern char datatoc_edit_curve_overlay_frag_glsl[]; +extern char datatoc_edit_curve_overlay_handle_vert_glsl[]; extern char datatoc_edit_curve_overlay_handle_geom_glsl[]; extern char datatoc_gpu_shader_3D_vert_glsl[]; -extern char datatoc_gpu_shader_uniform_color_frag_glsl[]; -extern char datatoc_gpu_shader_point_uniform_color_frag_glsl[]; -extern char datatoc_gpu_shader_flat_color_frag_glsl[]; +extern char datatoc_gpu_shader_point_varying_color_frag_glsl[]; +extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[]; /* *********** LISTS *********** */ /* All lists are per viewport specific datas. @@ -164,16 +163,16 @@ static void EDIT_CURVE_engine_init(void *vedata) if (!e_data.overlay_edge_sh) { e_data.overlay_edge_sh = DRW_shader_create_with_lib( - datatoc_edit_curve_overlay_loosevert_vert_glsl, + datatoc_edit_curve_overlay_handle_vert_glsl, datatoc_edit_curve_overlay_handle_geom_glsl, - datatoc_gpu_shader_flat_color_frag_glsl, + datatoc_gpu_shader_3D_smooth_color_frag_glsl, datatoc_common_globals_lib_glsl, NULL); } if (!e_data.overlay_vert_sh) { e_data.overlay_vert_sh = DRW_shader_create_with_lib( datatoc_edit_curve_overlay_loosevert_vert_glsl, NULL, - datatoc_edit_curve_overlay_frag_glsl, + datatoc_gpu_shader_point_varying_color_frag_glsl, datatoc_common_globals_lib_glsl, NULL); } } @@ -205,7 +204,7 @@ static void EDIT_CURVE_cache_init(void *vedata) psl->overlay_edge_pass = DRW_pass_create( "Curve Handle Overlay", - DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_WIRE); + DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND); grp = DRW_shgroup_create(e_data.overlay_edge_sh, psl->overlay_edge_pass); DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo); @@ -215,7 +214,7 @@ static void EDIT_CURVE_cache_init(void *vedata) psl->overlay_vert_pass = DRW_pass_create( "Curve Vert Overlay", - DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_POINT); + DRW_STATE_WRITE_COLOR | DRW_STATE_POINT); grp = DRW_shgroup_create(e_data.overlay_vert_sh, psl->overlay_vert_pass); DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo); diff --git a/source/blender/draw/modes/shaders/edit_curve_overlay_frag.glsl b/source/blender/draw/modes/shaders/edit_curve_overlay_frag.glsl deleted file mode 100644 index e78462b6915..00000000000 --- a/source/blender/draw/modes/shaders/edit_curve_overlay_frag.glsl +++ /dev/null @@ -1,22 +0,0 @@ - -flat in int vertFlag; - -#define VERTEX_SELECTED (1 << 0) -#define VERTEX_ACTIVE (1 << 1) - -out vec4 FragColor; - -void main() -{ - /* TODO: vertex size */ - - if ((vertFlag & VERTEX_SELECTED) != 0) { - FragColor = colorVertexSelect; - } - else if ((vertFlag & VERTEX_ACTIVE) != 0) { - FragColor = colorEditMeshActive; - } - else { - FragColor = colorVertex; - } -} diff --git a/source/blender/draw/modes/shaders/edit_curve_overlay_handle_geom.glsl b/source/blender/draw/modes/shaders/edit_curve_overlay_handle_geom.glsl index 9da8d9b50d7..734691a02b0 100644 --- a/source/blender/draw/modes/shaders/edit_curve_overlay_handle_geom.glsl +++ b/source/blender/draw/modes/shaders/edit_curve_overlay_handle_geom.glsl @@ -1,14 +1,30 @@ -#define ACTIVE_NURB 1 << 7 /* Keep the same value of `ACTIVE_NURB` in `draw_cache_imp_curve.c` */ +#define VERTEX_ACTIVE 1 << 0 +#define VERTEX_SELECTED 1 << 1 +#define ACTIVE_NURB 1 << 2 /* Keep the same value of `ACTIVE_NURB` in `draw_cache_imp_curve.c` */ +#define NURBS_EDGE_SELECTED (((vertFlag[1] & vertFlag[0]) & VERTEX_SELECTED) != 0) layout(lines) in; -layout(line_strip, max_vertices = 6) out; +layout(triangle_strip, max_vertices = 10) out; uniform vec2 viewportSize; flat in int vertFlag[]; -flat out vec4 finalColor; +out vec4 finalColor; + +void output_line(vec2 offset, vec4 color) +{ + finalColor = color; + + gl_Position = gl_in[0].gl_Position; + gl_Position.xy += offset * gl_in[0].gl_Position.w; + EmitVertex(); + + gl_Position = gl_in[1].gl_Position; + gl_Position.xy += offset * gl_in[1].gl_Position.w; + EmitVertex(); +} void main() { @@ -17,63 +33,53 @@ void main() vec4 v1 = gl_in[0].gl_Position; vec4 v2 = gl_in[1].gl_Position; - int is_active_nurb = vertFlag[1] & ACTIVE_NURB; - int color_id = vertFlag[1] ^ is_active_nurb; + int is_active_nurb = (vertFlag[1] & ACTIVE_NURB); + int color_id = (vertFlag[1] >> 3); - if (is_active_nurb != 0) { - /* draw the outline. */ - vec2 v1_2 = (v2.xy/v2.w - v1.xy/v1.w); - vec2 offset; - if (abs(v1_2.x * viewportSize.x) < abs(v1_2.y * viewportSize.y)) { - offset = vec2(2.0 / viewportSize.x, 0.0); - } - else { - offset = vec2(0.0, 2.0 / viewportSize.y); - } + bool edge_selected = (((vertFlag[1] | vertFlag[0]) & VERTEX_SELECTED) != 0); - finalColor = colorActiveSpline; + vec4 inner_color; + if (color_id == 0) inner_color = (edge_selected) ? colorHandleSelFree : colorHandleFree; + else if (color_id == 1) inner_color = (edge_selected) ? colorHandleSelAuto : colorHandleAuto; + else if (color_id == 2) inner_color = (edge_selected) ? colorHandleSelVect : colorHandleVect; + else if (color_id == 3) inner_color = (edge_selected) ? colorHandleSelAlign : colorHandleAlign; + else if (color_id == 4) inner_color = (edge_selected) ? colorHandleSelAutoclamp : colorHandleAutoclamp; + else inner_color = (NURBS_EDGE_SELECTED) ? colorNurbSelUline : colorNurbUline; - gl_Position = v1; - gl_Position.xy += offset * v1.w; - EmitVertex(); + vec4 outer_color = (is_active_nurb != 0) + ? mix(colorActiveSpline, inner_color, 0.25) /* Minimize active color bleeding on inner_color. */ + : vec4(inner_color.rgb, 0.0); - gl_Position = v2; - gl_Position.xy += offset * v2.w; - EmitVertex(); + vec2 v1_2 = (v2.xy/v2.w - v1.xy/v1.w); + vec2 offset = sizeEdge * 4.0 / viewportSize; /* 4.0 is eyeballed */ - EndPrimitive(); + if (abs(v1_2.x * viewportSize.x) < abs(v1_2.y * viewportSize.y)) { + offset.y = 0.0; + } + else { + offset.x = 0.0; + } - gl_Position = v1; - gl_Position.xy -= offset * v1.w; - EmitVertex(); + /* draw the transparent border (AA). */ + if (is_active_nurb != 0) { + offset *= 0.75; /* Don't make the active "halo" appear very thick. */ + output_line(offset * 2.0, vec4(colorActiveSpline.rgb, 0.0)); + } - gl_Position = v2; - gl_Position.xy -= offset * v2.w; - EmitVertex(); + /* draw the outline. */ + output_line(offset, outer_color); - EndPrimitive(); - } + /* draw the core of the line. */ + output_line(vec2(0.0), inner_color); - if (color_id == 0) finalColor = colorHandleFree; - else if (color_id == 1) finalColor = colorHandleAuto; - else if (color_id == 2) finalColor = colorHandleVect; - else if (color_id == 3) finalColor = colorHandleAlign; - else if (color_id == 4) finalColor = colorHandleAutoclamp; - else if (color_id == 5) finalColor = colorHandleSelFree; - else if (color_id == 6) finalColor = colorHandleSelAuto; - else if (color_id == 7) finalColor = colorHandleSelVect; - else if (color_id == 8) finalColor = colorHandleSelAlign; - else if (color_id == 9) finalColor = colorHandleSelAutoclamp; - else if (color_id == 10) finalColor = colorNurbUline; - else if (color_id == 11) finalColor = colorNurbSelUline; - else finalColor = colorVertexSelect; - - gl_Position = v1; - EmitVertex(); + /* draw the outline. */ + output_line(-offset, outer_color); - gl_Position = v2; - EmitVertex(); + /* draw the transparent border (AA). */ + if (is_active_nurb != 0) { + output_line(offset * -2.0, vec4(colorActiveSpline.rgb, 0.0)); + } EndPrimitive(); } diff --git a/source/blender/draw/modes/shaders/edit_curve_overlay_handle_vert.glsl b/source/blender/draw/modes/shaders/edit_curve_overlay_handle_vert.glsl new file mode 100644 index 00000000000..d3f9deedf0c --- /dev/null +++ b/source/blender/draw/modes/shaders/edit_curve_overlay_handle_vert.glsl @@ -0,0 +1,15 @@ + +/* Draw Curve Handles */ + +uniform mat4 ModelViewProjectionMatrix; + +in vec3 pos; +in int data; + +flat out int vertFlag; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + vertFlag = data; +} diff --git a/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl b/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl index 9150ef8cd63..44d15602f4f 100644 --- a/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl +++ b/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl @@ -7,33 +7,23 @@ uniform vec2 viewportSize; in vec3 pos; in int data; -/* these are the same for all vertices - * and does not need interpolation */ -flat out int vertFlag; -flat out int clipCase; +out vec4 finalColor; -/* See fragment shader */ -noperspective out vec4 eData1; -flat out vec4 eData2; - -/* project to screen space */ -vec2 proj(vec4 pos) -{ - return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize; -} +#define VERTEX_ACTIVE (1 << 0) +#define VERTEX_SELECTED (1 << 1) void main() { - clipCase = 0; - - vec4 pPos = ModelViewProjectionMatrix * vec4(pos, 1.0); - - /* only vertex position 0 is used */ - eData1 = eData2 = vec4(1e10); - eData2.zw = proj(pPos); - - vertFlag = data; - - gl_Position = pPos; - gl_PointSize = sizeVertex; + if ((data & VERTEX_ACTIVE) != 0) { + finalColor = colorEditMeshActive; + } + if ((data & VERTEX_SELECTED) != 0) { + finalColor = colorVertexSelect; + } + else { + finalColor = colorVertex; + } + + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + gl_PointSize = sizeVertex * 2.0; } |