Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c215
-rw-r--r--source/blender/draw/modes/overlay_mode.c87
-rw-r--r--source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl38
-rw-r--r--source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl41
4 files changed, 253 insertions, 128 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 0228f108c1d..6fe0344bf76 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -1176,7 +1176,7 @@ static int mesh_render_data_loose_verts_len_get_maybe_mapped(const MeshRenderDat
return ((rdata->mapped.use == false) ? rdata->loose_vert_len : rdata->mapped.loose_vert_len);
}
-static int UNUSED_FUNCTION(mesh_render_data_edges_len_get)(const MeshRenderData *rdata)
+static int mesh_render_data_edges_len_get(const MeshRenderData *rdata)
{
BLI_assert(rdata->types & MR_DATATYPE_EDGE);
return rdata->edge_len;
@@ -1750,6 +1750,7 @@ typedef struct MeshBatchCache {
GPUVertBuf *loop_pos_nor;
GPUVertBuf *loop_uv_tan;
GPUVertBuf *loop_vcol;
+ GPUVertBuf *loop_edge_fac;
} ordered;
/* Tesselated: (all verts specified for each triangles).
@@ -1795,13 +1796,14 @@ typedef struct MeshBatchCache {
/* Indices to vloops. */
GPUIndexBuf *loops_tris;
GPUIndexBuf *loops_lines;
+ GPUIndexBuf *loops_line_strips;
/* Edit mode. */
GPUIndexBuf *edit_loops_points; /* verts */
GPUIndexBuf *edit_loops_lines; /* edges */
GPUIndexBuf *edit_loops_tris; /* faces */
/* Edit UVs */
GPUIndexBuf *edituv_loops_points; /* verts */
- GPUIndexBuf *edituv_loops_lines; /* edges */
+ GPUIndexBuf *edituv_loops_line_strips; /* edges */
GPUIndexBuf *edituv_loops_tri_fans; /* faces */
} ibo;
@@ -1832,6 +1834,7 @@ typedef struct MeshBatchCache {
GPUBatch *all_edges;
GPUBatch *loose_edges;
GPUBatch *edge_detection;
+ GPUBatch *wire_edges; /* Individual edges with face normals. */
GPUBatch *wire_loops; /* Loops around faces. */
GPUBatch *wire_loops_uvs; /* Same as wire_loops but only has uvs. */
GPUBatch *wire_triangles; /* Triangles for object mode wireframe. */
@@ -1998,7 +2001,7 @@ static void mesh_batch_cache_discard_uvedit(MeshBatchCache *cache)
GPU_VERTBUF_DISCARD_SAFE(cache->edit.facedots_uv);
GPU_VERTBUF_DISCARD_SAFE(cache->edit.facedots_uv_data);
GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_tri_fans);
- GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_lines);
+ GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_line_strips);
GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_points);
GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_strech_area);
GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_strech_angle);
@@ -2847,6 +2850,115 @@ static void mesh_create_weights(MeshRenderData *rdata, GPUVertBuf *vbo, DRW_Mesh
GPU_vertbuf_attr_fill(vbo, attr_id.weight, vert_weight);
}
+static float mesh_loop_edge_factor_get(
+ const float f_no[3], const float v_co[3], const float v_no[3], const float v_next_co[3])
+{
+ float enor[3], evec[3];
+ sub_v3_v3v3(evec, v_next_co, v_co);
+ cross_v3_v3v3(enor, v_no, evec);
+ normalize_v3(enor);
+ float d = fabsf(dot_v3v3(enor, f_no));
+ /* Rescale to the slider range. */
+ d *= (1.0f / 0.065f);
+ CLAMP(d, 0.0f, 1.0f);
+ return d;
+}
+
+static void mesh_create_loop_edge_fac(MeshRenderData *rdata, GPUVertBuf *vbo)
+{
+ static GPUVertFormat format = { 0 };
+ static struct { uint wd; } attr_id;
+ if (format.attr_len == 0) {
+ attr_id.wd = GPU_vertformat_attr_add(&format, "wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ }
+ const int poly_len = mesh_render_data_polys_len_get(rdata);
+ const int loop_len = mesh_render_data_loops_len_get(rdata);
+ const int edge_len = mesh_render_data_edges_len_get(rdata);
+
+ GPU_vertbuf_init_with_format(vbo, &format);
+ GPU_vertbuf_data_alloc(vbo, loop_len);
+
+ GPUVertBufRaw wd_step;
+ GPU_vertbuf_attr_get_raw_data(vbo, attr_id.wd, &wd_step);
+
+ if (rdata->mapped.use == false) {
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter iter_efa, iter_loop;
+ BMFace *efa;
+ BMLoop *loop;
+ uint f;
+
+ BM_ITER_MESH_INDEX (efa, &iter_efa, bm, BM_FACES_OF_MESH, f) {
+ BM_ITER_ELEM (loop, &iter_loop, efa, BM_LOOPS_OF_FACE) {
+ float ratio = mesh_loop_edge_factor_get(efa->no, loop->v->co, loop->v->no, loop->next->v->co);
+ *((uchar *)GPU_vertbuf_raw_step(&wd_step)) = ratio * 255;
+ }
+ }
+ BLI_assert(GPU_vertbuf_raw_used(&wd_step) == loop_len);
+ }
+ else {
+ const MVert *mvert = rdata->mvert;
+ const MPoly *mpoly = rdata->mpoly;
+ const MLoop *mloop = rdata->mloop;
+ MEdge *medge = (MEdge *)rdata->medge;
+ bool use_edge_render = false;
+
+ /* TODO(fclem) We don't need them to be packed. But we need rdata->poly_normals */
+ mesh_render_data_ensure_poly_normals_pack(rdata);
+
+ /* Reset flag */
+ for (int edge = 0; edge < edge_len; ++edge) {
+ /* NOTE: not thread safe. */
+ medge[edge].flag &= ~ME_EDGE_TMP_TAG;
+
+ /* HACK(fclem) Feels like a hack. Detecting the need for edge render. */
+ if ((medge[edge].flag & ME_EDGERENDER) == 0) {
+ use_edge_render = true;
+ }
+ }
+
+ for (int a = 0; a < poly_len; a++, mpoly++) {
+ const float *fnor = rdata->poly_normals[a];
+ for (int b = 0; b < mpoly->totloop; b++) {
+ const MLoop *ml1 = &mloop[mpoly->loopstart + b];
+ const MLoop *ml2 = &mloop[mpoly->loopstart + (b + 1) % mpoly->totloop];
+
+ /* Will only work for edges that have an odd number of faces connected. */
+ MEdge *ed = (MEdge *)rdata->medge + ml1->e;
+ ed->flag ^= ME_EDGE_TMP_TAG;
+
+ if (use_edge_render) {
+ *((uchar *)GPU_vertbuf_raw_step(&wd_step)) = (ed->flag & ME_EDGERENDER) ? 255 : 0;
+ }
+ else {
+ float vnor_f[3];
+ normal_short_to_float_v3(vnor_f, mvert[ml1->v].no);
+ float ratio = mesh_loop_edge_factor_get(fnor,
+ mvert[ml1->v].co,
+ vnor_f,
+ mvert[ml2->v].co);
+ *((uchar *)GPU_vertbuf_raw_step(&wd_step)) = ratio * 253 + 1;
+ }
+ }
+ }
+ /* Gather non-manifold edges. */
+ for (int l = 0; l < loop_len; l++, mloop++) {
+ MEdge *ed = (MEdge *)rdata->medge + mloop->e;
+ if (ed->flag & ME_EDGE_TMP_TAG) {
+ uchar data = 255;
+ GPU_vertbuf_attr_set(vbo, attr_id.wd, l, &data);
+ }
+ }
+
+ BLI_assert(loop_len == GPU_vertbuf_raw_used(&wd_step));
+ }
+ }
+ else {
+ BLI_assert(0);
+ }
+}
+
static void mesh_create_loop_pos_and_nor(MeshRenderData *rdata, GPUVertBuf *vbo)
{
/* TODO deduplicate format creation*/
@@ -3604,6 +3716,72 @@ static void mesh_create_surf_tris(MeshRenderData *rdata, GPUIndexBuf *ibo, const
static void mesh_create_loops_lines(
MeshRenderData *rdata, GPUIndexBuf *ibo, const bool use_hide)
{
+ const int edge_len = mesh_render_data_edges_len_get(rdata);
+ const int loop_len = mesh_render_data_loops_len_get(rdata);
+ const int poly_len = mesh_render_data_polys_len_get(rdata);
+
+ GPUIndexBufBuilder elb;
+ GPU_indexbuf_init(&elb, GPU_PRIM_LINES, edge_len, loop_len);
+
+ if (rdata->mapped.use == false) {
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter iter;
+ BMEdge *bm_edge;
+
+ BM_ITER_MESH (bm_edge, &iter, bm, BM_EDGES_OF_MESH) {
+ /* use_hide always for edit-mode */
+ if (!BM_elem_flag_test(bm_edge, BM_ELEM_HIDDEN) &&
+ bm_edge->l != NULL)
+ {
+ BMLoop *bm_loop1 = BM_vert_find_first_loop(bm_edge->v1);
+ BMLoop *bm_loop2 = BM_vert_find_first_loop(bm_edge->v2);
+ int v1 = BM_elem_index_get(bm_loop1);
+ int v2 = BM_elem_index_get(bm_loop2);
+ if (v1 > v2) {
+ SWAP(int, v1, v2);
+ }
+ GPU_indexbuf_add_line_verts(&elb, v1, v2);
+ }
+ }
+ }
+ else {
+ MLoop *mloop = (MLoop *)rdata->mloop;
+ MEdge *medge = (MEdge *)rdata->medge;
+
+ /* Reset flag */
+ for (int edge = 0; edge < edge_len; ++edge) {
+ /* NOTE: not thread safe. */
+ medge[edge].flag &= ~ME_EDGE_TMP_TAG;
+ }
+
+ for (int poly = 0; poly < poly_len; poly++) {
+ const MPoly *mp = &rdata->mpoly[poly];
+ if (!(use_hide && (mp->flag & ME_HIDE))) {
+ for (int j = 0; j < mp->totloop; j++) {
+ MEdge *ed = (MEdge *)rdata->medge + mloop[mp->loopstart + j].e;
+ if ((ed->flag & ME_EDGE_TMP_TAG) == 0) {
+ ed->flag |= ME_EDGE_TMP_TAG;
+ int v1 = mp->loopstart + j;
+ int v2 = mp->loopstart + (j + 1) % mp->totloop;
+ GPU_indexbuf_add_line_verts(&elb, v1, v2);
+ }
+ }
+ }
+ }
+ }
+ }
+ else {
+ /* Implement ... eventually if needed. */
+ BLI_assert(0);
+ }
+
+ GPU_indexbuf_build_in_place(&elb, ibo);
+}
+
+static void mesh_create_loops_line_strips(
+ MeshRenderData *rdata, GPUIndexBuf *ibo, const bool use_hide)
+{
const int loop_len = mesh_render_data_loops_len_get(rdata);
const int poly_len = mesh_render_data_polys_len_get(rdata);
@@ -4125,7 +4303,7 @@ GPUBatch *DRW_mesh_batch_cache_get_edge_detection(Mesh *me, bool *r_is_manifold)
GPUBatch *DRW_mesh_batch_cache_get_wireframes_face(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
- return DRW_batch_request(&cache->batch.wire_triangles);
+ return DRW_batch_request(&cache->batch.wire_edges);
}
GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(
@@ -4705,7 +4883,7 @@ void DRW_mesh_batch_cache_create_requested(
GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_uv);
GPU_VERTBUF_DISCARD_SAFE(cache->edit.facedots_uv);
GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_tri_fans);
- GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_lines);
+ GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_line_strips);
GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_points);
/* We only clear the batches as they may already have been referenced. */
GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_faces_strech_area);
@@ -4750,11 +4928,16 @@ void DRW_mesh_batch_cache_create_requested(
DRW_vbo_request(cache->batch.surface_weights, &cache->ordered.weights);
}
if (DRW_batch_requested(cache->batch.wire_loops, GPU_PRIM_LINE_STRIP)) {
- DRW_ibo_request(cache->batch.wire_loops, &cache->ibo.loops_lines);
+ DRW_ibo_request(cache->batch.wire_loops, &cache->ibo.loops_line_strips);
DRW_vbo_request(cache->batch.wire_loops, &cache->ordered.loop_pos_nor);
}
+ if (DRW_batch_requested(cache->batch.wire_edges, GPU_PRIM_LINES)) {
+ DRW_ibo_request(cache->batch.wire_edges, &cache->ibo.loops_lines);
+ DRW_vbo_request(cache->batch.wire_edges, &cache->ordered.loop_pos_nor);
+ DRW_vbo_request(cache->batch.wire_edges, &cache->ordered.loop_edge_fac);
+ }
if (DRW_batch_requested(cache->batch.wire_loops_uvs, GPU_PRIM_LINE_STRIP)) {
- DRW_ibo_request(cache->batch.wire_loops_uvs, &cache->ibo.loops_lines);
+ DRW_ibo_request(cache->batch.wire_loops_uvs, &cache->ibo.loops_line_strips);
/* For paint overlay. Active layer should have been queried. */
if (cache->cd_lused[CD_MLOOPUV] != 0) {
DRW_vbo_request(cache->batch.wire_loops_uvs, &cache->ordered.loop_uv_tan);
@@ -4809,7 +4992,7 @@ void DRW_mesh_batch_cache_create_requested(
DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &cache->edit.loop_stretch_angle);
}
if (DRW_batch_requested(cache->batch.edituv_edges, GPU_PRIM_LINES)) {
- DRW_ibo_request(cache->batch.edituv_edges, &cache->ibo.edituv_loops_lines);
+ DRW_ibo_request(cache->batch.edituv_edges, &cache->ibo.edituv_loops_line_strips);
DRW_vbo_request(cache->batch.edituv_edges, &cache->edit.loop_uv);
DRW_vbo_request(cache->batch.edituv_edges, &cache->edit.loop_uv_data);
}
@@ -4877,11 +5060,13 @@ void DRW_mesh_batch_cache_create_requested(
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_pos_nor, MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_uv_tan, MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_SHADING);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_vcol, MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_SHADING);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_edge_fac, MR_DATATYPE_POLY | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->tess.pos_nor, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI | MR_DATATYPE_POLY);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->tess.wireframe_data, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI);
DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.surf_tris, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI);
DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.loops_tris, MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI);
- DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.loops_lines, MR_DATATYPE_LOOP | MR_DATATYPE_POLY);
+ DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.loops_lines, MR_DATATYPE_LOOP | MR_DATATYPE_EDGE | MR_DATATYPE_POLY);
+ DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.loops_line_strips, MR_DATATYPE_LOOP | MR_DATATYPE_POLY);
DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.edges_lines, MR_DATATYPE_VERT | MR_DATATYPE_EDGE);
DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.edges_adj_lines, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI);
DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.loose_edges_lines, MR_DATATYPE_VERT | MR_DATATYPE_EDGE);
@@ -4906,7 +5091,7 @@ void DRW_mesh_batch_cache_create_requested(
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.facedots_uv, combined_edit_flag | MR_DATATYPE_LOOPUV);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.facedots_uv_data, combined_edit_flag);
DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edituv_loops_points, combined_edit_flag);
- DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edituv_loops_lines, combined_edit_flag);
+ DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edituv_loops_line_strips, combined_edit_flag);
DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edituv_loops_tri_fans, combined_edit_flag);
/* TODO: Some of the flags here may not be needed. */
DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edit_loops_points, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI);
@@ -4936,6 +5121,9 @@ void DRW_mesh_batch_cache_create_requested(
if (DRW_vbo_requested(cache->ordered.loop_pos_nor)) {
mesh_create_loop_pos_and_nor(rdata, cache->ordered.loop_pos_nor);
}
+ if (DRW_vbo_requested(cache->ordered.loop_edge_fac)) {
+ mesh_create_loop_edge_fac(rdata, cache->ordered.loop_edge_fac);
+ }
if (DRW_vbo_requested(cache->ordered.loop_uv_tan)) {
mesh_create_loop_uv_and_tan(rdata, cache->ordered.loop_uv_tan);
}
@@ -4963,6 +5151,9 @@ void DRW_mesh_batch_cache_create_requested(
if (DRW_ibo_requested(cache->ibo.loops_lines)) {
mesh_create_loops_lines(rdata, cache->ibo.loops_lines, use_hide);
}
+ if (DRW_ibo_requested(cache->ibo.loops_line_strips)) {
+ mesh_create_loops_line_strips(rdata, cache->ibo.loops_line_strips, use_hide);
+ }
if (DRW_ibo_requested(cache->ibo.loops_tris)) {
mesh_create_loops_tris(rdata, &cache->ibo.loops_tris, 1, use_hide);
}
@@ -5042,14 +5233,14 @@ void DRW_mesh_batch_cache_create_requested(
DRW_vbo_requested(cache->edit.facedots_uv) ||
DRW_vbo_requested(cache->edit.facedots_uv_data) ||
DRW_ibo_requested(cache->ibo.edituv_loops_points) ||
- DRW_ibo_requested(cache->ibo.edituv_loops_lines) ||
+ DRW_ibo_requested(cache->ibo.edituv_loops_line_strips) ||
DRW_ibo_requested(cache->ibo.edituv_loops_tri_fans))
{
mesh_create_uvedit_buffers(rdata,
cache->edit.loop_stretch_area, cache->edit.loop_stretch_angle,
cache->edit.facedots_uv, cache->edit.facedots_uv_data,
cache->ibo.edituv_loops_points,
- cache->ibo.edituv_loops_lines,
+ cache->ibo.edituv_loops_line_strips,
cache->ibo.edituv_loops_tri_fans);
}
diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c
index 550dfe0be7a..9ff8e2b30f1 100644
--- a/source/blender/draw/modes/overlay_mode.c
+++ b/source/blender/draw/modes/overlay_mode.c
@@ -55,7 +55,7 @@ typedef struct OVERLAY_PrivateData {
DRWShadingGroup *flat_wires_shgrp;
DRWShadingGroup *sculpt_wires_shgrp;
View3DOverlay overlay;
- float wire_step_param[2];
+ float wire_step_param;
bool ghost_stencil_test;
bool show_overlays;
} OVERLAY_PrivateData; /* Transient data */
@@ -127,9 +127,8 @@ static void overlay_engine_init(void *vedata)
});
sh_data->face_wireframe_sculpt = GPU_shader_create_from_arrays({
.vert = (const char *[]){sh_cfg_data->lib, datatoc_overlay_face_wireframe_vert_glsl, NULL},
- .geom = (const char *[]){sh_cfg_data->lib, datatoc_overlay_face_wireframe_geom_glsl, NULL},
.frag = (const char *[]){datatoc_overlay_face_wireframe_frag_glsl, NULL},
- .defs = (const char *[]){sh_cfg_data->def, "#define USE_SCULPT\n", NULL},
+ .defs = (const char *[]){sh_cfg_data->def, NULL},
});
}
}
@@ -179,7 +178,7 @@ static void overlay_cache_init(void *vedata)
{
/* Wireframe */
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND | DRW_STATE_FIRST_VERTEX_CONVENTION;
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_FIRST_VERTEX_CONVENTION | DRW_STATE_OFFSET_NEGATIVE;
float wire_size = max_ff(0.0f, U.pixelsize - 1.0f) * 0.5f;
const bool use_select = (DRW_state_is_select() || DRW_state_is_depth());
@@ -200,7 +199,7 @@ static void overlay_cache_init(void *vedata)
}
g_data->face_wires_shgrp = DRW_shgroup_create(face_wires_sh, psl->face_wireframe_pass);
- DRW_shgroup_uniform_vec2(g_data->face_wires_shgrp, "wireStepParam", g_data->wire_step_param, 1);
+ DRW_shgroup_uniform_float(g_data->face_wires_shgrp, "wireStepParam", &g_data->wire_step_param, 1);
if (rv3d->rflag & RV3D_CLIPPING) {
DRW_shgroup_world_clip_planes_from_rv3d(g_data->face_wires_shgrp, rv3d);
}
@@ -210,14 +209,7 @@ static void overlay_cache_init(void *vedata)
DRW_shgroup_uniform_float_copy(g_data->face_wires_shgrp, "wireSize", wire_size);
}
- /* Control aspect of the falloff. */
- const float sharpness = 4.0f;
- /* Scale and bias: Adjust with wiredata encoding. (see mesh_batch_cache_create_edges_wireframe_data) */
- const float decompress = (0xFF / (float)(0xFF - 0x20));
- g_data->wire_step_param[0] = -sharpness * decompress;
- g_data->wire_step_param[1] = decompress + sharpness * stl->g_data->overlay.wireframe_threshold;
-
-
+ g_data->wire_step_param = stl->g_data->overlay.wireframe_threshold - 254.0f / 255.0f;
}
}
@@ -227,7 +219,6 @@ static void overlay_cache_populate(void *vedata, Object *ob)
OVERLAY_StorageList *stl = data->stl;
OVERLAY_PrivateData *pd = stl->g_data;
const DRWContextState *draw_ctx = DRW_context_state_get();
- RegionView3D *rv3d = draw_ctx->rv3d;
View3D *v3d = draw_ctx->v3d;
if ((!pd->show_overlays) ||
@@ -266,14 +257,14 @@ static void overlay_cache_populate(void *vedata, Object *ob)
{
const bool is_active = (ob == draw_ctx->obact);
const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
- const bool all_wires = (pd->overlay.wireframe_threshold == 1.0f) ||
- (ob->dtx & OB_DRAW_ALL_EDGES);
+ const bool all_wires = (ob->dtx & OB_DRAW_ALL_EDGES);
const bool is_wire = (ob->dt < OB_SOLID);
const int stencil_mask = (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF;
DRWShadingGroup *shgrp = NULL;
const float *rim_col = NULL;
const float *wire_col = NULL;
+
if (UNLIKELY(ob->base_flag & BASE_FROM_SET)) {
rim_col = G_draw.block.colorDupli;
wire_col = G_draw.block.colorDupli;
@@ -312,47 +303,29 @@ static void overlay_cache_populate(void *vedata, Object *ob)
}
BLI_assert(rim_col && wire_col);
- /* This fixes only the biggest case which is a plane in ortho view. */
- int flat_axis = 0;
- bool is_flat_object_viewed_from_side = (
- (rv3d->persp == RV3D_ORTHO) &&
- DRW_object_is_flat(ob, &flat_axis) &&
- DRW_object_axis_orthogonal_to_view(ob, flat_axis));
-
- if (is_flat_object_viewed_from_side && !is_sculpt_mode) {
- /* Avoid losing flat objects when in ortho views (see T56549) */
- struct GPUBatch *geom = DRW_cache_object_all_edges_get(ob);
- if (geom) {
- shgrp = pd->flat_wires_shgrp;
- shgrp = DRW_shgroup_create_sub(shgrp);
+ struct GPUBatch *geom;
+ geom = DRW_cache_object_face_wireframe_get(ob);
+
+ if (geom || is_sculpt_mode) {
+ shgrp = (is_sculpt_mode) ? pd->sculpt_wires_shgrp : pd->face_wires_shgrp;
+ shgrp = DRW_shgroup_create_sub(shgrp);
+
+ static float all_wires_param = 10.0f;
+ DRW_shgroup_uniform_vec2(
+ shgrp, "wireStepParam", (all_wires) ?
+ &all_wires_param : &pd->wire_step_param, 1);
+
+ if (!(DRW_state_is_select() || DRW_state_is_depth())) {
DRW_shgroup_stencil_mask(shgrp, stencil_mask);
- DRW_shgroup_call_object_add(shgrp, geom, ob);
- DRW_shgroup_uniform_vec4(shgrp, "color", rim_col, 1);
+ DRW_shgroup_uniform_vec3(shgrp, "wireColor", wire_col, 1);
+ DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1);
}
- }
- else {
- struct GPUBatch *geom = DRW_cache_object_face_wireframe_get(ob);
- if (geom || is_sculpt_mode) {
- shgrp = (is_sculpt_mode) ? pd->sculpt_wires_shgrp : pd->face_wires_shgrp;
- shgrp = DRW_shgroup_create_sub(shgrp);
-
- static float all_wires_params[2] = {0.0f, 10.0f}; /* Parameters for all wires */
- DRW_shgroup_uniform_vec2(
- shgrp, "wireStepParam", (all_wires) ?
- all_wires_params : pd->wire_step_param, 1);
-
- if (!(DRW_state_is_select() || DRW_state_is_depth())) {
- DRW_shgroup_stencil_mask(shgrp, stencil_mask);
- DRW_shgroup_uniform_vec3(shgrp, "wireColor", wire_col, 1);
- DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1);
- }
- if (is_sculpt_mode) {
- DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat);
- }
- else {
- DRW_shgroup_call_add(shgrp, geom, ob->obmat);
- }
+ if (is_sculpt_mode) {
+ DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat);
+ }
+ else {
+ DRW_shgroup_call_add(shgrp, geom, ob->obmat);
}
}
if (is_wire && shgrp != NULL) {
@@ -392,12 +365,18 @@ static void overlay_draw_scene(void *vedata)
OVERLAY_Data *data = vedata;
OVERLAY_PassList *psl = data->psl;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(dfbl->default_fb);
}
DRW_draw_pass(psl->face_orientation_pass);
+
+ MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl);
+
DRW_draw_pass(psl->face_wireframe_pass);
+
+ MULTISAMPLE_SYNC_DISABLE(dfbl, dtxl);
}
static void overlay_engine_free(void)
diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl
index cefd4eab2e3..1a984b2fbc6 100644
--- a/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl
+++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl
@@ -1,41 +1,23 @@
+
uniform vec3 wireColor;
uniform vec3 rimColor;
+flat in float edgeSharpness;
in float facing;
-in vec3 barycentric;
-flat in vec3 edgeSharpness;
out vec4 fragColor;
-float max_v3(vec3 v) { return max(v.x, max(v.y, v.z)); }
-
-/* In pixels */
-uniform float wireSize = 0.0; /* Expands the core of the wire (part that is 100% wire color) */
-const float wire_smooth = 1.2; /* Smoothing distance after the 100% core. */
-
-/* Alpha constants could be exposed in the future. */
-const float front_alpha = 0.35;
-const float rim_alpha = 0.75;
-
void main()
{
- vec3 dx = dFdx(barycentric);
- vec3 dy = dFdy(barycentric);
- vec3 d = vec3(
- length(vec2(dx.x, dy.x)),
- length(vec2(dx.y, dy.y)),
- length(vec2(dx.z, dy.z))
- );
- vec3 dist_to_edge = barycentric / d;
-
- vec3 fac = abs(dist_to_edge);
-
- fac = smoothstep(wireSize + wire_smooth, wireSize, fac);
+ if (edgeSharpness < 0.0) {
+ discard;
+ }
- float facing_clamped = clamp((gl_FrontFacing) ? facing : -facing, 0.0, 1.0);
+ float facing_clamped = clamp(abs(facing), 0.0, 1.0);
- vec3 final_front_col = mix(rimColor, wireColor, 0.05);
- fragColor = mix(vec4(rimColor, rim_alpha), vec4(final_front_col, front_alpha), facing_clamped);
+ vec3 final_front_col = mix(rimColor, wireColor, 0.4);
+ vec3 final_rim_col = mix(rimColor, wireColor, 0.1);
- fragColor.a *= max_v3(fac * edgeSharpness);
+ fragColor.rgb = mix(final_rim_col, final_front_col, facing_clamped);
+ fragColor.a = 1.0f;
}
diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
index 1ae204de60d..4e7560141f6 100644
--- a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
+++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
@@ -3,22 +3,11 @@ uniform mat4 ModelViewProjectionMatrix;
uniform mat4 ModelMatrix;
uniform mat3 NormalMatrix;
-uniform vec2 wireStepParam;
-
-vec3 get_edge_sharpness(vec3 wd)
-{
- bvec3 do_edge = greaterThan(wd, vec3(0.0));
- bvec3 force_edge = equal(wd, vec3(1.0));
- wd = clamp(wireStepParam.x * wd + wireStepParam.y, 0.0, 1.0);
- return clamp(wd * vec3(do_edge) + vec3(force_edge), 0.0, 1.0);
-}
+uniform float wireStepParam;
float get_edge_sharpness(float wd)
{
- bool do_edge = (wd > 0.0);
- bool force_edge = (wd == 1.0);
- wd = (wireStepParam.x * wd + wireStepParam.y);
- return clamp(wd * float(do_edge) + float(force_edge), 0.0, 1.0);
+ return (wd == 1.0) ? 1.0 : ((wd == 0.0) ? -1.0 : (wd + wireStepParam));
}
/* Geometry shader version */
@@ -51,35 +40,19 @@ void main()
#else /* SELECT_EDGES */
-/* Consecutive pos of the nth vertex
- * Only valid for first vertex in the triangle.
- * Assuming GL_FRIST_VERTEX_CONVENTION. */
-in vec3 pos0;
-in vec3 pos1;
-in vec3 pos2;
-in float wd0; /* wiredata */
-in float wd1;
-in float wd2;
+in vec3 pos;
in vec3 nor;
+in float wd;
out float facing;
-out vec3 barycentric;
-flat out vec3 edgeSharpness;
+flat out float edgeSharpness;
void main()
{
- int v_n = gl_VertexID % 3;
-
- barycentric = vec3(equal(ivec3(2, 0, 1), ivec3(v_n)));
-
- vec3 wb = vec3(wd0, wd1, wd2);
- edgeSharpness = get_edge_sharpness(wb);
-
- /* Don't generate any fragment if there is no edge to draw. */
- vec3 pos = (!any(greaterThan(edgeSharpness, vec3(0.04))) && (v_n == 0)) ? pos1 : pos0;
-
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ edgeSharpness = get_edge_sharpness(wd);
+
facing = normalize(NormalMatrix * nor).z;
#ifdef USE_WORLD_CLIP_PLANES