From 7a94d4362afbe64f3fcf2bd7e89601a7ea54cb98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 27 Mar 2018 23:50:26 +0200 Subject: DRW: Opti: Make cursor use batch instead of immediate API. This is also much cleaner and taking 1 drawcall instead of 2. --- source/blender/draw/intern/draw_cache.c | 91 +++++++++++++++++++++++++++++++++ source/blender/draw/intern/draw_cache.h | 3 ++ source/blender/draw/intern/draw_view.c | 63 ++++------------------- 3 files changed, 104 insertions(+), 53 deletions(-) (limited to 'source/blender/draw') diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 6b1a3356b51..8fdf1a2fce7 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -32,6 +32,8 @@ #include "DNA_modifier_types.h" #include "DNA_lattice_types.h" +#include "UI_resources.h" + #include "BLI_utildefines.h" #include "BLI_math.h" @@ -43,6 +45,7 @@ /* Batch's only (free'd as an array) */ static struct DRWShapeCache { Gwn_Batch *drw_single_vertice; + Gwn_Batch *drw_cursor; Gwn_Batch *drw_fullscreen_quad; Gwn_Batch *drw_quad; Gwn_Batch *drw_sphere; @@ -2709,3 +2712,91 @@ Gwn_Batch *DRW_cache_particles_get_prim(int type) return NULL; } + +/* 3D cursor */ +Gwn_Batch *DRW_cache_cursor_get(void) +{ + if (!SHC.drw_cursor) { + const float f5 = 0.25f; + const float f10 = 0.5f; + const float f20 = 1.0f; + + const int segments = 16; + const int vert_ct = segments + 8; + const int index_ct = vert_ct + 5; + + unsigned char red[3] = {255, 0, 0}; + unsigned char white[3] = {255, 255, 255}; + unsigned char crosshair_color[3]; + UI_GetThemeColor3ubv(TH_VIEW_OVERLAY, crosshair_color); + + static Gwn_VertFormat format = { 0 }; + static struct { uint pos, color; } attr_id; + if (format.attrib_ct == 0) { + attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + attr_id.color = GWN_vertformat_attr_add(&format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + } + + Gwn_IndexBufBuilder elb; + GWN_indexbuf_init_ex(&elb, GWN_PRIM_LINE_STRIP, index_ct, vert_ct, true); + + Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); + GWN_vertbuf_data_alloc(vbo, vert_ct); + + int v = 0; + for (int i = 0; i < segments; ++i) { + float angle = (float)(2 * M_PI) * ((float)i / (float)segments); + float x = f10 * cosf(angle); + float y = f10 * sinf(angle); + + if (i % 2 == 0) + GWN_vertbuf_attr_set(vbo, attr_id.color, v, red); + else + GWN_vertbuf_attr_set(vbo, attr_id.color, v, white); + + GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){x, y}); + GWN_indexbuf_add_generic_vert(&elb, v++); + } + GWN_indexbuf_add_generic_vert(&elb, 0); + GWN_indexbuf_add_primitive_restart(&elb); + + GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){-f20, 0}); + GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GWN_indexbuf_add_generic_vert(&elb, v++); + GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){-f5, 0}); + GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GWN_indexbuf_add_generic_vert(&elb, v++); + + GWN_indexbuf_add_primitive_restart(&elb); + + GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){+f5, 0}); + GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GWN_indexbuf_add_generic_vert(&elb, v++); + GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){+f20, 0}); + GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GWN_indexbuf_add_generic_vert(&elb, v++); + + GWN_indexbuf_add_primitive_restart(&elb); + + GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, -f20}); + GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GWN_indexbuf_add_generic_vert(&elb, v++); + GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, -f5}); + GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GWN_indexbuf_add_generic_vert(&elb, v++); + + GWN_indexbuf_add_primitive_restart(&elb); + + GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, +f5}); + GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GWN_indexbuf_add_generic_vert(&elb, v++); + GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, +f20}); + GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GWN_indexbuf_add_generic_vert(&elb, v++); + + Gwn_IndexBuf *ibo = GWN_indexbuf_build(&elb); + + SHC.drw_cursor = GWN_batch_create_ex(GWN_PRIM_LINE_STRIP, vbo, ibo, GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX); + } + return SHC.drw_cursor; +} \ No newline at end of file diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index c039bb8883d..60c41ddc798 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -33,6 +33,9 @@ struct ModifierData; void DRW_shape_cache_free(void); +/* 3D cursor */ +struct Gwn_Batch *DRW_cache_cursor_get(void); + /* Common Shapes */ struct Gwn_Batch *DRW_cache_fullscreen_quad_get(void); struct Gwn_Batch *DRW_cache_quad_get(void); diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index d9ffbde38e7..f38a7689c06 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -645,7 +645,7 @@ void DRW_draw_cursor(void) { const DRWContextState *draw_ctx = DRW_context_state_get(); View3D *v3d = draw_ctx->v3d; - RegionView3D *rv3d = draw_ctx->rv3d; + ARegion *ar = draw_ctx->ar; Scene *scene = draw_ctx->scene; ViewLayer *view_layer = draw_ctx->view_layer; @@ -655,61 +655,18 @@ void DRW_draw_cursor(void) glLineWidth(1.0f); if (is_cursor_visible(draw_ctx, scene, view_layer)) { - float *co = ED_view3d_cursor3d_get(scene, v3d); - unsigned char crosshair_color[3]; - - const float f5 = 0.25f; - const float f10 = 0.5f; - const float f20 = 1.0f; - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - unsigned int wpos = GWN_vertformat_attr_add(format, "world_pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + int co[2]; + if (ED_view3d_project_int_global(ar, ED_view3d_cursor3d_get(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { - /* XXX Using instance shader without instance */ - immBindBuiltinProgram(GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR); - immUniform1f("size", U.widget_unit); - immUniform1f("pixel_size", *DRW_viewport_pixelsize_get()); - immUniformArray3fv("screen_vecs", DRW_viewport_screenvecs_get(), 2); - immUniformMatrix4fv("ViewProjectionMatrix", rv3d->persmat); + ED_region_pixelspace(ar); + gpuTranslate2f(co[0], co[1]); + gpuScale2f(U.widget_unit, U.widget_unit); - const int segments = 16; - - immBegin(GWN_PRIM_LINE_LOOP, segments); - immAttrib3fv(wpos, co); - - for (int i = 0; i < segments; ++i) { - float angle = (float)(2 * M_PI) * ((float)i / (float)segments); - float x = f10 * cosf(angle); - float y = f10 * sinf(angle); - - if (i % 2 == 0) - immAttrib3ub(color, 255, 0, 0); - else - immAttrib3ub(color, 255, 255, 255); - - immVertex2f(pos, x, y); + Gwn_Batch *cursor_batch = DRW_cache_cursor_get(); + GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_FLAT_COLOR); + GWN_batch_program_set(cursor_batch, GPU_shader_get_program(shader), GPU_shader_get_interface(shader)); + GWN_batch_draw(cursor_batch); } - immEnd(); - - UI_GetThemeColor3ubv(TH_VIEW_OVERLAY, crosshair_color); - - immBegin(GWN_PRIM_LINES, 8); - immAttrib3ubv(color, crosshair_color); - immAttrib3fv(wpos, co); - - immVertex2f(pos, -f20, 0); - immVertex2f(pos, -f5, 0); - immVertex2f(pos, +f5, 0); - immVertex2f(pos, +f20, 0); - immVertex2f(pos, 0, -f20); - immVertex2f(pos, 0, -f5); - immVertex2f(pos, 0, +f5); - immVertex2f(pos, 0, +f20); - immEnd(); - - immUnbindProgram(); } } -- cgit v1.2.3