DRW: Opti: Make cursor use batch instead of immediate API.

This is also much cleaner and taking 1 drawcall instead of 2.
This commit is contained in:
Clément Foucault 2018-03-27 23:50:26 +02:00
parent 2117680094
commit 7a94d4362a
3 changed files with 104 additions and 53 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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];
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) {
const float f5 = 0.25f;
const float f10 = 0.5f;
const float f20 = 1.0f;
ED_region_pixelspace(ar);
gpuTranslate2f(co[0], co[1]);
gpuScale2f(U.widget_unit, U.widget_unit);
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);
/* 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);
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();
}
}