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
path: root/source
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2018-12-07 07:03:01 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-12-07 07:33:53 +0300
commite929cad7067875bb2f1815a01daae32e441f99b7 (patch)
treee20a4173feb9ebef5b217f4234a6f7d9866a3d6b /source
parent9f5a27c5be0a0f6a9f36360e618dcf5254ae689e (diff)
DRW: Rework wireframe overlay implementation
The shader is way simpler and run way faster on lower end hardware (2x faster on intel HD5000) but did not notice any improvement on AMD Vega. This also adds a few changes to the way the wireframes are drawn: - the slider is more linearly progressive. - optimize display shows all wires and progressively decrease "inner" wires intensity. This is subject to change in the future. - text/surface/metaballs support is pretty rough. More work needs to be done. This remove the optimization introduced in f1975a46390a5bf85bb7012375f9bc1e761fc516. This also removes the GPU side "sharpness" calculation which means that animated meshes with wireframe display will update slower. The CPU sharpness calculation has still room for optimization. Also it is not excluded that GPU calculation can be added back as a separate preprocessing pass (saving the computation result [compute or feedback]). The goal here was to have more speed for static objects and remove the dependency of having buffer textures with triangle count. This is preparation work for multithreading the whole DRW manager.
Diffstat (limited to 'source')
-rw-r--r--source/blender/draw/intern/draw_cache.c54
-rw-r--r--source/blender/draw/intern/draw_cache.h18
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h12
-rw-r--r--source/blender/draw/intern/draw_cache_impl_curve.c59
-rw-r--r--source/blender/draw/intern/draw_cache_impl_displist.c86
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c185
-rw-r--r--source/blender/draw/intern/draw_cache_impl_metaball.c66
-rw-r--r--source/blender/draw/intern/draw_manager_data.c2
-rw-r--r--source/blender/draw/modes/overlay_mode.c162
-rw-r--r--source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl16
-rw-r--r--source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl117
-rw-r--r--source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl188
12 files changed, 307 insertions, 658 deletions
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 2e13e1a343e..f68239440b1 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -696,25 +696,21 @@ GPUBatch *DRW_cache_object_edge_detection_get(Object *ob, bool *r_is_manifold)
}
/* Returns a buffer texture. */
-void DRW_cache_object_face_wireframe_get(
- Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count, bool reduce_len)
+GPUBatch *DRW_cache_object_face_wireframe_get(Object *ob)
{
switch (ob->type) {
case OB_MESH:
- DRW_cache_mesh_face_wireframe_get(ob, r_vert_tx, r_faceid_tx, r_tri_count, reduce_len);
- break;
+ return DRW_cache_mesh_face_wireframe_get(ob);
case OB_CURVE:
- DRW_cache_curve_face_wireframe_get(ob, r_vert_tx, r_faceid_tx, r_tri_count, reduce_len);
- break;
+ return DRW_cache_curve_face_wireframe_get(ob);
case OB_SURF:
- DRW_cache_surf_face_wireframe_get(ob, r_vert_tx, r_faceid_tx, r_tri_count, reduce_len);
- break;
+ return DRW_cache_surf_face_wireframe_get(ob);
case OB_FONT:
- DRW_cache_text_face_wireframe_get(ob, r_vert_tx, r_faceid_tx, r_tri_count, reduce_len);
- break;
+ return DRW_cache_text_face_wireframe_get(ob);
case OB_MBALL:
- DRW_cache_mball_face_wireframe_get(ob, r_vert_tx, r_faceid_tx, r_tri_count, reduce_len);
- break;
+ return DRW_cache_mball_face_wireframe_get(ob);
+ default:
+ return NULL;
}
}
@@ -3065,16 +3061,12 @@ GPUBatch *DRW_cache_mesh_surface_get(Object *ob, bool use_hide)
return DRW_mesh_batch_cache_get_triangles_with_normals(me, use_hide);
}
-void DRW_cache_mesh_face_wireframe_get(
- Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count, bool reduce_len)
+GPUBatch *DRW_cache_mesh_face_wireframe_get(Object *ob)
{
BLI_assert(ob->type == OB_MESH);
- const DRWContextState *draw_ctx = DRW_context_state_get();
- reduce_len = reduce_len && !(DRW_state_is_playback() && BKE_object_is_deform_modified(draw_ctx->scene, ob));
-
Mesh *me = ob->data;
- DRW_mesh_batch_cache_get_wireframes_face_texbuf(me, r_vert_tx, r_faceid_tx, r_tri_count, reduce_len);
+ return DRW_mesh_batch_cache_get_wireframes_face(me);
}
GPUBatch *DRW_cache_mesh_loose_edges_get(Object *ob)
@@ -3268,13 +3260,12 @@ GPUBatch *DRW_cache_curve_surface_get(Object *ob)
return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->runtime.curve_cache);
}
-void DRW_cache_curve_face_wireframe_get(
- Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count, bool reduce_len)
+GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob)
{
BLI_assert(ob->type == OB_CURVE);
struct Curve *cu = ob->data;
- DRW_curve_batch_cache_get_wireframes_face_texbuf(cu, ob->runtime.curve_cache, r_vert_tx, r_faceid_tx, r_tri_count, reduce_len);
+ return DRW_curve_batch_cache_get_wireframes_face(cu, ob->runtime.curve_cache);
}
/* Return list of batches */
@@ -3300,11 +3291,10 @@ GPUBatch *DRW_cache_mball_surface_get(Object *ob)
return DRW_metaball_batch_cache_get_triangles_with_normals(ob);
}
-void DRW_cache_mball_face_wireframe_get(
- Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count, bool reduce_len)
+GPUBatch *DRW_cache_mball_face_wireframe_get(Object *ob)
{
BLI_assert(ob->type == OB_MBALL);
- DRW_metaball_batch_cache_get_wireframes_face_texbuf(ob, r_vert_tx, r_faceid_tx, r_tri_count, reduce_len);
+ return DRW_metaball_batch_cache_get_wireframes_face(ob);
}
GPUBatch **DRW_cache_mball_surface_shaded_get(
@@ -3340,19 +3330,14 @@ GPUBatch *DRW_cache_text_surface_get(Object *ob)
return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->runtime.curve_cache);
}
-void DRW_cache_text_face_wireframe_get(
- Object *ob,
- struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count, bool reduce_len)
+GPUBatch *DRW_cache_text_face_wireframe_get(Object *ob)
{
BLI_assert(ob->type == OB_FONT);
struct Curve *cu = ob->data;
if (cu->editfont && (cu->flag & CU_FAST)) {
- *r_vert_tx = NULL;
- *r_faceid_tx = NULL;
- *r_tri_count = 0;
- return;
+ return NULL;
}
- DRW_curve_batch_cache_get_wireframes_face_texbuf(cu, ob->runtime.curve_cache, r_vert_tx, r_faceid_tx, r_tri_count, reduce_len);
+ return DRW_curve_batch_cache_get_wireframes_face(cu, ob->runtime.curve_cache);
}
GPUBatch **DRW_cache_text_surface_shaded_get(
@@ -3395,13 +3380,12 @@ GPUBatch *DRW_cache_surf_surface_get(Object *ob)
return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->runtime.curve_cache);
}
-void DRW_cache_surf_face_wireframe_get(
- Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count, bool reduce_len)
+GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob)
{
BLI_assert(ob->type == OB_SURF);
struct Curve *cu = ob->data;
- DRW_curve_batch_cache_get_wireframes_face_texbuf(cu, ob->runtime.curve_cache, r_vert_tx, r_faceid_tx, r_tri_count, reduce_len);
+ return DRW_curve_batch_cache_get_wireframes_face(cu, ob->runtime.curve_cache);
}
/* Return list of batches */
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index 0f262b37bd9..87021360108 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -58,8 +58,7 @@ struct GPUBatch *DRW_cache_object_loose_edges_get(struct Object *ob);
struct GPUBatch **DRW_cache_object_surface_material_get(
struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len, bool use_hide,
char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count);
-void DRW_cache_object_face_wireframe_get(
- Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count, bool reduce_len);
+struct GPUBatch *DRW_cache_object_face_wireframe_get(Object *ob);
/* Empties */
struct GPUBatch *DRW_cache_plain_axes_get(void);
@@ -153,8 +152,7 @@ struct GPUBatch **DRW_cache_mesh_surface_shaded_get(
char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count);
struct GPUBatch **DRW_cache_mesh_surface_texpaint_get(struct Object *ob, bool use_hide);
struct GPUBatch *DRW_cache_mesh_surface_texpaint_single_get(struct Object *ob);
-void DRW_cache_mesh_face_wireframe_get(
- Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count, bool reduce_len);
+struct GPUBatch *DRW_cache_mesh_face_wireframe_get(struct Object *ob);
void DRW_cache_mesh_sculpt_coords_ensure(struct Object *ob);
@@ -164,8 +162,7 @@ struct GPUBatch **DRW_cache_curve_surface_shaded_get(
struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
struct GPUBatch *DRW_cache_curve_surface_verts_get(struct Object *ob);
struct GPUBatch *DRW_cache_curve_edge_wire_get(struct Object *ob);
-void DRW_cache_curve_face_wireframe_get(
- Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count, bool reduce_len);
+struct GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob);
/* edit-mode */
struct GPUBatch *DRW_cache_curve_edge_normal_get(struct Object *ob, float normal_size);
struct GPUBatch *DRW_cache_curve_edge_overlay_get(struct Object *ob);
@@ -176,8 +173,7 @@ struct GPUBatch *DRW_cache_text_edge_wire_get(struct Object *ob);
struct GPUBatch *DRW_cache_text_surface_get(struct Object *ob);
struct GPUBatch **DRW_cache_text_surface_shaded_get(
struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
-void DRW_cache_text_face_wireframe_get(
- Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count, bool reduce_len);
+struct GPUBatch *DRW_cache_text_face_wireframe_get(Object *ob);
/* edit-mode */
struct GPUBatch *DRW_cache_text_cursor_overlay_get(struct Object *ob);
struct GPUBatch *DRW_cache_text_select_overlay_get(struct Object *ob);
@@ -186,8 +182,7 @@ struct GPUBatch *DRW_cache_text_select_overlay_get(struct Object *ob);
struct GPUBatch *DRW_cache_surf_surface_get(struct Object *ob);
struct GPUBatch **DRW_cache_surf_surface_shaded_get(
struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
-void DRW_cache_surf_face_wireframe_get(
- Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count, bool reduce_len);
+struct GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob);
/* Lattice */
struct GPUBatch *DRW_cache_lattice_verts_get(struct Object *ob);
@@ -210,7 +205,6 @@ struct GPUBatch *DRW_cache_particles_get_prim(int type);
/* Metaball */
struct GPUBatch *DRW_cache_mball_surface_get(struct Object *ob);
struct GPUBatch **DRW_cache_mball_surface_shaded_get(struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
-void DRW_cache_mball_face_wireframe_get(
- Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count, bool reduce_len);
+struct GPUBatch *DRW_cache_mball_face_wireframe_get(Object *ob);
#endif /* __DRAW_CACHE_H__ */
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 5e2061f7fe5..d316f63ffa2 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -75,15 +75,12 @@ struct GPUBatch *DRW_curve_batch_cache_get_triangles_with_normals(
struct GPUBatch **DRW_curve_batch_cache_get_surface_shaded(
struct Curve *cu, struct CurveCache *ob_curve_cache,
struct GPUMaterial **gpumat_array, uint gpumat_array_len);
-void DRW_curve_batch_cache_get_wireframes_face_texbuf(
- struct Curve *cu, struct CurveCache *ob_curve_cache,
- struct GPUTexture **verts_data, struct GPUTexture **face_indices, int *tri_count, bool reduce_len);
+struct GPUBatch *DRW_curve_batch_cache_get_wireframes_face(struct Curve *cu, struct CurveCache *ob_curve_cache);
/* Metaball */
struct GPUBatch *DRW_metaball_batch_cache_get_triangles_with_normals(struct Object *ob);
struct GPUBatch **DRW_metaball_batch_cache_get_surface_shaded(struct Object *ob, struct MetaBall *mb, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
-void DRW_metaball_batch_cache_get_wireframes_face_texbuf(
- struct Object *ob, struct GPUTexture **verts_data, struct GPUTexture **face_indices, int *tri_count, bool reduce_len);
+struct GPUBatch *DRW_metaball_batch_cache_get_wireframes_face(struct Object *ob);
/* Curve (Font) */
struct GPUBatch *DRW_curve_batch_cache_get_overlay_cursor(struct Curve *cu);
@@ -96,7 +93,7 @@ struct GPUIndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_mate
struct ListBase *lb, uint gpumat_array_len);
struct GPUBatch **DRW_displist_batch_calc_tri_pos_normals_and_uv_split_by_material(
struct ListBase *lb, uint gpumat_array_len);
-struct GPUVertBuf *DRW_displist_create_edges_overlay_texture_buf(ListBase *lb);
+struct GPUBatch *DRW_displist_create_edges_overlay_batch(ListBase *lb);
/* Lattice */
struct GPUBatch *DRW_lattice_batch_cache_get_all_edges(struct Lattice *lt, bool use_weight, const int actdef);
@@ -161,8 +158,7 @@ struct GPUBatch *DRW_mesh_batch_cache_get_facedots_with_select_id(struct Mesh *m
struct GPUBatch *DRW_mesh_batch_cache_get_edges_with_select_id(struct Mesh *me, uint select_id_offset);
struct GPUBatch *DRW_mesh_batch_cache_get_verts_with_select_id(struct Mesh *me, uint select_id_offset);
/* Object mode Wireframe overlays */
-void DRW_mesh_batch_cache_get_wireframes_face_texbuf(
- struct Mesh *me, struct GPUTexture **verts_data, struct GPUTexture **face_indices, int *tri_count, bool reduce_len);
+struct GPUBatch *DRW_mesh_batch_cache_get_wireframes_face(struct Mesh *me);
void DRW_mesh_cache_sculpt_coords_ensure(struct Mesh *me);
diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.c
index 79d94ef15d8..6f5fb177a64 100644
--- a/source/blender/draw/intern/draw_cache_impl_curve.c
+++ b/source/blender/draw/intern/draw_cache_impl_curve.c
@@ -325,10 +325,7 @@ typedef struct CurveBatchCache {
/* Wireframes */
struct {
- GPUVertBuf *elem_vbo;
- GPUTexture *elem_tx;
- GPUTexture *verts_tx;
- uint tri_count;
+ GPUBatch *batch;
} face_wire;
/* 3d text */
@@ -450,10 +447,7 @@ static void curve_batch_cache_clear(Curve *cu)
GPU_BATCH_DISCARD_ARRAY_SAFE(cache->surface.shaded_triangles, cache->surface.mat_len);
GPU_BATCH_DISCARD_SAFE(cache->surface.batch);
- GPU_VERTBUF_DISCARD_SAFE(cache->face_wire.elem_vbo);
- DRW_TEXTURE_FREE_SAFE(cache->face_wire.elem_tx);
- DRW_TEXTURE_FREE_SAFE(cache->face_wire.verts_tx);
- cache->face_wire.tri_count = 0;
+ GPU_BATCH_DISCARD_SAFE(cache->face_wire.batch);
/* don't own vbo & elems */
GPU_BATCH_DISCARD_SAFE(cache->wire.batch);
@@ -801,40 +795,6 @@ static GPUBatch *curve_batch_cache_get_pos_and_normals(CurveRenderData *rdata, C
return cache->surface.batch;
}
-static GPUTexture *curve_batch_cache_get_edges_overlay_texture_buf(CurveRenderData *rdata, CurveBatchCache *cache)
-{
- BLI_assert(rdata->types & CU_DATATYPE_SURFACE);
-
- if (cache->face_wire.elem_tx != NULL) {
- return cache->face_wire.elem_tx;
- }
-
- ListBase *lb = &rdata->ob_curve_cache->disp;
-
- /* We need a special index buffer. */
- GPUVertBuf *vbo = cache->face_wire.elem_vbo = DRW_displist_create_edges_overlay_texture_buf(lb);
-
- /* Upload data early because we need to create the texture for it. */
- GPU_vertbuf_use(vbo);
- cache->face_wire.elem_tx = GPU_texture_create_from_vertbuf(vbo);
- cache->face_wire.tri_count = vbo->vertex_alloc / 3;
-
- return cache->face_wire.elem_tx;
-}
-
-static GPUTexture *curve_batch_cache_get_vert_pos_and_nor_in_order_buf(CurveRenderData *rdata, CurveBatchCache *cache)
-{
- BLI_assert(rdata->types & CU_DATATYPE_SURFACE);
-
- if (cache->face_wire.verts_tx == NULL) {
- curve_batch_cache_get_pos_and_normals(rdata, cache);
- GPU_vertbuf_use(cache->surface.verts); /* Upload early for buffer texture creation. */
- cache->face_wire.verts_tx = GPU_texture_create_buffer(GPU_R32F, cache->surface.verts->vbo_id);
- }
-
- return cache->face_wire.verts_tx;
-}
-
/** \} */
@@ -1074,24 +1034,21 @@ GPUBatch **DRW_curve_batch_cache_get_surface_shaded(
return cache->surface.shaded_triangles;
}
-void DRW_curve_batch_cache_get_wireframes_face_texbuf(
- Curve *cu, CurveCache *ob_curve_cache,
- GPUTexture **verts_data, GPUTexture **face_indices, int *tri_count, bool UNUSED(reduce_len))
+GPUBatch *DRW_curve_batch_cache_get_wireframes_face(Curve *cu, CurveCache *ob_curve_cache)
{
CurveBatchCache *cache = curve_batch_cache_get(cu);
- if (cache->face_wire.elem_tx == NULL || cache->face_wire.verts_tx == NULL) {
+ if (cache->face_wire.batch == NULL) {
CurveRenderData *rdata = curve_render_data_create(cu, ob_curve_cache, CU_DATATYPE_SURFACE);
- curve_batch_cache_get_edges_overlay_texture_buf(rdata, cache);
- curve_batch_cache_get_vert_pos_and_nor_in_order_buf(rdata, cache);
+ ListBase *lb = &rdata->ob_curve_cache->disp;
+
+ cache->face_wire.batch = DRW_displist_create_edges_overlay_batch(lb);
curve_render_data_free(rdata);
}
- *tri_count = cache->face_wire.tri_count;
- *face_indices = cache->face_wire.elem_tx;
- *verts_data = cache->face_wire.verts_tx;
+ return cache->face_wire.batch;
}
/* -------------------------------------------------------------------- */
diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c
index d6a57676a8d..2f9fa73b7e6 100644
--- a/source/blender/draw/intern/draw_cache_impl_displist.c
+++ b/source/blender/draw/intern/draw_cache_impl_displist.c
@@ -218,55 +218,89 @@ GPUIndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_material(Li
}
typedef struct DRWDisplistWireThunk {
- uint index_id, vidx;
- short dl_type;
+ uint wd_id, pos_id, nor_id, vidx, ofs;
+ const DispList *dl;
GPUVertBuf *vbo;
} DRWDisplistWireThunk;
static void set_overlay_wires_tri_indices(void *thunk, uint v1, uint v2, uint v3)
{
DRWDisplistWireThunk *dwt = (DRWDisplistWireThunk *)thunk;
- /* Tag real edges. */
- v1 |= (1 << 30);
- v2 |= (1 << 30);
- v3 |= (1 << 30);
- GPU_vertbuf_attr_set(dwt->vbo, dwt->index_id, dwt->vidx++, &v1);
- GPU_vertbuf_attr_set(dwt->vbo, dwt->index_id, dwt->vidx++, &v2);
- GPU_vertbuf_attr_set(dwt->vbo, dwt->index_id, dwt->vidx++, &v3);
+ const DispList *dl = dwt->dl;
+ uint indices[3] = {v1, v2, v3};
+ const bool ndata_is_single = dl->type == DL_INDEX3;
+
+ for (int i = 0; i < 3; ++i) {
+ uint v = indices[i] - dwt->ofs;
+ /* TODO: Compute sharpness. For now, only tag real egdes. */
+ uchar sharpness = 0xFF;
+ short short_no[3];
+ const float(*verts)[3] = (float(*)[3])dl->verts;
+ const float(*nors)[3] = (float(*)[3])dl->nors;
+ normal_float_to_short_v3(short_no, nors[(ndata_is_single) ? 0 : v]);
+ GPU_vertbuf_attr_set(dwt->vbo, dwt->wd_id, dwt->vidx, &sharpness);
+ GPU_vertbuf_attr_set(dwt->vbo, dwt->pos_id, dwt->vidx, verts[v]);
+ GPU_vertbuf_attr_set(dwt->vbo, dwt->nor_id, dwt->vidx, short_no);
+ dwt->vidx++;
+ }
}
static void set_overlay_wires_quad_tri_indices(void *thunk, uint v1, uint v2, uint v3)
{
DRWDisplistWireThunk *dwt = (DRWDisplistWireThunk *)thunk;
- /* Tag real edges. */
- v2 |= (1 << 30);
- v3 |= (1 << 30);
- GPU_vertbuf_attr_set(dwt->vbo, dwt->index_id, dwt->vidx++, &v1);
- GPU_vertbuf_attr_set(dwt->vbo, dwt->index_id, dwt->vidx++, &v2);
- GPU_vertbuf_attr_set(dwt->vbo, dwt->index_id, dwt->vidx++, &v3);
+ const DispList *dl = dwt->dl;
+ uint indices[3] = {v1, v2, v3};
+ const bool ndata_is_single = dl->type == DL_INDEX3;
+
+ for (int i = 0; i < 3; ++i) {
+ uint v = indices[i] - dwt->ofs;
+ /* TODO: Compute sharpness. For now, only tag real egdes. */
+ uchar sharpness = (i == 0) ? 0x00 : 0xFF;
+ short short_no[3];
+ const float(*verts)[3] = (float(*)[3])dl->verts;
+ const float(*nors)[3] = (float(*)[3])dl->nors;
+ normal_float_to_short_v3(short_no, nors[(ndata_is_single) ? 0 : v]);
+ GPU_vertbuf_attr_set(dwt->vbo, dwt->wd_id, dwt->vidx, &sharpness);
+ GPU_vertbuf_attr_set(dwt->vbo, dwt->pos_id, dwt->vidx, verts[v]);
+ GPU_vertbuf_attr_set(dwt->vbo, dwt->nor_id, dwt->vidx, short_no);
+ dwt->vidx++;
+ }
}
-GPUVertBuf *DRW_displist_create_edges_overlay_texture_buf(ListBase *lb)
+GPUBatch *DRW_displist_create_edges_overlay_batch(ListBase *lb)
{
- GPUVertFormat format = {0};
- uint index_id = GPU_vertformat_attr_add(&format, "index", GPU_COMP_U32, 1, GPU_FETCH_INT);
- GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
+ static DRWDisplistWireThunk thunk;
+ static GPUVertFormat format = {0};
+ if (format.attr_len == 0) {
+ thunk.wd_id = GPU_vertformat_attr_add(&format, "wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ thunk.pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ thunk.nor_id = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ GPU_vertformat_triple_load(&format);
+ }
- GPU_vertbuf_data_alloc(vbo, curve_render_surface_tri_len_get(lb) * 3);
+ thunk.vbo = GPU_vertbuf_create_with_format(&format);
- DRWDisplistWireThunk thunk = {.index_id = index_id, .vbo = vbo, .vidx = 0};
+ int vert_len = curve_render_surface_tri_len_get(lb) * 3;
+ GPU_vertbuf_data_alloc(thunk.vbo, vert_len);
- int ofs = 0;
+ thunk.vidx = 0;
+ thunk.ofs = 0;
for (const DispList *dl = lb->first; dl; dl = dl->next) {
- thunk.dl_type = dl->type;
+ thunk.dl = dl;
+ BKE_displist_normals_add(lb);
+
/* TODO consider non-manifold edges correctly. */
displist_indexbufbuilder_set(set_overlay_wires_tri_indices,
set_overlay_wires_quad_tri_indices,
- &thunk, dl, ofs);
- ofs += dl_vert_len(dl);
+ &thunk, dl, thunk.ofs);
+ thunk.ofs += dl_vert_len(dl);
}
- return vbo;
+ if (thunk.vidx < vert_len) {
+ GPU_vertbuf_data_resize(thunk.vbo, thunk.vidx);
+ }
+
+ return GPU_batch_create_ex(GPU_PRIM_TRIS, thunk.vbo, NULL, GPU_BATCH_OWNS_VBO);
}
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 8757eec5d6b..55a0467c7a8 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -2016,6 +2016,8 @@ typedef struct MeshBatchCache {
GPUVertBuf *pos_with_normals;
GPUVertBuf *pos_with_normals_visible_only;
+ GPUVertBuf *pos_with_normals_edit;
+ GPUVertBuf *pos_with_normals_visible_only_edit;
GPUVertBuf *tri_aligned_uv; /* Active UV layer (mloopuv) */
/**
@@ -2050,7 +2052,8 @@ typedef struct MeshBatchCache {
GPUBatch *edge_detection;
- GPUVertBuf *edges_face_overlay;
+ GPUVertBuf *edges_face_overlay_data;
+ GPUBatch *edges_face_overlay;
GPUTexture *edges_face_overlay_tx;
int edges_face_overlay_tri_count; /* Number of tri in edges_face_overlay(_adj)_tx */
int edges_face_overlay_tri_count_low; /* Number of tri that are sure to produce edges. */
@@ -2371,7 +2374,9 @@ static void mesh_batch_cache_clear_selective(Mesh *me, GPUVertBuf *vert)
BLI_assert(vert != NULL);
- if (ELEM(vert, cache->pos_with_normals, cache->pos_with_normals_visible_only)) {
+ if (ELEM(vert, cache->pos_with_normals, cache->pos_with_normals_visible_only,
+ cache->pos_with_normals_edit, cache->pos_with_normals_visible_only_edit))
+ {
GPU_BATCH_DISCARD_SAFE(cache->triangles_with_normals);
GPU_BATCH_DISCARD_SAFE(cache->triangles_with_weights);
GPU_BATCH_DISCARD_SAFE(cache->triangles_with_vert_colors);
@@ -2445,6 +2450,8 @@ static void mesh_batch_cache_clear(Mesh *me)
GPU_BATCH_DISCARD_SAFE(cache->ledges_with_normals);
GPU_VERTBUF_DISCARD_SAFE(cache->pos_with_normals);
GPU_VERTBUF_DISCARD_SAFE(cache->pos_with_normals_visible_only);
+ GPU_VERTBUF_DISCARD_SAFE(cache->pos_with_normals_edit);
+ GPU_VERTBUF_DISCARD_SAFE(cache->pos_with_normals_visible_only_edit);
GPU_BATCH_DISCARD_SAFE(cache->triangles_with_weights);
GPU_BATCH_DISCARD_SAFE(cache->triangles_with_vert_colors);
GPU_VERTBUF_DISCARD_SAFE(cache->tri_aligned_uv);
@@ -2462,7 +2469,8 @@ static void mesh_batch_cache_clear(Mesh *me)
GPU_INDEXBUF_DISCARD_SAFE(cache->edges_adjacency);
GPU_BATCH_DISCARD_SAFE(cache->edge_detection);
- GPU_VERTBUF_DISCARD_SAFE(cache->edges_face_overlay);
+ GPU_VERTBUF_DISCARD_SAFE(cache->edges_face_overlay_data);
+ GPU_BATCH_DISCARD_SAFE(cache->edges_face_overlay);
DRW_TEXTURE_FREE_SAFE(cache->edges_face_overlay_tx);
mesh_batch_cache_discard_shaded_tri(cache);
@@ -2812,6 +2820,7 @@ static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex(
if (format.attr_len == 0) {
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ GPU_vertformat_triple_load(&format);
}
const int tri_len = mesh_render_data_looptri_len_get_maybe_mapped(rdata);
@@ -3004,7 +3013,15 @@ static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex(
return *r_vbo;
}
-static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals(
+static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals_edit(
+ MeshRenderData *rdata, MeshBatchCache *cache, bool use_hide)
+{
+ return mesh_batch_cache_get_tri_pos_and_normals_ex(
+ rdata, use_hide,
+ use_hide ? &cache->pos_with_normals_visible_only_edit : &cache->pos_with_normals_edit);
+}
+
+static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals_final(
MeshRenderData *rdata, MeshBatchCache *cache, bool use_hide)
{
return mesh_batch_cache_get_tri_pos_and_normals_ex(
@@ -4305,31 +4322,30 @@ static EdgeHash *create_looptri_edge_adjacency_hash(MeshRenderData *rdata, EdgeA
return eh;
}
-static GPUVertBuf *mesh_batch_cache_create_edges_overlay_texture_buf(
- MeshRenderData *rdata, MeshBatchCache *cache, bool reduce_len)
+static GPUVertBuf *mesh_batch_cache_create_edges_wireframe_data(MeshRenderData *rdata, MeshBatchCache *cache)
{
- if (cache->edges_face_overlay != NULL) {
- return cache->edges_face_overlay;
+ if (cache->edges_face_overlay_data != NULL) {
+ return cache->edges_face_overlay_data;
}
const int tri_len = mesh_render_data_looptri_len_get(rdata);
GPUVertFormat format = {0};
- uint index_id = GPU_vertformat_attr_add(&format, "index", GPU_COMP_U32, 1, GPU_FETCH_INT);
- GPUVertBuf *vbo = cache->edges_face_overlay = GPU_vertbuf_create_with_format(&format);
+ uint index_id = GPU_vertformat_attr_add(&format, "wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ GPU_vertformat_triple_load(&format);
+
+ GPUVertBuf *vbo = cache->edges_face_overlay_data = GPU_vertbuf_create_with_format(&format);
int vbo_len_capacity = tri_len * 3;
GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
int vidx = 0;
- int vidx_end = vbo_len_capacity;
EdgeHash *eh = NULL;
EdgeAdjacentVerts *adj_data = NULL;
eh = create_looptri_edge_adjacency_hash(rdata, &adj_data);
for (int i = 0; i < tri_len; i++) {
- uint vdata[3] = {0, 0, 0};
- bool face_has_edges = false;
+ uchar vdata[3] = {0, 0, 0};
const MVert *mvert = rdata->mvert;
const MEdge *medge = rdata->medge;
@@ -4339,47 +4355,39 @@ static GPUVertBuf *mesh_batch_cache_create_edges_overlay_texture_buf(
int j, j_next;
for (j = 2, j_next = 0; j_next < 3; j = j_next++) {
const MEdge *ed = &medge[mloop[mlt->tri[j]].e];
- const uint tri_edge[2] = {mloop[mlt->tri[j]].v, mloop[mlt->tri[j_next]].v};
+ const uint tri_edge[2] = {mloop[mlt->tri[j]].v, mloop[mlt->tri[j_next]].v};
if ((((ed->v1 == tri_edge[0]) && (ed->v2 == tri_edge[1])) ||
- ((ed->v1 == tri_edge[1]) && (ed->v2 == tri_edge[0]))) &&
- (ed->flag & ME_EDGERENDER) != 0)
+ ((ed->v1 == tri_edge[1]) && (ed->v2 == tri_edge[0]))))
{
/* Real edge. */
- vdata[j] |= (1 << 30);
+ /* Temp Workaround. If a mesh has a subdiv mod we should not
+ * compute the edge sharpness. Instead, we just mix both for now. */
+ vdata[j] = ((ed->flag & ME_EDGERENDER) != 0) ? 0xFD : 0xFE;
}
}
/* If at least one edge is real. */
if (vdata[0] || vdata[1] || vdata[2]) {
- /* Decide if face has at least a "dominant" edge. */
-
float fnor[3];
- if (reduce_len) {
- normal_tri_v3(fnor,
- mvert[mloop[mlt->tri[0]].v].co,
- mvert[mloop[mlt->tri[1]].v].co,
- mvert[mloop[mlt->tri[2]].v].co);
- }
+ normal_tri_v3(fnor,
+ mvert[mloop[mlt->tri[0]].v].co,
+ mvert[mloop[mlt->tri[1]].v].co,
+ mvert[mloop[mlt->tri[2]].v].co);
for (int e = 0; e < 3; e++) {
- int v0 = mloop[mlt->tri[e]].v;
- int v1 = mloop[mlt->tri[(e + 1) % 3]].v;
- /* The only breakage it would cause is drawing issues. */
- /* BLI_assert(3FFFFFFF > v0); */
- vdata[e] |= (uint)v0;
/* Non-real edge. */
if (vdata[e] == 0) {
continue;
}
+ int v0 = mloop[mlt->tri[e]].v;
+ int v1 = mloop[mlt->tri[(e + 1) % 3]].v;
EdgeAdjacentVerts *eav = BLI_edgehash_lookup(eh, v0, v1);
/* If Non Manifold. */
if (eav->vert_index[1] == -1) {
- face_has_edges = true;
- vdata[e] |= (1u << 31);
+ vdata[e] = 0xFF;
}
- /* Search for dominant edge. */
- if (reduce_len && !face_has_edges) {
+ else if (vdata[e] == 0xFD) {
int v2 = mloop[mlt->tri[(e + 2) % 3]].v;
/* Select the right opposite vertex */
v2 = (eav->vert_index[1] == v2) ? eav->vert_index[0] : eav->vert_index[1];
@@ -4389,70 +4397,28 @@ static GPUVertBuf *mesh_batch_cache_create_edges_overlay_texture_buf(
mvert[v0].co,
mvert[v2].co);
float fac = dot_v3v3(fnor_adj, fnor);
- if (fac < 0.999f) {
- face_has_edges = true;
+ fac = fac * fac * 50.0f - 49.0f;
+ CLAMP(fac, 0.0f, 0.999f);
+ /* Shorten the range to make the non-ME_EDGERENDER fade first.
+ * Add one because 0x0 is no edges. */
+ vdata[e] = (uchar)(0xDF * fac) + 1;
+ if (vdata[e] < 0.999f) {
+ /* TODO construct fast face wire index buffer. */
}
}
}
}
- if (!face_has_edges) {
- vidx_end -= 3;
- }
-
for (int e = 0; e < 3; e++) {
- /* Add faces most likely to draw anything at the begining of the VBO
- * to enable fast drawing the visible edges. */
- if (face_has_edges) {
- GPU_vertbuf_attr_set(vbo, index_id, vidx++, &vdata[e]);
- }
- else {
- GPU_vertbuf_attr_set(vbo, index_id, vidx_end + e, &vdata[e]);
- }
+ GPU_vertbuf_attr_set(vbo, index_id, vidx++, &vdata[e]);
}
}
- cache->edges_face_overlay_tri_count = vbo->vertex_alloc / 3;
- cache->edges_face_overlay_tri_count_low = vidx / 3;
- cache->edges_face_reduce_len = reduce_len;
-
BLI_edgehash_free(eh, NULL);
MEM_freeN(adj_data);
return vbo;
}
-static GPUTexture *mesh_batch_cache_get_edges_overlay_texture_buf(
- MeshRenderData *rdata, MeshBatchCache *cache, bool reduce_len)
-{
- BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI));
-
-
- if (cache->edges_face_overlay_tx != NULL) {
- return cache->edges_face_overlay_tx;
- }
-
- GPUVertBuf *vbo = mesh_batch_cache_create_edges_overlay_texture_buf(rdata, cache, reduce_len);
-
- /* Upload data early because we need to create the texture for it. */
- GPU_vertbuf_use(vbo);
- cache->edges_face_overlay_tx = GPU_texture_create_from_vertbuf(vbo);
-
- return cache->edges_face_overlay_tx;
-}
-
-static GPUTexture *mesh_batch_cache_get_vert_pos_and_nor_in_order_buf(MeshRenderData *rdata, MeshBatchCache *cache)
-{
- BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI));
-
- if (cache->pos_in_order_tx == NULL) {
- GPUVertBuf *pos_in_order = mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache);
- GPU_vertbuf_use(pos_in_order); /* Upload early for buffer texture creation. */
- cache->pos_in_order_tx = GPU_texture_create_buffer(GPU_R32F, pos_in_order->vbo_id);
- }
-
- return cache->pos_in_order_tx;
-}
-
static GPUIndexBuf *mesh_batch_cache_get_triangles_in_order(MeshRenderData *rdata, MeshBatchCache *cache)
{
BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI));
@@ -4847,10 +4813,24 @@ GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals(Mesh *me, bool use_hid
if (cache->triangles_with_normals == NULL) {
const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY;
+
+ /* Hack to show the final result. */
+ const bool use_em_final = (
+ me->edit_btmesh &&
+ me->edit_btmesh->mesh_eval_final &&
+ (me->edit_btmesh->mesh_eval_final->runtime.is_original == false));
+ Mesh me_fake;
+ if (use_em_final) {
+ me_fake = *me->edit_btmesh->mesh_eval_final;
+ me_fake.mat = me->mat;
+ me_fake.totcol = me->totcol;
+ me = &me_fake;
+ }
+
MeshRenderData *rdata = mesh_render_data_create(me, datatype);
cache->triangles_with_normals = GPU_batch_create(
- GPU_PRIM_TRIS, mesh_batch_cache_get_tri_pos_and_normals(rdata, cache, use_hide), NULL);
+ GPU_PRIM_TRIS, mesh_batch_cache_get_tri_pos_and_normals_final(rdata, cache, use_hide), NULL);
mesh_render_data_free(rdata);
}
@@ -4897,7 +4877,7 @@ GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(
DRW_mesh_weight_state_copy(&cache->weight_state, wstate);
- GPUVertBuf *vbo_tris = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache, use_hide);
+ GPUVertBuf *vbo_tris = mesh_batch_cache_get_tri_pos_and_normals_final(rdata, cache, use_hide);
GPU_batch_vertbuf_add(cache->triangles_with_weights, vbo_tris);
@@ -4920,7 +4900,7 @@ GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(Mesh *
cache->triangles_with_vert_colors = GPU_batch_create_ex(
GPU_PRIM_TRIS, mesh_create_tri_vert_colors(rdata, use_hide), NULL, GPU_BATCH_OWNS_VBO);
- GPUVertBuf *vbo_tris = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache, use_hide);
+ GPUVertBuf *vbo_tris = mesh_batch_cache_get_tri_pos_and_normals_final(rdata, cache, use_hide);
GPU_batch_vertbuf_add(cache->triangles_with_vert_colors, vbo_tris);
mesh_render_data_free(rdata);
@@ -4951,7 +4931,7 @@ struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_id(
cache->triangles_with_select_id = GPU_batch_create_ex(
GPU_PRIM_TRIS, mesh_create_tri_select_id(rdata, use_hide, select_id_offset), NULL, GPU_BATCH_OWNS_VBO);
- GPUVertBuf *vbo_tris = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache, use_hide);
+ GPUVertBuf *vbo_tris = mesh_batch_cache_get_tri_pos_and_normals_edit(rdata, cache, use_hide);
GPU_batch_vertbuf_add(cache->triangles_with_select_id, vbo_tris);
mesh_render_data_free(rdata);
@@ -4975,7 +4955,7 @@ struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_mask(struct Mesh
rdata->mapped.use = true;
}
- GPUVertBuf *vbo_tris = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache, use_hide);
+ GPUVertBuf *vbo_tris = mesh_batch_cache_get_tri_pos_and_normals_edit(rdata, cache, use_hide);
cache->triangles_with_select_mask = GPU_batch_create(
GPU_PRIM_TRIS, vbo_tris, NULL);
@@ -4995,7 +4975,7 @@ GPUBatch *DRW_mesh_batch_cache_get_points_with_normals(Mesh *me)
MeshRenderData *rdata = mesh_render_data_create(me, datatype);
cache->points_with_normals = GPU_batch_create(
- GPU_PRIM_POINTS, mesh_batch_cache_get_tri_pos_and_normals(rdata, cache, false), NULL);
+ GPU_PRIM_POINTS, mesh_batch_cache_get_tri_pos_and_normals_edit(rdata, cache, false), NULL);
mesh_render_data_free(rdata);
}
@@ -5108,17 +5088,11 @@ GPUBatch *DRW_mesh_batch_cache_get_edge_detection(Mesh *me, bool *r_is_manifold)
return cache->edge_detection;
}
-void DRW_mesh_batch_cache_get_wireframes_face_texbuf(
- Mesh *me, GPUTexture **verts_data, GPUTexture **face_indices, int *tri_count, bool reduce_len)
+GPUBatch *DRW_mesh_batch_cache_get_wireframes_face(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
- if (!cache->edges_face_reduce_len && reduce_len) {
- GPU_VERTBUF_DISCARD_SAFE(cache->edges_face_overlay);
- DRW_TEXTURE_FREE_SAFE(cache->edges_face_overlay_tx);
- }
-
- if (cache->edges_face_overlay_tx == NULL || cache->pos_in_order_tx == NULL) {
+ if (cache->edges_face_overlay == NULL) {
const int options = MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI;
/* Hack to show the final result. */
@@ -5136,15 +5110,14 @@ void DRW_mesh_batch_cache_get_wireframes_face_texbuf(
MeshRenderData *rdata = mesh_render_data_create(me, options);
- mesh_batch_cache_get_edges_overlay_texture_buf(rdata, cache, reduce_len);
- mesh_batch_cache_get_vert_pos_and_nor_in_order_buf(rdata, cache);
+ cache->edges_face_overlay = GPU_batch_create(
+ GPU_PRIM_TRIS, mesh_batch_cache_create_edges_wireframe_data(rdata, cache), NULL);
+ GPU_batch_vertbuf_add(cache->edges_face_overlay, mesh_batch_cache_get_tri_pos_and_normals_final(rdata, cache, false));
mesh_render_data_free(rdata);
}
- *tri_count = reduce_len ? cache->edges_face_overlay_tri_count_low : cache->edges_face_overlay_tri_count;
- *face_indices = cache->edges_face_overlay_tx;
- *verts_data = cache->pos_in_order_tx;
+ return cache->edges_face_overlay;
}
static void mesh_batch_cache_create_overlay_batches(Mesh *me)
@@ -5430,7 +5403,7 @@ GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(
rdata, cache,
bm_mapped, p_origindex, use_hide);
- GPUVertBuf *vbo = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache, false);
+ GPUVertBuf *vbo = mesh_batch_cache_get_tri_pos_and_normals_final(rdata, cache, false);
GPUVertBuf *vbo_shading = mesh_batch_cache_get_tri_shading_data(rdata, cache);
for (int i = 0; i < mat_len; i++) {
@@ -5483,7 +5456,7 @@ GPUBatch **DRW_mesh_batch_cache_get_surface_texpaint(Mesh *me, bool use_hide)
GPUIndexBuf **el = mesh_batch_cache_get_triangles_in_order_split_by_material(rdata, cache, NULL, NULL, use_hide);
- GPUVertBuf *vbo = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache, false);
+ GPUVertBuf *vbo = mesh_batch_cache_get_tri_pos_and_normals_final(rdata, cache, false);
for (int i = 0; i < mat_len; i++) {
cache->texpaint_triangles[i] = GPU_batch_create(
@@ -5509,7 +5482,7 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_texpaint_single(Mesh *me)
MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOPUV;
MeshRenderData *rdata = mesh_render_data_create(me, datatype);
- GPUVertBuf *vbo = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache, false);
+ GPUVertBuf *vbo = mesh_batch_cache_get_tri_pos_and_normals_final(rdata, cache, false);
cache->texpaint_triangles_single = GPU_batch_create(
GPU_PRIM_TRIS, vbo, NULL);
diff --git a/source/blender/draw/intern/draw_cache_impl_metaball.c b/source/blender/draw/intern/draw_cache_impl_metaball.c
index 17ca9ec317e..10f5db42bf1 100644
--- a/source/blender/draw/intern/draw_cache_impl_metaball.c
+++ b/source/blender/draw/intern/draw_cache_impl_metaball.c
@@ -59,10 +59,7 @@ typedef struct MetaBallBatchCache {
/* Wireframe */
struct {
- GPUVertBuf *elem_vbo;
- GPUTexture *elem_tx;
- GPUTexture *verts_tx;
- int tri_count;
+ GPUBatch *batch;
} face_wire;
/* settings to determine if cache is invalid */
@@ -94,10 +91,7 @@ static void metaball_batch_cache_init(MetaBall *mb)
cache->shaded_triangles = NULL;
cache->is_dirty = false;
cache->pos_nor_in_order = NULL;
- cache->face_wire.elem_vbo = NULL;
- cache->face_wire.elem_tx = NULL;
- cache->face_wire.verts_tx = NULL;
- cache->face_wire.tri_count = 0;
+ cache->face_wire.batch = NULL;
}
static MetaBallBatchCache *metaball_batch_cache_get(MetaBall *mb)
@@ -131,10 +125,7 @@ static void metaball_batch_cache_clear(MetaBall *mb)
return;
}
- GPU_VERTBUF_DISCARD_SAFE(cache->face_wire.elem_vbo);
- DRW_TEXTURE_FREE_SAFE(cache->face_wire.elem_tx);
- DRW_TEXTURE_FREE_SAFE(cache->face_wire.verts_tx);
-
+ GPU_BATCH_DISCARD_SAFE(cache->face_wire.batch);
GPU_BATCH_DISCARD_SAFE(cache->batch);
GPU_VERTBUF_DISCARD_SAFE(cache->pos_nor_in_order);
/* Note: shaded_triangles[0] is already freed by cache->batch */
@@ -157,36 +148,6 @@ static GPUVertBuf *mball_batch_cache_get_pos_and_normals(Object *ob, MetaBallBat
return cache->pos_nor_in_order;
}
-static GPUTexture *mball_batch_cache_get_edges_overlay_texture_buf(Object *ob, MetaBallBatchCache *cache)
-{
- if (cache->face_wire.elem_tx != NULL) {
- return cache->face_wire.elem_tx;
- }
-
- ListBase *lb = &ob->runtime.curve_cache->disp;
-
- /* We need a special index buffer. */
- GPUVertBuf *vbo = cache->face_wire.elem_vbo = DRW_displist_create_edges_overlay_texture_buf(lb);
-
- /* Upload data early because we need to create the texture for it. */
- GPU_vertbuf_use(vbo);
- cache->face_wire.elem_tx = GPU_texture_create_from_vertbuf(vbo);
- cache->face_wire.tri_count = vbo->vertex_alloc / 3;
-
- return cache->face_wire.elem_tx;
-}
-
-static GPUTexture *mball_batch_cache_get_vert_pos_and_nor_in_order_buf(Object *ob, MetaBallBatchCache *cache)
-{
- if (cache->face_wire.verts_tx == NULL) {
- GPUVertBuf *vbo = mball_batch_cache_get_pos_and_normals(ob, cache);
- GPU_vertbuf_use(vbo); /* Upload early for buffer texture creation. */
- cache->face_wire.verts_tx = GPU_texture_create_buffer(GPU_R32F, vbo->vbo_id);
- }
-
- return cache->face_wire.verts_tx;
-}
-
/* -------------------------------------------------------------------- */
/** \name Public Object/MetaBall API
@@ -232,26 +193,19 @@ GPUBatch **DRW_metaball_batch_cache_get_surface_shaded(Object *ob, MetaBall *mb,
}
-void DRW_metaball_batch_cache_get_wireframes_face_texbuf(
- Object *ob, struct GPUTexture **verts_data, struct GPUTexture **face_indices, int *tri_count, bool UNUSED(reduce_len))
+GPUBatch *DRW_metaball_batch_cache_get_wireframes_face(Object *ob)
{
if (!BKE_mball_is_basis(ob)) {
- *verts_data = NULL;
- *face_indices = NULL;
- *tri_count = 0;
- return;
+ return NULL;
}
MetaBall *mb = ob->data;
MetaBallBatchCache *cache = metaball_batch_cache_get(mb);
- if (cache->face_wire.verts_tx == NULL) {
- *verts_data = mball_batch_cache_get_vert_pos_and_nor_in_order_buf(ob, cache);
- *face_indices = mball_batch_cache_get_edges_overlay_texture_buf(ob, cache);
- }
- else {
- *verts_data = cache->face_wire.verts_tx;
- *face_indices = cache->face_wire.elem_tx;
+ if (cache->face_wire.batch == NULL) {
+ ListBase *lb = &ob->runtime.curve_cache->disp;
+ cache->face_wire.batch = DRW_displist_create_edges_overlay_batch(lb);
}
- *tri_count = cache->face_wire.tri_count;
+
+ return cache->face_wire.batch;
}
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 1f6f95456a1..5863eb57745 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -1040,7 +1040,7 @@ DRWShadingGroup *DRW_shgroup_create_sub(DRWShadingGroup *shgroup)
DRWShadingGroup *shgroup_new = BLI_mempool_alloc(DST.vmempool->shgroups);
*shgroup_new = *shgroup;
- shgroup_new->uniforms = NULL; /* Not sure about that.. Should we copy them instead? */
+ shgroup_new->uniforms = NULL;
shgroup_new->calls.first = NULL;
shgroup_new->calls.last = NULL;
diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c
index 912c8cdec49..489f9af070e 100644
--- a/source/blender/draw/modes/overlay_mode.c
+++ b/source/blender/draw/modes/overlay_mode.c
@@ -42,9 +42,7 @@ typedef struct OVERLAY_StorageList {
typedef struct OVERLAY_PassList {
struct DRWPass *face_orientation_pass;
- struct DRWPass *flat_wireframe_pass;
struct DRWPass *face_wireframe_pass;
- struct DRWPass *face_wireframe_full_pass;
} OVERLAY_PassList;
typedef struct OVERLAY_Data {
@@ -57,7 +55,8 @@ typedef struct OVERLAY_Data {
typedef struct OVERLAY_PrivateData {
DRWShadingGroup *face_orientation_shgrp;
- DRWShadingGroup *sculpt_wires_full;
+ DRWShadingGroup *face_wires;
+ DRWShadingGroup *flat_wires;
DRWShadingGroup *sculpt_wires;
View3DOverlay overlay;
float wire_step_param[2];
@@ -72,9 +71,7 @@ static struct {
/* Wireframe shader */
struct GPUShader *select_wireframe_sh;
struct GPUShader *face_wireframe_sh;
- struct GPUShader *face_wireframe_pretty_sh;
struct GPUShader *face_wireframe_sculpt_sh;
- struct GPUShader *face_wireframe_sculpt_pretty_sh;
} e_data = {NULL};
/* Shaders */
@@ -84,6 +81,7 @@ extern char datatoc_overlay_face_orientation_vert_glsl[];
extern char datatoc_overlay_face_wireframe_vert_glsl[];
extern char datatoc_overlay_face_wireframe_geom_glsl[];
extern char datatoc_overlay_face_wireframe_frag_glsl[];
+extern char datatoc_gpu_shader_depth_only_frag_glsl[];
extern struct GlobalsUboStorage ts; /* draw_common.c */
@@ -107,45 +105,23 @@ static void overlay_engine_init(void *vedata)
}
if (!e_data.face_wireframe_sh) {
- bool use_geom = GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY);
-
e_data.select_wireframe_sh = DRW_shader_create(
datatoc_overlay_face_wireframe_vert_glsl,
datatoc_overlay_face_wireframe_geom_glsl,
- datatoc_overlay_face_wireframe_frag_glsl,
- "#define SELECT_EDGES\n"
- "#define LIGHT_EDGES\n"
- "#define USE_GEOM_SHADER\n");
+ datatoc_gpu_shader_depth_only_frag_glsl,
+ "#define SELECT_EDGES\n");
e_data.face_wireframe_sh = DRW_shader_create(
datatoc_overlay_face_wireframe_vert_glsl,
- use_geom ? datatoc_overlay_face_wireframe_geom_glsl : NULL,
+ NULL,
datatoc_overlay_face_wireframe_frag_glsl,
- use_geom ? "#define USE_GEOM_SHADER\n"
- : NULL);
-
- e_data.face_wireframe_pretty_sh = DRW_shader_create(
- datatoc_overlay_face_wireframe_vert_glsl,
- use_geom ? datatoc_overlay_face_wireframe_geom_glsl : NULL,
- datatoc_overlay_face_wireframe_frag_glsl,
- use_geom ? "#define USE_GEOM_SHADER\n"
- "#define LIGHT_EDGES\n"
- : "#define LIGHT_EDGES\n");
+ NULL);
e_data.face_wireframe_sculpt_sh = DRW_shader_create(
datatoc_overlay_face_wireframe_vert_glsl,
datatoc_overlay_face_wireframe_geom_glsl,
datatoc_overlay_face_wireframe_frag_glsl,
- "#define USE_SCULPT\n"
- "#define USE_GEOM_SHADER\n");
-
- e_data.face_wireframe_sculpt_pretty_sh = DRW_shader_create(
- datatoc_overlay_face_wireframe_vert_glsl,
- datatoc_overlay_face_wireframe_geom_glsl,
- datatoc_overlay_face_wireframe_frag_glsl,
- "#define USE_SCULPT\n"
- "#define USE_GEOM_SHADER\n"
- "#define LIGHT_EDGES\n");
+ "#define USE_SCULPT\n");
}
}
@@ -154,73 +130,68 @@ static void overlay_cache_init(void *vedata)
OVERLAY_Data *data = vedata;
OVERLAY_PassList *psl = data->psl;
OVERLAY_StorageList *stl = data->stl;
+ OVERLAY_PrivateData *g_data = stl->g_data;
const DRWContextState *DCS = DRW_context_state_get();
View3D *v3d = DCS->v3d;
if (v3d) {
- stl->g_data->overlay = v3d->overlay;
- stl->g_data->show_overlays = (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0;
+ g_data->overlay = v3d->overlay;
+ g_data->show_overlays = (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0;
}
else {
- memset(&stl->g_data->overlay, 0, sizeof(stl->g_data->overlay));
- stl->g_data->show_overlays = false;
+ memset(&g_data->overlay, 0, sizeof(g_data->overlay));
+ g_data->show_overlays = false;
}
- if (stl->g_data->show_overlays == false) {
- stl->g_data->overlay.flag = 0;
+ if (g_data->show_overlays == false) {
+ g_data->overlay.flag = 0;
}
if (v3d->shading.type == OB_WIRE) {
- stl->g_data->overlay.flag |= V3D_OVERLAY_WIREFRAMES;
- stl->g_data->show_overlays = true;
+ g_data->overlay.flag |= V3D_OVERLAY_WIREFRAMES;
+ g_data->show_overlays = true;
}
{
/* Face Orientation Pass */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND;
psl->face_orientation_pass = DRW_pass_create("Face Orientation", state);
- stl->g_data->face_orientation_shgrp = DRW_shgroup_create(
+ g_data->face_orientation_shgrp = DRW_shgroup_create(
e_data.face_orientation_sh, psl->face_orientation_pass);
}
{
/* Wireframe */
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND;
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND | DRW_STATE_FIRST_VERTEX_CONVENTION;
float wire_size = max_ff(0.0f, U.pixelsize - 1.0f) * 0.5f;
- psl->flat_wireframe_pass = DRW_pass_create("Flat Object Wires", state | DRW_STATE_WRITE_DEPTH);
+ const bool use_select = (DRW_state_is_select() || DRW_state_is_depth());
+ GPUShader *sculpt_wire_sh = use_select ? e_data.select_wireframe_sh : e_data.face_wireframe_sculpt_sh;
+ GPUShader *face_wires_sh = use_select ? e_data.select_wireframe_sh : e_data.face_wireframe_sh;
+ GPUShader *flat_wires_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ psl->face_wireframe_pass = DRW_pass_create("Face Wires", state);
- psl->face_wireframe_full_pass = DRW_pass_create("All Face Wires", state);
+ g_data->flat_wires = DRW_shgroup_create(flat_wires_sh, psl->face_wireframe_pass);
+ DRW_shgroup_uniform_vec4(g_data->flat_wires, "color", ts.colorWire, 1);
- stl->g_data->sculpt_wires_full = DRW_shgroup_create(e_data.face_wireframe_sculpt_sh, psl->face_wireframe_full_pass);
- DRW_shgroup_uniform_float_copy(stl->g_data->sculpt_wires_full, "wireSize", wire_size);
+ g_data->sculpt_wires = DRW_shgroup_create(sculpt_wire_sh, psl->face_wireframe_pass);
- DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.face_wireframe_sh, psl->face_wireframe_full_pass);
- DRW_shgroup_uniform_float_copy(shgrp, "wireSize", wire_size);
+ g_data->face_wires = DRW_shgroup_create(face_wires_sh, psl->face_wireframe_pass);
+ DRW_shgroup_uniform_vec2(g_data->face_wires, "wireStepParam", g_data->wire_step_param, 1);
- psl->face_wireframe_pass = DRW_pass_create("Face Wires", state);
+ if (!use_select) {
+ DRW_shgroup_uniform_float_copy(g_data->sculpt_wires, "wireSize", wire_size);
+ DRW_shgroup_uniform_float_copy(g_data->face_wires, "wireSize", wire_size);
+ }
- stl->g_data->sculpt_wires = DRW_shgroup_create(e_data.face_wireframe_sculpt_pretty_sh, psl->face_wireframe_pass);
- DRW_shgroup_uniform_vec2(stl->g_data->sculpt_wires, "wireStepParam", stl->g_data->wire_step_param, 1);
- DRW_shgroup_uniform_float_copy(stl->g_data->sculpt_wires, "wireSize", wire_size);
-
- shgrp = DRW_shgroup_create(e_data.face_wireframe_pretty_sh, psl->face_wireframe_pass);
- DRW_shgroup_uniform_vec2(shgrp, "wireStepParam", stl->g_data->wire_step_param, 1);
- DRW_shgroup_uniform_float_copy(shgrp, "wireSize", wire_size);
-
- /**
- * The wireframe threshold ranges from 0.0 to 1.0
- * When 1.0 we show all the edges, when 0.5 we show as many as 2.7.
- *
- * If we wanted 0.0 to match 2.7, factor would need to be 0.003f.
- * The range controls the falloff effect. If range was 0.0f we would get a hard cut (as in 2.7).
- * That said we are using a different algorithm so the results will always differ.
- */
- const float factor = 0.0045f;
- const float range = 0.00125f;
- stl->g_data->wire_step_param[1] = (1.0f - factor) + stl->g_data->overlay.wireframe_threshold * factor;
- stl->g_data->wire_step_param[0] = stl->g_data->wire_step_param[1] + range;
+ /* 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;
}
}
@@ -229,7 +200,6 @@ static void overlay_cache_populate(void *vedata, Object *ob)
OVERLAY_Data *data = vedata;
OVERLAY_StorageList *stl = data->stl;
OVERLAY_PrivateData *pd = stl->g_data;
- OVERLAY_PassList *psl = data->psl;
const DRWContextState *draw_ctx = DRW_context_state_get();
RegionView3D *rv3d = draw_ctx->rv3d;
View3D *v3d = draw_ctx->v3d;
@@ -281,64 +251,45 @@ static void overlay_cache_populate(void *vedata, Object *ob)
DRW_object_is_flat(ob, &flat_axis) &&
DRW_object_axis_orthogonal_to_view(ob, flat_axis);
- if (is_sculpt_mode) {
- shgrp = (all_wires || DRW_object_is_flat_normal(ob))
- ? stl->g_data->sculpt_wires_full
- : stl->g_data->sculpt_wires;
- if (is_wire) {
- shgrp = DRW_shgroup_create_sub(shgrp);
- }
- DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat);
- }
- else if (is_flat_object_viewed_from_side) {
+ 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_wire_outline_get(ob);
if (geom) {
- GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
- shgrp = DRW_shgroup_create(sh, psl->flat_wireframe_pass);
+ shgrp = DRW_shgroup_create_sub(shgrp);
DRW_shgroup_stencil_mask(shgrp, stencil_mask);
- DRW_shgroup_uniform_vec4(shgrp, "color", ts.colorWire, 1);
DRW_shgroup_call_object_add(shgrp, geom, ob);
}
}
else {
- /* Manually tweaked so the shader hidding matches. */
- const bool reduced_tri_len = (stl->g_data->wire_step_param[1] < 0.9988) && !all_wires;
- int tri_count;
- GPUTexture *verts = NULL, *faceids;
- DRW_cache_object_face_wireframe_get(ob, &verts, &faceids, &tri_count, reduced_tri_len);
- if (verts) {
+ struct GPUBatch *geom = DRW_cache_object_face_wireframe_get(ob);
+ if (geom || is_sculpt_mode) {
float *rim_col = ts.colorWire;
- if (!has_edit_mesh_cage && ((ob->base_flag & BASE_SELECTED) != 0)) {
+ if (!is_sculpt_mode && !has_edit_mesh_cage && ((ob->base_flag & BASE_SELECTED) != 0)) {
rim_col = (ob == draw_ctx->obact) ? ts.colorActive : ts.colorSelect;
}
- DRWPass *pass = (all_wires) ? psl->face_wireframe_full_pass : psl->face_wireframe_pass;
- GPUShader *sh = (all_wires) ? e_data.face_wireframe_sh : e_data.face_wireframe_pretty_sh;
+ shgrp = (is_sculpt_mode) ? pd->sculpt_wires : pd->face_wires;
+ shgrp = DRW_shgroup_create_sub(shgrp);
if ((DRW_state_is_select() || DRW_state_is_depth())) {
static float params[2] = {1.2f, 1.0f}; /* Parameters for all wires */
-
- sh = e_data.select_wireframe_sh;
- shgrp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_vec2(shgrp, "wireStepParam", (all_wires)
? params
: stl->g_data->wire_step_param, 1);
- DRW_shgroup_uniform_texture(shgrp, "vertData", verts);
- DRW_shgroup_uniform_texture(shgrp, "faceIds", faceids);
- DRW_shgroup_call_object_procedural_triangles_culled_add(shgrp, tri_count, ob);
}
else {
- shgrp = DRW_shgroup_create(sh, pass);
DRW_shgroup_stencil_mask(shgrp, stencil_mask);
- DRW_shgroup_uniform_texture(shgrp, "vertData", verts);
- DRW_shgroup_uniform_texture(shgrp, "faceIds", faceids);
DRW_shgroup_uniform_vec3(shgrp, "wireColor", ts.colorWire, 1);
DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1);
- DRW_shgroup_call_object_procedural_triangles_culled_add(shgrp, tri_count, ob);
+ }
+
+ 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) {
/* If object is wireframe, don't try to use stencil test. */
DRW_shgroup_state_disable(shgrp, DRW_STATE_STENCIL_EQUAL);
@@ -367,7 +318,6 @@ static void overlay_cache_finish(void *vedata)
if (v3d->shading.type == OB_SOLID && (v3d->shading.flag & XRAY_FLAG(v3d)) == 0) {
if (stl->g_data->ghost_stencil_test) {
DRW_pass_state_add(psl->face_wireframe_pass, DRW_STATE_STENCIL_EQUAL);
- DRW_pass_state_add(psl->face_wireframe_full_pass, DRW_STATE_STENCIL_EQUAL);
}
}
}
@@ -382,9 +332,7 @@ static void overlay_draw_scene(void *vedata)
GPU_framebuffer_bind(dfbl->default_fb);
}
DRW_draw_pass(psl->face_orientation_pass);
- DRW_draw_pass(psl->flat_wireframe_pass);
DRW_draw_pass(psl->face_wireframe_pass);
- DRW_draw_pass(psl->face_wireframe_full_pass);
}
static void overlay_engine_free(void)
@@ -392,9 +340,7 @@ static void overlay_engine_free(void)
DRW_SHADER_FREE_SAFE(e_data.face_orientation_sh);
DRW_SHADER_FREE_SAFE(e_data.select_wireframe_sh);
DRW_SHADER_FREE_SAFE(e_data.face_wireframe_sh);
- DRW_SHADER_FREE_SAFE(e_data.face_wireframe_pretty_sh);
DRW_SHADER_FREE_SAFE(e_data.face_wireframe_sculpt_sh);
- DRW_SHADER_FREE_SAFE(e_data.face_wireframe_sculpt_pretty_sh);
}
static const DrawEngineDataSize overlay_data_size = DRW_VIEWPORT_DATA_SIZE(OVERLAY_Data);
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 69af4858a48..cefd4eab2e3 100644
--- a/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl
+++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl
@@ -1,18 +1,12 @@
-#ifndef SELECT_EDGES
uniform vec3 wireColor;
uniform vec3 rimColor;
in float facing;
in vec3 barycentric;
-
-# ifdef LIGHT_EDGES
flat in vec3 edgeSharpness;
-# endif
out vec4 fragColor;
-#endif
-float min_v3(vec3 v) { return min(v.x, min(v.y, v.z)); }
float max_v3(vec3 v) { return max(v.x, max(v.y, v.z)); }
/* In pixels */
@@ -25,7 +19,6 @@ const float rim_alpha = 0.75;
void main()
{
-#ifndef SELECT_EDGES
vec3 dx = dFdx(barycentric);
vec3 dy = dFdy(barycentric);
vec3 d = vec3(
@@ -35,11 +28,7 @@ void main()
);
vec3 dist_to_edge = barycentric / d;
-# ifdef LIGHT_EDGES
vec3 fac = abs(dist_to_edge);
-# else
- float fac = min_v3(abs(dist_to_edge));
-# endif
fac = smoothstep(wireSize + wire_smooth, wireSize, fac);
@@ -48,10 +37,5 @@ void main()
vec3 final_front_col = mix(rimColor, wireColor, 0.05);
fragColor = mix(vec4(rimColor, rim_alpha), vec4(final_front_col, front_alpha), facing_clamped);
-# ifdef LIGHT_EDGES
fragColor.a *= max_v3(fac * edgeSharpness);
-# else
- fragColor.a *= fac;
-# endif
-#endif
}
diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl
index e0ec9563ef4..7a40dd59571 100644
--- a/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl
+++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl
@@ -1,6 +1,5 @@
-/* This shader is only used for intel GPU where the Geom shader is faster
- * than doing everything thrice in the vertex shader. */
+/* This shader is only used for edge selection & sculpt mode wires (because of indexed drawing). */
layout(triangles) in;
#ifdef SELECT_EDGES
@@ -9,125 +8,53 @@ layout(line_strip, max_vertices = 6) out;
layout(triangle_strip, max_vertices = 3) out;
#endif
-uniform vec2 wireStepParam;
-
-in vec2 ssPos[];
-in float facingOut[];
+in float facing_g[];
+in float edgeSharpness_g[];
#ifndef SELECT_EDGES
-out vec3 barycentric;
out float facing;
-#endif
-
-#ifdef LIGHT_EDGES
-in vec3 obPos[];
-in vec3 vNor[];
-in float forceEdge[];
-
-# ifndef SELECT_EDGES
+out vec3 barycentric;
flat out vec3 edgeSharpness;
-# endif
#endif
-#define NO_EDGE vec3(10000.0);
-
-vec3 get_edge_normal(vec3 n1, vec3 n2, vec3 edge)
-{
- edge = normalize(edge);
- vec3 n = n1 + n2;
- float p = dot(edge, n);
- return normalize(n - p * edge);
-}
-
-float get_edge_sharpness(vec3 fnor, vec3 vnor)
-{
- float sharpness = abs(dot(fnor, vnor));
- return smoothstep(wireStepParam.x, wireStepParam.y, sharpness);
-}
-
-vec3 get_barycentric(bvec3 do_edge, const int v)
-{
- int v_n = v;
- int v_n1 = (v + 1) % 3;
- int v_n2 = (v + 2) % 3;
- vec3 bary;
- bary[v_n] = do_edge[v_n] ? 0.0 : 1.0;
- bary[v_n1] = 1.0;
- bary[v_n2] = do_edge[v_n2] ? 0.0 : 1.0;
- return bary;
-}
-
void main(void)
{
- vec3 facings = vec3(facingOut[0], facingOut[1], facingOut[2]);
- bvec3 do_edge = greaterThan(abs(facings), vec3(1.0));
- facings = fract(facings) - clamp(-sign(facings), 0.0, 1.0);
-
-#ifdef SELECT_EDGES
- vec3 edgeSharpness;
-#endif
-
-#ifdef LIGHT_EDGES
- vec3 edges[3];
- edges[0] = obPos[1] - obPos[0];
- edges[1] = obPos[2] - obPos[1];
- edges[2] = obPos[0] - obPos[2];
- vec3 fnor = normalize(cross(edges[0], -edges[2]));
-
- edgeSharpness.x = get_edge_sharpness(fnor, get_edge_normal(vNor[0], vNor[1], edges[0]));
- edgeSharpness.y = get_edge_sharpness(fnor, get_edge_normal(vNor[1], vNor[2], edges[1]));
- edgeSharpness.z = get_edge_sharpness(fnor, get_edge_normal(vNor[2], vNor[0], edges[2]));
- edgeSharpness.x = (forceEdge[0] == 1.0) ? 1.0 : edgeSharpness.x;
- edgeSharpness.y = (forceEdge[1] == 1.0) ? 1.0 : edgeSharpness.y;
- edgeSharpness.z = (forceEdge[2] == 1.0) ? 1.0 : edgeSharpness.z;
-
- do_edge = greaterThan(edgeSharpness, vec3(0.005));
- if (!any(do_edge)) {
- /* Don't generate any fragment. */
- return;
- }
-#endif
-
#ifdef SELECT_EDGES
const float edge_select_threshold = 0.3;
- if (edgeSharpness.x > edge_select_threshold) {
- gl_Position = gl_in[0].gl_Position;
- EmitVertex();
- gl_Position = gl_in[1].gl_Position;
- EmitVertex();
+ if (edgeSharpness_g[0] > edge_select_threshold) {
+ gl_Position = gl_in[0].gl_Position; EmitVertex();
+ gl_Position = gl_in[1].gl_Position; EmitVertex();
EndPrimitive();
}
- if (edgeSharpness.y > edge_select_threshold) {
- gl_Position = gl_in[1].gl_Position;
- EmitVertex();
- gl_Position = gl_in[2].gl_Position;
- EmitVertex();
+ if (edgeSharpness_g[1] > edge_select_threshold) {
+ gl_Position = gl_in[1].gl_Position; EmitVertex();
+ gl_Position = gl_in[2].gl_Position; EmitVertex();
EndPrimitive();
}
- if (edgeSharpness.z > edge_select_threshold) {
- gl_Position = gl_in[2].gl_Position;
- EmitVertex();
- gl_Position = gl_in[0].gl_Position;
- EmitVertex();
+ if (edgeSharpness_g[2] > edge_select_threshold) {
+ gl_Position = gl_in[2].gl_Position; EmitVertex();
+ gl_Position = gl_in[0].gl_Position; EmitVertex();
EndPrimitive();
}
#else
- barycentric = get_barycentric(do_edge, 0);
+ edgeSharpness = vec3(edgeSharpness_g[0], edgeSharpness_g[1], edgeSharpness_g[2]);
+
+ barycentric = vec3(1.0, 0.0, 0.0);
gl_Position = gl_in[0].gl_Position;
- facing = facings.x;
+ facing = facing_g[0];
EmitVertex();
- barycentric = get_barycentric(do_edge, 1);
+ barycentric = vec3(0.0, 1.0, 0.0);
gl_Position = gl_in[1].gl_Position;
- facing = facings.y;
+ facing = facing_g[1];
EmitVertex();
- barycentric = get_barycentric(do_edge, 2);
+ barycentric = vec3(0.0, 0.0, 1.0);
gl_Position = gl_in[2].gl_Position;
- facing = facings.z;
+ facing = facing_g[2];
EmitVertex();
EndPrimitive();
-#endif
+#endif /* SELECT_EDGES */
}
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 ca077f29abd..d5c2bdeefea 100644
--- a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
+++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
@@ -1,181 +1,81 @@
uniform mat4 ModelViewProjectionMatrix;
-uniform mat4 ModelViewMatrix;
-uniform mat4 ProjectionMatrix;
uniform mat3 NormalMatrix;
uniform vec2 wireStepParam;
-uniform float nearDist;
-uniform samplerBuffer vertData;
-uniform usamplerBuffer faceIds;
-
-#ifdef USE_SCULPT
-in vec3 pos;
-in vec3 nor;
-#endif
-
-float short_to_unit_float(uint s)
+vec3 get_edge_sharpness(vec3 wd)
{
- int value = int(s) & 0x7FFF;
- if ((s & 0x8000u) != 0u) {
- value |= ~0x7FFF;
- }
- return float(value) / float(0x7FFF);
+ 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);
}
-vec3 get_vertex_nor(uint id)
+float get_edge_sharpness(float wd)
{
- int v_id = int(id) * 5; /* See vertex format for explanation. */
- /* Fetch compressed normal as float and unpack them. */
- vec2 data;
- data.x = texelFetch(vertData, v_id + 3).r;
- data.y = texelFetch(vertData, v_id + 4).r;
-
- uvec2 udata = floatBitsToUint(data);
-
- vec3 nor;
- nor.x = short_to_unit_float(udata.x & 0xFFFFu);
- nor.y = short_to_unit_float(udata.x >> 16u);
- nor.z = short_to_unit_float(udata.y & 0xFFFFu);
- return nor;
+ 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);
}
-vec3 get_vertex_pos(uint id)
-{
- int v_id = int(id) * 5; /* See vertex format for explanation. */
- vec3 pos;
- pos.x = texelFetch(vertData, v_id).r;
- pos.y = texelFetch(vertData, v_id + 1).r;
- pos.z = texelFetch(vertData, v_id + 2).r;
- return pos;
-}
+/* Geometry shader version */
+#if defined(SELECT_EDGES) || defined(USE_SCULPT)
-vec3 get_edge_normal(vec3 n1, vec3 n2, vec3 edge)
-{
- edge = normalize(edge);
- vec3 n = n1 + n2;
- float p = dot(edge, n);
- return normalize(n - p * edge);
-}
-
-float get_edge_sharpness(vec3 fnor, vec3 vnor)
-{
- float sharpness = abs(dot(fnor, vnor));
- return smoothstep(wireStepParam.x, wireStepParam.y, sharpness);
-}
-
-#ifdef USE_GEOM_SHADER
+in vec3 pos;
+in vec3 nor;
+in float wd; /* wiredata */
-# ifdef LIGHT_EDGES
-out vec3 obPos;
-out vec3 vNor;
-out float forceEdge;
-# endif
-out float facingOut; /* abs(facing) > 1.0 if we do edge */
+out float facing_g;
+out float edgeSharpness_g;
void main()
{
# ifndef USE_SCULPT
- uint v_id = texelFetch(faceIds, gl_VertexID).r;
-
- bool do_edge = (v_id & (1u << 30u)) != 0u;
- bool force_edge = (v_id & (1u << 31u)) != 0u;
- v_id = (v_id << 2u) >> 2u;
-
- vec3 pos = get_vertex_pos(v_id);
- vec3 nor = get_vertex_nor(v_id);
+ edgeSharpness_g = get_edge_sharpness(wd);
# else
- const bool do_edge = true;
- const bool force_edge = false;
+ /* TODO approximation using normals. */
+ edgeSharpness_g = 1.0;
# endif
- facingOut = normalize(NormalMatrix * nor).z;
- facingOut += (do_edge) ? ((facingOut > 0.0) ? 2.0 : -2.0) : 0.0;
-
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
-# ifdef LIGHT_EDGES
- obPos = pos;
- vNor = nor;
- forceEdge = float(force_edge); /* meh, could try to also encode it in facingOut */
-# endif
+ facing_g = normalize(NormalMatrix * nor).z;
}
-#else /* USE_GEOM_SHADER */
+#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 nor;
-# ifdef LIGHT_EDGES
-flat out vec3 edgeSharpness;
-# endif
out float facing;
out vec3 barycentric;
+flat out vec3 edgeSharpness;
void main()
{
- int v_0 = (gl_VertexID / 3) * 3;
int v_n = gl_VertexID % 3;
- int v_n1 = (gl_VertexID + 1) % 3;
- int v_n2 = (gl_VertexID + 2) % 3;
-
- /* Getting the same positions for each of the 3 verts. */
- uvec3 v_id;
- v_id.x = texelFetch(faceIds, v_0).r;
- v_id.y = texelFetch(faceIds, v_0 + 1).r;
- v_id.z = texelFetch(faceIds, v_0 + 2).r;
-
- bvec3 do_edge, force_edge;
- do_edge.x = (v_id.x & (1u << 30u)) != 0u;
- do_edge.y = (v_id.y & (1u << 30u)) != 0u;
- do_edge.z = (v_id.z & (1u << 30u)) != 0u;
- force_edge.x = (v_id.x & (1u << 31u)) != 0u;
- force_edge.y = (v_id.y & (1u << 31u)) != 0u;
- force_edge.z = (v_id.z & (1u << 31u)) != 0u;
- v_id = (v_id << 2u) >> 2u;
-
- vec3 pos[3];
- vec4 p_pos[3];
-
- pos[v_n] = get_vertex_pos(v_id[v_n]);
- gl_Position = p_pos[v_n] = ModelViewProjectionMatrix * vec4(pos[v_n], 1.0);
-
- bvec3 bary = equal(ivec3(0, 1, 2), ivec3(v_n1));
- /* This is equivalent to component wise : (do_edge ? bary : 1.0) */
- barycentric = vec3(lessThanEqual(ivec3(do_edge), ivec3(bary)));
-
-# ifndef LIGHT_EDGES
- vec3 nor = get_vertex_nor(v_id[v_n]);
-# else
- pos[v_n1] = get_vertex_pos(v_id[v_n1]);
- pos[v_n2] = get_vertex_pos(v_id[v_n2]);
-
- vec3 edges[3];
- edges[0] = pos[1] - pos[0];
- edges[1] = pos[2] - pos[1];
- edges[2] = pos[0] - pos[2];
- vec3 fnor = normalize(cross(edges[0], -edges[2]));
-
- vec3 nors[3];
- nors[0] = get_vertex_nor(v_id.x);
- nors[1] = get_vertex_nor(v_id.y);
- nors[2] = get_vertex_nor(v_id.z);
- edgeSharpness.x = get_edge_sharpness(fnor, get_edge_normal(nors[0], nors[1], edges[0]));
- edgeSharpness.y = get_edge_sharpness(fnor, get_edge_normal(nors[1], nors[2], edges[1]));
- edgeSharpness.z = get_edge_sharpness(fnor, get_edge_normal(nors[2], nors[0], edges[2]));
- edgeSharpness.x = force_edge.x ? 1.0 : edgeSharpness.x;
- edgeSharpness.y = force_edge.y ? 1.0 : edgeSharpness.y;
- edgeSharpness.z = force_edge.z ? 1.0 : edgeSharpness.z;
-
- do_edge = greaterThan(edgeSharpness, vec3(0.01));
- if (!any(do_edge)) {
- /* Don't generate any fragment. */
- gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
- }
-
- vec3 nor = nors[v_n];
-# endif
+ 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);
facing = normalize(NormalMatrix * nor).z;
}
-#endif /* USE_GEOM_SHADER */
+#endif /* SELECT_EDGES */