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:
parent
2117680094
commit
7a94d4362a
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue