diff options
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r-- | source/blender/draw/intern/draw_cache.h | 11 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_gpencil.cc | 189 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_data.cc | 6 | ||||
-rw-r--r-- | source/blender/draw/intern/shaders/common_gpencil_lib.glsl | 88 | ||||
-rw-r--r-- | source/blender/draw/intern/shaders/draw_view_info.hh | 17 |
5 files changed, 153 insertions, 158 deletions
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 058f28f094d..44abf3c7064 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -13,6 +13,7 @@ extern "C" { struct GPUBatch; struct GPUMaterial; +struct GPUVertBuf; struct ModifierData; struct Object; struct PTCacheEdit; @@ -257,14 +258,16 @@ struct GPUBatch *DRW_cache_volume_selection_surface_get(struct Object *ob); /* GPencil */ -struct GPUBatch *DRW_cache_gpencil_strokes_get(struct Object *ob, int cfra); -struct GPUBatch *DRW_cache_gpencil_fills_get(struct Object *ob, int cfra); +struct GPUBatch *DRW_cache_gpencil_get(struct Object *ob, int cfra); +struct GPUVertBuf *DRW_cache_gpencil_position_buffer_get(struct Object *ob, int cfra); +struct GPUVertBuf *DRW_cache_gpencil_color_buffer_get(struct Object *ob, int cfra); struct GPUBatch *DRW_cache_gpencil_edit_lines_get(struct Object *ob, int cfra); struct GPUBatch *DRW_cache_gpencil_edit_points_get(struct Object *ob, int cfra); struct GPUBatch *DRW_cache_gpencil_edit_curve_handles_get(struct Object *ob, int cfra); struct GPUBatch *DRW_cache_gpencil_edit_curve_points_get(struct Object *ob, int cfra); -struct GPUBatch *DRW_cache_gpencil_sbuffer_stroke_get(struct Object *ob); -struct GPUBatch *DRW_cache_gpencil_sbuffer_fill_get(struct Object *ob); +struct GPUBatch *DRW_cache_gpencil_sbuffer_get(struct Object *ob); +struct GPUVertBuf *DRW_cache_gpencil_sbuffer_position_buffer_get(struct Object *ob); +struct GPUVertBuf *DRW_cache_gpencil_sbuffer_color_buffer_get(struct Object *ob); int DRW_gpencil_material_count_get(struct bGPdata *gpd); struct GPUBatch *DRW_cache_gpencil_face_wireframe_get(struct Object *ob); diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.cc b/source/blender/draw/intern/draw_cache_impl_gpencil.cc index 94925bfae71..eadb7772f4c 100644 --- a/source/blender/draw/intern/draw_cache_impl_gpencil.cc +++ b/source/blender/draw/intern/draw_cache_impl_gpencil.cc @@ -23,12 +23,14 @@ #include "DEG_depsgraph_query.h" #include "BLI_hash.h" +#include "BLI_math_vec_types.hh" #include "BLI_polyfill_2d.h" #include "draw_cache.h" #include "draw_cache_impl.h" #include "../engines/gpencil/gpencil_defines.h" +#include "../engines/gpencil/gpencil_shader_shared.h" #define BEZIER_HANDLE (1 << 3) #define COLOR_SHIFT 5 @@ -41,11 +43,13 @@ typedef struct GpencilBatchCache { /** Instancing Data */ GPUVertBuf *vbo; GPUVertBuf *vbo_col; - /** Fill Topology */ + /** Indices in material order, then stroke order with fill first. + * Strokes can be individually rendered using `gps->runtime.stroke_start` and + * `gps->runtime.stroke_start`. */ GPUIndexBuf *ibo; - /** Instancing Batches */ - GPUBatch *stroke_batch; - GPUBatch *fill_batch; + /** Batches */ + GPUBatch *geom_batch; + /** Stroke lines only */ GPUBatch *lines_batch; /** Edit Mode */ @@ -117,8 +121,7 @@ static void gpencil_batch_cache_clear(GpencilBatchCache *cache) } GPU_BATCH_DISCARD_SAFE(cache->lines_batch); - GPU_BATCH_DISCARD_SAFE(cache->fill_batch); - GPU_BATCH_DISCARD_SAFE(cache->stroke_batch); + GPU_BATCH_DISCARD_SAFE(cache->geom_batch); GPU_VERTBUF_DISCARD_SAFE(cache->vbo); GPU_VERTBUF_DISCARD_SAFE(cache->vbo_col); GPU_INDEXBUF_DISCARD_SAFE(cache->ibo); @@ -173,9 +176,10 @@ void DRW_gpencil_batch_cache_free(bGPdata *gpd) /* MUST match the format below. */ typedef struct gpStrokeVert { - int32_t mat, stroke_id, point_id, packed_asp_hard_rot; /** Position and thickness packed in the same attribute. */ float pos[3], thickness; + /** Material Index, Stroke Index, Point Index, Packed aspect + hardness + rotation. */ + int32_t mat, stroke_id, point_id, packed_asp_hard_rot; /** UV and strength packed in the same attribute. */ float uv_fill[2], u_stroke, strength; } gpStrokeVert; @@ -184,12 +188,9 @@ static GPUVertFormat *gpencil_stroke_format(void) { static GPUVertFormat format = {0}; if (format.attr_len == 0) { - GPU_vertformat_attr_add(&format, "ma", GPU_COMP_I32, 4, GPU_FETCH_INT); GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + GPU_vertformat_attr_add(&format, "ma", GPU_COMP_I32, 4, GPU_FETCH_INT); GPU_vertformat_attr_add(&format, "uv", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - /* IMPORTANT: This means having only 4 attributes - * to fit into GPU module limit of 16 attributes. */ - GPU_vertformat_multiload_enable(&format, 4); } return &format; } @@ -239,9 +240,6 @@ static GPUVertFormat *gpencil_color_format(void) if (format.attr_len == 0) { GPU_vertformat_attr_add(&format, "col", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); GPU_vertformat_attr_add(&format, "fcol", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - /* IMPORTANT: This means having only 4 attributes - * to fit into GPU module limit of 16 attributes. */ - GPU_vertformat_multiload_enable(&format, 4); } return &format; } @@ -296,7 +294,8 @@ BLI_INLINE int32_t pack_rotation_aspect_hardness(float rot, float asp, float har return packed; } -static void gpencil_buffer_add_point(gpStrokeVert *verts, +static void gpencil_buffer_add_point(GPUIndexBufBuilder *ibo, + gpStrokeVert *verts, gpColorVert *cols, const bGPDstroke *gps, const bGPDspoint *pt, @@ -330,27 +329,36 @@ static void gpencil_buffer_add_point(gpStrokeVert *verts, vert->packed_asp_hard_rot = pack_rotation_aspect_hardness( pt->uv_rot, aspect_ratio, gps->hardeness); + + if (!is_endpoint) { + /* Issue a Quad per point. */ + /* The attribute loading uses a different shader and will undo this bit packing. */ + int v_mat = (v << GP_VERTEX_ID_SHIFT) | GP_IS_STROKE_VERTEX_BIT; + GPU_indexbuf_add_tri_verts(ibo, v_mat + 0, v_mat + 1, v_mat + 2); + GPU_indexbuf_add_tri_verts(ibo, v_mat + 2, v_mat + 1, v_mat + 3); + } } -static void gpencil_buffer_add_stroke(gpStrokeVert *verts, +static void gpencil_buffer_add_stroke(GPUIndexBufBuilder *ibo, + gpStrokeVert *verts, gpColorVert *cols, const bGPDstroke *gps) { const bGPDspoint *pts = gps->points; int pts_len = gps->totpoints; bool is_cyclic = gpencil_stroke_is_cyclic(gps); - int v = gps->runtime.stroke_start; + int v = gps->runtime.vertex_start; /* First point for adjacency (not drawn). */ int adj_idx = (is_cyclic) ? (pts_len - 1) : min_ii(pts_len - 1, 1); - gpencil_buffer_add_point(verts, cols, gps, &pts[adj_idx], v++, true); + gpencil_buffer_add_point(ibo, verts, cols, gps, &pts[adj_idx], v++, true); for (int i = 0; i < pts_len; i++) { - gpencil_buffer_add_point(verts, cols, gps, &pts[i], v++, false); + gpencil_buffer_add_point(ibo, verts, cols, gps, &pts[i], v++, false); } /* Draw line to first point to complete the loop for cyclic strokes. */ if (is_cyclic) { - gpencil_buffer_add_point(verts, cols, gps, &pts[0], v, false); + gpencil_buffer_add_point(ibo, verts, cols, gps, &pts[0], v, false); /* UV factor needs to be adjusted for the last point to not be equal to the UV factor of the * first point. It should be the factor of the last point plus the distance from the last point * to the first. @@ -361,16 +369,20 @@ static void gpencil_buffer_add_stroke(gpStrokeVert *verts, } /* Last adjacency point (not drawn). */ adj_idx = (is_cyclic) ? 1 : max_ii(0, pts_len - 2); - gpencil_buffer_add_point(verts, cols, gps, &pts[adj_idx], v++, true); + gpencil_buffer_add_point(ibo, verts, cols, gps, &pts[adj_idx], v++, true); } static void gpencil_buffer_add_fill(GPUIndexBufBuilder *ibo, const bGPDstroke *gps) { int tri_len = gps->tot_triangles; - int v = gps->runtime.stroke_start; + int v = gps->runtime.vertex_start + 1; for (int i = 0; i < tri_len; i++) { uint *tri = gps->triangles[i].verts; - GPU_indexbuf_add_tri_verts(ibo, v + tri[0], v + tri[1], v + tri[2]); + /* The attribute loading uses a different shader and will undo this bit packing. */ + GPU_indexbuf_add_tri_verts(ibo, + (v + tri[0]) << GP_VERTEX_ID_SHIFT, + (v + tri[1]) << GP_VERTEX_ID_SHIFT, + (v + tri[2]) << GP_VERTEX_ID_SHIFT); } } @@ -380,10 +392,10 @@ static void gpencil_stroke_iter_cb(bGPDlayer *UNUSED(gpl), void *thunk) { gpIterData *iter = (gpIterData *)thunk; - gpencil_buffer_add_stroke(iter->verts, iter->cols, gps); if (gps->tot_triangles > 0) { gpencil_buffer_add_fill(&iter->ibo, gps); } + gpencil_buffer_add_stroke(&iter->ibo, iter->verts, iter->cols, gps); } static void gpencil_object_verts_count_cb(bGPDlayer *UNUSED(gpl), @@ -392,12 +404,15 @@ static void gpencil_object_verts_count_cb(bGPDlayer *UNUSED(gpl), void *thunk) { gpIterData *iter = (gpIterData *)thunk; - - /* Store first index offset */ - gps->runtime.stroke_start = iter->vert_len; + int stroke_vert_len = gps->totpoints + gpencil_stroke_is_cyclic(gps); + gps->runtime.vertex_start = iter->vert_len; + /* Add additional padding at the start and end. */ + iter->vert_len += 1 + stroke_vert_len + 1; + /* Store first index offset. */ gps->runtime.fill_start = iter->tri_len; - iter->vert_len += gps->totpoints + 2 + gpencil_stroke_is_cyclic(gps); iter->tri_len += gps->tot_triangles; + gps->runtime.stroke_start = iter->tri_len; + iter->tri_len += stroke_vert_len * 2; } static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache, int cfra) @@ -407,7 +422,7 @@ static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache, int cfr if (cache->vbo == NULL) { /* Should be discarded together. */ BLI_assert(cache->vbo == NULL && cache->ibo == NULL); - BLI_assert(cache->fill_batch == NULL && cache->stroke_batch == NULL); + BLI_assert(cache->geom_batch == NULL); /* TODO/PERF: Could be changed to only do it if needed. * For now it's simpler to assume we always need it * since multiple viewport could or could not need it. @@ -420,25 +435,26 @@ static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache, int cfr .gpd = gpd, .verts = NULL, .ibo = {0}, - .vert_len = 1, /* Start at 1 for the gl_InstanceID trick to work (see vert shader). */ + .vert_len = 0, .tri_len = 0, .curve_len = 0, }; BKE_gpencil_visible_stroke_advanced_iter( NULL, ob, NULL, gpencil_object_verts_count_cb, &iter, do_onion, cfra); + GPUUsageType vbo_flag = GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY; /* Create VBOs. */ GPUVertFormat *format = gpencil_stroke_format(); GPUVertFormat *format_col = gpencil_color_format(); - cache->vbo = GPU_vertbuf_create_with_format(format); - cache->vbo_col = GPU_vertbuf_create_with_format(format_col); + cache->vbo = GPU_vertbuf_create_with_format_ex(format, vbo_flag); + cache->vbo_col = GPU_vertbuf_create_with_format_ex(format_col, vbo_flag); /* 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_col, iter.vert_len + 2); iter.verts = (gpStrokeVert *)GPU_vertbuf_get_data(cache->vbo); iter.cols = (gpColorVert *)GPU_vertbuf_get_data(cache->vbo_col); /* 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, 0xFFFFFFFFu); /* Fill buffers with data. */ BKE_gpencil_visible_stroke_advanced_iter( @@ -453,33 +469,39 @@ static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache, int cfr /* Finish the IBO. */ cache->ibo = GPU_indexbuf_build(&iter.ibo); - /* Create the batches */ - cache->fill_batch = GPU_batch_create(GPU_PRIM_TRIS, cache->vbo, cache->ibo); - GPU_batch_vertbuf_add(cache->fill_batch, cache->vbo_col); - cache->stroke_batch = GPU_batch_create(GPU_PRIM_TRI_STRIP, gpencil_dummy_buffer_get(), NULL); - GPU_batch_instbuf_add_ex(cache->stroke_batch, cache->vbo, 0); - GPU_batch_instbuf_add_ex(cache->stroke_batch, cache->vbo_col, 0); + cache->geom_batch = GPU_batch_create(GPU_PRIM_TRIS, cache->vbo, cache->ibo); + /* Allow creation of buffer texture. */ + GPU_vertbuf_use(cache->vbo); + GPU_vertbuf_use(cache->vbo_col); gpd->flag &= ~GP_DATA_CACHE_IS_DIRTY; cache->is_dirty = false; } } -GPUBatch *DRW_cache_gpencil_strokes_get(Object *ob, int cfra) +GPUBatch *DRW_cache_gpencil_get(Object *ob, int cfra) { GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra); gpencil_batches_ensure(ob, cache, cfra); - return cache->stroke_batch; + return cache->geom_batch; } -GPUBatch *DRW_cache_gpencil_fills_get(Object *ob, int cfra) +GPUVertBuf *DRW_cache_gpencil_position_buffer_get(Object *ob, int cfra) { GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra); gpencil_batches_ensure(ob, cache, cfra); - return cache->fill_batch; + return cache->vbo; +} + +GPUVertBuf *DRW_cache_gpencil_color_buffer_get(Object *ob, int cfra) +{ + GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra); + gpencil_batches_ensure(ob, cache, cfra); + + return cache->vbo_col; } static void gpencil_lines_indices_cb(bGPDlayer *UNUSED(gpl), @@ -490,7 +512,7 @@ static void gpencil_lines_indices_cb(bGPDlayer *UNUSED(gpl), gpIterData *iter = (gpIterData *)thunk; int pts_len = gps->totpoints + gpencil_stroke_is_cyclic(gps); - int start = gps->runtime.stroke_start + 1; + int start = gps->runtime.vertex_start + 1; int end = start + pts_len; for (int i = start; i < end; i++) { GPU_indexbuf_add_generic_vert(&iter->ibo, i); @@ -573,7 +595,7 @@ static void gpencil_sbuffer_stroke_ensure(bGPdata *gpd, bool do_stroke, bool do_ /* DRW_cache_gpencil_sbuffer_stroke_data_get need to have been called previously. */ BLI_assert(gps != NULL); - if (do_stroke && (gpd->runtime.sbuffer_stroke_batch == NULL)) { + if (do_stroke && (gpd->runtime.sbuffer_batch == NULL)) { gps->points = (bGPDspoint *)MEM_mallocN(vert_len * sizeof(*gps->points), __func__); const DRWContextState *draw_ctx = DRW_context_state_get(); @@ -597,35 +619,24 @@ static void gpencil_sbuffer_stroke_ensure(bGPdata *gpd, bool do_stroke, bool do_ /* Calc uv data along the stroke. */ BKE_gpencil_stroke_uv_update(gps); + int vert_len = gps->tot_triangles + (gps->totpoints + gpencil_stroke_is_cyclic(gps)) * 2; + /* Create IBO. */ + GPUIndexBufBuilder ibo_builder; + GPU_indexbuf_init(&ibo_builder, GPU_PRIM_TRIS, vert_len, 0xFFFFFFFFu); /* Create VBO. */ + GPUUsageType vbo_flag = GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY; GPUVertFormat *format = gpencil_stroke_format(); GPUVertFormat *format_color = gpencil_color_format(); - GPUVertBuf *vbo = GPU_vertbuf_create_with_format(format); - GPUVertBuf *vbo_col = GPU_vertbuf_create_with_format(format_color); - /* Add extra space at the end (and start) of the buffer because of quad load and cyclic. */ - GPU_vertbuf_data_alloc(vbo, 1 + vert_len + 1 + 2); - GPU_vertbuf_data_alloc(vbo_col, 1 + vert_len + 1 + 2); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format_ex(format, vbo_flag); + GPUVertBuf *vbo_col = GPU_vertbuf_create_with_format_ex(format_color, vbo_flag); + /* Add extra space at the end the buffer because of quad load and cyclic. */ + GPU_vertbuf_data_alloc(vbo, vert_len + 2); + GPU_vertbuf_data_alloc(vbo_col, vert_len + 2); gpStrokeVert *verts = (gpStrokeVert *)GPU_vertbuf_get_data(vbo); gpColorVert *cols = (gpColorVert *)GPU_vertbuf_get_data(vbo_col); - /* Fill buffers with data. */ - gpencil_buffer_add_stroke(verts, cols, gps); - - GPUBatch *batch = GPU_batch_create(GPU_PRIM_TRI_STRIP, gpencil_dummy_buffer_get(), NULL); - GPU_batch_instbuf_add_ex(batch, vbo, true); - GPU_batch_instbuf_add_ex(batch, vbo_col, true); - - gpd->runtime.sbuffer_stroke_batch = batch; - - MEM_freeN(gps->points); - } - - if (do_fill && (gpd->runtime.sbuffer_fill_batch == NULL)) { - /* Create IBO. */ - GPUIndexBufBuilder ibo_builder; - GPU_indexbuf_init(&ibo_builder, GPU_PRIM_TRIS, gps->tot_triangles, vert_len); - - if (gps->tot_triangles > 0) { + /* Create fill indices. */ + if (do_fill && gps->tot_triangles > 0) { float(*tpoints2d)[2] = (float(*)[2])MEM_mallocN(sizeof(*tpoints2d) * vert_len, __func__); /* Triangulate in 2D. */ for (int i = 0; i < vert_len; i++) { @@ -645,40 +656,56 @@ static void gpencil_sbuffer_stroke_ensure(bGPdata *gpd, bool do_stroke, bool do_ MEM_freeN(tpoints2d); } - GPUIndexBuf *ibo = GPU_indexbuf_build(&ibo_builder); - GPUVertBuf *vbo = gpd->runtime.sbuffer_stroke_batch->inst[0]; - GPUVertBuf *vbo_col = gpd->runtime.sbuffer_stroke_batch->inst[1]; + /* Fill buffers with data. */ + gpencil_buffer_add_stroke(&ibo_builder, verts, cols, gps); + + GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_TRIS, + gpencil_dummy_buffer_get(), + GPU_indexbuf_build(&ibo_builder), + GPU_BATCH_OWNS_INDEX); - GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, ibo, GPU_BATCH_OWNS_INDEX); - GPU_batch_vertbuf_add(batch, vbo_col); + gpd->runtime.sbuffer_position_buf = vbo; + gpd->runtime.sbuffer_color_buf = vbo_col; + gpd->runtime.sbuffer_batch = batch; - gpd->runtime.sbuffer_fill_batch = batch; + MEM_freeN(gps->points); } } -GPUBatch *DRW_cache_gpencil_sbuffer_stroke_get(Object *ob) +GPUBatch *DRW_cache_gpencil_sbuffer_get(Object *ob) +{ + bGPdata *gpd = (bGPdata *)ob->data; + /* Fill batch also need stroke batch to be created (vbo is shared). */ + gpencil_sbuffer_stroke_ensure(gpd, true, true); + + return gpd->runtime.sbuffer_batch; +} + +GPUVertBuf *DRW_cache_gpencil_sbuffer_position_buffer_get(Object *ob) { bGPdata *gpd = (bGPdata *)ob->data; - gpencil_sbuffer_stroke_ensure(gpd, true, false); + /* Fill batch also need stroke batch to be created (vbo is shared). */ + gpencil_sbuffer_stroke_ensure(gpd, true, true); - return gpd->runtime.sbuffer_stroke_batch; + return gpd->runtime.sbuffer_position_buf; } -GPUBatch *DRW_cache_gpencil_sbuffer_fill_get(Object *ob) +GPUVertBuf *DRW_cache_gpencil_sbuffer_color_buffer_get(Object *ob) { bGPdata *gpd = (bGPdata *)ob->data; /* Fill batch also need stroke batch to be created (vbo is shared). */ gpencil_sbuffer_stroke_ensure(gpd, true, true); - return gpd->runtime.sbuffer_fill_batch; + return gpd->runtime.sbuffer_color_buf; } void DRW_cache_gpencil_sbuffer_clear(Object *ob) { bGPdata *gpd = (bGPdata *)ob->data; MEM_SAFE_FREE(gpd->runtime.sbuffer_gps); - GPU_BATCH_DISCARD_SAFE(gpd->runtime.sbuffer_fill_batch); - GPU_BATCH_DISCARD_SAFE(gpd->runtime.sbuffer_stroke_batch); + GPU_BATCH_DISCARD_SAFE(gpd->runtime.sbuffer_batch); + GPU_VERTBUF_DISCARD_SAFE(gpd->runtime.sbuffer_position_buf); + GPU_VERTBUF_DISCARD_SAFE(gpd->runtime.sbuffer_color_buf); } /** \} */ diff --git a/source/blender/draw/intern/draw_manager_data.cc b/source/blender/draw/intern/draw_manager_data.cc index 981206e56fe..b9e0db71122 100644 --- a/source/blender/draw/intern/draw_manager_data.cc +++ b/source/blender/draw/intern/draw_manager_data.cc @@ -589,7 +589,7 @@ void DRW_shgroup_buffer_texture(DRWShadingGroup *shgroup, const char *name, GPUVertBuf *vertex_buffer) { - int location = GPU_shader_get_ssbo(shgroup->shader, name); + int location = GPU_shader_get_texture_binding(shgroup->shader, name); if (location == -1) { return; } @@ -606,7 +606,7 @@ void DRW_shgroup_buffer_texture_ref(DRWShadingGroup *shgroup, const char *name, GPUVertBuf **vertex_buffer) { - int location = GPU_shader_get_ssbo(shgroup->shader, name); + int location = GPU_shader_get_texture_binding(shgroup->shader, name); if (location == -1) { return; } @@ -695,7 +695,7 @@ static void drw_call_obinfos_init(DRWObjectInfos *ob_infos, Object *ob) drw_call_calc_orco(ob, ob_infos->orcotexfac); /* Random float value. */ uint random = (DST.dupli_source) ? - DST.dupli_source->random_id : + DST.dupli_source->random_id : /* TODO(fclem): this is rather costly to do at runtime. Maybe we can * put it in ob->runtime and make depsgraph ensure it is up to date. */ BLI_hash_int_2d(BLI_hash_string(ob->id.name + 2), 0); diff --git a/source/blender/draw/intern/shaders/common_gpencil_lib.glsl b/source/blender/draw/intern/shaders/common_gpencil_lib.glsl index 123c493b572..def841b07aa 100644 --- a/source/blender/draw/intern/shaders/common_gpencil_lib.glsl +++ b/source/blender/draw/intern/shaders/common_gpencil_lib.glsl @@ -90,10 +90,15 @@ float gpencil_clamp_small_stroke_thickness(float thickness, vec4 ndc_pos) #ifdef GPU_VERTEX_SHADER -/* Trick to detect if a drawcall is stroke or fill. - * This does mean that we need to draw an empty stroke segment before starting - * to draw the real stroke segments. */ -# define GPENCIL_IS_STROKE_VERTEX (gl_InstanceID != 0) +int gpencil_stroke_point_id() +{ + return (gl_VertexID & ~GP_IS_STROKE_VERTEX_BIT) >> GP_VERTEX_ID_SHIFT; +} + +bool gpencil_is_stroke_vertex() +{ + return flag_test(gl_VertexID, GP_IS_STROKE_VERTEX_BIT); +} /** * Returns value of gl_Position. @@ -120,20 +125,7 @@ float gpencil_clamp_small_stroke_thickness(float thickness, vec4 ndc_pos) * WARNING: Max attribute count is actually 14 because OSX OpenGL implementation * considers gl_VertexID and gl_InstanceID as vertex attribute. (see T74536) */ -vec4 gpencil_vertex(ivec4 ma, - ivec4 ma1, - ivec4 ma2, - ivec4 ma3, - vec4 pos, - vec4 pos1, - vec4 pos2, - vec4 pos3, - vec4 uv1, - vec4 uv2, - vec4 col1, - vec4 col2, - vec4 fcol1, - vec4 viewport_size, +vec4 gpencil_vertex(vec4 viewport_size, gpMaterialFlag material_flags, vec2 alignment_rot, /* World Position. */ @@ -155,6 +147,24 @@ vec4 gpencil_vertex(ivec4 ma, /* Stroke hardness. */ out float out_hardness) { + int stroke_point_id = (gl_VertexID & ~GP_IS_STROKE_VERTEX_BIT) >> GP_VERTEX_ID_SHIFT; + + /* Attribute Loading. */ + vec4 pos = texelFetch(gp_pos_tx, (stroke_point_id - 1) * 3 + 0); + vec4 pos1 = texelFetch(gp_pos_tx, (stroke_point_id + 0) * 3 + 0); + vec4 pos2 = texelFetch(gp_pos_tx, (stroke_point_id + 1) * 3 + 0); + vec4 pos3 = texelFetch(gp_pos_tx, (stroke_point_id + 2) * 3 + 0); + ivec4 ma = floatBitsToInt(texelFetch(gp_pos_tx, (stroke_point_id - 1) * 3 + 1)); + ivec4 ma1 = floatBitsToInt(texelFetch(gp_pos_tx, (stroke_point_id + 0) * 3 + 1)); + ivec4 ma2 = floatBitsToInt(texelFetch(gp_pos_tx, (stroke_point_id + 1) * 3 + 1)); + ivec4 ma3 = floatBitsToInt(texelFetch(gp_pos_tx, (stroke_point_id + 2) * 3 + 1)); + vec4 uv1 = texelFetch(gp_pos_tx, (stroke_point_id + 0) * 3 + 2); + vec4 uv2 = texelFetch(gp_pos_tx, (stroke_point_id + 1) * 3 + 2); + + vec4 col1 = texelFetch(gp_col_tx, (stroke_point_id + 0) * 2 + 0); + vec4 col2 = texelFetch(gp_col_tx, (stroke_point_id + 1) * 2 + 0); + vec4 fcol1 = texelFetch(gp_col_tx, (stroke_point_id + 0) * 2 + 1); + # define thickness1 pos1.w # define thickness2 pos2.w # define strength1 uv1.w @@ -167,7 +177,7 @@ vec4 gpencil_vertex(ivec4 ma, vec4 out_ndc; - if (GPENCIL_IS_STROKE_VERTEX) { + if (gpencil_is_stroke_vertex()) { bool is_dot = flag_test(material_flags, GP_STROKE_ALIGNMENT); bool is_squares = !flag_test(material_flags, GP_STROKE_DOTS); @@ -177,13 +187,6 @@ vec4 gpencil_vertex(ivec4 ma, is_squares = false; } - /* Endpoints, we discard the vertices. */ - if (ma1.x == -1 || (!is_dot && ma2.x == -1)) { - /* We set the vertex at the camera origin to generate 0 fragments. */ - out_ndc = vec4(0.0, 0.0, -3e36, 0.0); - return out_ndc; - } - /* Avoid using a vertex attribute for quad positioning. */ float x = float(gl_VertexID & 1) * 2.0 - 1.0; /* [-1..1] */ float y = float(gl_VertexID & 2) - 1.0; /* [-1..1] */ @@ -336,8 +339,7 @@ vec4 gpencil_vertex(ivec4 ma, out_N = safe_normalize(N); /* Decode fill opacity. */ - out_color = vec4(fcol1.rgb, floor(fcol1.a / 10.0)); - out_color.a /= 10000.0; + out_color = vec4(fcol1.rgb, floor(fcol1.a / 10.0) / 10000.0); /* We still offset the fills a little to avoid overlaps */ out_ndc.z += 0.000002; @@ -355,20 +357,7 @@ vec4 gpencil_vertex(ivec4 ma, return out_ndc; } -vec4 gpencil_vertex(ivec4 ma, - ivec4 ma1, - ivec4 ma2, - ivec4 ma3, - vec4 pos, - vec4 pos1, - vec4 pos2, - vec4 pos3, - vec4 uv1, - vec4 uv2, - vec4 col1, - vec4 col2, - vec4 fcol1, - vec4 viewport_size, +vec4 gpencil_vertex(vec4 viewport_size, out vec3 out_P, out vec3 out_N, out vec4 out_color, @@ -379,20 +368,7 @@ vec4 gpencil_vertex(ivec4 ma, out vec2 out_thickness, out float out_hardness) { - return gpencil_vertex(ma, - ma1, - ma2, - ma3, - pos, - pos1, - pos2, - pos3, - uv1, - uv2, - col1, - col2, - fcol1, - viewport_size, + return gpencil_vertex(viewport_size, 0u, vec2(1.0, 0.0), out_P, diff --git a/source/blender/draw/intern/shaders/draw_view_info.hh b/source/blender/draw/intern/shaders/draw_view_info.hh index 7b500f66a68..114dbab799f 100644 --- a/source/blender/draw/intern/shaders/draw_view_info.hh +++ b/source/blender/draw/intern/shaders/draw_view_info.hh @@ -122,26 +122,15 @@ GPU_SHADER_CREATE_INFO(draw_volume).additional_info("draw_modelmat", "draw_resou GPU_SHADER_CREATE_INFO(draw_gpencil) .typedef_source("gpencil_shader_shared.h") .define("DRW_GPENCIL_INFO") - .vertex_in(0, Type::IVEC4, "ma") - .vertex_in(1, Type::IVEC4, "ma1") - .vertex_in(2, Type::IVEC4, "ma2") - .vertex_in(3, Type::IVEC4, "ma3") - .vertex_in(4, Type::VEC4, "pos") - .vertex_in(5, Type::VEC4, "pos1") - .vertex_in(6, Type::VEC4, "pos2") - .vertex_in(7, Type::VEC4, "pos3") - .vertex_in(8, Type::VEC4, "uv1") - .vertex_in(9, Type::VEC4, "uv2") - .vertex_in(10, Type::VEC4, "col1") - .vertex_in(11, Type::VEC4, "col2") - .vertex_in(12, Type::VEC4, "fcol1") + .sampler(0, ImageType::FLOAT_BUFFER, "gp_pos_tx") + .sampler(1, ImageType::FLOAT_BUFFER, "gp_col_tx") /* Per Object */ .push_constant(Type::FLOAT, "gpThicknessScale") /* TODO(fclem): Replace with object info. */ .push_constant(Type::FLOAT, "gpThicknessWorldScale") /* TODO(fclem): Same as above. */ .define("gpThicknessIsScreenSpace", "(gpThicknessWorldScale < 0.0)") /* Per Layer */ .push_constant(Type::FLOAT, "gpThicknessOffset") - .additional_info("draw_modelmat", "draw_resource_id_uniform", "draw_object_infos"); + .additional_info("draw_modelmat", "draw_object_infos"); /** \} */ |