Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/intern/draw_cache_impl_gpencil.c
| Show First 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | typedef struct GpencilBatchCache { | ||||
| GPUVertBuf *edit_vbo; | GPUVertBuf *edit_vbo; | ||||
| GPUBatch *edit_lines_batch; | GPUBatch *edit_lines_batch; | ||||
| GPUBatch *edit_points_batch; | GPUBatch *edit_points_batch; | ||||
| /** Cache is dirty */ | /** Cache is dirty */ | ||||
| bool is_dirty; | bool is_dirty; | ||||
| /** Last cache frame */ | /** Last cache frame */ | ||||
| int cache_frame; | int cache_frame; | ||||
| /** Actual View Layer */ | |||||
| ViewLayer *view_layer; | |||||
| } GpencilBatchCache; | } GpencilBatchCache; | ||||
| static bool gpencil_batch_cache_valid(GpencilBatchCache *cache, bGPdata *gpd, int cfra) | static bool gpencil_batch_cache_valid(GpencilBatchCache *cache, bGPdata *gpd, int cfra) | ||||
| { | { | ||||
| bool valid = true; | bool valid = true; | ||||
| if (cache == NULL) { | if (cache == NULL) { | ||||
| return false; | return false; | ||||
| Show All 10 Lines | static bool gpencil_batch_cache_valid(GpencilBatchCache *cache, bGPdata *gpd, int cfra) | ||||
| } | } | ||||
| return valid; | return valid; | ||||
| } | } | ||||
| static GpencilBatchCache *gpencil_batch_cache_init(Object *ob, int cfra) | static GpencilBatchCache *gpencil_batch_cache_init(Object *ob, int cfra) | ||||
| { | { | ||||
| bGPdata *gpd = (bGPdata *)ob->data; | bGPdata *gpd = (bGPdata *)ob->data; | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | |||||
| GpencilBatchCache *cache = gpd->runtime.gpencil_cache; | GpencilBatchCache *cache = gpd->runtime.gpencil_cache; | ||||
| if (!cache) { | if (!cache) { | ||||
| cache = gpd->runtime.gpencil_cache = MEM_callocN(sizeof(*cache), __func__); | cache = gpd->runtime.gpencil_cache = MEM_callocN(sizeof(*cache), __func__); | ||||
| } | } | ||||
| else { | else { | ||||
| memset(cache, 0, sizeof(*cache)); | memset(cache, 0, sizeof(*cache)); | ||||
| } | } | ||||
| cache->is_dirty = true; | cache->is_dirty = true; | ||||
| cache->cache_frame = cfra; | cache->cache_frame = cfra; | ||||
| /* View layer is only used in final render image for filtering gp layer. */ | |||||
| cache->view_layer = DRW_state_is_image_render() ? draw_ctx->view_layer : NULL; | |||||
| return cache; | return cache; | ||||
| } | } | ||||
| static void gpencil_batch_cache_clear(GpencilBatchCache *cache) | static void gpencil_batch_cache_clear(GpencilBatchCache *cache) | ||||
| { | { | ||||
| if (!cache) { | if (!cache) { | ||||
| return; | return; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 247 Lines • ▼ Show 20 Lines | static void gp_object_verts_count_cb(bGPDlayer *UNUSED(gpl), | ||||
| gps->runtime.fill_start = iter->tri_len; | gps->runtime.fill_start = iter->tri_len; | ||||
| iter->vert_len += gps->totpoints + 2 + gpencil_stroke_is_cyclic(gps); | iter->vert_len += gps->totpoints + 2 + gpencil_stroke_is_cyclic(gps); | ||||
| iter->tri_len += gps->tot_triangles; | iter->tri_len += gps->tot_triangles; | ||||
| } | } | ||||
| static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache, int cfra) | static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache, int cfra) | ||||
| { | { | ||||
| bGPdata *gpd = (bGPdata *)ob->data; | bGPdata *gpd = (bGPdata *)ob->data; | ||||
fclem: not sure you want to hide inside the batch creation. | |||||
| if (cache->vbo == NULL) { | if (cache->vbo == NULL) { | ||||
| /* Should be discarded together. */ | /* Should be discarded together. */ | ||||
| BLI_assert(cache->vbo == NULL && cache->ibo == NULL); | BLI_assert(cache->vbo == NULL && cache->ibo == NULL); | ||||
| BLI_assert(cache->stroke_batch == NULL && cache->stroke_batch == NULL); | BLI_assert(cache->stroke_batch == NULL && cache->stroke_batch == NULL); | ||||
| /* TODO/PERF: Could be changed to only do it if needed. | /* TODO/PERF: Could be changed to only do it if needed. | ||||
| * For now it's simpler to assume we always need it | * For now it's simpler to assume we always need it | ||||
| * since multiple viewport could or could not need it. | * since multiple viewport could or could not need it. | ||||
| * Ideally we should have a dedicated onion skin geom batch. */ | * Ideally we should have a dedicated onion skin geom batch. */ | ||||
| /* IMPORTANT: Keep in sync with gpencil_edit_batches_ensure() */ | /* IMPORTANT: Keep in sync with gpencil_edit_batches_ensure() */ | ||||
| bool do_onion = true; | bool do_onion = true; | ||||
| /* First count how many vertices and triangles are needed for the whole object. */ | /* First count how many vertices and triangles are needed for the whole object. */ | ||||
| gpIterData iter = { | gpIterData iter = { | ||||
| .gpd = gpd, | .gpd = gpd, | ||||
| .verts = NULL, | .verts = NULL, | ||||
| .ibo = {0}, | .ibo = {0}, | ||||
| .vert_len = 1, /* Start at 1 for the gl_InstanceID trick to work (see vert shader). */ | .vert_len = 1, /* Start at 1 for the gl_InstanceID trick to work (see vert shader). */ | ||||
| .tri_len = 0, | .tri_len = 0, | ||||
| }; | }; | ||||
| BKE_gpencil_visible_stroke_iter(ob, NULL, gp_object_verts_count_cb, &iter, do_onion, cfra); | BKE_gpencil_visible_stroke_iter( | ||||
| cache->view_layer, ob, NULL, gp_object_verts_count_cb, &iter, do_onion, cfra); | |||||
| /* Create VBOs. */ | /* Create VBOs. */ | ||||
| GPUVertFormat *format = gpencil_stroke_format(); | GPUVertFormat *format = gpencil_stroke_format(); | ||||
| GPUVertFormat *format_col = gpencil_color_format(); | GPUVertFormat *format_col = gpencil_color_format(); | ||||
| cache->vbo = GPU_vertbuf_create_with_format(format); | cache->vbo = GPU_vertbuf_create_with_format(format); | ||||
| cache->vbo_col = GPU_vertbuf_create_with_format(format_col); | cache->vbo_col = GPU_vertbuf_create_with_format(format_col); | ||||
| /* Add extra space at the end of the buffer because of quad load. */ | /* Add extra space at the end of the buffer because of quad load. */ | ||||
| GPU_vertbuf_data_alloc(cache->vbo, iter.vert_len + 2); | GPU_vertbuf_data_alloc(cache->vbo, iter.vert_len + 2); | ||||
| GPU_vertbuf_data_alloc(cache->vbo_col, iter.vert_len + 2); | GPU_vertbuf_data_alloc(cache->vbo_col, iter.vert_len + 2); | ||||
| iter.verts = (gpStrokeVert *)cache->vbo->data; | iter.verts = (gpStrokeVert *)cache->vbo->data; | ||||
| iter.cols = (gpColorVert *)cache->vbo_col->data; | iter.cols = (gpColorVert *)cache->vbo_col->data; | ||||
| /* Create IBO. */ | /* Create IBO. */ | ||||
| GPU_indexbuf_init(&iter.ibo, GPU_PRIM_TRIS, iter.tri_len, iter.vert_len); | GPU_indexbuf_init(&iter.ibo, GPU_PRIM_TRIS, iter.tri_len, iter.vert_len); | ||||
| /* Fill buffers with data. */ | /* Fill buffers with data. */ | ||||
| BKE_gpencil_visible_stroke_iter(ob, NULL, gpencil_stroke_iter_cb, &iter, do_onion, cfra); | BKE_gpencil_visible_stroke_iter( | ||||
| cache->view_layer, ob, NULL, gpencil_stroke_iter_cb, &iter, do_onion, cfra); | |||||
| /* Mark last 2 verts as invalid. */ | /* Mark last 2 verts as invalid. */ | ||||
| for (int i = 0; i < 2; i++) { | for (int i = 0; i < 2; i++) { | ||||
| iter.verts[iter.vert_len + i].mat = -1; | iter.verts[iter.vert_len + i].mat = -1; | ||||
| } | } | ||||
| /* Finish the IBO. */ | /* Finish the IBO. */ | ||||
| cache->ibo = GPU_indexbuf_build(&iter.ibo); | cache->ibo = GPU_indexbuf_build(&iter.ibo); | ||||
| Show All 40 Lines | for (int i = start; i < end; i++) { | ||||
| GPU_indexbuf_add_generic_vert(&iter->ibo, i); | GPU_indexbuf_add_generic_vert(&iter->ibo, i); | ||||
| } | } | ||||
| GPU_indexbuf_add_primitive_restart(&iter->ibo); | GPU_indexbuf_add_primitive_restart(&iter->ibo); | ||||
| } | } | ||||
| GPUBatch *DRW_cache_gpencil_face_wireframe_get(Object *ob) | GPUBatch *DRW_cache_gpencil_face_wireframe_get(Object *ob) | ||||
| { | { | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | const DRWContextState *draw_ctx = DRW_context_state_get(); | ||||
| ViewLayer *view_layer = DRW_state_is_image_render() ? draw_ctx->view_layer : NULL; | |||||
| int cfra = DEG_get_ctime(draw_ctx->depsgraph); | int cfra = DEG_get_ctime(draw_ctx->depsgraph); | ||||
| GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra); | GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra); | ||||
| gpencil_batches_ensure(ob, cache, cfra); | gpencil_batches_ensure(ob, cache, cfra); | ||||
| if (cache->lines_batch == NULL) { | if (cache->lines_batch == NULL) { | ||||
| GPUVertBuf *vbo = cache->vbo; | GPUVertBuf *vbo = cache->vbo; | ||||
| gpIterData iter = { | gpIterData iter = { | ||||
| .gpd = ob->data, | .gpd = ob->data, | ||||
| .ibo = {0}, | .ibo = {0}, | ||||
| }; | }; | ||||
| GPU_indexbuf_init_ex(&iter.ibo, GPU_PRIM_LINE_STRIP, vbo->vertex_len, vbo->vertex_len); | GPU_indexbuf_init_ex(&iter.ibo, GPU_PRIM_LINE_STRIP, vbo->vertex_len, vbo->vertex_len); | ||||
| /* IMPORTANT: Keep in sync with gpencil_edit_batches_ensure() */ | /* IMPORTANT: Keep in sync with gpencil_edit_batches_ensure() */ | ||||
| bool do_onion = true; | bool do_onion = true; | ||||
| BKE_gpencil_visible_stroke_iter(ob, NULL, gp_lines_indices_cb, &iter, do_onion, cfra); | BKE_gpencil_visible_stroke_iter( | ||||
| view_layer, ob, NULL, gp_lines_indices_cb, &iter, do_onion, cfra); | |||||
| GPUIndexBuf *ibo = GPU_indexbuf_build(&iter.ibo); | GPUIndexBuf *ibo = GPU_indexbuf_build(&iter.ibo); | ||||
| cache->lines_batch = GPU_batch_create_ex(GPU_PRIM_LINE_STRIP, vbo, ibo, GPU_BATCH_OWNS_INDEX); | cache->lines_batch = GPU_batch_create_ex(GPU_PRIM_LINE_STRIP, vbo, ibo, GPU_BATCH_OWNS_INDEX); | ||||
| } | } | ||||
| return cache->lines_batch; | return cache->lines_batch; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 232 Lines • ▼ Show 20 Lines | if (cache->edit_vbo == NULL) { | ||||
| /* Create VBO. */ | /* Create VBO. */ | ||||
| GPUVertFormat *format = gpencil_edit_stroke_format(); | GPUVertFormat *format = gpencil_edit_stroke_format(); | ||||
| cache->edit_vbo = GPU_vertbuf_create_with_format(format); | cache->edit_vbo = GPU_vertbuf_create_with_format(format); | ||||
| /* Add extra space at the end of the buffer because of quad load. */ | /* Add extra space at the end of the buffer because of quad load. */ | ||||
| GPU_vertbuf_data_alloc(cache->edit_vbo, vert_len); | GPU_vertbuf_data_alloc(cache->edit_vbo, vert_len); | ||||
| iter.verts = (gpEditVert *)cache->edit_vbo->data; | iter.verts = (gpEditVert *)cache->edit_vbo->data; | ||||
| /* Fill buffers with data. */ | /* Fill buffers with data. */ | ||||
| BKE_gpencil_visible_stroke_iter(ob, NULL, gpencil_edit_stroke_iter_cb, &iter, do_onion, cfra); | BKE_gpencil_visible_stroke_iter( | ||||
| NULL, ob, NULL, gpencil_edit_stroke_iter_cb, &iter, do_onion, cfra); | |||||
| /* Create the batches */ | /* Create the batches */ | ||||
| cache->edit_points_batch = GPU_batch_create(GPU_PRIM_POINTS, cache->vbo, NULL); | cache->edit_points_batch = GPU_batch_create(GPU_PRIM_POINTS, cache->vbo, NULL); | ||||
| GPU_batch_vertbuf_add(cache->edit_points_batch, cache->edit_vbo); | GPU_batch_vertbuf_add(cache->edit_points_batch, cache->edit_vbo); | ||||
| cache->edit_lines_batch = GPU_batch_create(GPU_PRIM_LINE_STRIP, cache->vbo, NULL); | cache->edit_lines_batch = GPU_batch_create(GPU_PRIM_LINE_STRIP, cache->vbo, NULL); | ||||
| GPU_batch_vertbuf_add(cache->edit_lines_batch, cache->edit_vbo); | GPU_batch_vertbuf_add(cache->edit_lines_batch, cache->edit_vbo); | ||||
| Show All 24 Lines | |||||
not sure you want to hide inside the batch creation.