diff options
-rw-r--r-- | source/blender/draw/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 45 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.h | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl.h | 29 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_curve.c | 901 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_displist.c | 36 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_mesh.c | 34 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_metaball.c | 6 | ||||
-rw-r--r-- | source/blender/draw/modes/edit_curve_mode.c | 22 | ||||
-rw-r--r-- | source/blender/draw/modes/shaders/edit_curve_overlay_normals_vert.glsl | 23 |
10 files changed, 499 insertions, 600 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 286cf9753e7..4fcd43dc2a8 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -281,6 +281,7 @@ data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_frag.glsl SRC) data_to_c_simple(modes/shaders/edit_curve_overlay_handle_vert.glsl SRC) data_to_c_simple(modes/shaders/edit_curve_overlay_handle_geom.glsl SRC) data_to_c_simple(modes/shaders/edit_curve_overlay_loosevert_vert.glsl SRC) +data_to_c_simple(modes/shaders/edit_curve_overlay_normals_vert.glsl SRC) data_to_c_simple(modes/shaders/edit_lattice_overlay_frag.glsl SRC) data_to_c_simple(modes/shaders/edit_lattice_overlay_loosevert_vert.glsl SRC) data_to_c_simple(modes/shaders/edit_normals_vert.glsl SRC) diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 39e4ecf0520..3e49d890327 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -3195,15 +3195,15 @@ GPUBatch *DRW_cache_curve_edge_wire_get(Object *ob) BLI_assert(ob->type == OB_CURVE); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_wire_edge(cu, ob->runtime.curve_cache); + return DRW_curve_batch_cache_get_wire_edge(cu); } -GPUBatch *DRW_cache_curve_edge_normal_get(Object *ob, float normal_size) +GPUBatch *DRW_cache_curve_edge_normal_get(Object *ob) { BLI_assert(ob->type == OB_CURVE); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_normal_edge(cu, ob->runtime.curve_cache, normal_size); + return DRW_curve_batch_cache_get_normal_edge(cu); } GPUBatch *DRW_cache_curve_edge_overlay_get(Object *ob) @@ -3227,7 +3227,7 @@ GPUBatch *DRW_cache_curve_surface_get(Object *ob) BLI_assert(ob->type == OB_CURVE); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->runtime.curve_cache); + return DRW_curve_batch_cache_get_triangles_with_normals(cu); } GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob) @@ -3235,7 +3235,7 @@ GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob) BLI_assert(ob->type == OB_CURVE); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_wireframes_face(cu, ob->runtime.curve_cache); + return DRW_curve_batch_cache_get_wireframes_face(cu); } /* Return list of batches */ @@ -3245,7 +3245,7 @@ GPUBatch **DRW_cache_curve_surface_shaded_get( BLI_assert(ob->type == OB_CURVE); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_surface_shaded(cu, ob->runtime.curve_cache, gpumat_array, gpumat_array_len); + return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); } /** \} */ @@ -3287,7 +3287,7 @@ GPUBatch *DRW_cache_text_edge_wire_get(Object *ob) BLI_assert(ob->type == OB_FONT); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_wire_edge(cu, ob->runtime.curve_cache); + return DRW_curve_batch_cache_get_wire_edge(cu); } GPUBatch *DRW_cache_text_surface_get(Object *ob) @@ -3297,7 +3297,7 @@ GPUBatch *DRW_cache_text_surface_get(Object *ob) if (cu->editfont && (cu->flag & CU_FAST)) { return NULL; } - return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->runtime.curve_cache); + return DRW_curve_batch_cache_get_triangles_with_normals(cu); } GPUBatch *DRW_cache_text_face_wireframe_get(Object *ob) @@ -3307,7 +3307,7 @@ GPUBatch *DRW_cache_text_face_wireframe_get(Object *ob) if (cu->editfont && (cu->flag & CU_FAST)) { return NULL; } - return DRW_curve_batch_cache_get_wireframes_face(cu, ob->runtime.curve_cache); + return DRW_curve_batch_cache_get_wireframes_face(cu); } GPUBatch **DRW_cache_text_surface_shaded_get( @@ -3318,21 +3318,7 @@ GPUBatch **DRW_cache_text_surface_shaded_get( if (cu->editfont && (cu->flag & CU_FAST)) { return NULL; } - return DRW_curve_batch_cache_get_surface_shaded(cu, ob->runtime.curve_cache, gpumat_array, gpumat_array_len); -} - -GPUBatch *DRW_cache_text_cursor_overlay_get(Object *ob) -{ - BLI_assert(ob->type == OB_FONT); - struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_edit_cursor(cu); -} - -GPUBatch *DRW_cache_text_select_overlay_get(Object *ob) -{ - BLI_assert(ob->type == OB_FONT); - struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_edit_select(cu); + return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); } /** \} */ @@ -3347,7 +3333,7 @@ GPUBatch *DRW_cache_surf_surface_get(Object *ob) BLI_assert(ob->type == OB_SURF); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->runtime.curve_cache); + return DRW_curve_batch_cache_get_triangles_with_normals(cu); } GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob) @@ -3355,7 +3341,7 @@ GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob) BLI_assert(ob->type == OB_SURF); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_wireframes_face(cu, ob->runtime.curve_cache); + return DRW_curve_batch_cache_get_wireframes_face(cu); } /* Return list of batches */ @@ -3365,7 +3351,7 @@ GPUBatch **DRW_cache_surf_surface_shaded_get( BLI_assert(ob->type == OB_SURF); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_surface_shaded(cu, ob->runtime.curve_cache, gpumat_array, gpumat_array_len); + return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); } /** \} */ @@ -3748,6 +3734,11 @@ void drw_batch_cache_generate_requested(Object *ob) case OB_MESH: DRW_mesh_batch_cache_create_requested(ob); break; + case OB_CURVE: + case OB_FONT: + case OB_SURF: + DRW_curve_batch_cache_create_requested(ob); + break; /* TODO all cases */ default: break; diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 20f92cdd526..39743b705ae 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -156,7 +156,7 @@ struct GPUBatch *DRW_cache_curve_surface_verts_get(struct Object *ob); struct GPUBatch *DRW_cache_curve_edge_wire_get(struct Object *ob); 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_normal_get(struct Object *ob); struct GPUBatch *DRW_cache_curve_edge_overlay_get(struct Object *ob); struct GPUBatch *DRW_cache_curve_vert_overlay_get(struct Object *ob, bool handles); diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index a22d05fa20f..6df7a896ffa 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -64,36 +64,31 @@ void DRW_gpencil_batch_cache_dirty_tag(struct bGPdata *gpd); void DRW_gpencil_batch_cache_free(struct bGPdata *gpd); /* Curve */ -struct GPUBatch *DRW_curve_batch_cache_get_wire_edge(struct Curve *cu, struct CurveCache *ob_curve_cache); -struct GPUBatch *DRW_curve_batch_cache_get_normal_edge( - struct Curve *cu, struct CurveCache *ob_curve_cache, float normal_size); +void DRW_curve_batch_cache_create_requested(struct Object *ob); + +struct GPUBatch *DRW_curve_batch_cache_get_wire_edge(struct Curve *cu); +struct GPUBatch *DRW_curve_batch_cache_get_normal_edge(struct Curve *cu); struct GPUBatch *DRW_curve_batch_cache_get_edit_edges(struct Curve *cu); struct GPUBatch *DRW_curve_batch_cache_get_edit_verts(struct Curve *cu, bool handles); -struct GPUBatch *DRW_curve_batch_cache_get_triangles_with_normals( - struct Curve *cu, struct CurveCache *ob_curve_cache); +struct GPUBatch *DRW_curve_batch_cache_get_triangles_with_normals(struct Curve *cu); 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); -struct GPUBatch *DRW_curve_batch_cache_get_wireframes_face(struct Curve *cu, struct CurveCache *ob_curve_cache); + struct Curve *cu, struct GPUMaterial **gpumat_array, uint gpumat_array_len); +struct GPUBatch *DRW_curve_batch_cache_get_wireframes_face(struct Curve *cu); /* 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); struct GPUBatch *DRW_metaball_batch_cache_get_wireframes_face(struct Object *ob); -/* Curve (Font) */ -struct GPUBatch *DRW_curve_batch_cache_get_edit_cursor(struct Curve *cu); -struct GPUBatch *DRW_curve_batch_cache_get_edit_select(struct Curve *cu); - /* DispList */ -struct GPUVertBuf *DRW_displist_vertbuf_calc_pos_with_normals(struct ListBase *lb); -struct GPUIndexBuf *DRW_displist_indexbuf_calc_triangles_in_order(struct ListBase *lb); +struct GPUVertBuf *DRW_displist_vertbuf_calc_pos_with_normals(struct ListBase *lb, struct GPUVertBuf *vbo); +struct GPUIndexBuf *DRW_displist_indexbuf_calc_triangles_in_order(struct ListBase *lb, struct GPUIndexBuf *vbo); struct GPUIndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_material( 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 GPUBatch *DRW_displist_create_edges_overlay_batch(ListBase *lb); +struct GPUBatch *DRW_displist_create_edges_overlay_batch(ListBase *lb, struct GPUVertBuf *vbo); /* Lattice */ struct GPUBatch *DRW_lattice_batch_cache_get_all_edges(struct Lattice *lt, bool use_weight, const int actdef); @@ -219,6 +214,10 @@ struct GPUBatch *DRW_particles_batch_cache_get_edit_tip_points( #define DRW_ADD_FLAG_FROM_VBO_REQUEST(flag, vbo, value) (flag |= DRW_vbo_requested(vbo) ? value : 0) #define DRW_ADD_FLAG_FROM_IBO_REQUEST(flag, ibo, value) (flag |= DRW_ibo_requested(ibo) ? value : 0) +/* Test and assign NULL if test fails */ +#define DRW_TEST_ASSIGN_VBO(v) (v = (DRW_vbo_requested(v) ? v : NULL)) +#define DRW_TEST_ASSIGN_IBO(v) (v = (DRW_ibo_requested(v) ? v : NULL)) + struct GPUBatch *DRW_batch_request(struct GPUBatch **batch); bool DRW_batch_requested(struct GPUBatch *batch, int prim_type); void DRW_ibo_request(struct GPUBatch *batch, struct GPUIndexBuf **ibo); diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.c index 3133a1d06d2..ac991336e05 100644 --- a/source/blender/draw/intern/draw_cache_impl_curve.c +++ b/source/blender/draw/intern/draw_cache_impl_curve.c @@ -99,14 +99,17 @@ static void curve_render_overlay_verts_edges_len_get( static void curve_render_wire_verts_edges_len_get( const CurveCache *ob_curve_cache, - int *r_vert_len, int *r_edge_len) + int *r_curve_len, int *r_vert_len, int *r_edge_len) { BLI_assert(r_vert_len || r_edge_len); int vert_len = 0; int edge_len = 0; + *r_curve_len = 0; for (const BevList *bl = ob_curve_cache->bev.first; bl; bl = bl->next) { if (bl->nr > 0) { const bool is_cyclic = bl->poly != -1; + /* Curve */ + *r_curve_len += 1; /* verts */ vert_len += bl->nr; @@ -159,6 +162,7 @@ typedef struct CurveRenderData { } overlay; struct { + int curve_len; int vert_len; int edge_len; } wire; @@ -216,7 +220,7 @@ static CurveRenderData *curve_render_data_create(Curve *cu, CurveCache *ob_curve if (types & CU_DATATYPE_WIRE) { curve_render_wire_verts_edges_len_get( rdata->ob_curve_cache, - &rdata->wire.vert_len, &rdata->wire.edge_len); + &rdata->wire.curve_len, &rdata->wire.vert_len, &rdata->wire.edge_len); } if (cu->editnurb) { @@ -281,6 +285,12 @@ static int curve_render_data_wire_edges_len_get(const CurveRenderData *rdata) return rdata->wire.edge_len; } +static int curve_render_data_wire_curve_len_get(const CurveRenderData *rdata) +{ + BLI_assert(rdata->types & CU_DATATYPE_WIRE); + return rdata->wire.curve_len; +} + static int curve_render_data_normal_len_get(const CurveRenderData *rdata) { BLI_assert(rdata->types & CU_DATATYPE_NORMAL); @@ -292,53 +302,53 @@ static int curve_render_data_normal_len_get(const CurveRenderData *rdata) /* Curve GPUBatch Cache */ typedef struct CurveBatchCache { - /* center-line */ struct { - GPUVertBuf *verts; - GPUVertBuf *edges; - GPUBatch *batch; - GPUIndexBuf *elem; - } wire; + /* Split by normals if necessary. */ + GPUVertBuf *pos_nor; + GPUVertBuf *curves_pos; + } ordered; - /* normals */ struct { - GPUVertBuf *verts; - GPUVertBuf *edges; - GPUBatch *batch; - GPUIndexBuf *elem; - } normal; + GPUVertBuf *pos_nor; - /* control handles and vertices */ - struct { - GPUBatch *edges; - GPUBatch *verts; - GPUBatch *verts_no_handles; - } overlay; + GPUVertBuf *wireframe_data; + } tess; struct { - GPUVertBuf *verts; - GPUIndexBuf *triangles_in_order; - GPUBatch **shaded_triangles; - GPUBatch *batch; - int mat_len; - } surface; - - /* Wireframes */ + /* Curve points. Aligned with ordered.pos_nor */ + GPUVertBuf *curves_nor; + GPUVertBuf *curves_weight; /* TODO. */ + /* Edit points (beztriples and bpoints) */ + GPUVertBuf *pos; + GPUVertBuf *data; + } edit; + struct { - GPUBatch *batch; - } face_wire; + GPUIndexBuf *surfaces_tris; + GPUIndexBuf *curves_lines; + /* Edit mode */ + GPUIndexBuf *edit_verts_points; /* Only control points. Not handles. */ + GPUIndexBuf *edit_lines; + } ibo; - /* 3d text */ struct { - GPUBatch *select; - GPUBatch *cursor; - } text; + GPUBatch *surfaces; + GPUBatch *curves; + /* control handles and vertices */ + GPUBatch *edit_edges; + GPUBatch *edit_verts; + GPUBatch *edit_handles_verts; + GPUBatch *edit_normals; + /* Triangles for object mode wireframe. */ + GPUBatch *wire_triangles; + } batch; + + GPUIndexBuf **surf_per_mat_tris; + GPUBatch **surf_per_mat; + int mat_len; /* settings to determine if cache is invalid */ bool is_dirty; - - float normal_size; - bool is_editmode; } CurveBatchCache; @@ -416,14 +426,11 @@ void DRW_curve_batch_cache_dirty_tag(Curve *cu, int mode) cache->is_dirty = true; break; case BKE_CURVE_BATCH_DIRTY_SELECT: - /* editnurb */ - GPU_BATCH_DISCARD_SAFE(cache->overlay.verts_no_handles); - GPU_BATCH_DISCARD_SAFE(cache->overlay.verts); - GPU_BATCH_DISCARD_SAFE(cache->overlay.edges); - - /* editfont */ - GPU_BATCH_DISCARD_SAFE(cache->text.select); - GPU_BATCH_DISCARD_SAFE(cache->text.cursor); + GPU_VERTBUF_DISCARD_SAFE(cache->edit.data); + + GPU_BATCH_DISCARD_SAFE(cache->batch.edit_edges); + GPU_BATCH_DISCARD_SAFE(cache->batch.edit_verts); + GPU_BATCH_DISCARD_SAFE(cache->batch.edit_handles_verts); break; default: BLI_assert(0); @@ -437,33 +444,34 @@ static void curve_batch_cache_clear(Curve *cu) return; } - GPU_BATCH_DISCARD_SAFE(cache->overlay.verts_no_handles); - GPU_BATCH_DISCARD_SAFE(cache->overlay.verts); - GPU_BATCH_DISCARD_SAFE(cache->overlay.edges); - - GPU_VERTBUF_DISCARD_SAFE(cache->surface.verts); - GPU_INDEXBUF_DISCARD_SAFE(cache->surface.triangles_in_order); - - GPU_BATCH_DISCARD_ARRAY_SAFE(cache->surface.shaded_triangles, cache->surface.mat_len); - GPU_BATCH_DISCARD_SAFE(cache->surface.batch); - - GPU_BATCH_DISCARD_SAFE(cache->face_wire.batch); - - /* don't own vbo & elems */ - GPU_BATCH_DISCARD_SAFE(cache->wire.batch); - GPU_VERTBUF_DISCARD_SAFE(cache->wire.verts); - GPU_VERTBUF_DISCARD_SAFE(cache->wire.edges); - GPU_INDEXBUF_DISCARD_SAFE(cache->wire.elem); - - /* don't own vbo & elems */ - GPU_BATCH_DISCARD_SAFE(cache->normal.batch); - GPU_VERTBUF_DISCARD_SAFE(cache->normal.verts); - GPU_VERTBUF_DISCARD_SAFE(cache->normal.edges); - GPU_INDEXBUF_DISCARD_SAFE(cache->normal.elem); + for (int i = 0; i < sizeof(cache->ordered) / sizeof(void *); ++i) { + GPUVertBuf **vbo = (GPUVertBuf **)&cache->ordered; + GPU_VERTBUF_DISCARD_SAFE(vbo[i]); + } + for (int i = 0; i < sizeof(cache->tess) / sizeof(void *); ++i) { + GPUVertBuf **vbo = (GPUVertBuf **)&cache->tess; + GPU_VERTBUF_DISCARD_SAFE(vbo[i]); + } + for (int i = 0; i < sizeof(cache->edit) / sizeof(void *); ++i) { + GPUVertBuf **vbo = (GPUVertBuf **)&cache->edit; + GPU_VERTBUF_DISCARD_SAFE(vbo[i]); + } + for (int i = 0; i < sizeof(cache->ibo) / sizeof(void *); ++i) { + GPUIndexBuf **ibo = (GPUIndexBuf **)&cache->ibo; + GPU_INDEXBUF_DISCARD_SAFE(ibo[i]); + } + for (int i = 0; i < sizeof(cache->batch) / sizeof(void *); ++i) { + GPUBatch **batch = (GPUBatch **)&cache->batch; + GPU_BATCH_DISCARD_SAFE(batch[i]); + } - /* 3d text */ - GPU_BATCH_DISCARD_SAFE(cache->text.cursor); - GPU_BATCH_DISCARD_SAFE(cache->text.select); + for (int i = 0; i < cache->mat_len; ++i) { + GPU_INDEXBUF_DISCARD_SAFE(cache->surf_per_mat_tris[i]); + GPU_BATCH_DISCARD_SAFE(cache->surf_per_mat[i]); + } + MEM_SAFE_FREE(cache->surf_per_mat_tris); + MEM_SAFE_FREE(cache->surf_per_mat); + cache->mat_len = 0; } void DRW_curve_batch_cache_free(Curve *cu) @@ -478,426 +486,258 @@ void DRW_curve_batch_cache_free(Curve *cu) * \{ */ /* GPUBatch cache usage. */ -static GPUVertBuf *curve_batch_cache_get_wire_verts(CurveRenderData *rdata, CurveBatchCache *cache) +static void curve_create_curves_pos(CurveRenderData *rdata, GPUVertBuf *vbo_curves_pos) { - BLI_assert(rdata->types & CU_DATATYPE_WIRE); BLI_assert(rdata->ob_curve_cache != NULL); - if (cache->wire.verts == NULL) { - static GPUVertFormat format = { 0 }; - static struct { uint pos; } attr_id; - if (format.attr_len == 0) { - /* initialize vertex format */ - attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - } + static GPUVertFormat format = { 0 }; + static struct { uint pos; } attr_id; + if (format.attr_len == 0) { + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + } - const int vert_len = curve_render_data_wire_verts_len_get(rdata); + const int vert_len = curve_render_data_wire_verts_len_get(rdata); + GPU_vertbuf_init_with_format(vbo_curves_pos, &format); + GPU_vertbuf_data_alloc(vbo_curves_pos, vert_len); - GPUVertBuf *vbo = cache->wire.verts = GPU_vertbuf_create_with_format(&format); - GPU_vertbuf_data_alloc(vbo, vert_len); - int vbo_len_used = 0; - for (const BevList *bl = rdata->ob_curve_cache->bev.first; bl; bl = bl->next) { - if (bl->nr > 0) { - const int i_end = vbo_len_used + bl->nr; - for (const BevPoint *bevp = bl->bevpoints; vbo_len_used < i_end; vbo_len_used++, bevp++) { - GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bevp->vec); - } - } + int v_idx = 0; + for (const BevList *bl = rdata->ob_curve_cache->bev.first; bl; bl = bl->next) { + if (bl->nr <= 0) { + continue; + } + const int i_end = v_idx + bl->nr; + for (const BevPoint *bevp = bl->bevpoints; v_idx < i_end; v_idx++, bevp++) { + GPU_vertbuf_attr_set(vbo_curves_pos, attr_id.pos, v_idx, bevp->vec); } - BLI_assert(vbo_len_used == vert_len); } - - return cache->wire.verts; + BLI_assert(v_idx == vert_len); } -static GPUIndexBuf *curve_batch_cache_get_wire_edges(CurveRenderData *rdata, CurveBatchCache *cache) +static void curve_create_curves_lines(CurveRenderData *rdata, GPUIndexBuf *ibo_curve_lines) { - BLI_assert(rdata->types & CU_DATATYPE_WIRE); BLI_assert(rdata->ob_curve_cache != NULL); - if (cache->wire.edges == NULL) { - const int vert_len = curve_render_data_wire_verts_len_get(rdata); - const int edge_len = curve_render_data_wire_edges_len_get(rdata); - int edge_len_used = 0; - - GPUIndexBufBuilder elb; - GPU_indexbuf_init(&elb, GPU_PRIM_LINES, edge_len, vert_len); - - int i = 0; - for (const BevList *bl = rdata->ob_curve_cache->bev.first; bl; bl = bl->next) { - if (bl->nr > 0) { - const bool is_cyclic = bl->poly != -1; - const int i_end = i + (bl->nr); - int i_prev; - if (is_cyclic) { - i_prev = i + (bl->nr - 1); - } - else { - i_prev = i; - i += 1; - } - for (; i < i_end; i_prev = i++) { - GPU_indexbuf_add_line_verts(&elb, i_prev, i); - edge_len_used += 1; - } - } + const int vert_len = curve_render_data_wire_verts_len_get(rdata); + const int edge_len = curve_render_data_wire_edges_len_get(rdata); + const int curve_len = curve_render_data_wire_curve_len_get(rdata); + /* Count the last vertex or each strip and the primitive restart. */ + const int index_len = edge_len + curve_len * 2; + + GPUIndexBufBuilder elb; + GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINE_STRIP, index_len, vert_len, true); + + int v_idx = 0; + for (const BevList *bl = rdata->ob_curve_cache->bev.first; bl; bl = bl->next) { + if (bl->nr <= 0) { + continue; + } + const bool is_cyclic = bl->poly != -1; + if (is_cyclic) { + GPU_indexbuf_add_generic_vert(&elb, v_idx + (bl->nr - 1)); + } + for (int i = 0; i < bl->nr; i++) { + GPU_indexbuf_add_generic_vert(&elb, v_idx + i); } - cache->wire.elem = GPU_indexbuf_build(&elb); + GPU_indexbuf_add_primitive_restart(&elb); + v_idx += bl->nr; } - return cache->wire.elem; + GPU_indexbuf_build_in_place(&elb, ibo_curve_lines); } -static GPUVertBuf *curve_batch_cache_get_normal_verts(CurveRenderData *rdata, CurveBatchCache *cache) +static void curve_create_edit_curves_nor(CurveRenderData *rdata, GPUVertBuf *vbo_curves_nor) { - BLI_assert(rdata->types & CU_DATATYPE_NORMAL); - BLI_assert(rdata->ob_curve_cache != NULL); - - if (cache->normal.verts == NULL) { - static GPUVertFormat format = { 0 }; - static struct { uint pos; } attr_id; - if (format.attr_len == 0) { - /* initialize vertex format */ - attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - } - - const int normal_len = curve_render_data_normal_len_get(rdata); - const int vert_len = normal_len * 3; - - GPUVertBuf *vbo = cache->normal.verts = GPU_vertbuf_create_with_format(&format); - GPU_vertbuf_data_alloc(vbo, vert_len); - int vbo_len_used = 0; + static GPUVertFormat format = { 0 }; + static struct { uint pos, nor, tan, rad; } attr_id; + if (format.attr_len == 0) { + /* initialize vertex formats */ + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.rad = GPU_vertformat_attr_add(&format, "rad", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); + attr_id.tan = GPU_vertformat_attr_add(&format, "tan", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); + } - const BevList *bl; - const Nurb *nu; + int verts_len_capacity = curve_render_data_normal_len_get(rdata) * 2; + int vbo_len_used = 0; - for (bl = rdata->ob_curve_cache->bev.first, nu = rdata->nurbs->first; - nu && bl; - bl = bl->next, nu = nu->next) - { - const BevPoint *bevp = bl->bevpoints; - int nr = bl->nr; - int skip = nu->resolu / 16; + GPU_vertbuf_init_with_format(vbo_curves_nor, &format); + GPU_vertbuf_data_alloc(vbo_curves_nor, verts_len_capacity); - while (nr-- > 0) { /* accounts for empty bevel lists */ - const float fac = bevp->radius * cache->normal_size; - float vec_a[3]; /* Offset perpendicular to the curve */ - float vec_b[3]; /* Delta along the curve */ + const BevList *bl; + const Nurb *nu; - vec_a[0] = fac; - vec_a[1] = 0.0f; - vec_a[2] = 0.0f; + for (bl = rdata->ob_curve_cache->bev.first, nu = rdata->nurbs->first; + nu && bl; + bl = bl->next, nu = nu->next) + { + const BevPoint *bevp = bl->bevpoints; + int nr = bl->nr; + int skip = nu->resolu / 16; - mul_qt_v3(bevp->quat, vec_a); - madd_v3_v3fl(vec_a, bevp->dir, -fac); + while (nr-- > 0) { /* accounts for empty bevel lists */ + float nor[3] = {1.0f, 0.0f, 0.0f}; + mul_qt_v3(bevp->quat, nor); - reflect_v3_v3v3(vec_b, vec_a, bevp->dir); - negate_v3(vec_b); + GPUPackedNormal pnor = GPU_normal_convert_i10_v3(nor); + GPUPackedNormal ptan = GPU_normal_convert_i10_v3(bevp->dir); - add_v3_v3(vec_a, bevp->vec); - add_v3_v3(vec_b, bevp->vec); + /* Only set attribs for one vertex. */ + GPU_vertbuf_attr_set(vbo_curves_nor, attr_id.pos, vbo_len_used, bevp->vec); + GPU_vertbuf_attr_set(vbo_curves_nor, attr_id.rad, vbo_len_used, &bevp->radius); + GPU_vertbuf_attr_set(vbo_curves_nor, attr_id.nor, vbo_len_used, &pnor); + GPU_vertbuf_attr_set(vbo_curves_nor, attr_id.tan, vbo_len_used, &ptan); + vbo_len_used++; - GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, vec_a); - GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, bevp->vec); - GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, vec_b); + /* Skip the other vertex (it does not need to be offseted). */ + GPU_vertbuf_attr_set(vbo_curves_nor, attr_id.pos, vbo_len_used, bevp->vec); + vbo_len_used++; - bevp += skip + 1; - nr -= skip; - } + bevp += skip + 1; + nr -= skip; } - BLI_assert(vbo_len_used == vert_len); } - - return cache->normal.verts; + BLI_assert(vbo_len_used == verts_len_capacity); } -static GPUIndexBuf *curve_batch_cache_get_normal_edges(CurveRenderData *rdata, CurveBatchCache *cache) +static char beztriple_vflag_get(CurveRenderData *rdata, char flag, char col_id, int v_idx, int nu_id) { - BLI_assert(rdata->types & CU_DATATYPE_NORMAL); - BLI_assert(rdata->ob_curve_cache != NULL); - - if (cache->normal.edges == NULL) { - const int normal_len = curve_render_data_normal_len_get(rdata); - const int vert_len = normal_len * 3; - const int edge_len = normal_len * 2; - - GPUIndexBufBuilder elb; - GPU_indexbuf_init(&elb, GPU_PRIM_LINES, edge_len, vert_len); - - int vbo_len_used = 0; - for (int i = 0; i < normal_len; i++) { - GPU_indexbuf_add_line_verts(&elb, vbo_len_used + 0, vbo_len_used + 1); - GPU_indexbuf_add_line_verts(&elb, vbo_len_used + 1, vbo_len_used + 2); - vbo_len_used += 3; - } + char vflag = 0; + SET_FLAG_FROM_TEST(vflag, (flag & SELECT), VFLAG_VERTEX_SELECTED); + SET_FLAG_FROM_TEST(vflag, (v_idx == rdata->actvert), VFLAG_VERTEX_ACTIVE); + SET_FLAG_FROM_TEST(vflag, (nu_id == rdata->actnu), ACTIVE_NURB); + /* handle color id */ + vflag |= col_id << 4; /* << 4 because of EVEN_U_BIT */ + return vflag; +} - BLI_assert(vbo_len_used == vert_len); +static char bpoint_vflag_get(CurveRenderData *rdata, char flag, int v_idx, int nu_id, int u) +{ + char vflag = 0; + SET_FLAG_FROM_TEST(vflag, (flag & SELECT), VFLAG_VERTEX_SELECTED); + SET_FLAG_FROM_TEST(vflag, (v_idx == rdata->actvert), VFLAG_VERTEX_ACTIVE); + SET_FLAG_FROM_TEST(vflag, (nu_id == rdata->actnu), ACTIVE_NURB); + SET_FLAG_FROM_TEST(vflag, ((u % 2) == 0), EVEN_U_BIT); + vflag |= COLOR_NURB_ULINE_ID << 4; /* << 4 because of EVEN_U_BIT */ + return vflag; +} - cache->normal.elem = GPU_indexbuf_build(&elb); +static void curve_create_edit_data_and_handles( + CurveRenderData *rdata, + GPUVertBuf *vbo_pos, GPUVertBuf *vbo_data, GPUIndexBuf *ibo_edit_verts_points, GPUIndexBuf *ibo_edit_lines) +{ + static GPUVertFormat format_pos = { 0 }; + static GPUVertFormat format_data = { 0 }; + static struct { uint pos, data; } attr_id; + if (format_pos.attr_len == 0) { + /* initialize vertex formats */ + attr_id.pos = GPU_vertformat_attr_add(&format_pos, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.data = GPU_vertformat_attr_add(&format_data, "data", GPU_COMP_U8, 1, GPU_FETCH_INT); } - return cache->normal.elem; -} + int verts_len_capacity = curve_render_data_overlay_verts_len_get(rdata); + int edges_len_capacity = curve_render_data_overlay_edges_len_get(rdata) * 2; + int vbo_len_used = 0; -static void curve_batch_cache_create_overlay_batches(Curve *cu) -{ - /* Since CU_DATATYPE_OVERLAY is slow to generate, generate them all at once */ - int options = CU_DATATYPE_OVERLAY; + if (DRW_TEST_ASSIGN_VBO(vbo_pos)) { + GPU_vertbuf_init_with_format(vbo_pos, &format_pos); + GPU_vertbuf_data_alloc(vbo_pos, verts_len_capacity); + } + if (DRW_TEST_ASSIGN_VBO(vbo_data)) { + GPU_vertbuf_init_with_format(vbo_data, &format_data); + GPU_vertbuf_data_alloc(vbo_data, verts_len_capacity); + } - CurveBatchCache *cache = curve_batch_cache_get(cu); - CurveRenderData *rdata = curve_render_data_create(cu, NULL, options); - - if (cache->overlay.verts == NULL) { - static GPUVertFormat format = { 0 }; - static struct { uint pos, data; } attr_id; - if (format.attr_len == 0) { - /* initialize vertex format */ - attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - attr_id.data = GPU_vertformat_attr_add(&format, "data", GPU_COMP_U8, 1, GPU_FETCH_INT); - } + GPUIndexBufBuilder elb_verts, *elbp_verts = NULL; + GPUIndexBufBuilder elb_lines, *elbp_lines = NULL; + if (DRW_TEST_ASSIGN_IBO(ibo_edit_verts_points)) { + elbp_verts = &elb_verts; + GPU_indexbuf_init(elbp_verts, GPU_PRIM_POINTS, verts_len_capacity, verts_len_capacity); + } + if (DRW_TEST_ASSIGN_IBO(ibo_edit_lines)) { + elbp_lines = &elb_lines; + GPU_indexbuf_init(elbp_lines, GPU_PRIM_LINES, edges_len_capacity, verts_len_capacity); + } - GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); - const int vbo_len_capacity = curve_render_data_overlay_verts_len_get(rdata); - GPUIndexBufBuilder elb; - GPU_indexbuf_init(&elb, GPU_PRIM_POINTS, vbo_len_capacity, vbo_len_capacity); - int vbo_len_used = 0; - GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); - int i = 0, nu_id = 0; - for (Nurb *nu = rdata->nurbs->first; nu; nu = nu->next, nu_id++) { - const bool is_active_nurb = (nu_id == cu->actnu); - if (nu->bezt) { - int a = 0; - for (const BezTriple *bezt = nu->bezt; a < nu->pntsu; a++, bezt++) { - if (bezt->hide == false) { - const bool is_active = (i == rdata->actvert); - GPU_indexbuf_add_point_vert(&elb, vbo_len_used + 1); - for (int j = 0; j < 3; j++) { - char vflag = ((&bezt->f1)[j] & SELECT) ? VFLAG_VERTEX_SELECTED : 0; - vflag |= (is_active) ? VFLAG_VERTEX_ACTIVE : 0; - vflag |= (is_active_nurb) ? ACTIVE_NURB : 0; - /* handle color id */ - char col_id = (&bezt->h1)[j / 2]; - vflag |= col_id << 4; /* << 4 because of EVEN_U_BIT */ - GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bezt->vec[j]); - GPU_vertbuf_attr_set(vbo, attr_id.data, vbo_len_used, &vflag); - vbo_len_used += 1; - } - } - i += 1; + int v_idx = 0, nu_id = 0; + for (Nurb *nu = rdata->nurbs->first; nu; nu = nu->next, nu_id++) { + const BezTriple *bezt = nu->bezt; + const BPoint *bp = nu->bp; + if (bezt && bezt->hide == false) { + for (int a = 0; a < nu->pntsu; a++, bezt++) { + if (elbp_verts) { + GPU_indexbuf_add_point_vert(elbp_verts, vbo_len_used + 1); } - } - else if (nu->bp) { - int a = 0; - int pt_len = nu->pntsu * nu->pntsv; - for (const BPoint *bp = nu->bp; a < pt_len; a++, bp++) { - if (bp->hide == false) { - const bool is_active = (i == rdata->actvert); - char vflag = (bp->f1 & SELECT) ? VFLAG_VERTEX_SELECTED : 0; - vflag |= (is_active) ? VFLAG_VERTEX_ACTIVE : 0; - vflag |= (is_active_nurb) ? ACTIVE_NURB : 0; - vflag |= (((a % nu->pntsu) % 2) == 0) ? EVEN_U_BIT : 0; - vflag |= COLOR_NURB_ULINE_ID << 4; /* << 4 because of EVEN_U_BIT */ - GPU_indexbuf_add_point_vert(&elb, vbo_len_used); - GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bp->vec); - GPU_vertbuf_attr_set(vbo, attr_id.data, vbo_len_used, &vflag); - vbo_len_used += 1; + if (elbp_lines) { + GPU_indexbuf_add_line_verts(elbp_lines, vbo_len_used + 0, vbo_len_used + 1); + GPU_indexbuf_add_line_verts(elbp_lines, vbo_len_used + 0, vbo_len_used + 2); + } + if (vbo_data) { + char vflag[3] = { + beztriple_vflag_get(rdata, bezt->f1, bezt->h1, v_idx, nu_id), + beztriple_vflag_get(rdata, bezt->f2, bezt->h1, v_idx, nu_id), + beztriple_vflag_get(rdata, bezt->f3, bezt->h2, v_idx, nu_id) + }; + for (int j = 0; j < 3; j++) { + GPU_vertbuf_attr_set(vbo_data, attr_id.data, vbo_len_used + j, &vflag[j]); } - i += 1; } - } - i += nu->pntsu; - } - if (vbo_len_capacity != vbo_len_used) { - GPU_vertbuf_data_resize(vbo, vbo_len_used); - } - - GPUIndexBuf *ibo = GPU_indexbuf_build(&elb); - - cache->overlay.verts = GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO); - cache->overlay.verts_no_handles = GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, ibo, GPU_BATCH_OWNS_INDEX); - } - - if (cache->overlay.edges == NULL) { - GPUVertBuf *vbo = cache->overlay.verts->verts[0]; - - const int edge_len = curve_render_data_overlay_edges_len_get(rdata); - const int vbo_len_capacity = edge_len * 2; - - GPUIndexBufBuilder elb; - GPU_indexbuf_init(&elb, GPU_PRIM_LINES, vbo_len_capacity, vbo->vertex_len); - - int curr_index = 0; - int i = 0; - for (Nurb *nu = rdata->nurbs->first; nu; nu = nu->next, i++) { - if (nu->bezt) { - int a = 0; - for (const BezTriple *bezt = nu->bezt; a < nu->pntsu; a++, bezt++) { - if (bezt->hide == false) { - GPU_indexbuf_add_line_verts(&elb, curr_index + 1, curr_index + 0); - GPU_indexbuf_add_line_verts(&elb, curr_index + 1, curr_index + 2); - curr_index += 3; + if (vbo_pos) { + for (int j = 0; j < 3; j++) { + GPU_vertbuf_attr_set(vbo_pos, attr_id.pos, vbo_len_used + j, bezt->vec[j]); } } + vbo_len_used += 3; + v_idx += 1; } - else if (nu->bp) { - int a = 0; - int next_v_index = curr_index; - for (const BPoint *bp = nu->bp; a < nu->pntsu; a++, bp++) { - if (bp->hide == false) { - next_v_index += 1; - } + } + else if (bp) { + int pt_len = nu->pntsu * nu->pntsv; + for (int a = 0; a < pt_len; a++, bp++) { + int u = (a % nu->pntsu); + int v = (a / nu->pntsu); + /* Use indexed rendering for bezier. + * Specify all points and use indices to hide/show. */ + if (elbp_verts && bp->hide == false) { + GPU_indexbuf_add_point_vert(elbp_verts, vbo_len_used); } - - int pt_len = nu->pntsu * nu->pntsv; - for (a = 0; a < pt_len; a++) { - const BPoint *bp_curr = &nu->bp[a]; - const BPoint *bp_next_u = ((a % nu->pntsu) < (nu->pntsu - 1)) ? &nu->bp[a + 1] : NULL; - const BPoint *bp_next_v = (a < (pt_len - nu->pntsu)) ? &nu->bp[a + nu->pntsu] : NULL; - if (bp_curr->hide == false) { - if (bp_next_u && (bp_next_u->hide == false)) { - GPU_indexbuf_add_line_verts(&elb, curr_index, curr_index + 1); - } - if (bp_next_v && (bp_next_v->hide == false)) { - GPU_indexbuf_add_line_verts(&elb, curr_index, next_v_index); - } - curr_index += 1; + if (elbp_lines && bp->hide == false) { + const BPoint *bp_next_u = (u < (nu->pntsu - 1)) ? &nu->bp[a + 1] : NULL; + const BPoint *bp_next_v = (v < (nu->pntsv - 1)) ? &nu->bp[a + nu->pntsu] : NULL; + if (bp_next_u && (bp_next_u->hide == false)) { + GPU_indexbuf_add_line_verts(elbp_lines, vbo_len_used, vbo_len_used + 1); } if (bp_next_v && (bp_next_v->hide == false)) { - next_v_index += 1; + GPU_indexbuf_add_line_verts(elbp_lines, vbo_len_used, vbo_len_used + nu->pntsu); } } + if (vbo_data) { + char vflag = bpoint_vflag_get(rdata, bp->f1, v_idx, nu_id, u); + GPU_vertbuf_attr_set(vbo_data, attr_id.data, vbo_len_used, &vflag); + } + if (vbo_pos) { + GPU_vertbuf_attr_set(vbo_pos, attr_id.pos, vbo_len_used, bp->vec); + } + vbo_len_used += 1; + v_idx += 1; } } - - GPUIndexBuf *ibo = GPU_indexbuf_build(&elb); - cache->overlay.edges = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, ibo, GPU_BATCH_OWNS_INDEX); } - curve_render_data_free(rdata); -} - -static GPUBatch *curve_batch_cache_get_pos_and_normals(CurveRenderData *rdata, CurveBatchCache *cache) -{ - BLI_assert(rdata->types & CU_DATATYPE_SURFACE); - if (cache->surface.batch == NULL) { - ListBase *lb = &rdata->ob_curve_cache->disp; - - if (cache->surface.verts == NULL) { - cache->surface.verts = DRW_displist_vertbuf_calc_pos_with_normals(lb); - } - if (cache->surface.triangles_in_order == NULL) { - cache->surface.triangles_in_order = DRW_displist_indexbuf_calc_triangles_in_order(lb); - } - cache->surface.batch = GPU_batch_create( - GPU_PRIM_TRIS, cache->surface.verts, cache->surface.triangles_in_order); + /* Resize & Finish */ + if (elbp_verts != NULL) { + GPU_indexbuf_build_in_place(elbp_verts, ibo_edit_verts_points); } - - return cache->surface.batch; -} - -/** \} */ - - -/* -------------------------------------------------------------------- */ - -/** \name Private Object/Font Cache API - * \{ */ - - -static GPUBatch *curve_batch_cache_get_edit_select(CurveRenderData *rdata, CurveBatchCache *cache) -{ - BLI_assert(rdata->types & CU_DATATYPE_TEXT_SELECT); - if (cache->text.select == NULL) { - EditFont *ef = rdata->text.edit_font; - static GPUVertFormat format = { 0 }; - static struct { uint pos; } attr_id; - if (format.attr_len == 0) { - attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - } - - GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); - const int vbo_len_capacity = ef->selboxes_len * 6; - int vbo_len_used = 0; - GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); - - float box[4][3]; - - /* fill in xy below */ - box[0][2] = box[1][2] = box[2][2] = box[3][2] = 0.001; - - for (int i = 0; i < ef->selboxes_len; i++) { - EditFontSelBox *sb = &ef->selboxes[i]; - - float selboxw; - if (i + 1 != ef->selboxes_len) { - if (ef->selboxes[i + 1].y == sb->y) - selboxw = ef->selboxes[i + 1].x - sb->x; - else - selboxw = sb->w; - } - else { - selboxw = sb->w; - } - - if (sb->rot == 0.0f) { - copy_v2_fl2(box[0], sb->x, sb->y); - copy_v2_fl2(box[1], sb->x + selboxw, sb->y); - copy_v2_fl2(box[2], sb->x + selboxw, sb->y + sb->h); - copy_v2_fl2(box[3], sb->x, sb->y + sb->h); - } - else { - float mat[2][2]; - - angle_to_mat2(mat, sb->rot); - - copy_v2_fl2(box[0], sb->x, sb->y); - - copy_v2_fl2(box[1], selboxw, 0.0f); - mul_m2v2(mat, box[1]); - add_v2_v2(box[1], &sb->x); - - copy_v2_fl2(box[2], selboxw, sb->h); - mul_m2v2(mat, box[2]); - add_v2_v2(box[2], &sb->x); - - copy_v2_fl2(box[3], 0.0f, sb->h); - mul_m2v2(mat, box[3]); - add_v2_v2(box[3], &sb->x); - } - - GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[0]); - GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[1]); - GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[2]); - - GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[0]); - GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[2]); - GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[3]); - } - BLI_assert(vbo_len_used == vbo_len_capacity); - cache->text.select = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO); + if (elbp_lines != NULL) { + GPU_indexbuf_build_in_place(elbp_lines, ibo_edit_lines); } - return cache->text.select; -} - -static GPUBatch *curve_batch_cache_get_edit_cursor(CurveRenderData *rdata, CurveBatchCache *cache) -{ - BLI_assert(rdata->types & CU_DATATYPE_TEXT_SELECT); - if (cache->text.cursor == NULL) { - static GPUVertFormat format = { 0 }; - static struct { uint pos; } attr_id; - if (format.attr_len == 0) { - attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + if (vbo_len_used != verts_len_capacity) { + if (vbo_pos != NULL) { + GPU_vertbuf_data_resize(vbo_pos, vbo_len_used); } - - GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); - const int vbo_len_capacity = 4; - GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); - for (int i = 0; i < 4; i++) { - GPU_vertbuf_attr_set(vbo, attr_id.pos, i, rdata->text.edit_font->textcurs[i]); + if (vbo_data != NULL) { + GPU_vertbuf_data_resize(vbo_data, vbo_len_used); } - cache->text.cursor = GPU_batch_create_ex(GPU_PRIM_TRI_FAN, vbo, NULL, GPU_BATCH_OWNS_VBO); } - return cache->text.cursor; } /** \} */ @@ -907,94 +747,46 @@ static GPUBatch *curve_batch_cache_get_edit_cursor(CurveRenderData *rdata, Curve /** \name Public Object/Curve API * \{ */ -GPUBatch *DRW_curve_batch_cache_get_wire_edge(Curve *cu, CurveCache *ob_curve_cache) +GPUBatch *DRW_curve_batch_cache_get_wire_edge(Curve *cu) { CurveBatchCache *cache = curve_batch_cache_get(cu); - - if (cache->wire.batch == NULL) { - /* create batch from Curve */ - CurveRenderData *rdata = curve_render_data_create(cu, ob_curve_cache, CU_DATATYPE_WIRE); - - cache->wire.batch = GPU_batch_create( - GPU_PRIM_LINES, - curve_batch_cache_get_wire_verts(rdata, cache), - curve_batch_cache_get_wire_edges(rdata, cache)); - - curve_render_data_free(rdata); - } - return cache->wire.batch; + return DRW_batch_request(&cache->batch.curves); } -GPUBatch *DRW_curve_batch_cache_get_normal_edge(Curve *cu, CurveCache *ob_curve_cache, float normal_size) +GPUBatch *DRW_curve_batch_cache_get_normal_edge(Curve *cu) { CurveBatchCache *cache = curve_batch_cache_get(cu); - - if (cache->normal.batch != NULL) { - cache->normal_size = normal_size; - if (cache->normal_size != normal_size) { - GPU_BATCH_DISCARD_SAFE(cache->normal.batch); - GPU_VERTBUF_DISCARD_SAFE(cache->normal.edges); - } - } - cache->normal_size = normal_size; - - if (cache->normal.batch == NULL) { - /* create batch from Curve */ - CurveRenderData *rdata = curve_render_data_create(cu, ob_curve_cache, CU_DATATYPE_NORMAL); - - cache->normal.batch = GPU_batch_create( - GPU_PRIM_LINES, - curve_batch_cache_get_normal_verts(rdata, cache), - curve_batch_cache_get_normal_edges(rdata, cache)); - - curve_render_data_free(rdata); - cache->normal_size = normal_size; - } - return cache->normal.batch; + return DRW_batch_request(&cache->batch.edit_normals); } GPUBatch *DRW_curve_batch_cache_get_edit_edges(Curve *cu) { CurveBatchCache *cache = curve_batch_cache_get(cu); - - if (cache->overlay.edges == NULL) { - curve_batch_cache_create_overlay_batches(cu); - } - - return cache->overlay.edges; + return DRW_batch_request(&cache->batch.edit_edges); } GPUBatch *DRW_curve_batch_cache_get_edit_verts(Curve *cu, bool handles) { CurveBatchCache *cache = curve_batch_cache_get(cu); - - if (cache->overlay.verts == NULL || cache->overlay.verts_no_handles == NULL) { - curve_batch_cache_create_overlay_batches(cu); + if (handles) { + return DRW_batch_request(&cache->batch.edit_handles_verts); + } + else { + return DRW_batch_request(&cache->batch.edit_verts); } - - return (handles) ? cache->overlay.verts : cache->overlay.verts_no_handles; } -GPUBatch *DRW_curve_batch_cache_get_triangles_with_normals( - struct Curve *cu, struct CurveCache *ob_curve_cache) +GPUBatch *DRW_curve_batch_cache_get_triangles_with_normals(struct Curve *cu) { CurveBatchCache *cache = curve_batch_cache_get(cu); - - if (cache->surface.batch == NULL) { - CurveRenderData *rdata = curve_render_data_create(cu, ob_curve_cache, CU_DATATYPE_SURFACE); - - curve_batch_cache_get_pos_and_normals(rdata, cache); - - curve_render_data_free(rdata); - } - - return cache->surface.batch; + return DRW_batch_request(&cache->batch.surfaces); } GPUBatch **DRW_curve_batch_cache_get_surface_shaded( - struct Curve *cu, struct CurveCache *ob_curve_cache, - struct GPUMaterial **UNUSED(gpumat_array), uint gpumat_array_len) + struct Curve *cu, + struct GPUMaterial **gpumat_array, uint gpumat_array_len) { +#if 0 CurveBatchCache *cache = curve_batch_cache_get(cu); if (cache->surface.mat_len != gpumat_array_len) { @@ -1032,58 +824,115 @@ GPUBatch **DRW_curve_batch_cache_get_surface_shaded( } return cache->surface.shaded_triangles; +#endif + return NULL; } -GPUBatch *DRW_curve_batch_cache_get_wireframes_face(Curve *cu, CurveCache *ob_curve_cache) +GPUBatch *DRW_curve_batch_cache_get_wireframes_face(Curve *cu) { CurveBatchCache *cache = curve_batch_cache_get(cu); - - if (cache->face_wire.batch == NULL) { - CurveRenderData *rdata = curve_render_data_create(cu, ob_curve_cache, CU_DATATYPE_SURFACE); - - ListBase *lb = &rdata->ob_curve_cache->disp; - - cache->face_wire.batch = DRW_displist_create_edges_overlay_batch(lb); - - curve_render_data_free(rdata); - } - - return cache->face_wire.batch; + return DRW_batch_request(&cache->batch.wire_triangles); } -/* -------------------------------------------------------------------- */ +/** \} */ -/** \name Public Object/Font API +/* -------------------------------------------------------------------- */ +/** \name Grouped batch generation * \{ */ -GPUBatch *DRW_curve_batch_cache_get_edit_select(Curve *cu) +void DRW_curve_batch_cache_create_requested(Object *ob) { - CurveBatchCache *cache = curve_batch_cache_get(cu); + BLI_assert(ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)); - if (cache->text.select == NULL) { - CurveRenderData *rdata = curve_render_data_create(cu, NULL, CU_DATATYPE_TEXT_SELECT); + Curve *me = (Curve *)ob->data; + CurveBatchCache *cache = curve_batch_cache_get(me); - curve_batch_cache_get_edit_select(rdata, cache); + /* Init batches and request VBOs & IBOs */ + if (DRW_batch_requested(cache->batch.surfaces, GPU_PRIM_TRIS)) { + DRW_ibo_request(cache->batch.surfaces, &cache->ibo.surfaces_tris); + DRW_vbo_request(cache->batch.surfaces, &cache->ordered.pos_nor); + } + if (DRW_batch_requested(cache->batch.curves, GPU_PRIM_LINE_STRIP)) { + DRW_ibo_request(cache->batch.curves, &cache->ibo.curves_lines); + DRW_vbo_request(cache->batch.curves, &cache->ordered.curves_pos); + } + if (DRW_batch_requested(cache->batch.wire_triangles, GPU_PRIM_TRIS)) { + DRW_vbo_request(cache->batch.wire_triangles, &cache->tess.pos_nor); + DRW_vbo_request(cache->batch.wire_triangles, &cache->tess.wireframe_data); + } - curve_render_data_free(rdata); + /* Edit mode */ + if (DRW_batch_requested(cache->batch.edit_edges, GPU_PRIM_LINES)) { + DRW_ibo_request(cache->batch.edit_edges, &cache->ibo.edit_lines); + DRW_vbo_request(cache->batch.edit_edges, &cache->edit.pos); + DRW_vbo_request(cache->batch.edit_edges, &cache->edit.data); + } + if (DRW_batch_requested(cache->batch.edit_verts, GPU_PRIM_POINTS)) { + DRW_ibo_request(cache->batch.edit_verts, &cache->ibo.edit_verts_points); + DRW_vbo_request(cache->batch.edit_verts, &cache->edit.pos); + DRW_vbo_request(cache->batch.edit_verts, &cache->edit.data); + } + if (DRW_batch_requested(cache->batch.edit_handles_verts, GPU_PRIM_POINTS)) { + DRW_vbo_request(cache->batch.edit_handles_verts, &cache->edit.pos); + DRW_vbo_request(cache->batch.edit_handles_verts, &cache->edit.data); + } + if (DRW_batch_requested(cache->batch.edit_normals, GPU_PRIM_LINES)) { + DRW_vbo_request(cache->batch.edit_normals, &cache->edit.curves_nor); } - return cache->text.select; -} + /* Generate MeshRenderData flags */ + int mr_flag = 0; + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.pos_nor, CU_DATATYPE_SURFACE); + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.curves_pos, CU_DATATYPE_WIRE); + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->tess.pos_nor, CU_DATATYPE_SURFACE); + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->tess.wireframe_data, CU_DATATYPE_SURFACE); + DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.surfaces_tris, CU_DATATYPE_SURFACE); + DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.curves_lines, CU_DATATYPE_WIRE); -GPUBatch *DRW_curve_batch_cache_get_edit_cursor(Curve *cu) -{ - CurveBatchCache *cache = curve_batch_cache_get(cu); + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->edit.pos, CU_DATATYPE_OVERLAY); + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->edit.data, CU_DATATYPE_OVERLAY); + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->edit.curves_nor, CU_DATATYPE_NORMAL); + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->edit.curves_weight, CU_DATATYPE_OVERLAY); + DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.edit_verts_points, CU_DATATYPE_OVERLAY); + DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.edit_lines, CU_DATATYPE_OVERLAY); - if (cache->text.cursor == NULL) { - CurveRenderData *rdata = curve_render_data_create(cu, NULL, CU_DATATYPE_TEXT_SELECT); + CurveRenderData *rdata = curve_render_data_create(me, ob->runtime.curve_cache, mr_flag); - curve_batch_cache_get_edit_cursor(rdata, cache); + /* DispLists */ + ListBase *lb = &rdata->ob_curve_cache->disp; - curve_render_data_free(rdata); + /* Generate VBOs */ + if (DRW_vbo_requested(cache->ordered.pos_nor)) { + DRW_displist_vertbuf_calc_pos_with_normals(lb, cache->ordered.pos_nor); + } + if (DRW_vbo_requested(cache->ordered.curves_pos)) { + curve_create_curves_pos(rdata, cache->ordered.curves_pos); + } + + if (DRW_vbo_requested(cache->tess.wireframe_data)) { + DRW_displist_create_edges_overlay_batch(lb, cache->tess.wireframe_data); + } + + if (DRW_ibo_requested(cache->ibo.curves_lines)) { + curve_create_curves_lines(rdata, cache->ibo.curves_lines); + } + if (DRW_ibo_requested(cache->ibo.surfaces_tris)) { + DRW_displist_indexbuf_calc_triangles_in_order(lb, cache->ibo.surfaces_tris); + } + + if (DRW_vbo_requested(cache->edit.pos) || + DRW_vbo_requested(cache->edit.data) || + DRW_ibo_requested(cache->ibo.edit_verts_points) || + DRW_ibo_requested(cache->ibo.edit_lines)) + { + curve_create_edit_data_and_handles(rdata, cache->edit.pos, cache->edit.data, + cache->ibo.edit_verts_points, cache->ibo.edit_lines); + } + if (DRW_vbo_requested(cache->edit.curves_nor)) { + curve_create_edit_curves_nor(rdata, cache->edit.curves_nor); } - return cache->text.cursor; + curve_render_data_free(rdata); } /** \} */ diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c index 2f9fa73b7e6..4e25fc692be 100644 --- a/source/blender/draw/intern/draw_cache_impl_displist.c +++ b/source/blender/draw/intern/draw_cache_impl_displist.c @@ -125,7 +125,7 @@ static void displist_indexbufbuilder_set( } } -GPUVertBuf *DRW_displist_vertbuf_calc_pos_with_normals(ListBase *lb) +GPUVertBuf *DRW_displist_vertbuf_calc_pos_with_normals(ListBase *lb, GPUVertBuf *vbo) { static GPUVertFormat format = { 0 }; static struct { uint pos, nor; } attr_id; @@ -135,7 +135,12 @@ GPUVertBuf *DRW_displist_vertbuf_calc_pos_with_normals(ListBase *lb) attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); } - GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + if (vbo == NULL) { + vbo = GPU_vertbuf_create_with_format(&format); + } + else { + GPU_vertbuf_init_with_format(vbo, &format); + } GPU_vertbuf_data_alloc(vbo, curve_render_surface_vert_len_get(lb)); BKE_displist_normals_add(lb); @@ -166,7 +171,7 @@ GPUVertBuf *DRW_displist_vertbuf_calc_pos_with_normals(ListBase *lb) return vbo; } -GPUIndexBuf *DRW_displist_indexbuf_calc_triangles_in_order(ListBase *lb) +GPUIndexBuf *DRW_displist_indexbuf_calc_triangles_in_order(ListBase *lb, GPUIndexBuf *ibo) { const int tri_len = curve_render_surface_tri_len_get(lb); const int vert_len = curve_render_surface_vert_len_get(lb); @@ -182,7 +187,13 @@ GPUIndexBuf *DRW_displist_indexbuf_calc_triangles_in_order(ListBase *lb) ofs += dl_vert_len(dl); } - return GPU_indexbuf_build(&elb); + if (ibo != NULL) { + GPU_indexbuf_build_in_place(&elb, ibo); + } + else { + ibo = GPU_indexbuf_build(&elb); + } + return ibo; } GPUIndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_material(ListBase *lb, uint gpumat_array_len) @@ -267,7 +278,7 @@ static void set_overlay_wires_quad_tri_indices(void *thunk, uint v1, uint v2, ui } } -GPUBatch *DRW_displist_create_edges_overlay_batch(ListBase *lb) +GPUBatch *DRW_displist_create_edges_overlay_batch(ListBase *lb, GPUVertBuf *vbo) { static DRWDisplistWireThunk thunk; static GPUVertFormat format = {0}; @@ -278,7 +289,13 @@ GPUBatch *DRW_displist_create_edges_overlay_batch(ListBase *lb) GPU_vertformat_triple_load(&format); } - thunk.vbo = GPU_vertbuf_create_with_format(&format); + if (vbo == NULL) { + thunk.vbo = GPU_vertbuf_create_with_format(&format); + } + else { + GPU_vertbuf_init_with_format(vbo, &format); + thunk.vbo = vbo; + } int vert_len = curve_render_surface_tri_len_get(lb) * 3; GPU_vertbuf_data_alloc(thunk.vbo, vert_len); @@ -300,7 +317,12 @@ GPUBatch *DRW_displist_create_edges_overlay_batch(ListBase *lb) GPU_vertbuf_data_resize(thunk.vbo, thunk.vidx); } - return GPU_batch_create_ex(GPU_PRIM_TRIS, thunk.vbo, NULL, GPU_BATCH_OWNS_VBO); + if (vbo == NULL) { + return GPU_batch_create_ex(GPU_PRIM_TRIS, thunk.vbo, NULL, GPU_BATCH_OWNS_VBO); + } + else { + return NULL; + } } diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 3037a2fe225..66eab91b15e 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -2070,7 +2070,7 @@ typedef struct MeshBatchCache { struct { /* Contains indices to unique edit vertices to not * draw the same vert multiple times (because of tesselation). */ - GPUIndexBuf *edit_verts; + GPUIndexBuf *edit_verts_points; } ibo; struct { @@ -3747,10 +3747,6 @@ static GPUVertFormat *edit_mesh_facedot_format(uint *r_pos_id, uint *r_nor_flag_ return &format_facedots; } -/* Test and assign NULL if test fails */ -#define TEST_ASSIGN_VBO(v) (v = (DRW_vbo_requested(v) ? v : NULL)) -#define TEST_ASSIGN_IBO(v) (v = (DRW_ibo_requested(v) ? v : NULL)) - static void mesh_create_edit_tris_and_verts( MeshRenderData *rdata, GPUVertBuf *vbo_data, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_lnor, GPUIndexBuf *ibo_verts) @@ -3768,23 +3764,23 @@ static void mesh_create_edit_tris_and_verts( GPUVertFormat *lnor_format = edit_mesh_lnor_format(&attr_id.lnor); /* Positions & Vert Normals */ - if (TEST_ASSIGN_VBO(vbo_pos_nor)) { + if (DRW_TEST_ASSIGN_VBO(vbo_pos_nor)) { GPU_vertbuf_init_with_format(vbo_pos_nor, pos_nor_format); GPU_vertbuf_data_alloc(vbo_pos_nor, verts_tri_len); } /* Overlay data */ - if (TEST_ASSIGN_VBO(vbo_data)) { + if (DRW_TEST_ASSIGN_VBO(vbo_data)) { GPU_vertbuf_init_with_format(vbo_data, data_format); GPU_vertbuf_data_alloc(vbo_data, verts_tri_len); } /* Loop Normals */ - if (TEST_ASSIGN_VBO(vbo_lnor)) { + if (DRW_TEST_ASSIGN_VBO(vbo_lnor)) { GPU_vertbuf_init_with_format(vbo_lnor, lnor_format); GPU_vertbuf_data_alloc(vbo_lnor, verts_tri_len); } /* Verts IBO */ GPUIndexBufBuilder elb, *elbp = NULL; - if (TEST_ASSIGN_IBO(ibo_verts)) { + if (DRW_TEST_ASSIGN_IBO(ibo_verts)) { elbp = &elb; GPU_indexbuf_init(elbp, GPU_PRIM_POINTS, points_len, verts_tri_len); /* Clear tag */ @@ -3861,12 +3857,12 @@ static void mesh_create_edit_loose_edges( GPUVertFormat *data_format = edit_mesh_data_format(&attr_id.data); /* Positions & Vert Normals */ - if (TEST_ASSIGN_VBO(vbo_pos_nor_ledges)) { + if (DRW_TEST_ASSIGN_VBO(vbo_pos_nor_ledges)) { GPU_vertbuf_init_with_format(vbo_pos_nor_ledges, pos_nor_format); GPU_vertbuf_data_alloc(vbo_pos_nor_ledges, verts_ledges_len); } /* Overlay data */ - if (TEST_ASSIGN_VBO(vbo_data_ledges)) { + if (DRW_TEST_ASSIGN_VBO(vbo_data_ledges)) { GPU_vertbuf_init_with_format(vbo_data_ledges, data_format); GPU_vertbuf_data_alloc(vbo_data_ledges, verts_ledges_len); } @@ -3913,12 +3909,12 @@ static void mesh_create_edit_loose_verts( GPUVertFormat *data_format = edit_mesh_data_format(&attr_id.data); /* Positions & Vert Normals */ - if (TEST_ASSIGN_VBO(vbo_pos_nor_lverts)) { + if (DRW_TEST_ASSIGN_VBO(vbo_pos_nor_lverts)) { GPU_vertbuf_init_with_format(vbo_pos_nor_lverts, pos_nor_format); GPU_vertbuf_data_alloc(vbo_pos_nor_lverts, verts_lverts_len); } /* Overlay data */ - if (TEST_ASSIGN_VBO(vbo_data_lverts)) { + if (DRW_TEST_ASSIGN_VBO(vbo_data_lverts)) { GPU_vertbuf_init_with_format(vbo_data_lverts, data_format); GPU_vertbuf_data_alloc(vbo_data_lverts, verts_lverts_len); } @@ -3961,7 +3957,7 @@ static void mesh_create_edit_facedots( struct { uint fdot_pos, fdot_nor_flag; } attr_id; GPUVertFormat *facedot_format = edit_mesh_facedot_format(&attr_id.fdot_pos, &attr_id.fdot_nor_flag); - if (TEST_ASSIGN_VBO(vbo_pos_nor_data_facedots)) { + if (DRW_TEST_ASSIGN_VBO(vbo_pos_nor_data_facedots)) { GPU_vertbuf_init_with_format(vbo_pos_nor_data_facedots, facedot_format); GPU_vertbuf_data_alloc(vbo_pos_nor_data_facedots, verts_facedot_len); /* TODO(fclem): Maybe move data generation to mesh_render_data_create() */ @@ -5788,7 +5784,7 @@ void DRW_mesh_batch_cache_create_requested(Object *ob) DRW_vbo_request(cache->batch.edit_triangles, &cache->edit.data); } if (DRW_batch_requested(cache->batch.edit_vertices, GPU_PRIM_POINTS)) { - DRW_ibo_request(cache->batch.edit_vertices, &cache->ibo.edit_verts); + DRW_ibo_request(cache->batch.edit_vertices, &cache->ibo.edit_verts_points); DRW_vbo_request(cache->batch.edit_vertices, &cache->edit.pos_nor); DRW_vbo_request(cache->batch.edit_vertices, &cache->edit.data); } @@ -5801,7 +5797,7 @@ void DRW_mesh_batch_cache_create_requested(Object *ob) DRW_vbo_request(cache->batch.edit_loose_verts, &cache->edit.data_lverts); } if (DRW_batch_requested(cache->batch.edit_triangles_nor, GPU_PRIM_POINTS)) { - DRW_ibo_request(cache->batch.edit_triangles_nor, &cache->ibo.edit_verts); + DRW_ibo_request(cache->batch.edit_triangles_nor, &cache->ibo.edit_verts_points); DRW_vbo_request(cache->batch.edit_triangles_nor, &cache->edit.pos_nor); } if (DRW_batch_requested(cache->batch.edit_triangles_lnor, GPU_PRIM_POINTS)) { @@ -5829,7 +5825,7 @@ void DRW_mesh_batch_cache_create_requested(Object *ob) DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.pos_nor_lverts, MR_DATATYPE_VERT | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_OVERLAY); DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.pos_nor_data_facedots, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_OVERLAY); DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.lnor, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI | MR_DATATYPE_OVERLAY); - DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edit_verts, MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI); + DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edit_verts_points, MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI); Mesh *me_original = me; MBC_GET_FINAL_MESH(me); @@ -5864,10 +5860,10 @@ void DRW_mesh_batch_cache_create_requested(Object *ob) if (DRW_vbo_requested(cache->edit.data) || DRW_vbo_requested(cache->edit.pos_nor) || DRW_vbo_requested(cache->edit.lnor) || - DRW_ibo_requested(cache->ibo.edit_verts)) + DRW_ibo_requested(cache->ibo.edit_verts_points)) { mesh_create_edit_tris_and_verts(rdata, cache->edit.data, cache->edit.pos_nor, - cache->edit.lnor, cache->ibo.edit_verts); + cache->edit.lnor, cache->ibo.edit_verts_points); } if (DRW_vbo_requested(cache->edit.data_ledges) || DRW_vbo_requested(cache->edit.pos_nor_ledges)) { mesh_create_edit_loose_edges(rdata, cache->edit.data_ledges, cache->edit.pos_nor_ledges); diff --git a/source/blender/draw/intern/draw_cache_impl_metaball.c b/source/blender/draw/intern/draw_cache_impl_metaball.c index 10f5db42bf1..304d93f465c 100644 --- a/source/blender/draw/intern/draw_cache_impl_metaball.c +++ b/source/blender/draw/intern/draw_cache_impl_metaball.c @@ -143,7 +143,7 @@ static GPUVertBuf *mball_batch_cache_get_pos_and_normals(Object *ob, MetaBallBat { if (cache->pos_nor_in_order == NULL) { ListBase *lb = &ob->runtime.curve_cache->disp; - cache->pos_nor_in_order = DRW_displist_vertbuf_calc_pos_with_normals(lb); + cache->pos_nor_in_order = DRW_displist_vertbuf_calc_pos_with_normals(lb, NULL); } return cache->pos_nor_in_order; } @@ -167,7 +167,7 @@ GPUBatch *DRW_metaball_batch_cache_get_triangles_with_normals(Object *ob) cache->batch = GPU_batch_create_ex( GPU_PRIM_TRIS, mball_batch_cache_get_pos_and_normals(ob, cache), - DRW_displist_indexbuf_calc_triangles_in_order(lb), + DRW_displist_indexbuf_calc_triangles_in_order(lb, NULL), GPU_BATCH_OWNS_INDEX); } @@ -204,7 +204,7 @@ GPUBatch *DRW_metaball_batch_cache_get_wireframes_face(Object *ob) if (cache->face_wire.batch == NULL) { ListBase *lb = &ob->runtime.curve_cache->disp; - cache->face_wire.batch = DRW_displist_create_edges_overlay_batch(lb); + cache->face_wire.batch = DRW_displist_create_edges_overlay_batch(lb, NULL); } return cache->face_wire.batch; diff --git a/source/blender/draw/modes/edit_curve_mode.c b/source/blender/draw/modes/edit_curve_mode.c index 3d716d77405..b3cb2cb3d80 100644 --- a/source/blender/draw/modes/edit_curve_mode.c +++ b/source/blender/draw/modes/edit_curve_mode.c @@ -47,11 +47,13 @@ extern struct GlobalsUboStorage ts; /* draw_common.c */ extern char datatoc_common_globals_lib_glsl[]; extern char datatoc_edit_curve_overlay_loosevert_vert_glsl[]; +extern char datatoc_edit_curve_overlay_normals_vert_glsl[]; extern char datatoc_edit_curve_overlay_handle_vert_glsl[]; extern char datatoc_edit_curve_overlay_handle_geom_glsl[]; extern char datatoc_gpu_shader_point_varying_color_frag_glsl[]; extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[]; +extern char datatoc_gpu_shader_uniform_color_frag_glsl[]; /* *********** LISTS *********** */ /* All lists are per viewport specific datas. @@ -83,6 +85,7 @@ typedef struct EDIT_CURVE_Data { static struct { GPUShader *wire_sh; + GPUShader *wire_normals_sh; GPUShader *overlay_edge_sh; /* handles and nurbs control cage */ GPUShader *overlay_vert_sh; } e_data = {NULL}; /* Engine data */ @@ -90,6 +93,7 @@ static struct { typedef struct EDIT_CURVE_PrivateData { /* resulting curve as 'wire' for curves (and optionally normals) */ DRWShadingGroup *wire_shgrp; + DRWShadingGroup *wire_normals_shgrp; DRWShadingGroup *overlay_edge_shgrp; DRWShadingGroup *overlay_vert_shgrp; @@ -108,6 +112,12 @@ static void EDIT_CURVE_engine_init(void *UNUSED(vedata)) e_data.wire_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR); } + if (!e_data.wire_normals_sh) { + e_data.wire_normals_sh = DRW_shader_create( + datatoc_edit_curve_overlay_normals_vert_glsl, NULL, + datatoc_gpu_shader_uniform_color_frag_glsl, NULL); + } + if (!e_data.overlay_edge_sh) { e_data.overlay_edge_sh = DRW_shader_create_with_lib( datatoc_edit_curve_overlay_handle_vert_glsl, @@ -152,6 +162,12 @@ static void EDIT_CURVE_cache_init(void *vedata) DRW_shgroup_uniform_vec4(grp, "color", ts.colorWireEdit, 1); stl->g_data->wire_shgrp = grp; + + grp = DRW_shgroup_create(e_data.wire_normals_sh, psl->wire_pass); + DRW_shgroup_uniform_vec4(grp, "color", ts.colorWireEdit, 1); + DRW_shgroup_uniform_float_copy(grp, "normalSize", v3d->overlay.normals_length); + stl->g_data->wire_normals_shgrp = grp; + psl->overlay_edge_pass = DRW_pass_create( "Curve Handle Overlay", DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND); @@ -190,8 +206,9 @@ static void EDIT_CURVE_cache_populate(void *vedata, Object *ob) DRW_shgroup_call_add(stl->g_data->wire_shgrp, geom, ob->obmat); if ((cu->flag & CU_3D) && (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_NORMALS) != 0) { - geom = DRW_cache_curve_edge_normal_get(ob, v3d->overlay.normals_length); - DRW_shgroup_call_add(stl->g_data->wire_shgrp, geom, ob->obmat); + static uint instance_len = 2; + geom = DRW_cache_curve_edge_normal_get(ob); + DRW_shgroup_call_instances_add(stl->g_data->wire_normals_shgrp, geom, ob->obmat, &instance_len); } geom = DRW_cache_curve_edge_overlay_get(ob); @@ -242,6 +259,7 @@ static void EDIT_CURVE_draw_scene(void *vedata) * Mostly used for freeing shaders */ static void EDIT_CURVE_engine_free(void) { + DRW_SHADER_FREE_SAFE(e_data.wire_normals_sh); DRW_SHADER_FREE_SAFE(e_data.overlay_edge_sh); DRW_SHADER_FREE_SAFE(e_data.overlay_vert_sh); } diff --git a/source/blender/draw/modes/shaders/edit_curve_overlay_normals_vert.glsl b/source/blender/draw/modes/shaders/edit_curve_overlay_normals_vert.glsl new file mode 100644 index 00000000000..06be402d737 --- /dev/null +++ b/source/blender/draw/modes/shaders/edit_curve_overlay_normals_vert.glsl @@ -0,0 +1,23 @@ + +/* Draw Curve Normals */ + +uniform mat4 ModelViewProjectionMatrix; +uniform float normalSize; + +in vec3 pos; +in vec3 nor; +in vec3 tan; +in float rad; + +void main() +{ + vec3 final_pos = pos; + + float flip = (gl_InstanceID != 0) ? -1.0 : 1.0; + + if (gl_VertexID % 2 == 0) { + final_pos += normalSize * rad * (flip * nor - tan); + } + + gl_Position = ModelViewProjectionMatrix * vec4(final_pos, 1.0); +} |